|
if (ctlp->len < sizeof (long)) err("getmsg: control portion length < sizeof (long): %d", ctlp->len); } expecting(prim, dlp) int prim; union DL_primitives *dlp; { if (dlp->dl_primitive != (u_long)prim) { err("unexpected dlprim error\n"); exit(1); } } strioctl(fd, cmd, timout, len, dp) int fd; int cmd; int timout; int len; char *dp; { struct strioctl sioc; int rc; sioc.ic_cmd = cmd; sioc.ic_timout = timout; sioc.ic_len = len; sioc.ic_dp = dp; rc = ioctl(fd, I_STR, &sioc); if (rc < 0) return (rc); else return (sioc.ic_len); } dlattachreq(fd, ppa) int fd; u_long ppa; { dl_attach_req_t attach_req; struct strbuf ctl; int flags; attach_req.dl_primitive = DL_ATTACH_REQ; attach_req.dl_ppa = ppa; ctl.maxlen = 0; ctl.len = sizeof (attach_req); ctl.buf = (char *) &attach_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlattachreq: putmsg"); } dlokack(fd, bufp) int fd; char *bufp; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_OK_ACK, dlp); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack: response ctl.len too short: %d", ctl.len); if (flags != RS_HIPRI) err("dlokack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_ok_ack_t)) err("dlokack: short response ctl.len: %d", ctl.len); } dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) int fd; u_long sap; u_long max_conind; u_long service_mode; u_long conn_mgmt; u_long xidtest; { dl_bind_req_t bind_req; struct strbuf ctl; int flags;
bind_req.dl_primitive = DL_BIND_REQ; bind_req.dl_sap = sap; bind_req.dl_max_conind = max_conind; bind_req.dl_service_mode = service_mode; bind_req.dl_conn_mgmt = conn_mgmt; bind_req.dl_xidtest_flg = xidtest; ctl.maxlen = 0; ctl.len = sizeof (bind_req); ctl.buf = (char *) &bind_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlbindreq: putmsg"); } dlbindack(fd, bufp) int fd; char *bufp; { union DL_primitives *dlp; struct strbuf ctl; int flags; ctl.maxlen = MAXDLBUF; ctl.len = 0; ctl.buf = bufp; strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack"); dlp = (union DL_primitives *) ctl.buf; expecting(DL_BIND_ACK, dlp); if (flags != RS_HIPRI) err("dlbindack: DL_OK_ACK was not M_PCPROTO"); if (ctl.len < sizeof (dl_bind_ack_t)) err("dlbindack: short response ctl.len: %d", ctl.len); } dlpromisconreq(fd, level) int fd; u_long level; { dl_promiscon_req_t promiscon_req; struct strbuf ctl; int flags; promiscon_req.dl_primitive = DL_PROMISCON_REQ; promiscon_req.dl_level = level; ctl.maxlen = 0; ctl.len = sizeof (promiscon_req); ctl.buf = (char *) &promiscon_req; flags = 0; if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) syserr("dlpromiscon: putmsg"); } syserr(s) char *s; { (void) perror(s); exit(1); } void filter(cp, pktlen) register char *cp; register u_int pktlen; { register struct ip *ip; register struct tcphdr *tcph; register struct ether_header *eth; char *head=cp; static long line_count=0;
u_short EtherType=ntohs(((struct ether_header *)cp)->ether_type); if(EtherType < 0x600) { EtherType = *(u_short *)(cp + SZETH + 6); cp+=8; pktlen-=8; } eth=(struct ether_header*)cp; fprintf(LOG,"%-5d",++line_count); if(EtherType == ETHERTYPE_IP) { ip=(struct ip *)(cp+SZETH); Mac_info(e->ether_shost); fprintf(LOG,"("); Ip_info(&ip->ip_src); fprintf(LOG,")"); fprintf(LOG,"--->"); Mac_info(e->ether_dhost); fprintf(LOG,"("); Ip_info(&ip->ip_dst); fprintf(LOG,")"); fprintf(LOG,"\n"); } else if(EtherType == ARP_PROTO) { cp+=SZETH; struct ether_arp *arp=(struct ether_arp *)cp; switch(ntohs(arp->ea_hdr.ar_op)) { case ARPOP_REQUEST: fprintf(LOG,"arp request:who has "); arp_ip_info(arp->arp_tpa); fprintf(LOG," tells "); arp_ip_info(arp->arp_spa); fprintf(LOG,"\n"); break; case ARPOP_REPLY: fprintf(LOG,"arp reply: "); arp_ip_info(arp->arp_spa); fprintf(LOG," is at "); Mac_info((struct ether_addr*)&arp->arp_sha); fprintf(LOG,"\n"); break; } //打印出arp数据报的内容 } } do_it() { long buf[MAXDLBUF]; char *device; int ppa; int fd; struct strbuf data; int flags; int i; int c; int offset; int len; struct timeval t; u_int chunksize = 16 * 1024; struct sb_hdr *bp; char *p, *limp; int mrwtmp; device = "/dev/bge"; ppa = 0; sap= 0x0806; if ((fd = open(device, 2)) < 0) syserr(device);
dlattachreq(fd, ppa); dlokack(fd, buf); if (promisc) { dlpromisconreq(fd, DL_PROMISC_PHYS); dlokack(fd, buf); }
dlbindreq(fd, sap, 0, DL_CLDLS, 0, 0); dlbindack(fd, buf);
if (strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0) syserr("DLIOCRAW"); if (bufmod) { if (ioctl(fd, I_PUSH, "bufmod") < 0) syserr("push bufmod"); t.tv_sec = 0; t.tv_usec = 500000; if (strioctl(fd, SBIOCSTIME, -1, sizeof (struct timeval), &t) < 0) syserr("SBIOCSTIME"); if (strioctl(fd, SBIOCSCHUNK, -1, sizeof (u_int), &chunksize) < 0) syserr("SBIOCSCHUNK"); } if (ioctl(fd, I_FLUSH, FLUSHR) < 0) syserr("I_FLUSH");
if(1){ data.buf = (char *) databuf; data.maxlen = MAXDLBUF; data.len = 0; while (((mrwtmp=getmsg(fd, NULL, &data, &flags))==0) || (mrwtmp==MOREDATA) || (mrwtmp=MORECTL)) { p = data.buf; limp = p + data.len; filter(data.buf, data.len); data.len = 0; } printf("finished getmsg() = %i\n",mrwtmp); } } int main(argc, argv) int argc; char **argv; { char cbuf[BUFSIZ]; struct ifconf ifc; int s, ac=1, backg=0;
ProgName=argv[0]; device=NIT_DEV; while((ac<argc) && (argv[ac][0] == '-')) { register char ch = argv[ac++][1]; switch(toupper(ch)) { case 'I': device=argv[ac++]; break; case 'O': if(!(LOG=fopen((LogName=argv[ac++]),"a"))) Zexit(1,"Output file cant be opened\n"); break; case 's': sap=atoi(argv[ac++]); break; default : fprintf(ERR, "Usage: %s [-s] [-i interface] [-o file]\n", ProgName); fprintf(ERR," -d int set new data limit (128 default)\n"); fprintf(ERR," -o <file> output to <file>\n"); exit(1); } }
fprintf(ERR,"Using logical device %s [%s]\n",device,NIT_DEV); fprintf(ERR,"Output to %s.%s%s",(LOG)?LogName:"stdout", (debug)?" (debug)":"",(backg)?" Backgrounding ":"\n"); if(!LOG) LOG=stdout; signal(SIGINT, death); signal(SIGTERM,death); signal(SIGKILL,death); signal(SIGQUIT,death); if(backg && debug) { fprintf(ERR,"[Cannot bg with debug on]\n"); backg=0; } fprintf(LOG,"\nLog started at => %s [pid %d]\n",NOWtm(),getpid()); fflush(LOG); do_it(); } 编译运行: #gcc -lsocket -lsnl -o sniffer sniffer.c #./sniffer 同时在另一个终端上运行ping 192.168.1.10 Using logical device /dev/bge [/dev/bge] Output to stdout. Log started at => Tue Jul 12 18:13:44 [pid 948] 1 arp request:who has 192.168.1.22 tells 192.168.1.10 2 arp request:who has 192.168.1.22 tells 192.168.1.10 3 arp request:who has 192.168.1.22 tells 192.168.1.10 4 arp request:who has 192.168.1.22 tells 192.168.1.10 5 arp request:who has 192.168.1.22 tells 192.168.1.10
|