resolve merge conflicts

Reviewed by:	bms (earlier version)
This commit is contained in:
Sam Leffler 2005-05-29 18:09:04 +00:00
parent 0a71d148de
commit c761ebcb2c
10 changed files with 600 additions and 895 deletions

View File

@ -23,7 +23,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.193.2.8 2004/03/29 20:53:47 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221 2005/03/27 22:10:23 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -35,7 +35,6 @@ static const char rcsid[] _U_ =
#else /* WIN32 */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#endif /* WIN32 */
/*
@ -61,6 +60,10 @@ static const char rcsid[] _U_ =
#include <setjmp.h>
#include <stdarg.h>
#ifdef MSDOS
#include "pcap-dos.h"
#endif
#include "pcap-int.h"
#include "ethertype.h"
@ -100,14 +103,12 @@ static const char rcsid[] _U_ =
static jmp_buf top_ctx;
static pcap_t *bpf_pcap;
/* Hack for updating VLAN offsets. */
static u_int orig_linktype = -1, orig_nl = -1, orig_nl_nosnap = -1;
/* Hack for updating VLAN, MPLS offsets. */
static u_int orig_linktype = -1U, orig_nl = -1U, orig_nl_nosnap = -1U;
/* XXX */
#ifdef PCAP_FDDIPAD
int pcap_fddipad = PCAP_FDDIPAD;
#else
int pcap_fddipad;
static int pcap_fddipad;
#endif
/* VARARGS */
@ -126,7 +127,7 @@ bpf_error(const char *fmt, ...)
/* NOTREACHED */
}
static void init_linktype(int);
static void init_linktype(pcap_t *);
static int alloc_reg(void);
static void free_reg(int);
@ -136,8 +137,10 @@ static struct block *root;
/*
* We divy out chunks of memory rather than call malloc each time so
* we don't have to worry about leaking memory. It's probably
* not a big deal if all this memory was wasted but it this ever
* not a big deal if all this memory was wasted but if this ever
* goes into a library that would probably not be a good idea.
*
* XXX - this *is* in a library....
*/
#define NCHUNKS 16
#define CHUNK0SIZE 1024
@ -168,6 +171,7 @@ static struct block *gen_uncond(int);
static inline struct block *gen_true(void);
static inline struct block *gen_false(void);
static struct block *gen_ether_linktype(int);
static struct block *gen_linux_sll_linktype(int);
static struct block *gen_linktype(int);
static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
static struct block *gen_llc(int);
@ -343,7 +347,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
}
lex_init(buf ? buf : "");
init_linktype(pcap_datalink(p));
init_linktype(p);
(void)pcap_parse();
if (n_errors)
@ -580,15 +584,15 @@ gen_ncmp(datasize, offset, mask, jtype, jvalue, reverse)
{
struct slist *s;
struct block *b;
s = new_stmt(BPF_LD|datasize|BPF_ABS);
s->s.k = offset;
if (mask != 0xffffffff) {
s->next = new_stmt(BPF_ALU|BPF_AND|BPF_K);
s->next->s.k = mask;
}
b = new_block(JMP(jtype));
b->stmts = s;
b->s.k = jvalue;
@ -681,10 +685,13 @@ static u_int off_nl_nosnap;
static int linktype;
static void
init_linktype(type)
int type;
init_linktype(p)
pcap_t *p;
{
linktype = type;
linktype = pcap_datalink(p);
#ifdef PCAP_FDDIPAD
pcap_fddipad = p->fddipad;
#endif
/*
* Assume it's not raw ATM with a pseudo-header, for now.
@ -701,7 +708,7 @@ init_linktype(type)
orig_nl = -1;
orig_nl_nosnap = -1;
switch (type) {
switch (linktype) {
case DLT_ARCNET:
off_linktype = 2;
@ -753,6 +760,7 @@ init_linktype(type)
return;
case DLT_PPP:
case DLT_PPP_PPPD:
case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
off_linktype = 2;
@ -925,7 +933,7 @@ init_linktype(type)
off_vpi = SUNATM_VPI_POS;
off_vci = SUNATM_VCI_POS;
off_proto = PROTO_POS;
off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */
off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */
off_payload = SUNATM_PKT_BEGIN_POS;
off_linktype = off_payload;
off_nl = off_payload+8; /* 802.2+SNAP */
@ -996,6 +1004,21 @@ init_linktype(type)
off_nl_nosnap = -1;
return;
case DLT_DOCSIS:
/*
* Currently, only raw "link[N:M]" filtering is supported.
*/
off_linktype = -1;
off_nl = -1;
off_nl_nosnap = -1;
return;
case DLT_SYMANTEC_FIREWALL:
off_linktype = 6;
off_nl = 44; /* Ethernet II */
off_nl_nosnap = 44; /* XXX - what does it do with 802.3 packets? */
return;
case DLT_PFLOG:
off_linktype = 0;
/* XXX read from header? */
@ -1003,6 +1026,25 @@ init_linktype(type)
off_nl_nosnap = PFLOG_HDRLEN;
return;
case DLT_JUNIPER_MLFR:
case DLT_JUNIPER_MLPPP:
off_linktype = 4;
off_nl = 4;
off_nl_nosnap = -1;
return;
case DLT_JUNIPER_ATM1:
off_linktype = 4; /* in reality variable between 4-8 */
off_nl = 4;
off_nl_nosnap = 14;
return;
case DLT_JUNIPER_ATM2:
off_linktype = 8; /* in reality variable between 8-12 */
off_nl = 8;
off_nl_nosnap = 18;
return;
#ifdef DLT_PFSYNC
case DLT_PFSYNC:
off_linktype = -1;
@ -1234,6 +1276,172 @@ gen_ether_linktype(proto)
}
}
static struct block *
gen_linux_sll_linktype(proto)
register int proto;
{
struct block *b0, *b1;
switch (proto) {
case LLCSAP_IP:
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_IP << 8) | LLCSAP_IP));
gen_and(b0, b1);
return b1;
case LLCSAP_ISONS:
/*
* OSI protocols always use 802.2 encapsulation.
* XXX - should we check both the DSAP and the
* SSAP, like this, or should we check just the
* DSAP?
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
gen_and(b0, b1);
return b1;
case LLCSAP_NETBEUI:
/*
* NetBEUI always uses 802.2 encapsulation.
* XXX - should we check both the DSAP and the
* LSAP, like this, or should we check just the
* DSAP?
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
gen_and(b0, b1);
return b1;
case LLCSAP_IPX:
/*
* Ethernet_II frames, which are Ethernet
* frames with a frame type of ETHERTYPE_IPX;
*
* Ethernet_802.3 frames, which have a frame
* type of LINUX_SLL_P_802_3;
*
* Ethernet_802.2 frames, which are 802.3
* frames with an 802.2 LLC header (i.e, have
* a frame type of LINUX_SLL_P_802_2) and
* with the IPX LSAP as the DSAP in the LLC
* header;
*
* Ethernet_SNAP frames, which are 802.3
* frames with an LLC header and a SNAP
* header and with an OUI of 0x000000
* (encapsulated Ethernet) and a protocol
* ID of ETHERTYPE_IPX in the SNAP header.
*
* First, do the checks on LINUX_SLL_P_802_2
* frames; generate the check for either
* Ethernet_802.2 or Ethernet_SNAP frames, and
* then put a check for LINUX_SLL_P_802_2 frames
* before it.
*/
b0 = gen_cmp(off_linktype + 2, BPF_B,
(bpf_int32)LLCSAP_IPX);
b1 = gen_snap(0x000000, ETHERTYPE_IPX,
off_linktype + 2);
gen_or(b0, b1);
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
gen_and(b0, b1);
/*
* Now check for 802.3 frames and OR that with
* the previous test.
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_3);
gen_or(b0, b1);
/*
* Now add the check for Ethernet_II frames, and
* do that before checking for the other frame
* types.
*/
b0 = gen_cmp(off_linktype, BPF_H,
(bpf_int32)ETHERTYPE_IPX);
gen_or(b0, b1);
return b1;
case ETHERTYPE_ATALK:
case ETHERTYPE_AARP:
/*
* EtherTalk (AppleTalk protocols on Ethernet link
* layer) may use 802.2 encapsulation.
*/
/*
* Check for 802.2 encapsulation (EtherTalk phase 2?);
* we check for the 802.2 protocol type in the
* "Ethernet type" field.
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
/*
* 802.2-encapsulated ETHERTYPE_ATALK packets are
* SNAP packets with an organization code of
* 0x080007 (Apple, for Appletalk) and a protocol
* type of ETHERTYPE_ATALK (Appletalk).
*
* 802.2-encapsulated ETHERTYPE_AARP packets are
* SNAP packets with an organization code of
* 0x000000 (encapsulated Ethernet) and a protocol
* type of ETHERTYPE_AARP (Appletalk ARP).
*/
if (proto == ETHERTYPE_ATALK)
b1 = gen_snap(0x080007, ETHERTYPE_ATALK,
off_linktype + 2);
else /* proto == ETHERTYPE_AARP */
b1 = gen_snap(0x000000, ETHERTYPE_AARP,
off_linktype + 2);
gen_and(b0, b1);
/*
* Check for Ethernet encapsulation (Ethertalk
* phase 1?); we just check for the Ethernet
* protocol type.
*/
b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
gen_or(b0, b1);
return b1;
default:
if (proto <= ETHERMTU) {
/*
* This is an LLC SAP value, so the frames
* that match would be 802.2 frames.
* Check for the 802.2 protocol type
* in the "Ethernet type" field, and
* then check the DSAP.
*/
b0 = gen_cmp(off_linktype, BPF_H,
LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_B,
(bpf_int32)proto);
gen_and(b0, b1);
return b1;
} else {
/*
* This is an Ethernet type, so compare
* the length/type field with it (if
* the frame is an 802.2 frame, the length
* field will be <= ETHERMTU, and, as
* "proto" is > ETHERMTU, this test
* will fail and the frame won't match,
* which is what we want).
*/
return gen_cmp(off_linktype, BPF_H,
(bpf_int32)proto);
}
}
}
static struct block *
gen_linktype(proto)
register int proto;
@ -1244,6 +1452,7 @@ gen_linktype(proto)
case DLT_EN10MB:
return gen_ether_linktype(proto);
/*NOTREACHED*/
break;
case DLT_C_HDLC:
@ -1255,6 +1464,7 @@ gen_linktype(proto)
default:
return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
/*NOTREACHED*/
break;
}
break;
@ -1268,6 +1478,7 @@ gen_linktype(proto)
case DLT_ATM_CLIP:
case DLT_IP_OVER_FC:
return gen_llc(proto);
/*NOTREACHED*/
break;
case DLT_SUNATM:
@ -1305,164 +1516,8 @@ gen_linktype(proto)
}
case DLT_LINUX_SLL:
switch (proto) {
case LLCSAP_IP:
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_IP << 8) | LLCSAP_IP));
gen_and(b0, b1);
return b1;
case LLCSAP_ISONS:
/*
* OSI protocols always use 802.2 encapsulation.
* XXX - should we check both the DSAP and the
* LSAP, like this, or should we check just the
* DSAP?
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
gen_and(b0, b1);
return b1;
case LLCSAP_NETBEUI:
/*
* NetBEUI always uses 802.2 encapsulation.
* XXX - should we check both the DSAP and the
* LSAP, like this, or should we check just the
* DSAP?
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
gen_and(b0, b1);
return b1;
case LLCSAP_IPX:
/*
* Ethernet_II frames, which are Ethernet
* frames with a frame type of ETHERTYPE_IPX;
*
* Ethernet_802.3 frames, which have a frame
* type of LINUX_SLL_P_802_3;
*
* Ethernet_802.2 frames, which are 802.3
* frames with an 802.2 LLC header (i.e, have
* a frame type of LINUX_SLL_P_802_2) and
* with the IPX LSAP as the DSAP in the LLC
* header;
*
* Ethernet_SNAP frames, which are 802.3
* frames with an LLC header and a SNAP
* header and with an OUI of 0x000000
* (encapsulated Ethernet) and a protocol
* ID of ETHERTYPE_IPX in the SNAP header.
*
* First, do the checks on LINUX_SLL_P_802_2
* frames; generate the check for either
* Ethernet_802.2 or Ethernet_SNAP frames, and
* then put a check for LINUX_SLL_P_802_2 frames
* before it.
*/
b0 = gen_cmp(off_linktype + 2, BPF_B,
(bpf_int32)LLCSAP_IPX);
b1 = gen_snap(0x000000, ETHERTYPE_IPX,
off_linktype + 2);
gen_or(b0, b1);
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
gen_and(b0, b1);
/*
* Now check for 802.3 frames and OR that with
* the previous test.
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_3);
gen_or(b0, b1);
/*
* Now add the check for Ethernet_II frames, and
* do that before checking for the other frame
* types.
*/
b0 = gen_cmp(off_linktype, BPF_H,
(bpf_int32)ETHERTYPE_IPX);
gen_or(b0, b1);
return b1;
case ETHERTYPE_ATALK:
case ETHERTYPE_AARP:
/*
* EtherTalk (AppleTalk protocols on Ethernet link
* layer) may use 802.2 encapsulation.
*/
/*
* Check for 802.2 encapsulation (EtherTalk phase 2?);
* we check for the 802.2 protocol type in the
* "Ethernet type" field.
*/
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
/*
* 802.2-encapsulated ETHERTYPE_ATALK packets are
* SNAP packets with an organization code of
* 0x080007 (Apple, for Appletalk) and a protocol
* type of ETHERTYPE_ATALK (Appletalk).
*
* 802.2-encapsulated ETHERTYPE_AARP packets are
* SNAP packets with an organization code of
* 0x000000 (encapsulated Ethernet) and a protocol
* type of ETHERTYPE_AARP (Appletalk ARP).
*/
if (proto == ETHERTYPE_ATALK)
b1 = gen_snap(0x080007, ETHERTYPE_ATALK,
off_linktype + 2);
else /* proto == ETHERTYPE_AARP */
b1 = gen_snap(0x000000, ETHERTYPE_AARP,
off_linktype + 2);
gen_and(b0, b1);
/*
* Check for Ethernet encapsulation (Ethertalk
* phase 1?); we just check for the Ethernet
* protocol type.
*/
b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
gen_or(b0, b1);
return b1;
default:
if (proto <= ETHERMTU) {
/*
* This is an LLC SAP value, so the frames
* that match would be 802.2 frames.
* Check for the 802.2 protocol type
* in the "Ethernet type" field, and
* then check the DSAP.
*/
b0 = gen_cmp(off_linktype, BPF_H,
LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_B,
(bpf_int32)proto);
gen_and(b0, b1);
return b1;
} else {
/*
* This is an Ethernet type, so compare
* the length/type field with it (if
* the frame is an 802.2 frame, the length
* field will be <= ETHERMTU, and, as
* "proto" is > ETHERMTU, this test
* will fail and the frame won't match,
* which is what we want).
*/
return gen_cmp(off_linktype, BPF_H,
(bpf_int32)proto);
}
}
return gen_linux_sll_linktype(proto);
/*NOTREACHED*/
break;
case DLT_SLIP:
@ -1486,9 +1541,11 @@ gen_linktype(proto)
default:
return gen_false(); /* always false */
}
/*NOTREACHED*/
break;
case DLT_PPP:
case DLT_PPP_PPPD:
case DLT_PPP_SERIAL:
case DLT_PPP_ETHER:
/*
@ -1672,6 +1729,7 @@ gen_linktype(proto)
#endif /* INET6 */
else
return gen_false();
/*NOTREACHED*/
break;
case DLT_ARCNET:
@ -1692,7 +1750,7 @@ gen_linktype(proto)
#endif /* INET6 */
case ETHERTYPE_IP:
b0 = gen_cmp(off_linktype, BPF_B,
b0 = gen_cmp(off_linktype, BPF_B,
(bpf_int32)ARCTYPE_IP);
b1 = gen_cmp(off_linktype, BPF_B,
(bpf_int32)ARCTYPE_IP_OLD);
@ -1702,7 +1760,7 @@ gen_linktype(proto)
case ETHERTYPE_ARP:
b0 = gen_cmp(off_linktype, BPF_B,
(bpf_int32)ARCTYPE_ARP);
b1 = gen_cmp(off_linktype, BPF_B,
b1 = gen_cmp(off_linktype, BPF_B,
(bpf_int32)ARCTYPE_ARP_OLD);
gen_or(b0, b1);
return (b1);
@ -1715,6 +1773,7 @@ gen_linktype(proto)
return (gen_cmp(off_linktype, BPF_B,
(bpf_int32)ARCTYPE_ATALK));
}
/*NOTREACHED*/
break;
case DLT_LTALK:
@ -1724,6 +1783,7 @@ gen_linktype(proto)
default:
return gen_false();
}
/*NOTREACHED*/
break;
case DLT_FRELAY:
@ -1769,10 +1829,27 @@ gen_linktype(proto)
default:
return gen_false();
}
/*NOTREACHED*/
break;
case DLT_JUNIPER_MLFR:
case DLT_JUNIPER_MLPPP:
case DLT_JUNIPER_ATM1:
case DLT_JUNIPER_ATM2:
/* just lets verify the magic number for now -
* on ATM we may have up to 6 different encapsulations on the wire
* and need a lot of heuristics to figure out that the payload
* might be;
*
* FIXME encapsulation specific BPF_ filters
*/
return gen_mcmp(0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
case DLT_LINUX_IRDA:
bpf_error("IrDA link-layer type filtering not implemented");
bpf_error("IrDA link-layer type filtering not implemented");
case DLT_DOCSIS:
bpf_error("DOCSIS link-layer type filtering not implemented");
}
/*
@ -2507,7 +2584,7 @@ gen_dnhostop(addr, dir, base_off)
return b1;
case Q_ISO:
bpf_error("ISO host filtering not implemented");
bpf_error("ISO host filtering not implemented");
default:
abort();
@ -2981,91 +3058,91 @@ gen_proto_abbrev(proto)
break;
case Q_ISO:
b1 = gen_linktype(LLCSAP_ISONS);
b1 = gen_linktype(LLCSAP_ISONS);
break;
case Q_ESIS:
b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
break;
case Q_ISIS:
b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
break;
case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
gen_or(b0, b1);
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
gen_or(b0, b1);
b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_LSP:
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
case Q_ISIS_LSP:
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_SNP:
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_CSNP:
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_ISIS_PSNP:
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
break;
case Q_CLNP:
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
break;
case Q_STP:
b1 = gen_linktype(LLCSAP_8021D);
b1 = gen_linktype(LLCSAP_8021D);
break;
case Q_IPX:
b1 = gen_linktype(LLCSAP_IPX);
b1 = gen_linktype(LLCSAP_IPX);
break;
case Q_NETBEUI:
b1 = gen_linktype(LLCSAP_NETBEUI);
b1 = gen_linktype(LLCSAP_NETBEUI);
break;
default:
@ -3306,8 +3383,11 @@ lookup_proto(name, proto)
case Q_LINK:
/* XXX should look up h/w protocol type based on linktype */
v = pcap_nametoeproto(name);
if (v == PROTO_UNDEF)
bpf_error("unknown ether proto '%s'", name);
if (v == PROTO_UNDEF) {
v = pcap_nametollc(name);
if (v == PROTO_UNDEF)
bpf_error("unknown ether proto '%s'", name);
}
break;
case Q_ISO:
@ -3699,6 +3779,7 @@ gen_proto(v, proto, dir)
* XXX - what about SNAP-encapsulated frames?
*/
return gen_cmp(2, BPF_H, (0x03<<8) | v);
/*NOTREACHED*/
break;
case DLT_C_HDLC:
@ -4139,6 +4220,7 @@ gen_mcode(s1, s2, masklen, q)
bpf_error("Mask syntax for networks only");
/* NOTREACHED */
}
/* NOTREACHED */
}
struct block *
@ -4773,6 +4855,7 @@ gen_broadcast(proto)
return b2;
}
bpf_error("only link-layer/IP broadcast filters supported");
/* NOTREACHED */
}
/*
@ -4989,6 +5072,7 @@ gen_multicast(proto)
#endif /* INET6 */
}
bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
/* NOTREACHED */
}
/*
@ -5039,6 +5123,31 @@ gen_inbound(dir)
(bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
break;
case DLT_PPP_PPPD:
if (dir) {
/* match outgoing packets */
b0 = gen_cmp(0, BPF_B, PPP_PPPD_OUT);
} else {
/* match incoming packets */
b0 = gen_cmp(0, BPF_B, PPP_PPPD_IN);
}
break;
case DLT_JUNIPER_MLFR:
case DLT_JUNIPER_MLPPP:
case DLT_JUNIPER_ATM1:
case DLT_JUNIPER_ATM2:
/* juniper flags (including direction) are stored
* the byte after the 3-byte magic number */
if (dir) {
/* match outgoing packets */
b0 = gen_mcmp(3, BPF_B, 0, 0x01);
} else {
/* match incoming packets */
b0 = gen_mcmp(3, BPF_B, 1, 0x01);
}
break;
default:
bpf_error("inbound/outbound not supported on linktype %d",
linktype);
@ -5067,7 +5176,7 @@ gen_pf_ifname(const char *ifname)
len-1);
/* NOTREACHED */
}
b0 = gen_bcmp(off, strlen(ifname), ifname);
b0 = gen_bcmp(off, strlen(ifname), (const u_char *)ifname);
return (b0);
}
@ -5087,7 +5196,7 @@ gen_pf_ruleset(char *ruleset)
/* NOTREACHED */
}
b0 = gen_bcmp(offsetof(struct pfloghdr, ruleset),
strlen(ruleset), ruleset);
strlen(ruleset), (const u_char *)ruleset);
return (b0);
}
@ -5243,7 +5352,80 @@ gen_vlan(vlan_num)
if (vlan_num >= 0) {
struct block *b1;
b1 = gen_cmp(orig_nl, BPF_H, (bpf_int32)vlan_num);
b1 = gen_mcmp(orig_nl, BPF_H, (bpf_int32)vlan_num, 0x0fff);
gen_and(b0, b1);
b0 = b1;
}
return (b0);
}
/*
* support for MPLS
*/
struct block *
gen_mpls(label_num)
int label_num;
{
struct block *b0;
/*
* Change the offsets to point to the type and data fields within
* the MPLS packet. This is somewhat of a kludge.
*/
if (orig_nl == (u_int)-1) {
orig_linktype = off_linktype; /* save original values */
orig_nl = off_nl;
orig_nl_nosnap = off_nl_nosnap;
switch (linktype) {
case DLT_EN10MB:
off_linktype = 16;
off_nl_nosnap = 18;
off_nl = 18;
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_MPLS);
break;
case DLT_PPP:
off_linktype = 6;
off_nl_nosnap = 8;
off_nl = 8;
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)PPP_MPLS_UCAST);
break;
case DLT_C_HDLC:
off_linktype = 6;
off_nl_nosnap = 8;
off_nl = 8;
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_MPLS);
break;
/* FIXME add other DLT_s ...
* for Frame-Relay/and ATM this may get messy due to SNAP headers
* leave it for now */
default:
bpf_error("no MPLS support for data link type %d",
linktype);
b0 = NULL;
/*NOTREACHED*/
}
} else {
bpf_error("'mpls' can't be combined with 'vlan' or another 'mpls'");
b0 = NULL;
/*NOTREACHED*/
}
/* If a specific MPLS label is requested, check it */
if (label_num >= 0) {
struct block *b1;
label_num = label_num << 12; /* label is shifted 12 bits on the wire */
b1 = gen_mcmp(orig_nl, BPF_W, (bpf_int32)label_num, 0xfffff000); /* only compare the first 20 bits */
gen_and(b0, b1);
b0 = b1;
}
@ -5428,15 +5610,15 @@ gen_msg_abbrev(type)
break;
case A_CALLPROCEED:
b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
break;
case A_CONNECT:
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
break;
break;
case A_CONNECTACK:
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
break;
case A_RELEASE:
@ -5444,7 +5626,7 @@ gen_msg_abbrev(type)
break;
case A_RELEASE_DONE:
b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
break;
default:
@ -5471,9 +5653,9 @@ gen_atmmulti_abbrev(type)
if (!is_atm)
bpf_error("'oamf4' supported only on raw ATM");
/* OAM F4 type */
b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
gen_or(b0, b1);
gen_or(b0, b1);
b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
gen_and(b0, b1);
break;

