blob: 32f42e904e9be6ce344427320495677210973d38 [file] [log] [blame]
Harald Welte923a3bd2009-02-14 12:51:36 +00001
2#include <unistd.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <netinet/in.h>
8#include <arpa/inet.h>
9
10
11#include <openbsc/select.h>
12#include <openbsc/timer.h>
Harald Welte4f361fc2009-02-15 15:32:53 +000013#include <openbsc/ipaccess.h>
Harald Welte37881962009-04-30 15:15:37 +000014#include <openbsc/gsm_data.h>
15
16static const char *idtag_names[] = {
17 [IPAC_IDTAG_SERNR] = "Serial Number",
18 [IPAC_IDTAG_UNITNAME] = "Unit Name",
19 [IPAC_IDTAG_LOCATION1] = "Location 1",
20 [IPAC_IDTAG_LOCATION2] = "Location 2",
21 [IPAC_IDTAG_EQUIPVERS] = "Equipment Version",
22 [IPAC_IDTAG_SWVERSION] = "Software Version",
23 [IPAC_IDTAG_IPADDR] = "IP Address",
24 [IPAC_IDTAG_MACADDR] = "MAC Address",
25 [IPAC_IDTAG_UNIT] = "Unit ID",
26};
27
28static const char *ipac_idtag_name(int tag)
29{
30 if (tag >= ARRAY_SIZE(idtag_names))
31 return "unknown";
32
33 return idtag_names[tag];
34}
Harald Welte923a3bd2009-02-14 12:51:36 +000035
36static int udp_sock(void)
37{
38 int fd, rc, bc = 1;
39 struct sockaddr_in sa;
40
41 fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
42 if (fd < 0)
43 return fd;
44
45 sa.sin_family = AF_INET;
46 sa.sin_port = htons(3006);
47 sa.sin_addr.s_addr = INADDR_ANY;
48 inet_aton("192.168.100.11", &sa.sin_addr);
49
50 rc = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
51 if (rc < 0)
52 goto err;
53
54 rc = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &bc, sizeof(bc));
55 if (rc < 0)
56 goto err;
57
58#if 0
59 rc = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
60 if (rc < 0)
61 goto err;
62#endif
63 return fd;
64
65err:
66 close(fd);
67 return rc;
68}
69
Harald Welte4f361fc2009-02-15 15:32:53 +000070const unsigned char find_pkt[] = { 0x00, 0x0b+8, IPAC_PROTO_IPACCESS, 0x00,
71 IPAC_MSGT_ID_GET,
72 0x01, IPAC_IDTAG_MACADDR,
73 0x01, IPAC_IDTAG_IPADDR,
74 0x01, IPAC_IDTAG_UNIT,
75 0x01, IPAC_IDTAG_LOCATION1,
76 0x01, IPAC_IDTAG_LOCATION2,
77 0x01, IPAC_IDTAG_EQUIPVERS,
78 0x01, IPAC_IDTAG_SWVERSION,
79 0x01, IPAC_IDTAG_UNITNAME,
80 0x01, IPAC_IDTAG_SERNR,
81 };
Harald Welte923a3bd2009-02-14 12:51:36 +000082
83
84static int bcast_find(int fd)
85{
86 struct sockaddr_in sa;
87
88 sa.sin_family = AF_INET;
89 sa.sin_port = htons(3006);
90 inet_aton("255.255.255.255", &sa.sin_addr);
91
92 return sendto(fd, find_pkt, sizeof(find_pkt), 0, (struct sockaddr *) &sa, sizeof(sa));
93}
94
95static int parse_response(unsigned char *buf, int len)
96{
97 u_int8_t t_len;
98 u_int8_t t_tag;
99 u_int8_t *cur = buf;
100
Harald Welte923a3bd2009-02-14 12:51:36 +0000101 while (cur < buf + len) {
102 t_len = *cur++;
103 t_tag = *cur++;
104
Harald Welte37881962009-04-30 15:15:37 +0000105 printf("%s='%s' ", ipac_idtag_name(t_tag), cur);
Harald Welte923a3bd2009-02-14 12:51:36 +0000106
107 cur += t_len;
108 }
109 printf("\n");
110 return 0;
111}
112
113static int read_response(int fd)
114{
115 unsigned char buf[255];
116 struct sockaddr_in sa;
117 int len;
118 socklen_t sa_len = sizeof(sa);
119
120 len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa, &sa_len);
121 if (len < 0)
122 return len;
123
Harald Welte4593ff32009-05-01 14:53:36 +0000124 return parse_response(buf+6, len-6);
Harald Welte923a3bd2009-02-14 12:51:36 +0000125}
126
127static int bfd_cb(struct bsc_fd *bfd, unsigned int flags)
128{
129 if (flags & BSC_FD_READ)
130 return read_response(bfd->fd);
131 if (flags & BSC_FD_WRITE) {
132 bfd->when &= ~BSC_FD_WRITE;
133 return bcast_find(bfd->fd);
134 }
135 return 0;
136}
137
138static struct timer_list timer;
139
140static void timer_cb(void *_data)
141{
142 struct bsc_fd *bfd = _data;
143
144 bfd->when |= BSC_FD_WRITE;
145
Harald Welteff117a82009-05-23 05:22:08 +0000146 bsc_schedule_timer(&timer, 5, 0);
Harald Welte923a3bd2009-02-14 12:51:36 +0000147}
148
149int main(int argc, char **argv)
150{
151 struct bsc_fd bfd;
152 int rc;
153
154 printf("ipaccess-find (C) 2009 by Harald Welte\n");
155 printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
156
157 bfd.cb = bfd_cb;
158 bfd.when = BSC_FD_READ | BSC_FD_WRITE;
159 bfd.fd = udp_sock();
160 if (bfd.fd < 0)
161 exit(2);
162
163 bsc_register_fd(&bfd);
164
165 timer.cb = timer_cb;
166 timer.data = &bfd;
167
Harald Welteff117a82009-05-23 05:22:08 +0000168 bsc_schedule_timer(&timer, 5, 0);
Harald Welte923a3bd2009-02-14 12:51:36 +0000169
170 printf("Trying to find ip.access BTS by broadcast UDP...\n");
171
172 while (1) {
173 rc = bsc_select_main();
174 if (rc < 0)
175 exit(3);
176 }
177
178 exit(0);
179}
180