static void show_dlts_and_exit(pcap_t *pd) { int n_dlts; int *dlts = 0; const char *dlt_name; n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); (void) fprintf(stderr, "Data link types (use option -y to set):\n"); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, pcap_datalink_val_to_description(dlts[n_dlts])); /* * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (not supported)"); putchar('\n'); } else { (void) fprintf(stderr, " DLT %d (not supported)\n", dlts[n_dlts]); } } free(dlts); exit(0); }
static u_int ppi_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { if_printer printer; const ppi_header_t *hdr; u_int caplen = h->caplen; u_int length = h->len; uint16_t len; uint32_t dlt; uint32_t hdrlen; struct pcap_pkthdr nhdr; if (caplen < sizeof(ppi_header_t)) { ND_PRINT((ndo, "[|ppi]")); return (caplen); } hdr = (const ppi_header_t *)p; len = EXTRACT_LE_16BITS(&hdr->ppi_len); if (caplen < len) { /* * If we don't have the entire PPI header, don't * bother. */ ND_PRINT((ndo, "[|ppi]")); return (caplen); } if (len < sizeof(ppi_header_t)) { ND_PRINT((ndo, "[|ppi]")); return (len); } dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt); if (ndo->ndo_eflag) ppi_header_print(ndo, p, length); length -= len; caplen -= len; p += len; if ((printer = lookup_printer(dlt)) != NULL) { nhdr = *h; nhdr.caplen = caplen; nhdr.len = length; hdrlen = printer(ndo, &nhdr, p); } else { if (!ndo->ndo_eflag) ppi_header_print(ndo, (const u_char *)hdr, length + len); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); hdrlen = 0; } return (len + hdrlen); }
static void show_dlts_and_exit(const char *device, pcap_t *pd) { int n_dlts; int *dlts = 0; const char *dlt_name; n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); /* * If the interface is known to support monitor mode, indicate * whether these are the data link types available when not in * monitor mode, if -I wasn't specified, or when in monitor mode, * when -I was specified (the link-layer types available in * monitor mode might be different from the ones available when * not in monitor mode). */ if (supports_monitor_mode) (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", device, Iflag ? "when in monitor mode" : "when not in monitor mode"); else (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", device); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, pcap_datalink_val_to_description(dlts[n_dlts])); /* * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL && lookup_ndo_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (printing not supported)"); putchar('\n'); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", dlts[n_dlts]); } } free(dlts); exit(0); }
/* * This is the top level routine of the printer. 'p' points * to the ether header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int pktap_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { uint32_t dlt, hdrlen, rectype; u_int caplen = h->caplen; u_int length = h->len; if_printer printer; const pktap_header_t *hdr; struct pcap_pkthdr nhdr; ndo->ndo_protocol = "pktap_if"; if (caplen < sizeof(pktap_header_t)) { nd_print_trunc(ndo); return (caplen); } hdr = (const pktap_header_t *)p; dlt = EXTRACT_LE_U_4(hdr->pkt_dlt); hdrlen = EXTRACT_LE_U_4(hdr->pkt_len); if (hdrlen < sizeof(pktap_header_t)) { /* * Claimed header length < structure length. * XXX - does this just mean some fields aren't * being supplied, or is it truly an error (i.e., * is the length supplied so that the header can * be expanded in the future)? */ nd_print_trunc(ndo); return (caplen); } if (caplen < hdrlen) { nd_print_trunc(ndo); return (caplen); } if (ndo->ndo_eflag) pktap_header_print(ndo, p, length); length -= hdrlen; caplen -= hdrlen; p += hdrlen; rectype = EXTRACT_LE_U_4(hdr->pkt_rectype); switch (rectype) { case PKT_REC_NONE: ND_PRINT("no data"); break; case PKT_REC_PACKET: if ((printer = lookup_printer(dlt)) != NULL) { nhdr = *h; nhdr.caplen = caplen; nhdr.len = length; hdrlen += printer(ndo, &nhdr, p); } else { if (!ndo->ndo_eflag) pktap_header_print(ndo, (const u_char *)hdr, length + hdrlen); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } break; } return (hdrlen); }
int main(int argc, char *argv[]) { struct bpf_program fcode; pcap_handler printer; char ebuf[PCAP_ERRBUF_SIZE]; int c,i,snaplen=512,size,packetcnt; bpf_u_int32 myself, localnet, netmask; unsigned char *pcap_userdata; filter_rule = argv[1]; signal(SIGINT,sig_int); opterr =0; if(argc-1 <1) { usage(); exit(1); } while( (c=getopt(argc,argv,"i:c:pher")) != -1) { switch(c) { case 'i' : device = optarg; break; case 'p' : pflag = 1; break; case 'c': cflag = 1; packetcnt = atoi(optarg); if(packetcnt <=0) { fprintf(stderr, "invalid pacet number %s",optarg); exit(1); } break; case 'e': eflag =1; break; case 'r': rflag =1; break; case 'h': usage(); exit(1); } } if(device == NULL) { if( (device = pcap_lookupdev(ebuf) ) ==NULL) { perror(ebuf); exit(-1); } } fprintf(stdout,"device = %s\n", device); pd = pcap_open_live(device , snaplen, PROMISCOUS, 1000, ebuf); if(pd == NULL) { perror(ebuf); exit(-1); } i = pcap_snapshot(pd); if(snaplen <i) { perror(ebuf); exit(-1); } if(pcap_lookupnet(device, &localnet, &netmask, ebuf) <0) { perror(ebuf); exit(-1); } setuid(getuid()); if(pcap_compile(pd, &fcode, filter_rule , 0, netmask)<0) { perror(ebuf); exit(-1); } if(pcap_setfilter(pd, &fcode) <0) { perror(ebuf); exit(-1); } fflush(stderr); printer = lookup_printer(pcap_datalink(pd)); pcap_userdata = 0; if(pcap_loop(pd,packetcnt, printer, pcap_userdata) <0) { perror("pcap_loop error"); exit(-1); } pcap_close(pd); exit(0); }
/* * This is the top level routine of the printer. 'p' points * to the ether header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int pktap_if_print(struct netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { uint32_t dlt, hdrlen, rectype; u_int caplen = h->caplen; u_int length = h->len; if_ndo_printer ndo_printer; if_printer printer; pktap_header_t *hdr; if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) { ND_PRINT((ndo, "[|pktap]")); return (0); } hdr = (pktap_header_t *)p; dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); if (hdrlen < sizeof(pktap_header_t)) { /* * Claimed header length < structure length. * XXX - does this just mean some fields aren't * being supplied, or is it truly an error (i.e., * is the length supplied so that the header can * be expanded in the future)? */ ND_PRINT((ndo, "[|pktap]")); return (0); } if (caplen < hdrlen || length < hdrlen) { ND_PRINT((ndo, "[|pktap]")); return (hdrlen); } if (ndo->ndo_eflag) pktap_header_print(ndo, p, length); length -= hdrlen; caplen -= hdrlen; p += hdrlen; rectype = EXTRACT_LE_32BITS(&hdr->pkt_rectype); switch (rectype) { case PKT_REC_NONE: ND_PRINT((ndo, "no data")); break; case PKT_REC_PACKET: if ((printer = lookup_printer(dlt)) != NULL) { printer(h, p); } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { ndo_printer(ndo, h, p); } else { if (!ndo->ndo_eflag) pktap_header_print(ndo, (u_char *)hdr, length + hdrlen); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } break; } return (hdrlen); }
void pcap_read(const char *dumpfile, const char *interface, const char *filter_cmd, int snaplen) { int fd; const char *device = NULL; struct bpf_program bprog; if (dumpfile != NULL) { /* read from a saved pcap file */ pd = pcap_open_offline(dumpfile, errbuf); if (pd == NULL) err(1, "%s", errbuf); } else { if (interface != NULL) { device = interface; } else { device = pcap_lookupdev(errbuf); if (device == NULL) errx(1, "%s", errbuf); } if (snaplen == 0) snaplen = DEFAULT_SNAPLEN; fprintf(stderr, "pcap_read: reading from %s with snaplen:%d\n", device, snaplen); pd = pcap_open_live(device, snaplen, 1, 0, errbuf); if (pd == NULL) errx(1, "%s", errbuf); } if (pcap_compile(pd, &bprog, filter_cmd, 0, 0) < 0) err(1, "pcap_compile: %s", pcap_geterr(pd)); else if (pcap_setfilter(pd, &bprog) < 0) err(1, "pcap_setfilter: %s", pcap_geterr(pd)); net_reader = lookup_printer(pcap_datalink(pd)); fd = fileno(pcap_file(pd)); if (device != NULL) { /* let user own process after interface has been opened */ setuid(getuid()); #if defined(BSD) && defined(BPF_MAXBUFSIZE) { /* check the buffer size */ u_int bufsize; if (ioctl(fd, BIOCGBLEN, (caddr_t)&bufsize) < 0) perror("BIOCGBLEN"); else fprintf(stderr, "bpf buffer size is %d\n", bufsize); } #endif /* BSD */ } while (1) { int cnt; cnt = pcap_dispatch(pd, 1, dump_reader, 0); if (cnt < 0) break; if (dumpfile != NULL && cnt == 0) /* EOF */ break; } pcap_close(pd); }
int main(int argc, char **argv) { register int cnt, op, i; bpf_u_int32 localnet, netmask; register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; pcap_handler printer; struct bpf_program fcode; RETSIGTYPE (*oldhandler)(int); u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; cnt = -1; device = NULL; infile = NULL; RFileName = NULL; WFileName = NULL; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; if (abort_on_misalignment(ebuf) < 0) error("%s", ebuf); opterr = 0; while ( (op = getopt(argc, argv, "ac:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF) switch (op) { case 'a': ++aflag; break; case 'c': cnt = atoi(optarg); if (cnt <= 0) error("invalid packet count %s", optarg); break; case 'd': ++dflag; break; case 'e': ++eflag; break; case 'f': ++fflag; break; case 'F': infile = optarg; break; case 'i': device = optarg; break; case 'l': #ifdef HAVE_SETLINEBUF setlinebuf(stdout); #else setvbuf(stdout, NULL, _IOLBF, 0); #endif break; case 'n': ++nflag; break; case 'N': ++Nflag; break; case 'O': Oflag = 0; break; case 'p': ++pflag; break; case 'q': ++qflag; break; case 'r': RFileName = optarg; break; case 's': snaplen = atoi(optarg); if (snaplen <= 0) error("invalid snaplen %s", optarg); break; case 'S': ++Sflag; break; case 't': --tflag; break; case 'T': if (strcasecmp(optarg, "vat") == 0) packettype = PT_VAT; else if (strcasecmp(optarg, "wb") == 0) packettype = PT_WB; else if (strcasecmp(optarg, "rpc") == 0) packettype = PT_RPC; else if (strcasecmp(optarg, "rtp") == 0) packettype = PT_RTP; else if (strcasecmp(optarg, "rtcp") == 0) packettype = PT_RTCP; else error("unknown packet type `%s'", optarg); break; case 'v': ++vflag; break; case 'w': WFileName = optarg; break; #ifdef YYDEBUG case 'Y': { /* Undocumented flag */ extern int yydebug; yydebug = 1; } break; #endif case 'x': ++xflag; break; default: usage(); /* NOTREACHED */ } if (aflag && nflag) error("-a and -n options are incompatible"); if (tflag > 0) thiszone = gmt2local(0); if (RFileName != NULL) { /* * We don't need network access, so set it back to the user id. * Also, this prevents the user from reading anyone's * trace file. */ setuid(getuid()); pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); localnet = 0; netmask = 0; if (fflag != 0) error("-f and -r options are incompatible"); } else { if (device == NULL) { device = pcap_lookupdev(ebuf); if (device == NULL) error("%s", ebuf); } pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); i = pcap_snapshot(pd); if (snaplen < i) { warning("snaplen raised from %d to %d", snaplen, i); snaplen = i; } if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { localnet = 0; netmask = 0; warning("%s", ebuf); } /* * Let user own process after socket has been opened. */ setuid(getuid()); } if (infile) cmdbuf = read_infile(infile); else cmdbuf = copy_argv(&argv[optind]); if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); if (dflag) { bpf_dump(&fcode, dflag); exit(0); } init_addrtoname(localnet, netmask); (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); /* Cooperate with nohup(1) */ if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); if (WFileName) { pcap_dumper_t *p = pcap_dump_open(pd, WFileName); if (p == NULL) error("%s", pcap_geterr(pd)); printer = pcap_dump; pcap_userdata = (u_char *)p; } else { printer = lookup_printer(pcap_datalink(pd)); pcap_userdata = 0; } if (RFileName == NULL) { (void)fprintf(stderr, "%s: listening on %s\n", program_name, device); (void)fflush(stderr); } if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) { (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); exit(1); } pcap_close(pd); exit(0); }