View File

@ -19,7 +19,7 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $FreeBSD$
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004/03/28 21:45:31 fenner Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60 2004/06/16 08:20:30 hannes Exp $ (LBL)
*/
/*
@ -274,6 +274,7 @@ struct block *gen_multicast(int);
struct block *gen_inbound(int);
struct block *gen_vlan(int);
struct block *gen_mpls(int);
struct block *gen_atmfield_code(int atmfield, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmtype_abbrev(int type);

View File

@ -23,7 +23,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004/03/28 21:45:32 fenner Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86 2004/12/18 08:49:23 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -34,7 +34,6 @@ static const char rcsid[] _U_ =
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#endif /* WIN32 */
@ -50,7 +49,6 @@ struct rtentry;
#endif /* WIN32 */
#include <stdio.h>
#include <strings.h>
#include "pcap-int.h"
@ -129,7 +127,7 @@ pcap_parse()
%token LSH RSH
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN
%token VLAN MPLS
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token STP
%token IPX
@ -325,6 +323,8 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-1); }
| MPLS pnum { $$ = gen_mpls($2); }
| MPLS { $$ = gen_mpls(-1); }
| pfvar { $$ = $1; }
;

View File

@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.68.2.3 2003/11/19 18:13:48 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77 2005/03/27 22:26:25 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -55,12 +55,19 @@ static const char rcsid[] _U_ =
#ifndef WIN32
#ifdef HAVE_ETHER_HOSTTON
/*
* XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
* ether_hostton()?
*/
#ifdef HAVE_NETINET_IF_ETHER_H
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
#include <netinet/if_ether.h>
#endif /* HAVE_NETINET_IF_ETHER_H */
#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
#include <netinet/ether.h>
#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
#include <netdb.h>
@ -126,6 +133,7 @@ pcap_nametoaddrinfo(const char *name)
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; /*not really*/
hints.ai_protocol = IPPROTO_TCP; /*not really*/
error = getaddrinfo(name, NULL, &hints, &res);
if (error)
return NULL;
@ -278,6 +286,30 @@ pcap_nametoeproto(const char *s)
return PROTO_UNDEF;
}
#include "llc.h"
/* Static data base of LLC values. */
static struct eproto llc_db[] = {
{ "iso", LLCSAP_ISONS },
{ "stp", LLCSAP_8021D },
{ "ipx", LLCSAP_IPX },
{ "netbeui", LLCSAP_NETBEUI },
{ (char *)0, 0 }
};
int
pcap_nametollc(const char *s)
{
struct eproto *p = llc_db;
while (p->s != 0) {
if (strcmp(p->s, s) == 0)
return p->p;
p += 1;
}
return PROTO_UNDEF;
}
/* Hex digit to integer. */
static inline int
xdtoi(c)
@ -391,18 +423,8 @@ pcap_ether_hostton(const char *name)
}
#else
/*
* XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files,
* for those OS versions that don't declare it, rather than being declared
* here? That way, for example, we could declare it on FreeBSD 2.x (which
* doesn't declare it), but not on FreeBSD 3.x (which declares it like
* this) or FreeBSD 4.x (which declares it with its first argument as
* "const char *", so no matter how we declare it here, it'll fail to
* compile on one of 3.x or 4.x).
*/
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
!defined(_UNICOSMP)
extern int ether_hostton(char *, struct ether_addr *);
#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
extern int ether_hostton(const char *, struct ether_addr *);
#endif
/* Use the os supplied routines */

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* $FreeBSD$
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68 2004/12/18 08:52:10 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
@ -47,6 +47,11 @@ extern "C" {
#include <packet32.h>
#endif /* WIN32 */
#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#endif
/*
* Savefile
*/
@ -75,13 +80,14 @@ struct pcap_md {
u_long TotDrops; /* count of dropped packets */
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
char *device; /* device name */
#ifdef linux
int sock_packet; /* using Linux 2.0 compatible interface */
int timeout; /* timeout specified to pcap_open_live */
int clear_promisc; /* must clear promiscuous mode when we close */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */
int lo_ifindex; /* interface index of the loopback device */
char *device; /* device name */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
#endif
@ -90,7 +96,7 @@ struct pcap_md {
u_int dag_mem_bottom; /* DAG card current memory bottom pointer */
u_int dag_mem_top; /* DAG card current memory top pointer */
int dag_fcs_bits; /* Number of checksum bits from link layer */
int dag_offset_flags; /* Flags to pass to dag_offset(). */
int dag_offset_flags; /* Flags to pass to dag_offset(). */
#endif
};
@ -103,6 +109,7 @@ struct pcap {
#else
int fd;
int selectable_fd;
int send_fd;
#endif /* WIN32 */
int snapshot;
int linktype;
@ -111,6 +118,15 @@ struct pcap {
int break_loop; /* flag set to force break from packet-reading loop */
#ifdef PCAP_FDDIPAD
int fddipad;
#endif
#ifdef MSDOS
int inter_packet_wait; /* offline: wait between packets */
void (*wait_proc)(void); /* call proc while waiting */
#endif
struct pcap_sf sf;
struct pcap_md md;
@ -131,6 +147,7 @@ struct pcap {
* Methods.
*/
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*inject_op)(pcap_t *, const void *, size_t);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
@ -145,7 +162,7 @@ struct pcap {
char errbuf[PCAP_ERRBUF_SIZE + 1];
int dlt_count;
int *dlt_list;
u_int *dlt_list;
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
};
@ -236,11 +253,13 @@ int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
/*
* Routines that most pcap implementations can use for non-blocking mode.
*/
#ifndef WIN32
#if !defined(WIN32) && !defined(MSDOS)
int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif
void pcap_close_common(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".
*
@ -251,10 +270,10 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
* "pcap_add_if()" adds an interface to the list of interfaces.
*/
int pcap_platform_finddevs(pcap_if_t **, char *);
int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *,
int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, char *);
int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);
int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *);
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
const char *, char *);
@ -263,9 +282,6 @@ int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
char *pcap_win32strerror(void);
#endif
/* XXX */
extern int pcap_fddipad;
int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *);

