blob: 63a5de10ece6b618d34ec0f0262831faca2e2b80 [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
101 cur += 6;
102
103 while (cur < buf + len) {
104 t_len = *cur++;
105 t_tag = *cur++;
106
Harald Welte37881962009-04-30 15:15:37 +0000107 printf("%s='%s' ", ipac_idtag_name(t_tag), cur);
Harald Welte923a3bd2009-02-14 12:51:36 +0000108
109 cur += t_len;
110 }
111 printf("\n");
112 return 0;
113}
114
115static int read_response(int fd)
116{
117 unsigned char buf[255];
118 struct sockaddr_in sa;
119 int len;
120 socklen_t sa_len = sizeof(sa);
121
122 len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa, &sa_len);
123 if (len < 0)
124 return len;
125
126 return parse_response(buf, len);
127}
128
129static int bfd_cb(struct bsc_fd *bfd, unsigned int flags)
130{
131 if (flags & BSC_FD_READ)
132 return read_response(bfd->fd);
133 if (flags & BSC_FD_WRITE) {
134 bfd->when &= ~BSC_FD_WRITE;
135 return bcast_find(bfd->fd);
136 }
137 return 0;
138}
139
140static struct timer_list timer;
141
142static void timer_cb(void *_data)
143{
144 struct bsc_fd *bfd = _data;
145
146 bfd->when |= BSC_FD_WRITE;
147
148 schedule_timer(&timer, 5, 0);
149}
150
151int main(int argc, char **argv)
152{
153 struct bsc_fd bfd;
154 int rc;
155
156 printf("ipaccess-find (C) 2009 by Harald Welte\n");
157 printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
158
159 bfd.cb = bfd_cb;
160 bfd.when = BSC_FD_READ | BSC_FD_WRITE;
161 bfd.fd = udp_sock();
162 if (bfd.fd < 0)
163 exit(2);
164
165 bsc_register_fd(&bfd);
166
167 timer.cb = timer_cb;
168 timer.data = &bfd;
169
170 schedule_timer(&timer, 5, 0);
171
172 printf("Trying to find ip.access BTS by broadcast UDP...\n");
173
174 while (1) {
175 rc = bsc_select_main();
176 if (rc < 0)
177 exit(3);
178 }
179
180 exit(0);
181}
182