CaptureReader::CaptureReader(const Params& params) : BaseReader{params.interface} { char errbuf[PCAP_ERRBUF_SIZE]; // storage of error description const char* device {source.c_str()}; handle = pcap_create(device, errbuf); if(!handle) { throw PcapError("pcap_create", errbuf); } if(int status {pcap_set_snaplen(handle, params.snaplen)}) { throw PcapError("pcap_set_snaplen", pcap_statustostr(status)); } if(int status {pcap_set_promisc(handle, params.promisc ? 1 : 0)}) { throw PcapError("pcap_set_promisc", pcap_statustostr(status)); } if(int status {pcap_set_timeout(handle, params.timeout_ms)}) { throw PcapError("pcap_set_timeout", pcap_statustostr(status)); } if(int status {pcap_set_buffer_size(handle, params.buffer_size)}) { throw PcapError("pcap_set_buffer_size", pcap_statustostr(status)); } if(int status {pcap_activate(handle)}) { throw PcapError("pcap_activate", pcap_statustostr(status)); } pcap_direction_t direction {PCAP_D_INOUT}; switch(params.direction) { using Direction = CaptureReader::Direction; case Direction::IN : direction = PCAP_D_IN; break; case Direction::OUT : direction = PCAP_D_OUT; break; case Direction::INOUT: direction = PCAP_D_INOUT; break; } if(int status {pcap_setdirection(handle, direction)}) { throw PcapError("pcap_setdirection", pcap_statustostr(status)); } bpf_u_int32 localnet, netmask; if(pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0) { throw PcapError("pcap_lookupnet", errbuf); } BPF bpf(handle, params.filter.c_str(), netmask); if(pcap_setfilter(handle, bpf) < 0) { throw PcapError("pcap_setfiltration", pcap_geterr(handle)); } }
pcap_t * pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) { pcap_t *p; int status; p = pcap_create(source, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; /* * Mark this as opened with pcap_open_live(), so that, for * example, we show the full list of DLT_ values, rather * than just the ones that are compatible with capturing * when not in monitor mode. That allows existing applications * to work the way they used to work, but allows new applications * that know about the new open API to, for example, find out the * DLT_ values that they can select without changing whether * the adapter is in monitor mode or not. */ p->oldstyle = 1; status = pcap_activate(p); if (status < 0) goto fail; return (p); fail: if (status == PCAP_ERROR) snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, p->errbuf); else if (status == PCAP_ERROR_NO_SUCH_DEVICE || status == PCAP_ERROR_PERM_DENIED || status == PCAP_ERROR_PROMISC_PERM_DENIED) snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, pcap_statustostr(status), p->errbuf); else snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, pcap_statustostr(status)); pcap_close(p); return (NULL); }
int main(void) { char ebuf[PCAP_ERRBUF_SIZE]; pcap_t *pd; int status = 0; pd = pcap_open_live("lo0", 65535, 0, 1000, ebuf); if (pd == NULL) { pd = pcap_open_live("lo", 65535, 0, 1000, ebuf); if (pd == NULL) { error("Neither lo0 nor lo could be opened: %s", ebuf); return 2; } } status = pcap_activate(pd); if (status != PCAP_ERROR_ACTIVATED) { if (status == 0) error("pcap_activate() of opened pcap_t succeeded"); else if (status == PCAP_ERROR) error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED", pcap_geterr(pd)); else error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED", pcap_statustostr(status)); } return 0; }
pcap_t * reader_libpcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) { pcap_t *p; int status; p = pcap_create(source, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; status = pcap_set_buffer_size(p, config.pcapBufferSize); if (status < 0) goto fail; status = pcap_activate(p); if (status < 0) goto fail; status = pcap_setnonblock(p, TRUE, errbuf); if (status < 0) { pcap_close(p); return (NULL); } return (p); fail: if (status == PCAP_ERROR) snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, pcap_geterr(p)); else if (status == PCAP_ERROR_NO_SUCH_DEVICE || status == PCAP_ERROR_PERM_DENIED) snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, pcap_statustostr(status), pcap_geterr(p)); else snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, pcap_statustostr(status)); pcap_close(p); return (NULL); }
static int tc_pcap_open(pcap_t **pd, char *device, int snap_len, int buf_size) { int status; char ebuf[PCAP_ERRBUF_SIZE]; *ebuf = '\0'; *pd = pcap_create(device, ebuf); if (*pd == NULL) { tc_log_info(LOG_ERR, 0, "pcap create error:%s", ebuf); return TC_ERROR; } status = pcap_set_snaplen(*pd, snap_len); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_snaplen error:%s", pcap_statustostr(status)); return TC_ERROR; } status = pcap_set_promisc(*pd, 0); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_promisc error:%s", pcap_statustostr(status)); return TC_ERROR; } status = pcap_set_timeout(*pd, 1000); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_timeout error:%s", pcap_statustostr(status)); return TC_ERROR; } status = pcap_set_buffer_size(*pd, buf_size); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_buffer_size error:%s", pcap_statustostr(status)); return TC_ERROR; } tc_log_info(LOG_NOTICE, 0, "pcap_set_buffer_size:%d", buf_size); status = pcap_activate(*pd); if (status < 0) { tc_log_info(LOG_ERR, 0, "pcap_activate error:%s", pcap_statustostr(status)); return TC_ERROR; } else if (status > 0) { tc_log_info(LOG_WARN, 0, "pcap activate warn:%s", pcap_statustostr(status)); } return TC_OK; }
static int input_pcap_interface_open(struct input *i) { struct input_pcap_priv *p = i->priv; char errbuf[PCAP_ERRBUF_SIZE + 1] = { 0 }; char *interface = PTYPE_STRING_GETVAL(p->tpriv.iface.p_interface); p->p = pcap_create(interface, errbuf); if (!p->p) { pomlog(POMLOG_ERR "Error opening interface %s : %s", interface, errbuf); return POM_ERR; } char *promisc = PTYPE_BOOL_GETVAL(p->tpriv.iface.p_promisc); int err = pcap_set_promisc(p->p, *promisc); if (err) pomlog(POMLOG_WARN "Error while setting promisc mode : %s", pcap_statustostr(err)); uint32_t buff_size = *PTYPE_UINT32_GETVAL(p->tpriv.iface.p_buff_size); err = pcap_set_buffer_size(p->p, buff_size); if (err) pomlog(POMLOG_WARN "Error while setting the pcap buffer size : %s", pcap_statustostr(err)); err = pcap_activate(p->p); if (err < 0) { pomlog(POMLOG_ERR "Error while activating pcap : %s", pcap_statustostr(err)); return POM_ERR; } else if (err > 0) { pomlog(POMLOG_WARN "Warning while activating pcap : %s", pcap_statustostr(err)); } return input_pcap_common_open(i); }
int main(int argc, char **argv) { register int op; register char *cp, *cmdbuf, *device; long longarg; char *p; int timeout = 1000; int immediate = 0; int nonblock = 0; bpf_u_int32 localnet, netmask; struct bpf_program fcode; char ebuf[PCAP_ERRBUF_SIZE]; int status; int packet_count; device = NULL; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; opterr = 0; while ((op = getopt(argc, argv, "i:mnt:")) != -1) { switch (op) { case 'i': device = optarg; break; case 'm': immediate = 1; break; case 'n': nonblock = 1; break; case 't': longarg = strtol(optarg, &p, 10); if (p == optarg || *p != '\0') { error("Timeout value \"%s\" is not a number", optarg); /* NOTREACHED */ } if (longarg < 0) { error("Timeout value %ld is negative", longarg); /* NOTREACHED */ } if (longarg > INT_MAX) { error("Timeout value %ld is too large (> %d)", longarg, INT_MAX); /* NOTREACHED */ } timeout = (int)longarg; break; default: usage(); /* NOTREACHED */ } } if (device == NULL) { device = pcap_lookupdev(ebuf); if (device == NULL) error("%s", ebuf); } *ebuf = '\0'; pd = pcap_create(device, ebuf); if (pd == NULL) error("%s", ebuf); status = pcap_set_snaplen(pd, 65535); if (status != 0) error("%s: pcap_set_snaplen failed: %s", device, pcap_statustostr(status)); if (immediate) { status = pcap_set_immediate_mode(pd, 1); if (status != 0) error("%s: pcap_set_immediate_mode failed: %s", device, pcap_statustostr(status)); } status = pcap_set_timeout(pd, timeout); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); status = pcap_activate(pd); if (status < 0) { /* * pcap_activate() failed. */ error("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us * of a problem it had. */ warning("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { localnet = 0; netmask = 0; warning("%s", ebuf); } cmdbuf = copy_argv(&argv[optind]); if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0) error("%s", pcap_geterr(pd)); if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); if (pcap_setnonblock(pd, nonblock, ebuf) == -1) error("pcap_setnonblock failed: %s", ebuf); printf("Listening on %s\n", device); for (;;) { packet_count = 0; status = pcap_dispatch(pd, -1, countme, (u_char *)&packet_count); if (status < 0) break; if (status != 0) { printf("%d packets seen, %d packets counted after pcap_dispatch returns\n", status, packet_count); } } if (status == -2) { /* * We got interrupted, so perhaps we didn't * manage to finish a line we were printing. * Print an extra newline, just in case. */ putchar('\n'); } (void)fflush(stdout); if (status == -1) { /* * Error. Report it. */ (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); } pcap_close(pd); exit(status == -1 ? 1 : 0); }
int main(int argc, char **argv) { register int op; register char *cp, *device; int dorfmon, dopromisc, snaplen, useactivate, bufsize; char ebuf[PCAP_ERRBUF_SIZE]; pcap_t *pd; int status = 0; device = NULL; dorfmon = 0; dopromisc = 0; snaplen = MAXIMUM_SNAPLEN; bufsize = 0; useactivate = 0; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; opterr = 0; while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) { switch (op) { case 'i': device = optarg; break; case 'I': dorfmon = 1; useactivate = 1; /* required for rfmon */ break; case 'p': dopromisc = 1; break; case 's': { char *end; snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); else if (snaplen == 0) snaplen = MAXIMUM_SNAPLEN; break; } case 'B': bufsize = atoi(optarg)*1024; if (bufsize <= 0) error("invalid packet buffer size %s", optarg); useactivate = 1; /* required for bufsize */ break; case 'a': useactivate = 1; break; default: usage(); /* NOTREACHED */ } } if (useactivate) { pd = pcap_create(device, ebuf); if (pd == NULL) error("%s", ebuf); status = pcap_set_snaplen(pd, snaplen); if (status != 0) error("%s: pcap_set_snaplen failed: %s", device, pcap_statustostr(status)); if (dopromisc) { status = pcap_set_promisc(pd, 1); if (status != 0) error("%s: pcap_set_promisc failed: %s", device, pcap_statustostr(status)); } if (dorfmon) { status = pcap_set_rfmon(pd, 1); if (status != 0) error("%s: pcap_set_rfmon failed: %s", device, pcap_statustostr(status)); } status = pcap_set_timeout(pd, 1000); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); if (bufsize != 0) { status = pcap_set_buffer_size(pd, bufsize); if (status != 0) error("%s: pcap_set_buffer_size failed: %s", device, pcap_statustostr(status)); } status = pcap_activate(pd); if (status < 0) { /* * pcap_activate() failed. */ error("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us * of a problem it had. */ warning("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } } else { *ebuf = '\0'; pd = pcap_open_live(device, 65535, 0, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); } pcap_close(pd); exit(status < 0 ? 1 : 0); }
int pcap_activate(pcap_t *p) { int status = 0; int fd; struct ifreq ifr; struct bpf_version bv; struct bpf_dltlist bdl; int new_dlt; u_int v; fd = bpf_open(p); if (fd < 0) { status = fd; goto bad; } p->fd = fd; if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "kernel bpf filter out of date"); status = PCAP_ERROR; goto bad; } #if 0 /* Just use the kernel default */ v = 32768; /* XXX this should be a user-accessible hook */ /* Ignore the return value - this is because the call fails on * BPF systems that don't have kernel malloc. And if the call * fails, it's no big deal, we just continue to use the standard * buffer size. */ (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); #endif /* * Set the buffer size. */ if (p->opt.buffer_size != 0) { /* * A buffer size was explicitly specified; use it. */ if (ioctl(fd, BIOCSBLEN, (caddr_t)&p->opt.buffer_size) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSBLEN: %s: %s", p->opt.source, pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } } /* * Now bind to the device. */ (void)strlcpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { status = check_setif_failure(p, errno); goto bad; } /* Get the data link layer type. */ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } #if _BSDI_VERSION - 0 >= 199510 /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ switch (v) { case DLT_SLIP: v = DLT_SLIP_BSDOS; break; case DLT_PPP: v = DLT_PPP_BSDOS; break; case 11: /*DLT_FR*/ v = DLT_FRELAY; break; case 12: /*DLT_C_HDLC*/ v = DLT_CHDLC; break; } #endif /* * We know the default link type -- now determine all the DLTs * this interface supports. If this fails with EINVAL, it's * not fatal; we just don't get to use the feature later. */ if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) { status = PCAP_ERROR; goto bad; } p->dlt_count = bdl.bfl_len; p->dlt_list = bdl.bfl_list; /* * *BSD with the new 802.11 ioctls. * Do we want monitor mode? */ if (p->opt.rfmon) { /* * Try to put the interface into monitor mode. */ status = monitor_mode(p, 1); if (status != 0) { /* * We failed. */ goto bad; } /* * We're in monitor mode. * Try to find the best 802.11 DLT_ value and, if we * succeed, try to switch to that mode if we're not * already in that mode. */ new_dlt = find_802_11(&bdl); if (new_dlt != -1) { /* * We have at least one 802.11 DLT_ value. * new_dlt is the best of the 802.11 * DLT_ values in the list. * * If the new mode we want isn't the default mode, * attempt to select the new mode. */ if (new_dlt != v) { if (ioctl(p->fd, BIOCSDLT, &new_dlt) != -1) { /* * We succeeded; make this the * new DLT_ value. */ v = new_dlt; } } } } p->linktype = v; /* set timeout */ if (p->md.timeout) { struct timeval to; to.tv_sec = p->md.timeout / 1000; to.tv_usec = (p->md.timeout * 1000) % 1000000; if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } } if (p->opt.promisc) { /* set promiscuous mode, just warn if it fails */ if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", pcap_strerror(errno)); status = PCAP_WARNING_PROMISC_NOTSUP; } } if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } p->bufsize = v; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); status = PCAP_ERROR; goto bad; } if (status < 0) goto bad; p->activated = 1; return (status); bad: pcap_cleanup_bpf(p); if (p->errbuf[0] == '\0') { /* * No error message supplied by the activate routine; * for the benefit of programs that don't specially * handle errors other than PCAP_ERROR, return the * error message corresponding to the status. */ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_statustostr(status)); } return (status); }
static ulink_recv_t *ulink_recv_open(const char *netdev) { int err; ulink_recv_t *t = NULL; if (getenv("debug") != NULL) { debug = 1; } t = (ulink_recv_t *)malloc(sizeof(ulink_recv_t)); memset(t, 0, sizeof(ulink_recv_t)); /* init the pcap */ { char errbuf[PCAP_ERRBUF_SIZE]; t->pcap_handle = pcap_create(netdev, errbuf); if (NULL == t->pcap_handle) { LOG_("pcap_open_live failed. %s", errbuf); free(t); return NULL; } err = pcap_set_snaplen(t->pcap_handle, 128); if (err) { LOG_("pcap_set_snaplen failed: %s", pcap_statustostr(err)); pcap_close(t->pcap_handle); free(t); return NULL; } err = pcap_set_rfmon(t->pcap_handle, 1); if (err) { LOG_("pcap_set_rfmon failed: %s", pcap_statustostr(err)); pcap_close(t->pcap_handle); free(t); return NULL; } err = pcap_set_timeout(t->pcap_handle, CHANNEL_SCAN_TIME); if (err) { LOG_("pcap_set_timeout failed: %s", pcap_statustostr(err)); pcap_close(t->pcap_handle); free(t); return NULL; } err = pcap_activate(t->pcap_handle); if (err) { LOG_("pcap_activate failed: %s", pcap_statustostr(err)); pcap_close(t->pcap_handle); free(t); return NULL; } /* filter */ err = pcap_compile(t->pcap_handle, &t->bpf, "ether multicast and type data subtype qos-data or subtype data", 1, 0); if (err) { LOG_("pcap_compile failed: %s", pcap_geterr(t->pcap_handle)); pcap_close(t->pcap_handle); free(t); return NULL; } err = pcap_setfilter(t->pcap_handle, &t->bpf); if (err) { LOG_("pcap_setfilter failed: %s", pcap_statustostr(err)); pcap_freecode(&t->bpf); pcap_close(t->pcap_handle); free(t); return NULL; } } return t; }
int main(int argc, char **argv) { char *cp, *device; int op; int dorfmon, useactivate; char ebuf[PCAP_ERRBUF_SIZE]; char *infile; char *cmdbuf; pcap_t *pd; int status = 0; int pcap_fd; #if defined(USE_BPF) struct bpf_program bad_fcode; struct bpf_insn uninitialized[INSN_COUNT]; #elif defined(USE_SOCKET_FILTERS) struct sock_fprog bad_fcode; struct sock_filter uninitialized[INSN_COUNT]; #endif struct bpf_program fcode; device = NULL; dorfmon = 0; useactivate = 0; infile = NULL; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; opterr = 0; while ((op = getopt(argc, argv, "aF:i:I")) != -1) { switch (op) { case 'a': useactivate = 1; break; case 'F': infile = optarg; break; case 'i': device = optarg; break; case 'I': dorfmon = 1; useactivate = 1; /* required for rfmon */ break; default: usage(); /* NOTREACHED */ } } if (device == NULL) { /* * No interface specified; get whatever pcap_lookupdev() * finds. */ device = pcap_lookupdev(ebuf); if (device == NULL) { error("couldn't find interface to use: %s", ebuf); } } if (infile != NULL) { /* * Filter specified with "-F" and a file containing * a filter. */ cmdbuf = read_infile(infile); } else { if (optind < argc) { /* * Filter specified with arguments on the * command line. */ cmdbuf = copy_argv(&argv[optind+1]); } else { /* * No filter specified; use an empty string, which * compiles to an "accept all" filter. */ cmdbuf = ""; } } if (useactivate) { pd = pcap_create(device, ebuf); if (pd == NULL) error("%s: pcap_create() failed: %s", device, ebuf); status = pcap_set_snaplen(pd, 65535); if (status != 0) error("%s: pcap_set_snaplen failed: %s", device, pcap_statustostr(status)); status = pcap_set_promisc(pd, 1); if (status != 0) error("%s: pcap_set_promisc failed: %s", device, pcap_statustostr(status)); if (dorfmon) { status = pcap_set_rfmon(pd, 1); if (status != 0) error("%s: pcap_set_rfmon failed: %s", device, pcap_statustostr(status)); } status = pcap_set_timeout(pd, 1000); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); status = pcap_activate(pd); if (status < 0) { /* * pcap_activate() failed. */ error("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us * of a problem it had. */ warning("%s: %s\n(%s)", device, pcap_statustostr(status), pcap_geterr(pd)); } } else { *ebuf = '\0'; pd = pcap_open_live(device, 65535, 1, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); } pcap_fd = pcap_fileno(pd); /* * Try setting a filter with an uninitialized bpf_program * structure. This should cause valgrind to report a * problem. * * We don't check for errors, because it could get an * error due to a bad pointer or count. */ #if defined(USE_BPF) ioctl(pcap_fd, BIOCSETF, &bad_fcode); #elif defined(USE_SOCKET_FILTERS) setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode, sizeof(bad_fcode)); #endif /* * Try setting a filter with an initialized bpf_program * structure that points to an uninitialized program. * That should also cause valgrind to report a problem. * * We don't check for errors, because it could get an * error due to a bad pointer or count. */ #if defined(USE_BPF) bad_fcode.bf_len = INSN_COUNT; bad_fcode.bf_insns = uninitialized; ioctl(pcap_fd, BIOCSETF, &bad_fcode); #elif defined(USE_SOCKET_FILTERS) bad_fcode.len = INSN_COUNT; bad_fcode.filter = uninitialized; setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode, sizeof(bad_fcode)); #endif /* * Now compile a filter and set the filter with that. * That should *not* cause valgrind to report a * problem. */ if (pcap_compile(pd, &fcode, cmdbuf, 1, 0) < 0) error("can't compile filter: %s", pcap_geterr(pd)); if (pcap_setfilter(pd, &fcode) < 0) error("can't set filter: %s", pcap_geterr(pd)); pcap_close(pd); exit(status < 0 ? 1 : 0); }
static int dns_run_pcap_loop (void) { pcap_t *pcap_obj; char pcap_error[PCAP_ERRBUF_SIZE]; struct bpf_program fp = { 0 }; int status; /* Don't block any signals */ { sigset_t sigmask; sigemptyset (&sigmask); pthread_sigmask (SIG_SETMASK, &sigmask, NULL); } /* Passing `pcap_device == NULL' is okay and the same as passign "any" */ DEBUG ("dns plugin: Creating PCAP object.."); pcap_obj = pcap_open_live ((pcap_device != NULL) ? pcap_device : "any", PCAP_SNAPLEN, 0 /* Not promiscuous */, (int) CDTIME_T_TO_MS (plugin_get_interval () / 2), pcap_error); if (pcap_obj == NULL) { ERROR ("dns plugin: Opening interface `%s' " "failed: %s", (pcap_device != NULL) ? pcap_device : "any", pcap_error); return (PCAP_ERROR); } status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0); if (status < 0) { ERROR ("dns plugin: pcap_compile failed: %s", pcap_statustostr (status)); return (status); } status = pcap_setfilter (pcap_obj, &fp); if (status < 0) { ERROR ("dns plugin: pcap_setfilter failed: %s", pcap_statustostr (status)); return (status); } DEBUG ("dns plugin: PCAP object created."); dnstop_set_pcap_obj (pcap_obj); dnstop_set_callback (dns_child_callback); status = pcap_loop (pcap_obj, -1 /* loop forever */, handle_pcap /* callback */, NULL /* user data */); INFO ("dns plugin: pcap_loop exited with status %i.", status); /* We need to handle "PCAP_ERROR" specially because libpcap currently * doesn't return PCAP_ERROR_IFACE_NOT_UP for compatibility reasons. */ if (status == PCAP_ERROR) status = PCAP_ERROR_IFACE_NOT_UP; pcap_close (pcap_obj); return (status); } /* int dns_run_pcap_loop */
static int tc_pcap_open(pcap_t **pd, char *device, int snap_len, int buf_size) { int status; char ebuf[PCAP_ERRBUF_SIZE]; *ebuf = '\0'; *pd = pcap_create(device, ebuf); if (*pd == NULL) { tc_log_info(LOG_ERR, 0, "pcap create error:%s", ebuf); fprintf(stderr, "pcap create error:%s\n", ebuf); return TC_ERR; } status = pcap_set_snaplen(*pd, snap_len); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_snaplen error:%s", pcap_statustostr(status)); return TC_ERR; } status = pcap_set_promisc(*pd, 1); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_promisc error:%s", pcap_statustostr(status)); } status = pcap_set_timeout(*pd, 10); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_timeout error:%s", pcap_statustostr(status)); return TC_ERR; } status = pcap_set_buffer_size(*pd, buf_size); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_buffer_size error:%s", pcap_statustostr(status)); return TC_ERR; } tc_log_info(LOG_NOTICE, 0, "pcap_set_buffer_size:%d", buf_size); #if (HAVE_SET_IMMEDIATE_MODE) status = pcap_set_immediate_mode(*pd, 1); if (status != 0) { tc_log_info(LOG_ERR, 0, "pcap_set_immediate_mode error:%s", pcap_statustostr(status)); return TC_ERR; } #endif status = pcap_activate(*pd); if (status < 0) { tc_log_info(LOG_ERR, 0, "pcap_activate error:%s", pcap_statustostr(status)); return TC_ERR; } else if (status > 0) { tc_log_info(LOG_WARN, 0, "pcap activate warn:%s", pcap_statustostr(status)); } return TC_OK; }
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf) { char name[PCAP_BUF_SIZE]; int type; pcap_t *fp; int status; /* * A null device name is equivalent to the "any" device - * which might not be supported on this platform, but * this means that you'll get a "not supported" error * rather than, say, a crash when we try to dereference * the null pointer. */ if (source == NULL) source = "any"; if (strlen(source) > PCAP_BUF_SIZE) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); return NULL; } /* * Determine the type of the source (file, local, remote) and, * if it's file or local, the name of the file or capture device. */ if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1) return NULL; switch (type) { case PCAP_SRC_FILE: return pcap_open_offline(name, errbuf); case PCAP_SRC_IFLOCAL: fp = pcap_create(name, errbuf); break; case PCAP_SRC_IFREMOTE: /* * Although we already have host, port and iface, we prefer * to pass only 'source' to pcap_open_rpcap(), so that it * has to call pcap_parsesrcstr() again. * This is less optimized, but much clearer. */ return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf); default: pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE); return NULL; } if (fp == NULL) return (NULL); status = pcap_set_snaplen(fp, snaplen); if (status < 0) goto fail; if (flags & PCAP_OPENFLAG_PROMISCUOUS) { status = pcap_set_promisc(fp, 1); if (status < 0) goto fail; } if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS) { status = pcap_set_immediate_mode(fp, 1); if (status < 0) goto fail; } #ifdef _WIN32 /* * This flag is supported on Windows only. * XXX - is there a way to support it with * the capture mechanisms on UN*X? It's not * exactly a "set direction" operation; I * think it means "do not capture packets * injected with pcap_sendpacket() or * pcap_inject()". */ /* disable loopback capture if requested */ if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL) fp->opt.nocapture_local = 1; #endif /* _WIN32 */ status = pcap_set_timeout(fp, read_timeout); if (status < 0) goto fail; status = pcap_activate(fp); if (status < 0) goto fail; return fp; fail: if (status == PCAP_ERROR) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", name, fp->errbuf); else if (status == PCAP_ERROR_NO_SUCH_DEVICE || status == PCAP_ERROR_PERM_DENIED || status == PCAP_ERROR_PROMISC_PERM_DENIED) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", name, pcap_statustostr(status), fp->errbuf); else pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", name, pcap_statustostr(status)); pcap_close(fp); return NULL; }