***
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 *)𝔦
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