static int p_seprint(Msg *m) { Hdr *h; uint32_t x; h = (Hdr*)m->ps; if(m->pe < (uint8_t*)h->sname) return -1; /* point past data */ m->ps = h->optdata; /* next protocol */ m->pr = nil; if(m->pe >= (uint8_t*)h->optdata){ x = NetL(h->optmagic); demux(p_mux, x, x, m, &dump); } m->p = seprint(m->p, m->e, "t=%s ht=%d hl=%d hp=%d xid=%x sec=%d fl=%4.4x ca=%V ya=%V sa=%V ga=%V cha=%E magic=%lx", op(h->op), h->htype, h->hlen, h->hops, NetL(h->xid), NetS(h->secs), NetS(h->flags), h->ciaddr, h->yiaddr, h->siaddr, h->giaddr, h->chaddr, (uint32_t)NetL(h->optmagic)); if(m->pe > (uint8_t*)h->sname && *h->sname) m->p = seprint(m->p, m->e, " snam=%s", h->sname); if(m->pe > (uint8_t*)h->file && *h->file) m->p = seprint(m->p, m->e, " file=%s", h->file); return 0; }
static int p_filter(Filter *f, Msg *m) { Hdr *h; if(m->pe - m->ps < ARPLEN) return 0; h = (Hdr*)m->ps; m->ps += ARPLEN; switch(f->subop){ case Ospa: return h->pln == 4 && NetL(h->spa) == f->ulv; case Otpa: return h->pln == 4 && NetL(h->tpa) == f->ulv; case Ostpa: return h->pln == 4 && (NetL(h->tpa) == f->ulv || NetL(h->spa) == f->ulv); case Osha: return memcmp(h->sha, f->a, h->hln) == 0; case Otha: return memcmp(h->tha, f->a, h->hln) == 0; case Ostha: return memcmp(h->sha, f->a, h->hln)==0 ||memcmp(h->tha, f->a, h->hln)==0; } return 0; }
int parsehdr(Hdr *h, uint8_t *s, uint8_t *e) { uint8_t *p; uint8_t n; if(e - s < 4) return -1; p = s; h->flags = NetS(p); p += 2; h->proto = NetS(p); p += 2; h->version = h->flags&GRE_version; if(parthdrlen(h->flags) > e - s) return -1; if(h->flags&(GRE_chksum|GRE_routing)){ h->chksum = NetS(p); p += 2; h->offset = NetS(p); p += 2; } if(h->flags&GRE_key){ h->key = NetL(p); p += 4; } if(h->flags&GRE_seq){ h->seq = NetL(p); p += 4; } if(h->flags&GRE_ack){ h->ack = NetL(p); p += 4; } if(h->flags&GRE_routing){ for(;;){ if(e - p < 4) return -1; if((n = p[3]) == 0) break; p += n; } } return p - s; }
static char* seprintccpopt(char *p, char *e, void *a, int len) { Lcpopt *o; uchar *cp, *ecp; cp = a; ecp = cp+len; for(; cp < ecp; cp += o->len){ o = (Lcpopt*)cp; if(cp + o->len > ecp){ p = seprint(p, e, " bad opt len %ux", o->type); return p; } switch(o->type){ default: p = seprint(p, e, " type=%d ", o->type); break; case 0: p = seprint(p, e, " OUI=(%d %.2ux%.2ux%.2ux) ", o->type, o->data[0], o->data[1], o->data[2]); break; case 17: p = seprint(p, e, " Stac-LZS"); break; case 18: p = seprint(p, e, " Microsoft-PPC=%ux", NetL(o->data)); break; } } return p; }
static int p_filter(Filter *f, Msg *m) { Hdr *h; h = (Hdr*)m->ps; if(m->pe < (uint8_t*)h->sname) return 0; m->ps = h->optdata; switch(f->subop){ case Oca: return NetL(h->ciaddr) == f->ulv || NetL(h->yiaddr) == f->ulv; case Osa: return NetL(h->siaddr) == f->ulv; case Ot: return NetL(h->optmagic) == f->ulv; } return 0; }
static int p_seprint(Msg *m) { Hdr *h; int dport, sport; if(m->pe - m->ps < ILLEN) return -1; h = (Hdr*)m->ps; m->ps += ILLEN; dport = NetS(h->dport); sport = NetS(h->sport); demux(p_mux, sport, dport, m, &dump); m->p = seprint(m->p, m->e, "s=%d d=%d t=%s id=%lud ack=%lud spec=%d ck=%4.4ux ln=%d", sport, dport, pkttype(h->type), (ulong)NetL(h->id), (ulong)NetL(h->ack), h->spec, NetS(h->sum), NetS(h->len)); return 0; }
static int p_filter(Filter *f, Msg *m) { Hdr *h; if(m->pe - m->ps < IPHDR) return 0; h = (Hdr*)m->ps; m->ps += (h->vihl & 0xf) << 2; switch(f->subop){ case Os: return NetL(h->src) == f->ulv; case Od: return NetL(h->dst) == f->ulv; case Osd: return NetL(h->src) == f->ulv || NetL(h->dst) == f->ulv; case Ot: return h->proto == f->ulv; } return 0; }
static int v6hdr_seprint(Msg *m) { int len = IP6HDR; uchar *pkt = m->ps; Hdr *h = (Hdr *) pkt; int pktlen = IP6HDR + NetS(h->length); uchar nexthdr = h->proto; int plen; pkt += len; plen = len; while ( (nexthdr == HBH_HDR) || (nexthdr == ROUT_HDR) || (nexthdr == FRAG_HDR) || (nexthdr == DEST_HDR) ) { switch (nexthdr) { case FRAG_HDR: m->p = seprint(m->p, m->e, "\n xthdr=frag id=%d offset=%d pr=%d more=%d res1=%d res2=%d", NetL(pkt+4), NetS(pkt+2) & ~7, (int) (*pkt), (int) (*(pkt+3) & 0x1), (int) *(pkt+1), (int) (*(pkt+3) & 0x6) ); len = FRAG_HSZ; break; case HBH_HDR: case ROUT_HDR: case DEST_HDR: len = ( ((int) *(pkt+1)) + 1) * 8; break; } if (plen + len > pktlen) { m->p = seprint(m->p, m->e, "bad pkt"); m->pr = &dump; return -1; } plen += len; pkt += len; nexthdr = *pkt; } m->ps = pkt; return 1; }
static char* seprintlcpopt(char *p, char *e, void *a, int len) { Lcpopt *o; int proto, x, period; uchar *cp, *ecp; cp = a; ecp = cp+len; for(; cp < ecp; cp += o->len){ o = (Lcpopt*)cp; if(cp + o->len > ecp || o->len == 0){ p = seprint(p, e, " bad-opt-len=%d", o->len); return p; } switch(o->type){ default: p = seprint(p, e, " (type=%d len=%d)", o->type, o->len); break; case Omtu: p = seprint(p, e, " mtu=%d", NetS(o->data)); break; case Octlmap: p = seprint(p, e, " ctlmap=%ux", NetL(o->data)); break; case Oauth: proto = NetS(o->data); switch(proto) { default: p = seprint(p, e, " auth=%d", proto); break; case PPP_passwd: p = seprint(p, e, " auth=passwd"); break; case PPP_chap: p = seprint(p, e, " (auth=chap data=%2.2ux)", o->data[2]); break; } break; case Oquality: proto = NetS(o->data); switch(proto) { default: p = seprint(p, e, " qproto=%d", proto); break; case PPP_lqm: x = NetL(o->data+2)*10; period = (x+(PPP_period-1))/PPP_period; p = seprint(p, e, " (qproto=lqm period=%d)", period); break; } case Omagic: p = seprint(p, e, " magic=%ux", NetL(o->data)); break; case Opc: p = seprint(p, e, " protocol-compress"); break; case Oac: p = seprint(p, e, " addr-compress"); break; } } return p; }
void main(int argc, char **argv) { uchar *pkt; char *buf, *file, *p, *e; int fd, cfd; int n; Binit(&out, 1, OWRITE); fmtinstall('E', eipfmt); fmtinstall('V', eipfmt); fmtinstall('I', eipfmt); fmtinstall('H', encodefmt); fmtinstall('F', fcallfmt); pkt = malloc(Pktlen+16); pkt += 16; buf = malloc(Blen); e = buf+Blen-1; pflag = 1; Nflag = 32; sflag = 0; mkprotograph(); ARGBEGIN{ default: usage(); case '?': printusage(); printhelp(ARGF()); exits(0); break; case 'M': p = EARGF(usage()); Mflag = atoi(p); break; case 'N': p = EARGF(usage()); Nflag = atoi(p); break; case 'f': p = EARGF(usage()); yyinit(p); yyparse(); break; case 's': sflag = 1; break; case 'h': p = EARGF(usage()); root = findproto(p); if(root == nil) sysfatal("unknown protocol: %s", p); break; case 'd': toflag = 1; break; case 'D': toflag = 1; pcap = 1; break; case 't': tiflag = 1; break; case 'C': Cflag = 1; break; case 'p': pflag = 0; break; }ARGEND; if(pcap) pcaphdr(); if(argc == 0){ file = "/net/ether0"; if(root != nil) root = ðer; } else file = argv[0]; if((!tiflag) && strstr(file, "ether")){ if(root == nil) root = ðer; snprint(buf, Blen, "%s!-1", file); fd = dial(buf, 0, 0, &cfd); if(fd < 0) sysfatal("dialing %s: %r", buf); if(pflag && fprint(cfd, prom, strlen(prom)) < 0) sysfatal("setting %s", prom); } else if((!tiflag) && strstr(file, "ipifc")){ if(root == nil) root = &ip; snprint(buf, Blen, "%s/snoop", file); fd = open(buf, OREAD); if(fd < 0) sysfatal("opening %s: %r", buf); } else { if(root == nil) root = ðer; fd = open(file, OREAD); if(fd < 0) sysfatal("opening %s: %r", file); } filter = compile(filter); if(tiflag){ /* read a trace file */ for(;;){ n = read(fd, pkt, 10); if(n != 10) break; pkttime = NetL(pkt+2); pkttime = (pkttime<<32) | NetL(pkt+6); if(starttime == 0LL) starttime = pkttime; n = NetS(pkt); if(readn(fd, pkt, n) != n) break; if(filterpkt(filter, pkt, pkt+n, root, 1)) if(toflag) tracepkt(pkt, n); else printpkt(buf, e, pkt, pkt+n); } } else { /* read a real time stream */ starttime = nsec(); for(;;){ n = root->framer(fd, pkt, Pktlen); if(n <= 0) break; pkttime = nsec(); if(filterpkt(filter, pkt, pkt+n, root, 1)) if(toflag) tracepkt(pkt, n); else printpkt(buf, e, pkt, pkt+n); } } }
void main(int argc, char *argv[]) { Etherpkt e; Ippkt *ip; long n; int fd, cfd; int ts, len, t; long start; int delta; uchar target[6]; char buf[256]; ulong samples; samples = -1; ARGBEGIN{ case 'd': debug++; break; case 's': samples = atoi(ARGF()); break; }ARGEND; if(argc < 2){ fprint(2, "usage: %s device ip-addr [minutes-per-sample]\n", argv0); exits("usage"); } if(argc > 2) delta = atoi(argv[2])*60*1000; else delta = 5*60*1000; parseether(target, argv[1]); fmtinstall('E', eipfmt); fmtinstall('I', eipfmt); snprint(buf, sizeof(buf), "%s!-2", argv[0]); fd = dial(buf, 0, 0, &cfd); if(fd < 0) error("opening ether data"); if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0) error("connecting"); start = 0; fd = -1; for(;;){ if(fd < 0){ fd = dial(buf, 0, 0, &cfd); if(fd < 0) error("opening ether data"); if(write(cfd, "promiscuous", sizeof("promiscuous")-1) <= 0) error("connecting"); close(cfd); } n = read(fd, &e, sizeof(e)); if(n <= 0) break; ts = NetL(&e.d[60]); n = NetS(&e.d[58]) - ETHERHDRSIZE; if(n < 0) continue; if(start == 0) start = ts; t = NetS(e.type); if(t == 0x0800 || (t&0xFF00) == 0x1000){ ip = (Ippkt*)e.data; len = NetS(ip->length); if(len > n) len = n; if(debug) fprint(2, "%I -> %I %d\n", ip->src, ip->dst, len); if(memcmp(e.s, target, 6) == 0){ protopin[0]++; protoin[0] += len; if(ip->proto){ protopin[ip->proto]++; protoin[ip->proto] += len; } } if(memcmp(e.d, target, 6) == 0){ protopout[0]++; protoout[0] += len; if(ip->proto){ protopout[ip->proto]++; protoout[ip->proto] += len; } } } if(ts - start >= delta){ print("%8.8ld %ld", time(0), ts - start); printproto(0); printproto(IP_MBONEPROTO); printproto(IP_UDPPROTO); printproto(IP_TCPPROTO); print("\n"); start = 0; memset(protoin, 0, sizeof(protoin)); memset(protoout, 0, sizeof(protoout)); memset(protopin, 0, sizeof(protopin)); memset(protopout, 0, sizeof(protopout)); close(fd); fd = -1; if(--samples == 0) break; } } exits(0); }