]> andersk Git - libfaim.git/blame - utils/aimdump/main.c
Fix last bugfix.
[libfaim.git] / utils / aimdump / main.c
CommitLineData
fa684c51 1/*
2 *
3 *
4 *
5 *
6 */
7
8#include "aimdump.h"
9
fa684c51 10#define DEVNAME "eth0"
11
12pcap_t *pd = NULL;
13
fa684c51 14pcap_t *open_pcap(char *device)
15{
16 pcap_t *pd = NULL;
17 char errbuf[PCAP_ERRBUF_SIZE];
18
19 if (device == NULL)
20 {
21 if ( (device = pcap_lookupdev(errbuf)) == NULL)
22 {
23 fprintf(stderr, "pcap_lookup: %s\n", errbuf);
24 return NULL;
25 }
26 }
27
28 if ( (pd = pcap_open_live(device, 1500, 1, 500, errbuf)) == NULL)
29 {
30 fprintf(stderr, "pcap_open_live: %s\n", errbuf);
31 return NULL;
32 }
33
34 return pd;
35}
36
37void showstats(pcap_t *pd)
38{
39 struct pcap_stat stats;
40
41 fflush(stdout);
42 printf("\n");
43
44 if (pcap_stats(pd, &stats) < 0)
45 {
46 fprintf(stderr, "cap_stats: %s\n", pcap_geterr(pd));
47 return;
48 }
49 printf("%d packets recieved by filter\n", stats.ps_recv);
50 printf("%d packets dropped by kernel\n", stats.ps_drop);
51
52 return;
53}
54
55char *next_pcap(pcap_t *pd, struct pcap_pkthdr *hdr)
56{
57 char *ptr;
58
59 while ( (ptr = (char *)pcap_next(pd, hdr)) == NULL)
60 ;
61
62 return ptr;
63}
64
65/*
66 * This covers stage two of the fast-path, after we've determined its
67 * an incoming RPL frame.
68 *
69 */
ee3071b9 70#if 0
fa684c51 71void processframe(struct pcap_pkthdr *hdr, char *pkt, char *device)
72{
73 static struct ether_header *ether = NULL;
74#if 0
75 u_int8_t cmpaddr[ETH_ALEN] = {0x10, 0x00, 0x5a, 0x3b, 0x0b, 0x72};
76 u_int8_t cmpaddr[ETH_ALEN] = {0x03, 0x00, 0x02, 0x00, 0x00, 0x00};
77#endif
78 if ( (!hdr) || (!pkt) )
79 return;
80
81 ether = (struct ether_header *)pkt;
82
83 if (hdr->caplen != hdr->len)
84 fprintf(stderr, "rpld: caplen/len mismatch\n");
85
86
87 if ((clientaddr[0] != 0xff) && cmpether(clientaddr, ether->ether_shost))
88 {
89 int command = 0x0000;
90 fprintf(stderr, "rpld: got a %sframe from our client\n", (cmpether(multicastaddr, ether->ether_dhost))?"multicast ":"");
91 command = (pkt[19]<<8)+pkt[20];
92 fprintf(stderr, "rpld: command: 0x%04x\n", command);
93
94#if 0
95 if (command == 0x0001) /* FIND */
96 send_found(link, device);
97 else if (command == 0x0010) /* Send File Request */
98 send_file(link, device);
99#endif
100
101 }
102 else if (cmpether(multicastaddr, ether->ether_dhost))
103 {
104 if (clientaddr[0] != 0xff)
105 {
106 /* we're already servicing another client */
107 fprintf(stderr, "rpld: not adding client %s\n", printether(ether->ether_shost));
108 return;
109 }
110 else
111 {
112 /* we're not busy yet, lets process this one */
113 fprintf(stderr, "rpld: adding client %s\n", printether(ether->ether_shost));
114 memcpy(clientaddr, ether->ether_shost, ETH_ALEN);
115 }
116 }
117#if 0
118 else if (cmpether(clientaddr, ether->ether_dhost))
119 {
120 fprintf(stderr, "rpld: showing outgoing frame...\n");
121 printframe(hdr, pkt);
122 }
123#endif
124 else
125 fprintf(stderr, "rpld: uncaught case\n");
126
127#if 0
128 if (cmpether(cmpaddr, ether->ether_shost) ||
129 cmpether(cmpaddr, ether->ether_dhost) )
130 {
131 printf("\n\n%s > ", printether(ether->ether_shost));
132 printf("%s\n", printether(ether->ether_dhost));
133
134 if (pkt[20] != 0x01)
135 printf("\aSTATUS CHANGE\n");
136
137 //pkt = 18; /* skip over ethernet headers */
138 for (i=0;i<hdr->caplen;i+=2)
139 {
140 if (!((i)%8))
141 printf("\n\t");
142 printf("%02x%02x ", pkt[i] &0xff, pkt[i+1] & 0xff);
143 }
144 }
145 else
146 return;
147#endif
148}
ee3071b9 149#endif
fa684c51 150
151void sigint(int sig)
152{
153 fflush(stdout);
154 showstats(pd);
155 exit(0);
156 return;
157}
158
159struct flaphdr {
ee3071b9 160 unsigned char start;
161 unsigned char channel;
162 unsigned short seqnum;
163 unsigned short len;
fa684c51 164};
165
166struct snachdr {
167 u_short family;
168 u_short subtype;
169 u_char flags[2];
170 u_long id;
171};
172
173struct subtype_s {
174 char *name;
175 void (*parser)(u_char *data, int len);
176};
177
178struct snactype_s {
179 char *family;
180 struct subtype_s subtypes[21];
181} snactypes[16] = {
182 {"Invalid", {
183 {NULL, NULL}}
184 },
185 {"General", {
186 {"Invalid", NULL},
187 {"Error", NULL},
188 {"Client Ready", NULL},
189 {"Server Ready", NULL},
190 {"Service Request", NULL},
191 {"Redirect", NULL},
192 {"Rate Information Request", NULL},
193 {"Rate Information", NULL},
194 {"Rate Information Ack", NULL},
195 {"Rate Information Change", NULL},
196 {"Server Pause", NULL},
197 {"Server Resume", NULL},
198 {"Request Personal User Information", NULL},
199 {"Personal User Information", NULL},
200 {"Evil Notification", NULL},
201 {"Migration notice", NULL},
202 {"Message of the Day", NULL},
203 {"Set Privacy Flags", NULL},
204 {"Well Known URL", NULL},
205 {"NOP", NULL},
206 {NULL, NULL}}
207 },
208 {"Location", {
209 {"Invalid", NULL},
210 {"Error", NULL},
211 {"Request Rights", NULL},
212 {"Rights Information", NULL},
213 {"Set user information", NULL},
214 {"Request User Information", NULL},
215 {"User Information", NULL},
216 {"Watcher Sub Request", NULL},
217 {"Watcher Notification", NULL},
218 {NULL, NULL}}
219 },
220 {"Buddy List Management", {
221 {"Invalid", NULL},
222 {"Error", NULL},
223 {"Request Rights", NULL},
224 {"Rights Information", NULL},
225 {"Add Buddy", NULL},
226 {"Remove Buddy", NULL},
227 {"Watcher List Query", NULL},
228 {"Watcher List Response", NULL},
229 {"Watcher SubRequest", NULL},
230 {"Watcher Notification", NULL},
231 {"Reject Notification", NULL},
232 {"Oncoming Buddy", NULL},
233 {"Offgoing Buddy", NULL},
234 {NULL, NULL}},
235 },
236 {"Messeging", {
237 {"Invalid", NULL},
238 {"Error", NULL},
239 {"Add ICBM Parameter", NULL},
240 {"Remove ICBM Parameter", NULL},
241 {"Request Parameter Information", NULL},
242 {"Parameter Information", NULL},
243 {"Outgoing Message", NULL},
244 {"Incoming Message", parser_icbm_incoming},
245 {"Evil Request", NULL},
246 {"Evil Reply", NULL},
247 {"Missed Calls", NULL},
248 {"Message Error", NULL},
249 {"Host Ack", NULL},
250 {NULL, NULL}}
251 },
252 {"Advertisements", {
253 {"Invalid", NULL},
254 {"Error", NULL},
255 {"Request Ad", NULL},
256 {"Ad Data (GIFs)", NULL},
257 {NULL, NULL}}
258 },
259 {"Invitation / Client-to-Client", {
260 {"Invalid", NULL},
261 {"Error", NULL},
262 {"Invite a Friend", NULL},
263 {"Invitation Ack", NULL},
264 {NULL, NULL}}
265 },
266 {"Administrative", {
267 {"Invalid", NULL},
268 {"Error", NULL},
269 {"Information Request", NULL},
270 {"Information Reply", NULL},
271 {"Information Change Request", NULL},
272 {"Information Chat Reply", NULL},
273 {"Account Confirm Request", NULL},
274 {"Account Confirm Reply", NULL},
275 {"Account Delete Request", NULL},
276 {"Account Delete Reply", NULL},
277 {NULL, NULL}}
278 },
279 {"Popups", {
280 {"Invalid", NULL},
281 {"Error", NULL},
282 {"Display Popup", NULL},
283 {NULL, NULL}}
284 },
285 {"BOS", {
286 {"Invalid", NULL},
287 {"Error", NULL},
288 {"Request Rights", NULL},
289 {"Rights Response", NULL},
290 {"Set group permission mask", NULL},
291 {"Add permission list entries", NULL},
292 {"Delete permission list entries", NULL},
293 {"Add deny list entries", NULL},
294 {"Delete deny list entries", NULL},
295 {"Server Error", NULL},
296 {NULL, NULL}}
297 },
298 {"User Lookup", {
299 {"Invalid", NULL},
300 {"Error", NULL},
301 {"Search Request", NULL},
302 {"Search Response", NULL},
303 {NULL, NULL}}
304 },
305 {"Stats", {
306 {"Invalid", NULL},
307 {"Error", NULL},
308 {"Set minimum report interval", NULL},
309 {"Report Events", NULL},
310 {NULL, NULL}}
311 },
312 {"Translate", {
313 {"Invalid", NULL},
314 {"Error", NULL},
315 {"Translate Request", NULL},
316 {"Translate Reply", NULL},
317 {NULL, NULL}}
318 },
319 {"Chat Navigation", {
320 {"Invalid", NULL},
321 {"Error", NULL},
322 {"Request rights", NULL},
323 {"Request Exchange Information", NULL},
324 {"Request Room Information", NULL},
325 {"Request Occupant List", NULL},
326 {"Search for Room", NULL},
327 {"Create Room", NULL},
328 {"Navigation Information", NULL},
329 {NULL, NULL}}
330 },
331 {"Chat", {
332 {"Invalid", NULL},
333 {"Error", NULL},
334 {"Room Information Update", NULL},
335 {"Users Joined", NULL},
336 {"Users Left", NULL},
337 {"Outgoing Message", NULL},
338 {"Incoming Message", NULL},
339 {"Evil Request", NULL},
340 {"Evil Reply", NULL},
341 {"Chat Error", NULL},
342 {NULL, NULL}}
343 },
344 {NULL, {
345 {NULL, NULL}}
346 }
347};
348
349void detectaim(struct pcap_pkthdr *hdr, char *pkt)
350{
351 int i;
352 struct ether_header *ether = NULL;
353 struct iphdr *ip = NULL;
354 struct tcphdr*tcp= NULL;
355 struct flaphdr *flap = NULL;
356 struct snachdr *snac = NULL;
357 char *orig = pkt;
358 u_int newlen;
359 int maxfamily = 0;
360 int maxsubtype = 0;
361
362 if ( (!hdr) || (!pkt) )
363 return;
364
365 if (hdr->caplen != hdr->len)
366 fprintf(stderr, "aimdump: caplen/len mismatch\n");
367
368 newlen = hdr->caplen;
369
370 ether = (struct ether_header *)pkt;
371
372#if 0
373 printf("\n\naimdump: %s > ", printether(ether->ether_shost));
374 printf("%s\n", printether(ether->ether_dhost));
375#endif
376
377 pkt += sizeof(struct ether_header); /* skip over ether headers */
378 newlen -= sizeof(struct ether_header);
379
380 ip = (struct iphdr *)pkt;
381 if (ip->version != 0x4)
382 return; /* ditch non IPv4 packets */
383 pkt += (ip->ihl)*4;
384 newlen -= (ip->ihl)*4;
385
386 tcp = (struct tcphdr *)pkt;
387 if(!tcp->psh) /* we only want actual data packets */
388 return;
389 pkt += sizeof(struct tcphdr);
390 newlen -= sizeof(struct tcphdr);
391
392 flap = (struct flaphdr *)pkt;
393
394 if (flap->start != 0x2a)
395 return; /* ditch non-FLAP packets */
396
397#if 0
398 /* TODO: notify user of new connections (SYN) and closed connections (FIN) */
399 printf("\nTCP options: %s %s %s %s %s %s\n\n",
400 tcp->fin?"fin":"",
401 tcp->syn?"syn":"",
402 tcp->rst?"rst":"",
403 tcp->psh?"psh":"",
404 tcp->ack?"ack":"",
405 tcp->urg?"urg":"");
406#endif
407
408 flap->seqnum = ntohs(flap->seqnum);
409 flap->len = ntohs(flap->len);
410
411 snac = (struct snachdr *)(pkt+6);
412
413 snac->family = ntohs(snac->family);
414 snac->subtype= ntohs(snac->subtype);
415 snac->id = (htons(snac->id & 0x0000ffff)) + (htons(snac->id >>16)<<16);
416
417 printf("\n--------------------\n");
ee3071b9 418 {
419 struct in_addr tmpaddr;
420 tmpaddr.s_addr = ip->saddr;
421 printf("%s -> ", inet_ntoa(tmpaddr));
422 tmpaddr.s_addr = ip->daddr;
423 printf("%s\n\n", inet_ntoa(tmpaddr));
424 }
fa684c51 425 printf("FLAP:\n");
426 printf("\tChannel:\t0x%02x\t\tSeqNum:\t0x%04x\n\tLength:\t\t0x%04x\n",
427 flap->channel,
428 flap->seqnum,
429 flap->len);
fa684c51 430
10972218 431 /* jump around flap */
432 pkt += 6;
433 newlen -= 6;
434
fe455ae9 435 if (snac->family == 0x0000)
fa684c51 436 {
fe455ae9 437 printf("\t\tNo SNAC.\n");
fa684c51 438 }
10972218 439 else
440 {
441 printf("SNAC:\n");
442
443 /* for overrun checking... */
444 for (maxfamily=1;snactypes[maxfamily].family; maxfamily++)
445 ;
446 if (snac->family <= maxfamily)
447 {
448 for (maxsubtype=1;snactypes[snac->family].subtypes[maxsubtype].name; maxsubtype++)
449 ;
450 }
451 maxfamily--;
452 maxsubtype--;
453
454 printf("\tFamily:\t\t0x%04x (%s)\n",
455 snac->family,
456 (snac->family > maxfamily)?"Out of Range":snactypes[snac->family].family);
457 printf("\tSubtype:\t0x%04x (%s)\n",
458 snac->subtype,
459 (snac->subtype > maxsubtype)?"Out of Range":snactypes[snac->family].subtypes[snac->subtype].name);
460 printf("\tFlags:\t\t0x%02x,0x%02x\tID:\t0x%08lx\n", snac->flags[0], snac->flags[1], snac->id);
461
462 /* jump around snac */
463 pkt += 16;
464 newlen -= 16;
fa684c51 465
10972218 466 if (snactypes[snac->family].subtypes[snac->subtype].parser)
467 (*(snactypes[snac->family].subtypes[snac->subtype].parser))((u_char *)pkt, newlen);
468 }
469
fa684c51 470 printf("\nRAW:\n");
10972218 471
fa684c51 472 for (i=0;i<newlen;i+=2)
473 {
474 if (!((i)%16))
475 printf("\n\t");
476 printf("%02x%02x ", pkt[i] &0xff, pkt[i+1] & 0xff);
477 }
478 printf("\n\n");
479
480 fflush(stdout);
481 pkt = orig;
482}
483
484int main(int argc, char **argv)
485{
486 struct pcap_pkthdr hdr;
487 char *pkt;
488
489 if ((pd = open_pcap(NULL)) == NULL)
490 {
491 fprintf(stderr, "error in open_pcap\n");
492 exit (-1);
493 }
494
495 signal(SIGINT, sigint);
496
497#if 0
498 if ((localmac = (u_int8_t *)get_hwaddr(link, DEVNAME, errbuf)) == NULL)
499 {
500 fprintf(stderr, "rpld: Unable to get local MAC address, using default\n");
501 localmac = defsource;
502 }
503
504 fprintf(stderr, "rpld: Local MAC Address: %s\n", printether((u_int8_t *)localmac));
505#endif
506
507#if 1
508 while ((pkt = next_pcap(pd, &hdr)))
509 {
510 detectaim(&hdr, pkt);
511 //printframe(&hdr, pkt);
512 }
513#endif
514#if 0
515 while (pkt = next_pcap(pd, &hdr))
516 {
517 /*
518 * Since this is the fast-path (it gets executed for
519 * EVERY frame that gets captured -- this could be HUGE
520 * on busy 100mb LANs), we need to determine if this frame
521 * needs further processing as fast as possible...
522 */
523 etherhdr = (struct ether_header *)pkt;
524
525 /* this should cover everything */
526 if ( (etherhdr->ether_type == (ETHERTYPE_INCOMING<<8)) ||
527 (etherhdr->ether_type == (ETHERTYPE_FOUND<<8)) ||
528 (etherhdr->ether_type == (ETHERTYPE_DATA<<8)) )
529 processframe(&hdr, pkt, link, DEVNAME);
530 else
531 fprintf(stderr, "rpld: skipping ethertype %04x\n", etherhdr->ether_type);
532 }
533#endif
534 showstats(pd);
535
536 return 0;
537}
This page took 0.23031 seconds and 5 git commands to generate.