jablonka.czprosek.czf

discover

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

 

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

Powered by WebSVN 2.2.1