#include #include #include #include #include #include #include // The next two functions should be replaced by identity in big endian machines. u_short sw2(u_short x){return x<<8 | x>>8;} u_int sw4(u_int x) {return sw2(x) <<16 | sw2(x>>16);} u_char * frmpp = (u_char*) "frmp"; int min(int a, int b){return a>8), 255&(xx>>16), xx>>24);} int IPcv(const u_int xx){int k=IPcc; while(k--) if(xx == IP[k]) return k; if(IPcc==IPmx) finish(printf("IP Crowd\n")); printf("[%d New IP addr: ", IPcc); pIP(xx); printf("]\n"); IP[IPcc] = xx; return IPcc++;} int IPn(const u_char * d){return IPcv(*(u_int*)d);} #define prmx 200 typedef struct{u_short toip; u_short topt; u_short frip; u_short frpt;} pr; int eqpr(pr * a, pr * b){return a->toip == b->toip && a->topt == b->topt && a->frip == b->frip && a->frpt == b->frpt;} pr rv(pr * a){return (pr){a->frip, a->frpt, a->toip, a->topt};} int prc = 0; pr PR[prmx]; int pPR(pr * a){pr r = rv(a); {int j = prc; while(j--) { if(eqpr(a, PR+j)) return 2*j; if(eqpr(&r, PR+j)) return 2*j+1;}} if(prc == prmx) finish(printf("path Crowd\n")); printf("[%d New Path: %d:%d, %d:%d]\n", 2*prc, a->toip, a->topt, a->frip, a->frpt); PR[prc] = *a; return 2*prc++;} void hndl(u_char * id, const struct pcap_pkthdr * ph, const u_char * data){ void p(int i, int d, int s){int j; printf("at %d: ", i); for(j=(0?i:0); jcaplen; ++j) { // ..... if(!(j<13 ? (j%6) : (j+2)&3)) putchar(' '); printf("%02x", data[j]);} printf("\n"); if(s) printf("ding%c\n", 7);} static int Tbase=0; if (id != frmpp) exit(printf("Foo1\n")); if (!Tbase) Tbase=ph->ts.tv_sec; printf("\nPacket %d: size=%d, when: %d sec + %d μsec\n", ++pc, ph->len, (int)ph->ts.tv_sec-Tbase, (int)ph->ts.tv_usec); printf("EN %d->%d ", maccv(data+6), maccv(data)); u_short et = sw2(*(short*)(data+12)); if(et == 0x0806) {p(12, printf("ARP \n"), 0); if(ph -> caplen != 42) exit(printf("Foo5\n")); if(*(u_int*)(data+14) != sw4(0x00010800)) p(14, printf("Foo2\n"), 1); if(*(u_short*)(data+18) != sw2(0x0604)) p(14, printf("Foo3\n"), 1); int d1=maccv(data), s1=maccv(data+6); {int d2=maccv(data+32); if(d1 != d2) p(0, printf("Destinations differ %d %d\n", d1, d2), 1);} {int s2=maccv(data+22); if(s1 != s2) p(0, printf("Senders differ %d %d\n", s1, s2), 1);} u_short o = sw2(*(u_short*)(data+20)); if(o==1) {if(d1) p(0, printf("Why is recipient not -1?\n"), 1); printf("MAC %d asks %d who is there?\n", s1, d1);} else if(o==2)p(28, printf("MAC %d replies to %d: I am IP %d\n", s1, d1, IPn(data+28)), 0); else p(20, printf("Unknown ARP order: %d\n", o), 1);} else if(et == 0x0800) {const u_char*pl= data+14+4*(data[14]&15); void pp(char * st){p(pl-data, 0? printf("%s %d:%d->%d:%d ", st, IPn(data+26), sw2(*(u_short*)pl), IPn(data+30), sw2(*(u_short*)(pl+2))) :({pr path = (pr){IPn(data+26), sw2(*(u_short*)pl), IPn(data+30), sw2(*(u_short*)(pl+2))}; printf("%s path: %d; ", st, pPR(&path));}), 0);} if(data[14]>>4 != 4) p(14, printf("Still IPv4 only: %d\n", data[14]), 1); if(data[15]) {u_char y=data[15]; char * prec[] = { "Routine", "Priority", "Immediate", "Flash", "Flash Override", "CRITIC/ECP", "Internetwork Control", "Network Control"}; serva |= y; printf("Precedence(%s %s %s %s)", prec[y>>5], y&16?"Low Delay, ":"", y&8?"High Throughput, ":"", y&4?"High Relibility":"");} if(data[23]==6) pp("TCP"); else if(data[23] == 17) {pp("UDP"); const u_char * eUDP = pl+sw2(*(u_short*)(pl+4)); if(0) if(eUDP <= data+ph->caplen) {u_int sm = (u_int)(pl[5]&1?*(eUDP-1):0)<<8; u_short* j; for(j=(u_short*)pl; j<(u_short*)eUDP; ++j) sm += *j; u_short cs = sm+(sm>>16); printf("csv=0x%08x ", sm); if(~cs) printf("Bad checksum "); // this code agrees with hand calculated checksum at least for even length packets. // received packets seem to have bad checksums. } else printf("too big ");} else p(14, printf("IP Protocol number %d?\n", data[23]), 1);} else if(et == 0x86dd) p(14, printf("IPv6?!?\n"), 1); else p(12, printf("EtherType?: %04x\n", et), 1);} void finish(int d) { printf("EN MAC map:\n"); {int j; for(j=0; jcaplen)>1000000) fin(); ++pc; tt+=ph->len; fwrite((void*)&ph->caplen, 4, 1, lg); fwrite((void*)ph, sizeof(struct pcap_pkthdr), 1, lg); fwrite((void*)data, ph->caplen, 1, lg);} int main(int argc, char *argv[]){ pcap_t* od(){char errbuf[PCAP_ERRBUF_SIZE+1]; pcap_t* dev = pcap_open_live("en1", ps, 1, 150, errbuf); printf("pcap_t at 0x%x\n", (u_int)dev); if(!dev){perror("Bah!"); errbuf[PCAP_ERRBUF_SIZE] = 0; printf("Wont open: %s\n", errbuf); exit(0);} {int j=40; while(j--) printf("%02x", *(j+(char*)dev)); printf("\n");} {int typ = pcap_datalink(dev); if(1 != DLT_EN10MB) exit(printf("Theory failure\n")); if(typ != 1) exit(printf("Type not Ethernet! %d %s: %s\n", typ, pcap_datalink_val_to_name(typ), pcap_datalink_val_to_description(typ)));} return dev;} if(argc>1) {int rc = atoi(argv[1]); if(rc) {lg = fopen("log", "w"); if(!lg) {perror("Can't make file!"); exit(0);} signal(SIGINT, fin); pcap_loop(od(), rc, wrt, frmpp); printf("Made %d records.\n", rc); } else {const int hs = sizeof(struct pcap_pkthdr); pi(); int fd = open("log", O_RDONLY); if(fd<0) {perror("No log file to process"); exit(0);} void * stuff = mmap(0, 1<<20, PROT_READ, MAP_SHARED, fd, 0), * sp = stuff; if((int)sp==-1) {perror("Bad mmap"); exit(33);} while(*(int*)sp){hndl(frmpp, sp+4, sp+4+hs); sp += 4+hs+*(int*)sp;} munmap(stuff, 1<<20); finish(0);} } else { pi(); signal(SIGINT, finish); pcap_loop(od(), 10, hndl, frmpp); finish(printf("Back from pcap_loop\n"));} return(0);} // perhaps disable around updating record. // gcc ag.c -lpcap -fnested-functions -Wmost // sudo ./a.out