View File

@ -31,11 +31,11 @@
* SUCH DAMAGE.
*
* $FreeBSD$
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10 2005/03/17 07:02:32 guy Exp $ (LBL)
*/
#ifndef lib_pcap_ethers_h
#define lib_pcap_ethers_h
#ifndef lib_pcap_namedb_h
#define lib_pcap_namedb_h
#ifdef __cplusplus
extern "C" {
@ -68,6 +68,7 @@ bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
int pcap_nametollc(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.

View File

@ -1,4 +1,4 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.51.2.9 2004/03/28 21:45:32 fenner Exp $
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64 2004/12/17 21:27:54 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@ -41,7 +41,9 @@ pcap_t *pcap_open_live(const char *device, int snaplen,
int promisc, int to_ms, char *errbuf)
pcap_t *pcap_open_dead(int linktype, int snaplen)
pcap_t *pcap_open_offline(const char *fname, char *errbuf)
pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)
pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp)
.ft
.LP
.ft B
@ -90,6 +92,11 @@ void pcap_breakloop(pcap_t *)
.ft
.LP
.ft B
int pcap_inject(pcap_t *p, const void *buf, size_t size)
int pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
.ft
.LP
.ft B
int pcap_datalink(pcap_t *p)
int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
int pcap_set_datalink(pcap_t *p, int dlt);
@ -103,7 +110,7 @@ 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)
int pcap_get_selectable_fd(pcap_t *p)
int pcap_get_selectable_fd(pcap_t *p);
void pcap_perror(pcap_t *p, char *prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int error)
@ -130,6 +137,7 @@ in
.BR pcap_open_live() ,
.BR pcap_open_dead() ,
.BR pcap_open_offline() ,
.BR pcap_fopen_offline() ,
.BR pcap_setnonblock() ,
.BR pcap_getnonblock() ,
.BR pcap_findalldevs() ,
@ -208,9 +216,16 @@ and
.BR tcpslice(1) .
The name "-" in a synonym for
.BR stdin .
Alternatively, you may call
.B pcap_fopen_offline()
to read dumped data from an existing open stream
.IR fp .
Note that on Windows, that stream should be opened in binary mode.
.I errbuf
is used to return error text and is only set when
.B pcap_open_offline()
or
.B pcap_fopen_offline()
fails and returns
.BR NULL .
.PP
@ -228,13 +243,18 @@ struct as returned by
or
.BR pcap_open_live() .
.I fname
specifies the name of the file to open.
specifies the name of the file to open. Alternatively, you may call
.B pcap_dump_fopen()
to write data to an existing open stream
.IR fp .
Note that on Windows, that stream should be opened in binary mode.
If
.B NULL
is returned,
.B pcap_geterr()
can be used to get the error text.
.PP
.PP
.B pcap_setnonblock()
puts a capture descriptor, opened with
.BR pcap_open_live() ,
@ -356,6 +376,13 @@ to by
may be null if the interface isn't a point-to-point interface
.RE
.PP
Note that not all the addresses in the list of addresses are
necessarily IPv4 or IPv6 addresses - you must check the
.B sa_family
member of the
.B "struct sockaddr"
before interpreting the contents of the address.
.PP
.B \-1
is returned on failure, in which case
.B errbuf
@ -630,6 +657,45 @@ the flag is cleared, so a subsequent call will resume reading packets.
If a positive number is returned, the flag is not cleared, so a
subsequent call will return \-2 and clear the flag.
.PP
.B pcap_inject()
sends a raw packet through the network interface;
.I buf
points to the data of the packet, including the link-layer header, and
.I size
is the number of bytes in the packet.
It returns the number of bytes written on success. A return of \-1
indicates an error in which case
.B pcap_perror()
or
.B pcap_geterr()
may be used to display the error text.
Note that, even if you successfully open the network interface, you
might not have permission to send packets on it, or it might not support
sending packets; as
.I pcap_open_live()
doesn't have a flag to indicate whether to open for capturing, sending,
or capturing and sending, you cannot request an open that supports
sending and be notified at open time whether sending will be possible.
Note also that some devices might not support sending packets.
.PP
Note that, on some platforms, the link-layer header of the packet that's
sent might not be the same as the link-layer header of the packet
supplied to
.BR pcap_inject() ,
as the source link-layer address, if the header contains such an
address, might be changed to be the address assigned to the interface on
which the packet it sent, if the platform doesn't support sending
completely raw and unchanged packets.
.PP
.B pcap_sendpacket()
is like
.BR pcap_inject() ,
but it returns 0 on success and \-1 on failure.
.RB ( pcap_inject()
comes from OpenBSD;
.B pcap_sendpacket()
comes from WinPcap. Both are provided for compatibility.)
.PP
.B pcap_dump()
outputs a packet to the ``savefile'' opened with
.BR pcap_dump_open() .

