diff options
Diffstat (limited to 'contrib/libpcap/pcap-bpf.c')
-rw-r--r-- | contrib/libpcap/pcap-bpf.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 0d97d41..6d74af7 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -204,9 +204,12 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) int fd; struct ifreq ifr; struct bpf_version bv; + struct bpf_dltlist bdl; u_int v; pcap_t *p; + bzero(&bdl, sizeof(bdl)); + p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", @@ -323,6 +326,30 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) #endif p->linktype = v; + /* + * We know the default link type -- now determine any additional + * DLTs this interface supports. If this fails, it's not fatal; + * we just don't get to use the feature later. + */ + if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) == 0) { + bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len); + if (bdl.bfl_list == NULL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + goto bad; + } + + if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) < 0) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + free(bdl.bfl_list); + goto bad; + } + + p->dlt_count = bdl.bfl_len; + p->dlt_list = bdl.bfl_list; + } + /* set timeout */ if (to_ms != 0) { struct timeval to; @@ -416,6 +443,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) return (p); bad: (void)close(fd); + if (bdl.bfl_list != NULL) + free(bdl.bfl_list); free(p); return (NULL); } @@ -441,3 +470,25 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) } return (0); } + +int +pcap_set_datalink(pcap_t *p, int dlt) +{ + int i; + + for (i = 0; i < p->dlt_count; i++) + if (p->dlt_list[i] == dlt) + break; + if (i >= p->dlt_count) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "No such DLT as %d", dlt); + return -1; + } + if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "Cannot set DLT %d: %s", dlt, strerror(errno)); + return -1; + } + p->linktype = dlt; + return 0; +} |