From d9b420231a4428234f666eb6c44a4dea6f1f2d71 Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 4 Apr 2008 19:37:44 +0000 Subject: From Paolo Abeni and me: split pcap_open_live() into a "get a pcap_t handle" routine, an 'activate a pcap_t handle" routine, and some "set the properties of the pcap_t handle" routines, so that, for example, the buffer size can be set on a BPF device before the device is bound to an interface. Add additional routines to set monitor mode, and make at least an initial attempt at supporting that on Linux, *BSD, and Mac OS X 10.4 and 10.5. (Very much "initial" for Linux, which is a twisty little maze of wireless drivers, many different.) Have a "timeout" member of the pcap_md structure on all platforms, use that on Windows instead of the "timeout" member of the pcap_t structure, and get rid of the "timeout" member of that structure. --- pcap-nit.c | 72 ++++++++++++++++++++++++++++---------------------------------- 1 file changed, 33 insertions(+), 39 deletions(-) (limited to 'pcap-nit.c') diff --git a/pcap-nit.c b/pcap-nit.c index 4cc122e..7ae5309 100644 --- a/pcap-nit.c +++ b/pcap-nit.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.60 2008-02-02 20:58:18 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.61 2008-04-04 19:37:45 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -237,51 +237,43 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf) return (0); } -static void -pcap_close_nit(pcap_t *p) -{ - pcap_close_common(p); - if (p->device != NULL) - free(p->device); -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) +static int +pcap_activate_nit(pcap_t *p) { int fd; struct sockaddr_nit snit; - register pcap_t *p; - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - return (NULL); + if (p->opt.rfmon) { + /* + * No monitor mode on SunOS 3.x or earlier (no + * Wi-Fi *devices* for the hardware that supported + * them!). + */ + return (PCAP_ERROR_RFMON_NOTSUP); } - if (snaplen < 96) + if (p->snapshot < 96) /* * NIT requires a snapshot length of at least 96. */ - snaplen = 96; + p->snapshot = 96; memset(p, 0, sizeof(*p)); p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); if (fd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "socket: %s", pcap_strerror(errno)); goto bad; } snit.snit_family = AF_NIT; - (void)strncpy(snit.snit_ifname, device, NITIFSIZ); + (void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ); if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); goto bad; } - p->snapshot = snaplen; - nit_setflags(p->fd, promisc, to_ms, ebuf); + nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf); /* * NIT supports only ethernets. @@ -291,17 +283,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, p->bufsize = BUFSPACE; p->buffer = (u_char *)malloc(p->bufsize); if (p->buffer == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - goto bad; - } - - /* - * We need the device name in order to send packets. - */ - p->device = strdup(device); - if (p->device == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - free(p->buffer); + strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); goto bad; } @@ -338,14 +320,26 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, p->getnonblock_op = pcap_getnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd; p->stats_op = pcap_stats_nit; - p->close_op = pcap_close_nit; + p->close_op = pcap_close_common; - return (p); + return (0); bad: if (fd >= 0) close(fd); - free(p); - return (NULL); + return (PCAP_ERROR); +} + +pcap_t * +pcap_create(const char *device, char *ebuf) +{ + pcap_t *p; + + p = pcap_create_common(device, ebuf); + if (p == NULL) + return (NULL); + + p->activate_op = pcap_activate_nit; + return (p); } int -- cgit v1.2.3