10 #define IMAGEFILE "ibmboot.img"
11 #define DEVNAME "eth0"
15 static u_int8_t clientaddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0x0ff, 0xff}; /* loaded with client address */
16 static u_int8_t multicastaddr[ETH_ALEN] = {0x03, 0x00, 0x02, 0x00, 0x00, 0x00};
18 pcap_t *open_pcap(char *device)
21 char errbuf[PCAP_ERRBUF_SIZE];
25 if ( (device = pcap_lookupdev(errbuf)) == NULL)
27 fprintf(stderr, "pcap_lookup: %s\n", errbuf);
32 if ( (pd = pcap_open_live(device, 1500, 1, 500, errbuf)) == NULL)
34 fprintf(stderr, "pcap_open_live: %s\n", errbuf);
41 void showstats(pcap_t *pd)
43 struct pcap_stat stats;
48 if (pcap_stats(pd, &stats) < 0)
50 fprintf(stderr, "cap_stats: %s\n", pcap_geterr(pd));
53 printf("%d packets recieved by filter\n", stats.ps_recv);
54 printf("%d packets dropped by kernel\n", stats.ps_drop);
59 char *next_pcap(pcap_t *pd, struct pcap_pkthdr *hdr)
63 while ( (ptr = (char *)pcap_next(pd, hdr)) == NULL)
70 * This covers stage two of the fast-path, after we've determined its
71 * an incoming RPL frame.
74 void processframe(struct pcap_pkthdr *hdr, char *pkt, char *device)
76 static struct ether_header *ether = NULL;
78 u_int8_t cmpaddr[ETH_ALEN] = {0x10, 0x00, 0x5a, 0x3b, 0x0b, 0x72};
79 u_int8_t cmpaddr[ETH_ALEN] = {0x03, 0x00, 0x02, 0x00, 0x00, 0x00};
81 if ( (!hdr) || (!pkt) )
84 ether = (struct ether_header *)pkt;
86 if (hdr->caplen != hdr->len)
87 fprintf(stderr, "rpld: caplen/len mismatch\n");
90 if ((clientaddr[0] != 0xff) && cmpether(clientaddr, ether->ether_shost))
93 fprintf(stderr, "rpld: got a %sframe from our client\n", (cmpether(multicastaddr, ether->ether_dhost))?"multicast ":"");
94 command = (pkt[19]<<8)+pkt[20];
95 fprintf(stderr, "rpld: command: 0x%04x\n", command);
98 if (command == 0x0001) /* FIND */
99 send_found(link, device);
100 else if (command == 0x0010) /* Send File Request */
101 send_file(link, device);
105 else if (cmpether(multicastaddr, ether->ether_dhost))
107 if (clientaddr[0] != 0xff)
109 /* we're already servicing another client */
110 fprintf(stderr, "rpld: not adding client %s\n", printether(ether->ether_shost));
115 /* we're not busy yet, lets process this one */
116 fprintf(stderr, "rpld: adding client %s\n", printether(ether->ether_shost));
117 memcpy(clientaddr, ether->ether_shost, ETH_ALEN);
121 else if (cmpether(clientaddr, ether->ether_dhost))
123 fprintf(stderr, "rpld: showing outgoing frame...\n");
124 printframe(hdr, pkt);
128 fprintf(stderr, "rpld: uncaught case\n");
131 if (cmpether(cmpaddr, ether->ether_shost) ||
132 cmpether(cmpaddr, ether->ether_dhost) )
134 printf("\n\n%s > ", printether(ether->ether_shost));
135 printf("%s\n", printether(ether->ether_dhost));
138 printf("\aSTATUS CHANGE\n");
140 //pkt = 18; /* skip over ethernet headers */
141 for (i=0;i<hdr->caplen;i+=2)
145 printf("%02x%02x ", pkt[i] &0xff, pkt[i+1] & 0xff);
177 void (*parser)(u_char *data, int len);
182 struct subtype_s subtypes[21];
190 {"Client Ready", NULL},
191 {"Server Ready", NULL},
192 {"Service Request", NULL},
194 {"Rate Information Request", NULL},
195 {"Rate Information", NULL},
196 {"Rate Information Ack", NULL},
197 {"Rate Information Change", NULL},
198 {"Server Pause", NULL},
199 {"Server Resume", NULL},
200 {"Request Personal User Information", NULL},
201 {"Personal User Information", NULL},
202 {"Evil Notification", NULL},
203 {"Migration notice", NULL},
204 {"Message of the Day", NULL},
205 {"Set Privacy Flags", NULL},
206 {"Well Known URL", NULL},
213 {"Request Rights", NULL},
214 {"Rights Information", NULL},
215 {"Set user information", NULL},
216 {"Request User Information", NULL},
217 {"User Information", NULL},
218 {"Watcher Sub Request", NULL},
219 {"Watcher Notification", NULL},
222 {"Buddy List Management", {
225 {"Request Rights", NULL},
226 {"Rights Information", NULL},
228 {"Remove Buddy", NULL},
229 {"Watcher List Query", NULL},
230 {"Watcher List Response", NULL},
231 {"Watcher SubRequest", NULL},
232 {"Watcher Notification", NULL},
233 {"Reject Notification", NULL},
234 {"Oncoming Buddy", NULL},
235 {"Offgoing Buddy", NULL},
241 {"Add ICBM Parameter", NULL},
242 {"Remove ICBM Parameter", NULL},
243 {"Request Parameter Information", NULL},
244 {"Parameter Information", NULL},
245 {"Outgoing Message", NULL},
246 {"Incoming Message", parser_icbm_incoming},
247 {"Evil Request", NULL},
248 {"Evil Reply", NULL},
249 {"Missed Calls", NULL},
250 {"Message Error", NULL},
257 {"Request Ad", NULL},
258 {"Ad Data (GIFs)", NULL},
261 {"Invitation / Client-to-Client", {
264 {"Invite a Friend", NULL},
265 {"Invitation Ack", NULL},
271 {"Information Request", NULL},
272 {"Information Reply", NULL},
273 {"Information Change Request", NULL},
274 {"Information Chat Reply", NULL},
275 {"Account Confirm Request", NULL},
276 {"Account Confirm Reply", NULL},
277 {"Account Delete Request", NULL},
278 {"Account Delete Reply", NULL},
284 {"Display Popup", NULL},
290 {"Request Rights", NULL},
291 {"Rights Response", NULL},
292 {"Set group permission mask", NULL},
293 {"Add permission list entries", NULL},
294 {"Delete permission list entries", NULL},
295 {"Add deny list entries", NULL},
296 {"Delete deny list entries", NULL},
297 {"Server Error", NULL},
303 {"Search Request", NULL},
304 {"Search Response", NULL},
310 {"Set minimum report interval", NULL},
311 {"Report Events", NULL},
317 {"Translate Request", NULL},
318 {"Translate Reply", NULL},
321 {"Chat Navigation", {
324 {"Request rights", NULL},
325 {"Request Exchange Information", NULL},
326 {"Request Room Information", NULL},
327 {"Request Occupant List", NULL},
328 {"Search for Room", NULL},
329 {"Create Room", NULL},
330 {"Navigation Information", NULL},
336 {"Room Information Update", NULL},
337 {"Users Joined", NULL},
338 {"Users Left", NULL},
339 {"Outgoing Message", NULL},
340 {"Incoming Message", NULL},
341 {"Evil Request", NULL},
342 {"Evil Reply", NULL},
343 {"Chat Error", NULL},
351 void detectaim(struct pcap_pkthdr *hdr, char *pkt)
354 struct ether_header *ether = NULL;
355 struct iphdr *ip = NULL;
356 struct tcphdr*tcp= NULL;
357 struct flaphdr *flap = NULL;
358 struct snachdr *snac = NULL;
364 if ( (!hdr) || (!pkt) )
367 if (hdr->caplen != hdr->len)
368 fprintf(stderr, "aimdump: caplen/len mismatch\n");
370 newlen = hdr->caplen;
372 ether = (struct ether_header *)pkt;
375 printf("\n\naimdump: %s > ", printether(ether->ether_shost));
376 printf("%s\n", printether(ether->ether_dhost));
379 pkt += sizeof(struct ether_header); /* skip over ether headers */
380 newlen -= sizeof(struct ether_header);
382 ip = (struct iphdr *)pkt;
383 if (ip->version != 0x4)
384 return; /* ditch non IPv4 packets */
386 newlen -= (ip->ihl)*4;
388 tcp = (struct tcphdr *)pkt;
389 if(!tcp->psh) /* we only want actual data packets */
391 pkt += sizeof(struct tcphdr);
392 newlen -= sizeof(struct tcphdr);
394 flap = (struct flaphdr *)pkt;
396 if (flap->start != 0x2a)
397 return; /* ditch non-FLAP packets */
400 /* TODO: notify user of new connections (SYN) and closed connections (FIN) */
401 printf("\nTCP options: %s %s %s %s %s %s\n\n",
410 flap->seqnum = ntohs(flap->seqnum);
411 flap->len = ntohs(flap->len);
413 snac = (struct snachdr *)(pkt+6);
415 snac->family = ntohs(snac->family);
416 snac->subtype= ntohs(snac->subtype);
417 snac->id = (htons(snac->id & 0x0000ffff)) + (htons(snac->id >>16)<<16);
419 printf("\n--------------------\n");
421 printf("\tChannel:\t0x%02x\t\tSeqNum:\t0x%04x\n\tLength:\t\t0x%04x\n",
428 /* for overrun checking... */
429 for (maxfamily=1;snactypes[maxfamily].family; maxfamily++)
431 if (snac->family <= maxfamily)
433 for (maxsubtype=1;snactypes[snac->family].subtypes[maxsubtype].name; maxsubtype++)
439 printf("\tFamily:\t\t0x%04x (%s)\n",
441 (snac->family > maxfamily)?"Out of Range":snactypes[snac->family].family);
442 printf("\tSubtype:\t0x%04x (%s)\n",
444 (snac->subtype > maxsubtype)?"Out of Range":snactypes[snac->family].subtypes[snac->subtype].name);
445 printf("\tFlags:\t\t0x%02x,0x%02x\tID:\t0x%08lx\n", snac->flags[0], snac->flags[1], snac->id);
447 /* jump around flap+snac */
451 if (snactypes[snac->family].subtypes[snac->subtype].parser)
452 (*(snactypes[snac->family].subtypes[snac->subtype].parser))((u_char *)pkt, newlen);
456 for (i=0;i<newlen;i+=2)
460 printf("%02x%02x ", pkt[i] &0xff, pkt[i+1] & 0xff);
468 int main(int argc, char **argv)
470 struct pcap_pkthdr hdr;
473 if ((pd = open_pcap(NULL)) == NULL)
475 fprintf(stderr, "error in open_pcap\n");
479 signal(SIGINT, sigint);
482 if ((localmac = (u_int8_t *)get_hwaddr(link, DEVNAME, errbuf)) == NULL)
484 fprintf(stderr, "rpld: Unable to get local MAC address, using default\n");
485 localmac = defsource;
488 fprintf(stderr, "rpld: Local MAC Address: %s\n", printether((u_int8_t *)localmac));
492 while ((pkt = next_pcap(pd, &hdr)))
494 detectaim(&hdr, pkt);
495 //printframe(&hdr, pkt);
499 while (pkt = next_pcap(pd, &hdr))
502 * Since this is the fast-path (it gets executed for
503 * EVERY frame that gets captured -- this could be HUGE
504 * on busy 100mb LANs), we need to determine if this frame
505 * needs further processing as fast as possible...
507 etherhdr = (struct ether_header *)pkt;
509 /* this should cover everything */
510 if ( (etherhdr->ether_type == (ETHERTYPE_INCOMING<<8)) ||
511 (etherhdr->ether_type == (ETHERTYPE_FOUND<<8)) ||
512 (etherhdr->ether_type == (ETHERTYPE_DATA<<8)) )
513 processframe(&hdr, pkt, link, DEVNAME);
515 fprintf(stderr, "rpld: skipping ethertype %04x\n", etherhdr->ether_type);