View File

@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* $FreeBSD$
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.45.2.4 2004/01/27 22:56:20 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52 2004/12/18 08:52:11 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
@ -135,6 +135,39 @@ struct pcap_stat {
#endif /* WIN32 */
};
#ifdef MSDOS
/*
* As returned by the pcap_stats_ex()
*/
struct pcap_stat_ex {
u_long rx_packets; /* total packets received */
u_long tx_packets; /* total packets transmitted */
u_long rx_bytes; /* total bytes received */
u_long tx_bytes; /* total bytes transmitted */
u_long rx_errors; /* bad packets received */
u_long tx_errors; /* packet transmit problems */
u_long rx_dropped; /* no space in Rx buffers */
u_long tx_dropped; /* no space available for Tx */
u_long multicast; /* multicast packets received */
u_long collisions;
/* detailed rx_errors: */
u_long rx_length_errors;
u_long rx_over_errors; /* receiver ring buff overflow */
u_long rx_crc_errors; /* recv'd pkt with crc error */
u_long rx_frame_errors; /* recv'd frame alignment error */
u_long rx_fifo_errors; /* recv'r fifo overrun */
u_long rx_missed_errors; /* recv'r missed packet */
/* detailed tx_errors */
u_long tx_aborted_errors;
u_long tx_carrier_errors;
u_long tx_fifo_errors;
u_long tx_heartbeat_errors;
u_long tx_window_errors;
};
#endif
/*
* Item in a list of interfaces.
*/
@ -167,6 +200,7 @@ int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
pcap_t *pcap_fopen_offline(FILE *, 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 *);
@ -179,6 +213,8 @@ int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);
int pcap_inject(pcap_t *, const void *, size_t);
int pcap_sendpacket(pcap_t *, const u_char *, int);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
@ -202,6 +238,7 @@ FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
@ -218,33 +255,44 @@ int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
#ifdef WIN32
#if defined(WIN32)
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif
#endif /* WPCAP */
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#else
#elif defined(MSDOS)
/*
* MS-DOS definitions
*/
int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
u_long pcap_mac_packets (void);
#else /* UN*X */
/*
* UN*X definitions
*/
int pcap_get_selectable_fd(pcap_t *);
#endif /* WIN32 */
#endif /* WIN32/MSDOS/UN*X */
#ifdef __cplusplus
}

