jablonka.czprosek.czf

discover

Subversion Repositories:
[/] [trunk/] [discover.c] - Blame information for rev 3

 

Line No. Rev Author Line
11simandl#include <arpa/inet.h>
2#include <netinet/in.h>
3#include <stdio.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <unistd.h>
7#include <stdlib.h>
8#include <string.h>
9#include <ctype.h>
10#include <netdb.h>
11#include <sys/select.h>
12#include <sys/time.h>
13#include <ifaddrs.h>
14#include <net/if.h>
15 
16#define BUFLEN 1024
17#define UBNT_PORT 10001
18 
19#define SNDLEN 4
20 
21 
22struct udisc_msg_hdr {
23 uint8_t vh;
24 uint8_t vl;
25 uint16_t length;
26} __attribute__((packed));
27 
28struct udisc_rec_hdr {
29 uint8_t type;
30 uint16_t length;
31} __attribute__((packed));
32 
33int main(int argc, char *argv[])
34{
35 
36 struct sockaddr_in si_srv;
37 struct sockaddr_in si_clnt;
38 int sock;
39 socklen_t soutlen = sizeof(si_srv);
40 socklen_t sinlen = sizeof(si_srv);
41 char rcvbuf[BUFLEN];
42 char sendbuf[BUFLEN];
43 ssize_t rlen;
44 
45 struct udisc_msg_hdr *umh;
46 struct udisc_rec_hdr *urh;
47 char *p;
48 char *dest;
49 
50 struct addrinfo hints;
51 struct addrinfo *ai_res;
52 int result;
53 int i, t;
54 
55 fd_set socks;
56 struct timeval tv;
57 
58 int multicast;
59 
60 int responses = 0;
61 
62 struct ifaddrs *ifa;
63 
643simandl memset(&hints, 0, sizeof(hints));
651simandl hints.ai_protocol = IPPROTO_UDP;
66 hints.ai_socktype = SOCK_DGRAM;
67 hints.ai_flags = AI_CANONNAME;
68 hints.ai_family = PF_UNSPEC;
69 
70 if (argc < 2) {
71 dest = "233.89.188.1";
72 multicast = 1;
73 } else {
74 dest = argv[1];
75 multicast = 0;
76 }
77 
78 if ((result = getaddrinfo(dest, NULL, &hints, &ai_res))) {
79 printf("getaddrinfo-failed: %s\n", gai_strerror(result));
80 exit(1);
81 }
82 
83 if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
84 perror("socket");
85 exit(1);
86 }
87 
88 memset((char *) &si_clnt, 0, sizeof(si_clnt));
89 si_clnt.sin_family = AF_INET;
90 si_clnt.sin_port = htons(UBNT_PORT);
91 si_clnt.sin_addr = ((struct sockaddr_in *)ai_res->ai_addr)->sin_addr;
92 
93 sendbuf[0] = 1;
94 sendbuf[1] = 0;
95 sendbuf[2] = 0;
96 sendbuf[3] = 0;
97 
98 if (multicast) {
99 
100 char loop = 0;
101 setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(char));
102 
103 if (getifaddrs(&ifa)) {
104 perror("getifaddrs");
105 exit(1);
106 }
107 
108 for (; ifa; ifa = ifa->ifa_next) {
109 
110 if (!(ifa->ifa_flags & IFF_UP))
111 continue;
112 if (!ifa->ifa_addr)
113 continue;
114 if (ifa->ifa_addr->sa_family != AF_INET)
115 continue;
116 if (!strcmp(ifa->ifa_name, "lo"))
117 continue;
118 if (!strncmp(ifa->ifa_name, "dummy", 5))
119 continue;
120 
121 printf("Probing %s:%d", inet_ntoa(si_clnt.sin_addr), UBNT_PORT);
122 printf(" via %s (%s).\n", ifa->ifa_name, inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr));
123 
124 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr), sizeof(struct in_addr))) {
125 perror("setsockopt");
126 exit(1);
127 }
128 
129 if (sendto(sock, sendbuf, SNDLEN, 0, (struct sockaddr *)&si_clnt, soutlen) == -1) {
130 perror("socket");
131 exit(1);
132 }
133 }
134 
135 } else {
136 
137 printf("Probing %s:%d.\n", inet_ntoa(si_clnt.sin_addr), UBNT_PORT);
138 
139 if (sendto(sock, sendbuf, SNDLEN, 0, (struct sockaddr *)&si_clnt, soutlen) == -1) {
140 perror("socket");
141 exit(1);
142 }
143 }
144 
145 
146 FD_ZERO(&socks);
147 FD_SET(sock, &socks);
148 tv.tv_sec = 0;
149 tv.tv_usec = 200000;
150 
151 while (select(sock + 1, &socks, NULL, NULL, &tv)) {
152 
153 if ((rlen = recvfrom(sock, rcvbuf, BUFLEN, 0, (struct sockaddr *)&si_srv, &sinlen)) == -1) {
154 perror("recvfrom");
155 exit(1);
156 }
157 
158 if (ntohs(si_srv.sin_port) != UBNT_PORT)
159 continue;
160 
161 responses++;
162 
163 printf("\n");
164 printf("Response : %s:%d\n", inet_ntoa(si_srv.sin_addr), ntohs(si_srv.sin_port));
165 
166 p = rcvbuf;
167 
168 umh = (void*)p;
169 p += sizeof(struct udisc_msg_hdr);
170 rlen -= sizeof(struct udisc_msg_hdr);
171 
172 printf("Discovery: v%d.%02d\n", umh->vh, umh->vl);
173 
174 if (umh->vh != 1 && umh->vl != 0 && ntohs(umh->length) != rlen) {
175 fprintf(stderr, "protocol invalid\n");
176 exit(1);
177 }
178 
179 while (rlen > 0) {
180 
181 urh = (void*)p;
182 p += sizeof(struct udisc_rec_hdr);
183 rlen -= sizeof(struct udisc_rec_hdr);
184 
185 
186 
187 
188 switch (urh->type) {
189 
190 
191 
192 case 2:
193 printf("IP Address: ");
194 for (i = 0; i < 4; i++) {
195 printf("%d", (unsigned char) p[i + 6]);
196 if (i < 3)
197 printf(".");
198 }
199 
200 printf(" (");
201 for (i = 0; i < 6; i++) {
202 printf("%02x", (unsigned char) p[i]);
203 if (i < 5)
204 printf(":");
205 }
206 
207 printf(")\n");
208 break;
209 
210 
211 case 1:
212 printf("MAC Address: ");
213 for (i = 0; i < 6; i++) {
214 printf("%02x", (unsigned char) p[i]);
215 if (i < 5)
216 printf(":");
217 }
218 
219 printf("\n");
220 break;
221 
222 
223 case 3:
224 case 11:
225 case 12:
226 case 13:
227 
228 switch(urh->type) {
229 
230 case 3:
231 printf("FW Version: ");
232 break;
233 case 11:
234 printf("Hostname: ");
235 break;
236 case 12:
237 printf("Model: ");
238 break;
239 case 13:
240 printf("ESSID: ");
241 break;
242 }
243 
244 for (i = 0; i < ntohs(urh->length); i++)
245 printf("%c", isprint(p[i]) ? p[i] : '.');
246 printf("\n");
247 
248 break;
249 
250 case 14:
251 
252 printf("Mode: %s (%d)\n", *p == 2 ? "Station" : (*p == 3 ? "AP" : "?"), *p);
253 break;
254 
255 case 10:
256 t = ntohl(*(uint32_t *)p);
257 printf("Uptime: %dd, %d:%02d:%02d\n", t / 60 / 60 / 24, t / 60 / 60 % 24, t / 60 % 60, t % 60);
258 break;
259 
260 default:
261 
262 printf("Entry %3d: ", urh->type);
263 
264 for (i = 0; i < ntohs(urh->length); i++)
265 printf("%02x ", (unsigned char) p[i]);
266 
267 printf(" >");
268 
269 for (i = 0; i < ntohs(urh->length); i++)
270 printf("%c", isprint(p[i]) ? p[i] : '.');
271 printf("<\n");
272 
273 
274 }
275 
276 p += ntohs(urh->length);
277 rlen -= ntohs(urh->length);
278 }
279 
280 
281 }
282 
283 
284 close(sock);
285 
286 if (!responses) {
287 printf("No UBNT routers found.\n");
288 return 1;
289 }
290 
291 printf("\n");
292 
293 return 0;
294 
295}
296 

Powered by WebSVN 2.2.1