diff options
Diffstat (limited to 'contrib/libpcap')
-rw-r--r-- | contrib/libpcap/VERSION | 2 | ||||
-rw-r--r-- | contrib/libpcap/pcap-bpf.c | 51 | ||||
-rw-r--r-- | contrib/libpcap/pcap.c | 20 |
3 files changed, 72 insertions, 1 deletions
diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION index eb49d7c..e2e9c15 100644 --- a/contrib/libpcap/VERSION +++ b/contrib/libpcap/VERSION @@ -1 +1 @@ -0.7 +0.7+multidlt 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; +} diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c index 6b82453..719c14c 100644 --- a/contrib/libpcap/pcap.c +++ b/contrib/libpcap/pcap.c @@ -123,6 +123,24 @@ pcap_datalink(pcap_t *p) } int +pcap_list_datalinks(pcap_t *p, int **dlt_buffer) +{ + if (p->dlt_count <= 0) { + *dlt_buffer = NULL; + return -1; + } + *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count); + if (*dlt_buffer == NULL) { + (void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", + pcap_strerror(errno)); + return -1; + } + (void)memcpy(*dlt_buffer, p->dlt_list, + sizeof(**dlt_buffer) * p->dlt_count); + return (p->dlt_count); +} + +int pcap_snapshot(pcap_t *p) { return (p->snapshot); @@ -281,6 +299,8 @@ pcap_close(pcap_t *p) free(p->sf.base); } else if (p->buffer != NULL) free(p->buffer); + if (p->dlt_list != NULL) + free(p->dlt_list); pcap_freecode(&p->fcode); free(p); |