View File

@ -24,7 +24,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004/03/28 21:45:33 fenner Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99 2004/06/16 08:20:28 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -261,6 +261,7 @@ inbound return INBOUND;
outbound return OUTBOUND;
vlan return VLAN;
mpls return MPLS;
lane return LANE;
llc return LLC;

View File

@ -1,632 +0,0 @@
/*
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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. Neither the name of the Institute 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 BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $";
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <pcap-int.h>
enum format_flags {
minus_flag = 1,
plus_flag = 2,
space_flag = 4,
alternate_flag = 8,
zero_flag = 16
};
/*
* Common state
*/
struct state {
unsigned char *str;
unsigned char *s;
unsigned char *theend;
size_t sz;
size_t max_sz;
int (*append_char)(struct state *, unsigned char);
int (*reserve)(struct state *, size_t);
/* XXX - methods */
};
#ifndef HAVE_VSNPRINTF
static int
sn_reserve (struct state *state, size_t n)
{
return state->s + n > state->theend;
}
static int
sn_append_char (struct state *state, unsigned char c)
{
if (sn_reserve (state, 1)) {
return 1;
} else {
*state->s++ = c;
return 0;
}
}
#endif
#if 0
static int
as_reserve (struct state *state, size_t n)
{
if (state->s + n > state->theend) {
int off = state->s - state->str;
unsigned char *tmp;
if (state->max_sz && state->sz >= state->max_sz)
return 1;
state->sz = max(state->sz * 2, state->sz + n);
if (state->max_sz)
state->sz = min(state->sz, state->max_sz);
tmp = realloc (state->str, state->sz);
if (tmp == NULL)
return 1;
state->str = tmp;
state->s = state->str + off;
state->theend = state->str + state->sz - 1;
}
return 0;
}
static int
as_append_char (struct state *state, unsigned char c)
{
if(as_reserve (state, 1))
return 1;
else {
*state->s++ = c;
return 0;
}
}
#endif
static int
append_number(struct state *state,
unsigned long num, unsigned base, char *rep,
int width, int prec, int flags, int minusp)
{
int len = 0;
int i;
/* given precision, ignore zero flag */
if(prec != -1)
flags &= ~zero_flag;
else
prec = 1;
/* zero value with zero precision -> "" */
if(prec == 0 && num == 0)
return 0;
do{
if((*state->append_char)(state, rep[num % base]))
return 1;
len++;
num /= base;
}while(num);
prec -= len;
/* pad with prec zeros */
while(prec-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
/* add length of alternate prefix (added later) to len */
if(flags & alternate_flag && (base == 16 || base == 8))
len += base / 8;
/* pad with zeros */
if(flags & zero_flag){
width -= len;
if(minusp || (flags & space_flag) || (flags & plus_flag))
width--;
while(width-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
}
/* add alternate prefix */
if(flags & alternate_flag && (base == 16 || base == 8)){
if(base == 16)
if((*state->append_char)(state, rep[10] + 23)) /* XXX */
return 1;
if((*state->append_char)(state, '0'))
return 1;
}
/* add sign */
if(minusp){
if((*state->append_char)(state, '-'))
return 1;
len++;
} else if(flags & plus_flag) {
if((*state->append_char)(state, '+'))
return 1;
len++;
} else if(flags & space_flag) {
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(flags & minus_flag)
/* swap before padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
width -= len;
while(width-- > 0){
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(!(flags & minus_flag))
/* swap after padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
return 0;
}
static int
append_string (struct state *state,
unsigned char *arg,
int width,
int prec,
int flags)
{
if(prec != -1)
width -= prec;
else
width -= strlen((char *)arg);
if(!(flags & minus_flag))
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
if (prec != -1) {
while (*arg && prec--)
if ((*state->append_char) (state, *arg++))
return 1;
} else {
while (*arg)
if ((*state->append_char) (state, *arg++))
return 1;
}
if(flags & minus_flag)
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
static int
append_char(struct state *state,
unsigned char arg,
int width,
int flags)
{
while(!(flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
if((*state->append_char) (state, arg))
return 1;
while((flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
/*
* This can't be made into a function...
*/
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
/*
* zyxprintf - return 0 or -1
*/
static int
xyzprintf (struct state *state, const char *char_format, va_list ap)
{
const unsigned char *format = (const unsigned char *)char_format;
unsigned char c;
while((c = *format++)) {
if (c == '%') {
int flags = 0;
int width = 0;
int prec = -1;
int long_flag = 0;
int short_flag = 0;
/* flags */
while((c = *format++)){
if(c == '-')
flags |= minus_flag;
else if(c == '+')
flags |= plus_flag;
else if(c == ' ')
flags |= space_flag;
else if(c == '#')
flags |= alternate_flag;
else if(c == '0')
flags |= zero_flag;
else
break;
}
if((flags & space_flag) && (flags & plus_flag))
flags ^= space_flag;
if((flags & minus_flag) && (flags & zero_flag))
flags ^= zero_flag;
/* width */
if (isdigit(c))
do {
width = width * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if(c == '*') {
width = va_arg(ap, int);
c = *format++;
}
/* precision */
if (c == '.') {
prec = 0;
c = *format++;
if (isdigit(c))
do {
prec = prec * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if (c == '*') {
prec = va_arg(ap, int);
c = *format++;
}
}
/* size */
if (c == 'h') {
short_flag = 1;
c = *format++;
} else if (c == 'l') {
long_flag = 1;
c = *format++;
}
switch (c) {
case 'c' :
if(append_char(state, va_arg(ap, int), width, flags))
return -1;
break;
case 's' :
if (append_string(state,
va_arg(ap, unsigned char*),
width,
prec,
flags))
return -1;
break;
case 'd' :
case 'i' : {
long arg;
unsigned long num;
int minusp = 0;
PARSE_INT_FORMAT(arg, ap, signed);
if (arg < 0) {
minusp = 1;
num = -arg;
} else
num = arg;
if (append_number (state, num, 10, "0123456789",
width, prec, flags, minusp))
return -1;
break;
}
case 'u' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 10, "0123456789",
width, prec, flags, 0))
return -1;
break;
}
case 'o' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 010, "01234567",
width, prec, flags, 0))
return -1;
break;
}
case 'x' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789abcdef",
width, prec, flags, 0))
return -1;
break;
}
case 'X' :{
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'p' : {
unsigned long arg = (unsigned long)va_arg(ap, void*);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'n' : {
int *arg = va_arg(ap, int*);
*arg = state->s - state->str;
break;
}
case '\0' :
--format;
/* FALLTHROUGH */
case '%' :
if ((*state->append_char)(state, c))
return -1;
break;
default :
if ( (*state->append_char)(state, '%')
|| (*state->append_char)(state, c))
return -1;
break;
}
} else
if ((*state->append_char) (state, c))
return -1;
}
return 0;
}
#ifndef HAVE_SNPRINTF
int
snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf (str, sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (sz);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return ret;
}
#endif
#if 0
#ifndef HAVE_ASPRINTF
int
asprintf (char **ret, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasprintf (ret, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_ASNPRINTF
int
asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasnprintf (ret, max_sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_VASPRINTF
int
vasprintf (char **ret, const char *format, va_list args)
{
return vasnprintf (ret, 0, format, args);
}
#endif
#ifndef HAVE_VASNPRINTF
int
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
size_t len;
struct state state;
state.max_sz = max_sz;
state.sz = 1;
state.str = malloc(state.sz);
if (state.str == NULL) {
*ret = NULL;
return -1;
}
state.s = state.str;
state.theend = state.s + state.sz - 1;
state.append_char = as_append_char;
state.reserve = as_reserve;
st = xyzprintf (&state, format, args);
if (st) {
free (state.str);
*ret = NULL;
return -1;
} else {
char *tmp;
*state.s = '\0';
len = state.s - state.str;
tmp = realloc (state.str, len+1);
if (tmp == NULL) {
free (state.str);
*ret = NULL;
return -1;
}
*ret = tmp;
return len;
}
}
#endif
#endif
#ifndef HAVE_VSNPRINTF
int
vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;
unsigned char *ustr = (unsigned char *)str;
state.max_sz = 0;
state.sz = sz;
state.str = ustr;
state.s = ustr;
state.theend = ustr + sz - 1;
state.append_char = sn_append_char;
state.reserve = sn_reserve;
ret = xyzprintf (&state, format, args);
*state.s = '\0';
if (ret)
return sz;
else
return state.s - state.str;
}
#endif