summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/pcap-bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/pcap-bpf.c')
-rw-r--r--contrib/libpcap/pcap-bpf.c51
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;
+}
OpenPOWER on IntegriCloud