aboutsummaryrefslogtreecommitdiffstats
path: root/pcap-nit.c
diff options
context:
space:
mode:
authorguy <guy>2008-04-04 19:37:44 +0000
committerguy <guy>2008-04-04 19:37:44 +0000
commitd9b420231a4428234f666eb6c44a4dea6f1f2d71 (patch)
tree83275824f39128a3f3ce9860b5cd8ed99b5a216f /pcap-nit.c
parent19d1a629c7adea3d04f53c69d08cc4ce9e1693b0 (diff)
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.
Diffstat (limited to 'pcap-nit.c')
-rw-r--r--pcap-nit.c72
1 files changed, 33 insertions, 39 deletions
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