*** Linux.vmdk.REDO ***
libpcap-0.4/pcap-nit.c
   444
  1774
    34
      13021  6253457565   7763
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap-nit.c,v 1.31 96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/nit.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
 * The chunk size for NIT.  This is the amount of buffering
 * done for read calls.
#define CHUNKSIZE (2*1024)
 * The total buffer space used by NIT.
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static int nit_setflags(int, int, int, char *);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      *ps = p->md.stat;
      return (0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      register int cc, n;
      register struct bpf_insn *fcode = p->fcode.bf_insns;
      register u_char *bp, *cp, *ep;
      register struct nit_hdr *nh;
      register int caplen;
      cc = p->cc;
      if (cc == 0) {
            cc = read(p->fd, (char *)p->buffer, p->bufsize);
            if (cc < 0) {
                  if (errno == EWOULDBLOCK)
                        return (0);
                  sprintf(p->errbuf, "pcap_read: %s",
                        pcap_strerror(errno));
                  return (-1);
            bp = p->buffer;
      } else
            bp = p->bp;
       * Loop through each packet.  The increment expression
       * rounds up to the next int boundary past the end of
       * the previous packet.
       */
      n = 0;
      ep = bp + cc;
      while (bp < ep) {
            nh = (struct nit_hdr *)bp;
            cp = bp + sizeof(*nh);
            switch (nh->nh_state) {
            case NIT_CATCH:
                  break;
            case NIT_NOMBUF:
            case NIT_NOCLUSTER:
            case NIT_NOSPACE:
                  p->md.stat.ps_drop = nh->nh_dropped;
                  continue;
            case NIT_SEQNO:
                  continue;
            default:
                  sprintf(p->errbuf, "bad nit state %d", nh->nh_state);
                  return (-1);
            ++p->md.stat.ps_recv;
            bp += ((sizeof(struct nit_hdr) + nh->nh_datalen +
                sizeof(int) - 1) & ~(sizeof(int) - 1));
            caplen = nh->nh_wirelen;
            if (caplen > p->snapshot)
                  caplen = p->snapshot;
            if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) {
                  struct pcap_pkthdr h;
                  h.ts = nh->nh_timestamp;
                  h.len = nh->nh_wirelen;
                  h.caplen = caplen;
                  (*callback)(user, &h, cp);
                  if (++n >= cnt && cnt >= 0) {
                        p->cc = ep - bp;
                        p->bp = bp;
                        return (n);
                  }
      p->cc = 0;
      return (n);
static int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
      struct nit_ioc nioc;
      bzero((char *)&nioc, sizeof(nioc));
      nioc.nioc_bufspace = BUFSPACE;
      nioc.nioc_chunksize = CHUNKSIZE;
      nioc.nioc_typetomatch = NT_ALLTYPES;
      nioc.nioc_snaplen = p->snapshot;
      nioc.nioc_bufalign = sizeof(int);
      nioc.nioc_bufoffset = 0;
      if (to_ms != 0) {
            nioc.nioc_flags |= NF_TIMEOUT;
            nioc.nioc_timeout.tv_sec = to_ms / 1000;
            nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000;
      if (promisc)
            nioc.nioc_flags |= NF_PROMISC;
      if (ioctl(fd, SIOCSNIT, &nioc) < 0) {
            sprintf(ebuf, "SIOCSNIT: %s", pcap_strerror(errno));
            return (-1);
      return (0);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
      int fd;
      struct sockaddr_nit snit;
      register pcap_t *p;
      p = (pcap_t *)malloc(sizeof(*p));
      if (p == NULL) {
            strcpy(ebuf, pcap_strerror(errno));
            return (NULL);
      if (snaplen < 96)
            /*
             * NIT requires a snapshot length of at least 96.
             */
            snaplen = 96;
      bzero(p, sizeof(*p));
      p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
      if (fd < 0) {
            sprintf(ebuf, "socket: %s", pcap_strerror(errno));
            goto bad;
      snit.snit_family = AF_NIT;
      (void)strncpy(snit.snit_ifname, device, NITIFSIZ);
      if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
            sprintf(ebuf, "bind: %s: %s", snit.snit_ifname,
                  pcap_strerror(errno));
            goto bad;
      p->snapshot = snaplen;
      nit_setflags(p->fd, promisc, to_ms, ebuf);
       * NIT supports only ethernets.
       */
      p->linktype = DLT_EN10MB;
      p->bufsize = BUFSPACE;
      p->buffer = (u_char *)malloc(p->bufsize);
      if (p->buffer == NULL) {
            strcpy(ebuf, pcap_strerror(errno));
            goto bad;
      return (p);
 bad:
      if (fd >= 0)
            close(fd);
      free(p);
      return (NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
      p->fcode = *fp;
      return (0);
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
 * The chunk size for NIT.  This is the amount of buffering
 * done for read calls.
#define CHUNKSIZE (2*1024)
 * The total buffer space usedlibpcap-0.4/pcap-nit.h
   444
  3060
    34
       1656  5577470036   7745
 * Copyright (c) 1990, 1994
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Lawrence Berkeley Laboratory,
 * Berkeley, CA.  The name of the University may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * @(#) $Header: pcap-nit.h,v 1.2 94/06/14 20:06:03 leres Exp $ (LBL)
, NITIFSIZ);
      if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
            sprintf(elibpcap-0.4/pcap-null.c
   444
  1774
    34
       4130  6253457565  10124
 * Copyright (c) 1994, 1995, 1996
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap-null.c,v 1.7 96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include <sys/param.h>                 /* optionally get BSD define */
#include <string.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
static char nosup[] = "live packet capture not supported on this system";
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      (void)sprintf(p->errbuf, "pcap_stats: %s", nosup);
      return (-1);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      (void)sprintf(p->errbuf, "pcap_read: %s", nosup);
      return (-1);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
      (void)strcpy(ebuf, nosup);
      return (NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
      if (p->sf.rfile == NULL) {
            (void)sprintf(p->errbuf, "pcap_setfilter: %s", nosup);
            return (-1);
      p->fcode = *fp;
      return (0);
 int, int, char *);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      *ps = p->md.stat;
      return (0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      register int cc, n;
      register struct bpf_insn *fcode = p->fcode.bf_insns;
      register u_char *bp, *cp, *ep;
      register struct nit_hdr *nh;
      register int caplen;
      cc = p->cc;
      if (cc == 0) {
            cc = read(p->fd, (char *)p->buffer, p->bufsize);
            iflibpcap-0.4/pcap-pf.c
   444
  1774
    34
      21416  6253457565   7605
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * packet filter subroutines for tcpdump
 *      Extraction/creation by Jeffrey Mogul, DECWRL
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap-pf.c,v 1.54 96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <net/pfilt.h>
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
 * BUFSPACE is the size in bytes of the packet read buffer.  Most tcpdump
 * applications aren't going to need more than 200 bytes of packet header
 * and the read shouldn't return more packets than packetfilter's internal
 * queue limit (bounded at 256).
#define BUFSPACE (200 * 256)
pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
      register u_char *p, *bp;
      struct bpf_insn *fcode;
      register int cc, n, buflen, inc;
      register struct enstamp *sp;
#ifdef LBL_ALIGN
      struct enstamp stamp;
#endif
#ifdef PCAP_FDDIPAD
      register int pad;
#endif
      fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns;
 again:
      cc = pc->cc;
      if (cc == 0) {
            cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize);
            if (cc < 0) {
                  if (errno == EWOULDBLOCK)
                        return (0);
                  if (errno == EINVAL &&
                      lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) {
                        /*
                         * Due to a kernel bug, after 2^31 bytes,
                         * the kernel file offset overflows and
                         * read fails with EINVAL. The lseek()
                         * to 0 will fix things.
                         */
                        (void)lseek(pc->fd, 0L, SEEK_SET);
                        goto again;
                  }
                  sprintf(pc->errbuf, "pf read: %s",
                        pcap_strerror(errno));
                  return (-1);
            bp = pc->buffer + pc->offset;
      } else
            bp = pc->bp;
       * Loop through each packet.
       */
      n = 0;
#ifdef PCAP_FDDIPAD
      if (pc->linktype == DLT_FDDI)
            pad = pcap_fddipad;
      else
            pad = 0;
#endif
      while (cc > 0) {
            if (cc < sizeof(*sp)) {
                  sprintf(pc->errbuf, "pf short read (%d)", cc);
                  return (-1);
#ifdef LBL_ALIGN
            if ((long)bp & 3) {
                  sp = &stamp;
                  memcpy((char *)sp, (char *)bp, sizeof(*sp));
            } else
#endif
                  sp = (struct enstamp *)bp;
            if (sp->ens_stamplen != sizeof(*sp)) {
                  sprintf(pc->errbuf, "pf short stamplen (%d)",
                      sp->ens_stamplen);
                  return (-1);
            p = bp + sp->ens_stamplen;
            buflen = sp->ens_count;
            if (buflen > pc->snapshot)
                  buflen = pc->snapshot;
            /* Calculate inc before possible pad update */
            inc = ENALIGN(buflen + sp->ens_stamplen);
            cc -= inc;
            bp += inc;
#ifdef PCAP_FDDIPAD
            p += pad;
            buflen -= pad;
#endif
            pc->md.TotPkts++;
            pc->md.TotDrops += sp->ens_dropped;
            pc->md.TotMissed = sp->ens_ifoverflows;
            if (pc->md.OrigMissed < 0)
                  pc->md.OrigMissed = pc->md.TotMissed;
            /*
             * Short-circuit evaluation: if using BPF filter
             * in kernel, no need to do it now.
             */
            if (fcode == NULL ||
                bpf_filter(fcode, p, sp->ens_count, buflen)) {
                  struct pcap_pkthdr h;
                  pc->md.TotAccepted++;
                  h.ts = sp->ens_tstamp;
#ifdef PCAP_FDDIPAD
                  h.len = sp->ens_count - pad;
#else
                  h.len = sp->ens_count;
#endif
                  h.caplen = buflen;
                  (*callback)(user, &h, p);
                  if (++n >= cnt && cnt > 0) {
                        pc->cc = cc;
                        pc->bp = bp;
                        return (n);
                  }
      pc->cc = 0;
      return (n);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      ps->ps_recv = p->md.TotAccepted;
      ps->ps_drop = p->md.TotDrops;
      ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
      return (0);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
      pcap_t *p;
      short enmode;
      int backlog = -1;    /* request the most */
      struct enfilter Filter;
      struct endevp devparams;
      p = (pcap_t *)malloc(sizeof(*p));
      if (p == NULL) {
            sprintf(ebuf, "pcap_open_live: %s", pcap_strerror(errno));
            return (0);
      bzero((char *)p, sizeof(*p));
      p->fd = pfopen(device, O_RDONLY);
      if (p->fd < 0) {
            sprintf(ebuf, "pf open: %s: %s\n\
your system may not be properly configured; see \"man packetfilter(4)\"\n",
                  device, pcap_strerror(errno));
            goto bad;
      p->md.OrigMissed = -1;
      enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
      if (promisc)
            enmode |= ENPROMISC;
      if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
            sprintf(ebuf, "EIOCMBIS: %s", pcap_strerror(errno));
            goto bad;
#ifdef      ENCOPYALL
      /* Try to set COPYALL mode so that we see packets to ourself */
      enmode = ENCOPYALL;
      (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */
#endif
      /* set the backlog */
      if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
            sprintf(ebuf, "EIOCSETW: %s", pcap_strerror(errno));
            goto bad;
      /* discover interface type */
      if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
            sprintf(ebuf, "EIOCDEVP: %s", pcap_strerror(errno));
            goto bad;
      /* HACK: to compile prior to Ultrix 4.2 */
#ifndef      ENDT_FDDI
#define      ENDT_FDDI   4
#endif
      switch (devparams.end_dev_type) {
      case ENDT_10MB:
            p->linktype = DLT_EN10MB;
            p->offset = 2;
            break;
      case ENDT_FDDI:
            p->linktype = DLT_FDDI;
            break;
      default:
            /*
             * XXX
             * Currently, the Ultrix packet filter supports only
             * Ethernet and FDDI.  Eventually, support for SLIP and PPP
             * (and possibly others: T1?) should be added.
             */
#ifdef notdef
            warning(
               "Packet filter data-link type %d unknown, assuming Ethernet",
                devparams.end_dev_type);
#endif
            p->linktype = DLT_EN10MB;
            p->offset = 2;
            break;
      /* set truncation */
#ifdef PCAP_FDDIPAD
      if (p->linktype == DLT_FDDI)
            /* packetfilter includes the padding in the snapshot */
            snaplen += pcap_fddipad;
#endif
      if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
            sprintf(ebuf, "EIOCTRUNCATE: %s", pcap_strerror(errno));
            goto bad;
      p->snapshot = snaplen;
      /* accept all packets */
      bzero((char *)&Filter, sizeof(Filter));
      Filter.enf_Priority = 37;      /* anything > 2 */
      Filter.enf_FilterLen = 0;      /* means "always true" */
      if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
            sprintf(ebuf, "EIOCSETF: %s", pcap_strerror(errno));
            goto bad;
      if (to_ms != 0) {
            struct timeval timeout;
            timeout.tv_sec = to_ms / 1000;
            timeout.tv_usec = (to_ms * 1000) % 1000000;
            if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
                  sprintf(ebuf, "EIOCSRTIMEOUT: %s",
                        pcap_strerror(errno));
                  goto bad;
      p->bufsize = BUFSPACE;
      p->buffer = (u_char*)malloc(p->bufsize + p->offset);
      return (p);
 bad:
      free(p);
      return (NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
       * See if BIOCSETF works.  If it does, the kernel supports
       * BPF-style filters, and we do not need to do post-filtering.
       */
      p->md.use_bpf = (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0);
      if (p->md.use_bpf) {
            struct bpf_version bv;
            if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) {
                  sprintf(p->errbuf, "BIOCVERSION: %s",
                        pcap_strerror(errno));
                  return (-1);
            else if (bv.bv_major != BPF_MAJOR_VERSION ||
                   bv.bv_minor < BPF_MINOR_VERSION) {
                  fprintf(stderr,
            "requires bpf language %d.%d or higher; kernel is %d.%d",
                        BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
                        bv.bv_major, bv.bv_minor);
                  /* don't give up, just be inefficient */
                  p->md.use_bpf = 0;
      } else
            p->fcode = *fp;
      /*XXX this goes in tcpdump*/
      if (p->md.use_bpf)
            fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
      else
            fprintf(stderr, "tcpdump: Filtering in user process\n");
      return (0);
turn (n);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      ps->ps_recv = p->md.TotAccepted;
      ps->ps_drop = p->md.TotDrops;
      ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
      return (0);
pcap_t *
pcap_open_live(char *device, int snlibpcap-0.4/pcap-pf.h
   444
  3060
    34
       1655  5577470075   7562
 * Copyright (c) 1990, 1994
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Lawrence Berkeley Laboratory,
 * Berkeley, CA.  The name of the University may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * @(#) $Header: pcap-pf.h,v 1.2 94/06/14 20:06:33 leres Exp $ (LBL)
      /* set the backlog */
      if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
            libpcap-0.4/pcap-snit.c
   444
  1774
    34
      16115  6253457566  10156
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * Modifications made to accommodate the new SunOS4.0 NIT facility by
 * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989.
 * This module now handles the STREAMS based NIT.
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap-snit.c,v 1.45 96/12/10 23:15:01 leres Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/dir.h>
#include <sys/fcntlcom.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stropts.h>
#include <net/if.h>
#include <net/nit.h>
#include <net/nit_if.h>
#include <net/nit_pf.h>
#include <net/nit_buf.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
 * The chunk size for NIT.  This is the amount of buffering
 * done for read calls.
#define CHUNKSIZE (2*1024)
 * The total buffer space used by NIT.
#define BUFSPACE (4*CHUNKSIZE)
/* Forwards */
static int nit_setflags(int, int, int, char *);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      *ps = p->md.stat;
      return (0);
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      register int cc, n;
      register struct bpf_insn *fcode = p->fcode.bf_insns;
      register u_char *bp, *cp, *ep;
      register struct nit_bufhdr *hdrp;
      register struct nit_iftime *ntp;
      register struct nit_iflen *nlp;
      register struct nit_ifdrops *ndp;
      register int caplen;
      cc = p->cc;
      if (cc == 0) {
            cc = read(p->fd, (char *)p->buffer, p->bufsize);
            if (cc < 0) {
                  if (errno == EWOULDBLOCK)
                        return (0);
                  sprintf(p->errbuf, "pcap_read: %s",
                        pcap_strerror(errno));
                  return (-1);
            bp = p->buffer;
      } else
            bp = p->bp;
       * loop through each snapshot in the chunk
       */
      n = 0;
      ep = bp + cc;
      while (bp < ep) {
            ++p->md.stat.ps_recv;
            cp = bp;
            /* get past NIT buffer  */
            hdrp = (struct nit_bufhdr *)cp;
            cp += sizeof(*hdrp);
            /* get past NIT timer   */
            ntp = (struct nit_iftime *)cp;
            cp += sizeof(*ntp);
            ndp = (struct nit_ifdrops *)cp;
            p->md.stat.ps_drop = ndp->nh_drops;
            cp += sizeof *ndp;
            /* get past packet len  */
            nlp = (struct nit_iflen *)cp;
            cp += sizeof(*nlp);
            /* next snapshot        */
            bp += hdrp->nhb_totlen;
            caplen = nlp->nh_pktlen;
            if (caplen > p->snapshot)
                  caplen = p->snapshot;
            if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
                  struct pcap_pkthdr h;
                  h.ts = ntp->nh_timestamp;
                  h.len = nlp->nh_pktlen;
                  h.caplen = caplen;
                  (*callback)(user, &h, cp);
                  if (++n >= cnt && cnt >= 0) {
                        p->cc = ep - bp;
                        p->bp = bp;
                        return (n);
                  }
      p->cc = 0;
      return (n);
static int
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
      bpf_u_int32 flags;
      struct strioctl si;
      struct timeval timeout;
      si.ic_timout = INFTIM;
      if (to_ms != 0) {
            timeout.tv_sec = to_ms / 1000;
            timeout.tv_usec = (to_ms * 1000) % 1000000;
            si.ic_cmd = NIOCSTIME;
            si.ic_len = sizeof(timeout);
            si.ic_dp = (char *)&timeout;
            if (ioctl(fd, I_STR, (char *)&si) < 0) {
                  sprintf(ebuf, "NIOCSTIME: %s", pcap_strerror(errno));
                  return (-1);
      flags = NI_TIMESTAMP | NI_LEN | NI_DROPS;
      if (promisc)
            flags |= NI_PROMISC;
      si.ic_cmd = NIOCSFLAGS;
      si.ic_len = sizeof(flags);
      si.ic_dp = (char *)&flags;
      if (ioctl(fd, I_STR, (char *)&si) < 0) {
            sprintf(ebuf, "NIOCSFLAGS: %s", pcap_strerror(errno));
            return (-1);
      return (0);
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
      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) {
            strcpy(ebuf, pcap_strerror(errno));
            return (NULL);
      if (snaplen < 96)
            /*
             * NIT requires a snapshot length of at least 96.
             */
            snaplen = 96;
      bzero(p, sizeof(*p));
      p->fd = fd = open(dev, O_RDONLY);
      if (fd < 0) {
            sprintf(ebuf, "%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) {
            sprintf(ebuf, "I_SRDOPT: %s", pcap_strerror(errno));
            goto bad;
      if (ioctl(fd, I_PUSH, "nbuf") < 0) {
            sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno));
            goto bad;
      /* set the chunksize */
      si.ic_cmd = NIOCSCHUNK;
      si.ic_timout = INFTIM;
      si.ic_len = sizeof(chunksize);
      si.ic_dp = (char *)&chunksize;
      if (ioctl(fd, I_STR, (char *)&si) < 0) {
            sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errno));
            goto bad;
      /* request the interface */
      strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
      ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
      si.ic_cmd = NIOCBIND;
      si.ic_len = sizeof(ifr);
      si.ic_dp = (char *)&ifr;
      if (ioctl(fd, I_STR, (char *)&si) < 0) {
            sprintf(ebuf, "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;
      if (ioctl(fd, I_STR, (char *)&si) < 0) {
            sprintf(ebuf, "NIOCSSNAP: %s", pcap_strerror(errno));
            goto bad;
      p->snapshot = snaplen;
      if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
            goto bad;
      (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
       * NIT supports only ethernets.
       */
      p->linktype = DLT_EN10MB;
      p->bufsize = BUFSPACE;
      p->buffer = (u_char *)malloc(p->bufsize);
      if (p->buffer == NULL) {
            strcpy(ebuf, pcap_strerror(errno));
            goto bad;
      return (p);
 bad:
      if (fd >= 0)
            close(fd);
      free(p);
      return (NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
      p->fcode = *fp;
      return (0);
eturn (0);
                  sprintf(p->errbuf, "pcap_read: %s",
                        pcap_strerror(errno));
                  return (-1);
            bp = p->buffer;
      } else
            bp = p->bp;
       * loop through each snapshot in the chunk
       */
      n = 0;
      ep = bp + cc;
      while (bp < ep) {
            ++p->md.stat.ps_recv;
            cp = bp;
            /* get past NIT buffer  */
            hdrp = (struct nit_bufhdr *)cp;
            cp += sizeof(*hdrp);
            /* get past NIT timer   */
            ntp = (struct nit_iftime *)cp;
            cp += sizeof(*nlibpcap-0.4/pcap-snoop.c
   444
  1774
    34
      13553  6322612745  10327
 * Copyright (c) 1993, 1994, 1995, 1996, 1997
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap-snoop.c,v 1.20 97/04/08 21:06:17 leres Exp $ (LBL)";
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/raw.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      int cc;
      register struct snoopheader *sh;
      register int datalen;
      register int caplen;
      register u_char *cp;
again:
      cc = read(p->fd, (char *)p->buffer, p->bufsize);
      if (cc < 0) {
            /* Don't choke when we get ptraced */
            switch (errno) {
            case EINTR:
                        goto again;
            case EWOULDBLOCK:
                  return (0);              /* XXX */
            sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
            return (-1);
      sh = (struct snoopheader *)p->buffer;
      datalen = sh->snoop_packetlen;
      caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
      cp = (u_char *)(sh + 1) + p->offset;        /* XXX */
      if (p->fcode.bf_insns == NULL ||
          bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
            struct pcap_pkthdr h;
            ++p->md.stat.ps_recv;
            h.ts = sh->snoop_timestamp;
            h.len = datalen;
            h.caplen = caplen;
            (*callback)(user, &h, cp);
            return (1);
      return (0);
pcap_stats(pcap_t *p, struct pcap_stat *ps)
      register struct rawstats *rs;
      struct rawstats rawstats;
      rs = &rawstats;
      bzero((char *)rs, sizeof(*rs));
      if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
            sprintf(p->errbuf, "SIOCRAWSTATS: %s", pcap_strerror(errno));
            return (-1);
      p->md.stat.ps_drop =
          rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops +
          rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops;
      *ps = p->md.stat;
      return (0);
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
      int fd;
      struct sockaddr_raw sr;
      struct snoopfilter sf;
      u_int v;
      pcap_t *p;
      p = (pcap_t *)malloc(sizeof(*p));
      if (p == NULL) {
            sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
            return (NULL);
      bzero((char *)p, sizeof(*p));
      fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
      if (fd < 0) {
            sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno));
            goto bad;
      p->fd = fd;
      bzero((char *)&sr, sizeof(sr));
      sr.sr_family = AF_RAW;
      (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
      if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
            sprintf(ebuf, "snoop bind: %s", pcap_strerror(errno));
            goto bad;
      bzero((char *)&sf, sizeof(sf));
      if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
            sprintf(ebuf, "SIOCADDSNOOP: %s", pcap_strerror(errno));
            goto bad;
      v = 64 * 1024;
      (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
      if (ioctl(fd, SIOCSNOOPLEN, &snaplen) < 0) {
            sprintf(ebuf, "SIOCSNOOPLEN: %s", pcap_strerror(errno));
            goto bad;
      p->snapshot = snaplen;
      v = 1;
      if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
            sprintf(ebuf, "SIOCSNOOPING: %s", pcap_strerror(errno));
            goto bad;
       * XXX hack - map device name to link layer type
       */
      if (strncmp("et", device, 2) == 0 ||      /* Challenge 10 Mbit */
          strncmp("ec", device, 2) == 0 ||      /* Indigo/Indy 10 Mbit,
                                       O2 10/100 */
          strncmp("ef", device, 2) == 0 ||      /* O200/2000 10/100 Mbit */
          strncmp("gfe", device, 3) == 0 ||      /* GIO 100 Mbit */
          strncmp("fxp", device, 3) == 0 ||      /* Challenge VME Enet */
          strncmp("ep", device, 2) == 0 ||      /* Challenge 8x10 Mbit EPLEX */
          strncmp("vfe", device, 3) == 0 ||      /* Challenge VME 100Mbit */
          strncmp("fa", device, 2) == 0 ||
          strncmp("qaa", device, 3) == 0) {
            p->linktype = DLT_EN10MB;
            p->offset = RAW_HDRPAD(sizeof(struct ether_header));
      } else if (strncmp("ipg", device, 3) == 0 ||
               strncmp("rns", device, 3) == 0 ||      /* O2/200/2000 FDDI */
               strncmp("xpi", device, 3) == 0) {
            p->linktype = DLT_FDDI;
            p->offset = 3;                        /* XXX yeah? */
      } else if (strncmp("ppp", device, 3) == 0) {
            p->linktype = DLT_RAW;
      } else if (strncmp("lo", device, 2) == 0) {
            p->linktype = DLT_NULL;
      } else {
            sprintf(ebuf, "snoop: unknown physical layer type");
            goto bad;
      p->bufsize = 4096;                   /* XXX */
      p->buffer = (u_char *)malloc(p->bufsize);
      if (p->buffer == NULL) {
            sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
            goto bad;
      return (p);
 bad:
      (void)close(fd);
      free(p);
      return (NULL);
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
      p->fcode = *fp;
      return (0);
en = sizeof(chunksize);
      si.ic_dp = (char *)&chunksize;
      if (ioctl(fd, I_STR, (char *)&si) < 0) {
            sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errlibpcap-0.4/pcap.3
   444
  1774
    34
      20513  6544336050   7103
.\" Copyright (c) 1994, 1996, 1997
.\"   The Regents of the University of California.  All rights reserved.
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.TH PCAP 3  "24 June 1998"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
.ft B
#include <pcap.h>
.ft B
pcap_t *pcap_open_live(char *device, int snaplen,
.ti +8
int promisc, int to_ms, char *ebuf)
pcap_t *pcap_open_offline(char *fname, char *ebuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
.ft B
char errbuf[PCAP_ERRBUF_SIZE];
char *pcap_lookupdev(char *errbuf)
int pcap_lookupnet(char *device, bpf_u_int32 *netp,
.ti +8
bpf_u_int32 *maskp, char *errbuf)
.ft B
int pcap_dispatch(pcap_t *p, int cnt,
.ti +8
pcap_handler callback, u_char *user)
int pcap_loop(pcap_t *p, int cnt,
.ti +8
pcap_handler callback, u_char *user)
void pcap_dump(u_char *user, struct pcap_pkthdr *h,
.ti +8
u_char *sp)
.ft B
int pcap_compile(pcap_t *p, struct bpf_program *fp,
.ti +8
char *str, int optimize, bpf_u_int32 netmask)
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
.ft B
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
.ft B
int pcap_datalink(pcap_t *p)
int pcap_snapshot(pcap_t *p)
int pcap_is_swapped(pcap_t *p)
int pcap_major_version(pcap_t *p)
int pcap_minor_version(pcap_t *p)
int pcap_stats(pcap_t *p, struct pcap_stat *ps)
FILE *pcap_file(pcap_t *p)
int pcap_fileno(pcap_t *p)
void pcap_perror(pcap_t *p, char *prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int error)
.ft B
void pcap_close(pcap_t *p)
void pcap_dump_close(pcap_dumper_t *p)
.SH DESCRIPTION
The Packet Capture library
provides a high level interface to packet capture systems. All packets
on the network, even those destined for other hosts, are accessible
through this mechanism.
.SH ROUTINES
.B pcap_open_live()
is used to obtain a packet capture descriptor to look
at packets on the network.
.I device
is a string that specifies the network device to open.
.I snaplen
specifies the maximum number of bytes to capture.
.I promisc
specifies if the interface is to be put into promiscuous mode.
(Note that even if this parameter is false, the interface
could well be in promiscuous mode for some other reason.)
.I to_ms
specifies the read timeout in milliseconds.
.I ebuf
is used to return error text and is only set when
.B pcap_open_live()
fails and returns
.BR NULL .
.B pcap_open_offline()
is called to open a ``savefile'' for reading.
.I fname
specifies the name of the file to open. The file has
the same format as those used by
.B tcpdump(1)
.BR tcpslice(1) .
The name "-" in a synonym for
.BR stdin .
.I ebuf
is used to return error text and is only set when
.B pcap_open_offline()
fails and returns
.BR NULL .
.B pcap_dump_open()
is called to open a ``savefile'' for writing. The name "-" in a synonym
.BR stdout .
.B NULL
is returned on failure.
.I p
is a
.I pcap
struct as returned by
.B pcap_open_offline()
.BR pcap_open_live() .
.I fname
specifies the name of the file to open.
.B NULL
is returned,
.B pcap_geterr()
can be used to get the error text.
.B pcap_lookupdev()
returns a pointer to a network device suitable for use with
.B pcap_open_live()
.BR pcap_lookupnet() .
If there is an error,
.B NULL
is returned and
.I errbuf
is filled in with with an appropriate error message.
.B pcap_lookupnet()
is used to determine the network number and mask
associated with the network device
.BR device .
Both
.I netp
.I maskp
.I bpf_u_int32
pointers.
A return of -1 indicates an error in which case
.I errbuf
is filled in with with an appropriate error message.
.B pcap_dispatch()
is used to collect and process packets.
.I cnt
specifies the maximum number of packets to process before returning. A
.I cnt
of -1 processes all the packets received in one buffer. A
.I cnt
of 0 processes all packets until an error occurs,
.B EOF
is reached, or the read times out (when doing live reads and a non-zero
read timeout is specified).
.I callback
specifies a routine to be called with three arguments:
.I u_char
pointer which is passed in from
.BR pcap_dispatch() ,
a pointer to the
.I pcap_pkthdr
struct (which precede the actual network headers and data),
and a
.I u_char
pointer to the packet data. The number of packets read is returned.
Zero is returned when
.B EOF
is reached in a ``savefile.'' A return of -1 indicates
an error in which case
.B pcap_perror()
.BR pcap_geterr()
may be used to display the error text.
.B pcap_dump()
outputs a packet to the ``savefile'' opened with
.BR pcap_dump_open() .
Note that its calling arguments are suitable for use with
.BR pcap_dispatch() .
.B pcap_compile()
is used to compile the string
.I str
into a filter program.
.I program
is a pointer to a
.I bpf_program
struct and is filled in by
.BR pcap_compile() .
.I optimize
controls whether optimization on the resulting code is performed.
.I netmask
specifies the netmask of the local net.
.B pcap_setfilter()
is used to specify a filter program.
.I fp
is a pointer to an array of
.I bpf_program
struct, usually the result of a call to
.BR pcap_compile() .
.B \-1
is returned on failure;
.B 0
is returned on success.
.B pcap_loop()
is similar to
.B pcap_dispatch()
except it keeps reading packets until
.I cnt
packets are processed or an error occurs.
It does
.B not
return when live read timeouts occur.
Rather, specifying a non-zero read timeout to
.B pcap_open_live()
and then calling
.B pcap_dispatch()
allows the reception and processing of any packets that arrive when the
timeout occurs.
A negative
.I cnt
causes
.B pcap_loop()
to loop forever (or at least until an error occurs).
.B pcap_next()
returns a
.I u_char
pointer to the next packet.
.B pcap_datalink()
returns the link layer type, e.g.
.BR DLT_EN10MB .
.B pcap_snapshot()
returns the snapshot length specified when
.B pcap_open_live
was called.
.B pcap_is_swapped()
returns true if the current ``savefile'' uses a different byte order
than the current system.
.B pcap_major_version()
returns the major number of the version of the pcap used to write the
savefile.
.B pcap_minor_version()
returns the minor number of the version of the pcap used to write the
savefile.
.B pcap_file()
returns the name of the ``savefile.''
.B int pcap_stats()
returns 0 and fills in a
.B pcap_stat
struct. The values represent packet statistics from the start of the
run to the time of the call. If there is an error or the under lying
packet capture doesn't support packet statistics, -1 is returned and
the error text can be obtained with
.B pcap_perror()
.BR pcap_geterr() .
.B pcap_fileno()
returns the file descriptor number of the ``savefile.''
.B pcap_perror()
prints the text of the last pcap library error on
.BR stderr ,
prefixed by
.IR prefix .
.B pcap_geterr()
returns the error text pertaining to the last pcap library error.
.B pcap_strerror()
is provided in case
.BR strerror (1)
isn't available.
.B pcap_close()
closes the files associated with
.I p
and deallocates resources.
.B pcap_dump_close()
closes the ``savefile.''
.SH SEE ALSO
tcpdump(1), tcpslice(1)
.SH AUTHORS
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
The current version is available via anonymous ftp:
.I ftp://ftp.ee.lbl.gov/libpcap.tar.Z
.SH BUGS
Please send bug reports to libpcap@ee.lbl.gov.
 the network number and mask
associated with the network device
.BR device .
Both
.I netp
.I maskp
.I bpf_u_int32
pointers.
A return of -1 indicates an error in which case
.libpcap-0.4/pcap.c
   444
  1774
    34
      10655  6552214553   7173
 * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the Computer Systems
 *      Engineering Group at Lawrence Berkeley Laboratory.
 * 4. Neither the name of the University nor of the Laboratory may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
#ifndef lint
static const char rcsid[] =
    "@(#) $Header: pcap.c,v 1.29 98/07/12 13:15:39 leres Exp $ (LBL)";
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      if (p->sf.rfile != NULL)
            return (pcap_offline_read(p, cnt, callback, user));
      return (pcap_read(p, cnt, callback, user));
pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
      register int n;
      for (;;) {
            if (p->sf.rfile != NULL)
                  n = pcap_offline_read(p, cnt, callback, user);
            else {
                  /*
                   * XXX keep reading until we get something
                   * (or an error occurs)
                   */
                  do {
                        n = pcap_read(p, cnt, callback, user);
                  } while (n == 0);
            if (n <= 0)
                  return (n);
            if (cnt > 0) {
                  cnt -= n;
                  if (cnt <= 0)
                        return (0);
struct singleton {
      struct pcap_pkthdr *hdr;
      const u_char *pkt;
static void
pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
      struct singleton *sp = (struct singleton *)userData;
      *sp->hdr = *h;
      sp->pkt = pkt;
const u_char *
pcap_next(pcap_t *p, struct pcap_pkthdr *h)
      struct singleton s;
      s.hdr = h;
      if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
            return (0);
      return (s.pkt);
pcap_datalink(pcap_t *p)
      return (p->linktype);
pcap_snapshot(pcap_t *p)
      return (p->snapshot);
pcap_is_swapped(pcap_t *p)
      return (p->sf.swapped);
pcap_major_version(pcap_t *p)
      return (p->sf.version_major);
pcap_minor_version(pcap_t *p)
      return (p->sf.version_minor);
FILE *
pcap_file(pcap_t *p)
      return (p->sf.rfile);
pcap_fileno(pcap_t *p)
      return (p->fd);
void
pcap_perror(pcap_t *p, char *prefix)
      fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
char *
pcap_geterr(pcap_t *p)
      return (p->errbuf);
 * Not all systems have strerror().
char *
pcap_strerror(int errnum)
#ifdef HAVE_STRERROR
      return (strerror(errnum));
#else
      extern int sys_nerr;
      extern const char *const sys_errlist[];
      static char ebuf[20];
      if ((unsigned int)errnum < sys_nerr)
            return ((char *)sys_errlist[errnum]);
      (void)sprintf(ebuf, "Unknown error: %d", errnum);
      return(ebuf);
#endif
void
pcap_close(pcap_t *p)
      /*XXX*/
      if (p->fd >= 0)
            close(p->fd);
      if (p->sf.rfile != NULL) {
            (void)fclose(p->sf.rfile);
            if (p->sf.base != NULL)
                  free(p->sf.base);
      } else if (p->buffer != NULL)
            free(p->buffer);
#ifdef linux
      if (p->md.device != NULL)
            free(p->md.device);
#endif
      free(p);
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <libpcap-0.4/pcap.h
   444
  1774
    34
      11460  6421317444   7171
 * Copyright (c) 1993, 1994, 1995, 1996, 1997
 *    The Regents of the University of California.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the Computer Systems
 *      Engineering Group at Lawrence Berkeley Laboratory.
 * 4. Neither the name of the University nor of the Laboratory may be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * @(#) $Header: pcap.h,v 1.21 97/10/15 21:59:13 leres Exp $ (LBL)
#ifndef lib_pcap_h
#define lib_pcap_h
#include <sys/types.h>
#include <sys/time.h>
#include <net/bpf.h>
#include <stdio.h>
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
 * Compatibility for systems that have a bpf.h that
 * predates the bpf typedefs for 64-bit support.
#if BPF_RELEASE - 0 < 199406
typedef      int bpf_int32;
typedef      u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
 * The first record in the file contains saved values for some
 * of the flags used in the printout phases of tcpdump.
 * Many fields here are 32 bit ints so compilers won't insert unwanted
 * padding; these files need to be interchangeable across architectures.
struct pcap_file_header {
      bpf_u_int32 magic;
      u_short version_major;
      u_short version_minor;
      bpf_int32 thiszone;      /* gmt to local correction */
      bpf_u_int32 sigfigs;      /* accuracy of timestamps */
      bpf_u_int32 snaplen;      /* max length saved portion of each pkt */
      bpf_u_int32 linktype;      /* data link type (DLT_*) */
 * Each packet in the dump file is prepended with this generic header.
 * This gets around the problem of different headers for different
 * packet interfaces.
struct pcap_pkthdr {
      struct timeval ts;      /* time stamp */
      bpf_u_int32 caplen;      /* length of portion present */
      bpf_u_int32 len;      /* length this packet (off wire) */
 * As returned by the pcap_stats()
struct pcap_stat {
      u_int ps_recv;          /* number of packets received */
      u_int ps_drop;          /* number of packets dropped */
      u_int ps_ifdrop;      /* drops by interface XXX not yet supported */
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
                       const u_char *);
char      *pcap_lookupdev(char *);
int      pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t      *pcap_open_live(char *, int, int, int, char *);
pcap_t      *pcap_open_offline(const char *, char *);
void      pcap_close(pcap_t *);
int      pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int      pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
      pcap_next(pcap_t *, struct pc