]> The Tcpdump Group git mirrors - libpcap/blobdiff - pcap-snit.c
From Paolo Abeni and me: split pcap_open_live() into a "get a pcap_t
[libpcap] / pcap-snit.c
index a14a2c30093d6c36782233996ea294474c725fce..13c7e9b41b2d164fe6660944cc221d00e2b4fd95 100644 (file)
@@ -25,7 +25,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.75 2008-02-02 20:58:18 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.76 2008-04-04 19:37:45 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -260,30 +260,29 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
        return (0);
 }
 
-pcap_t *
-pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
-    char *ebuf)
+static int
+pcap_activate_snit(pcap_t *p)
 {
        struct strioctl si;             /* struct for ioctl() */
        struct ifreq ifr;               /* interface request struct */
        int chunksize = CHUNKSIZE;
        int fd;
        static char dev[] = "/dev/nit";
-       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 4.x (no Wi-Fi devices on
+                * hardware supported by SunOS 4.x).
+                */
+               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));
        /*
         * Initially try a read/write open (to allow the inject
         * method to work).  If that fails due to permission
@@ -302,19 +301,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
        if (fd < 0 && errno == EACCES)
                p->fd = fd = open(dev, O_RDONLY);
        if (fd < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
                    pcap_strerror(errno));
                goto bad;
        }
 
        /* arrange to get discrete messages from the STREAM and use NIT_BUF */
        if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
                    pcap_strerror(errno));
                goto bad;
        }
        if (ioctl(fd, I_PUSH, "nbuf") < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
                    pcap_strerror(errno));
                goto bad;
        }
@@ -324,34 +323,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
        si.ic_len = sizeof(chunksize);
        si.ic_dp = (char *)&chunksize;
        if (ioctl(fd, I_STR, (char *)&si) < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
                    pcap_strerror(errno));
                goto bad;
        }
 
        /* request the interface */
-       strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+       strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
        ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
        si.ic_cmd = NIOCBIND;
        si.ic_len = sizeof(ifr);
        si.ic_dp = (char *)&ifr;
        if (ioctl(fd, I_STR, (char *)&si) < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
                        ifr.ifr_name, pcap_strerror(errno));
                goto bad;
        }
 
        /* set the snapshot length */
        si.ic_cmd = NIOCSSNAP;
-       si.ic_len = sizeof(snaplen);
-       si.ic_dp = (char *)&snaplen;
+       si.ic_len = sizeof(p->snapshot);
+       si.ic_dp = (char *)&p->snapshot;
        if (ioctl(fd, I_STR, (char *)&si) < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
+               snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
                    pcap_strerror(errno));
                goto bad;
        }
-       p->snapshot = snaplen;
-       if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
+       if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
                goto bad;
 
        (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
@@ -363,7 +361,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);
+               strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
                goto bad;
        }
 
@@ -403,12 +401,24 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
        p->stats_op = pcap_stats_snit;
        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_snit;
+       return (p);
 }
 
 int