Support checking for protocols specified by an LLC SAP on FDDI, Token
Ring, and RFC 1483-style ATM, as well as on Ethernet. Support checking for LLC SAP protocols other than OSI protocols on Ethernet - for now, we check only the DSAP on those, rather than checking both the DSAP and SSAP as we do for OSI, as I think, in some cases, the SSAP isn't the same as the DSAP. When generating protocol type checks on link-layer types with no type field, where packets are always IP (SLIP, BSD/OS SLIP, raw IP), generate a "test" that always succeeds if the protocol being checked for is IP or IPv6 and a "test" that always fails otherwise. (We originally did "gen_true()" if the protocol is IP, and bogusly generated code to check the field at an offset of -1 otherwise; a subsequent change caused us always to do "gen_true()", but that doesn't properly handle attempts to check for other protocols - those attempts should generate code that always fails, meaning that if you try to look for ARP packets in such a capture the BPF compiler will return "expression rejects all packets" as an error - and still generated extra code not all of which was removed by the optimizer. The current code generates no *more* BPF code.) Add "stp", which checks for the LLC SAP for the Spanning Tree Protocol.
This commit is contained in:
parent
90018ebb80
commit
2b3dac284e
177
gencode.c
177
gencode.c
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.140 2000-12-21 10:29:22 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.141 2001-01-14 04:34:51 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -60,8 +60,15 @@ struct rtentry;
|
|||
#include <sys/socket.h>
|
||||
#endif /*INET6*/
|
||||
|
||||
/*
|
||||
* LLC SAP values.
|
||||
* Note that these fit in one byte, and are thus less than 1500, and
|
||||
* are thus distinguishable from ETHERTYPE_ values, so we can use them
|
||||
* as protocol types values.
|
||||
*/
|
||||
#define LLC_SNAP_LSAP 0xaa
|
||||
#define LLC_ISO_LSAP 0xfe
|
||||
#define LLC_STP_LSAP 0x42
|
||||
|
||||
#define ETHERMTU 1500
|
||||
|
||||
|
@ -591,12 +598,13 @@ init_linktype(type)
|
|||
case DLT_FDDI:
|
||||
/*
|
||||
* FDDI doesn't really have a link-level type field.
|
||||
* We assume that SSAP = SNAP is being used and pick
|
||||
* out the encapsulated Ethernet type.
|
||||
* We set "off_linktype" to the offset of the LLC header.
|
||||
*
|
||||
* To check for Ethernet types, we assume that SSAP = SNAP
|
||||
* is being used and pick out the encapsulated Ethernet type.
|
||||
* XXX - should we generate code to check for SNAP?
|
||||
*/
|
||||
off_linktype = 19;
|
||||
off_linktype = 13;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
off_linktype += pcap_fddipad;
|
||||
#endif
|
||||
|
@ -609,9 +617,10 @@ init_linktype(type)
|
|||
case DLT_IEEE802:
|
||||
/*
|
||||
* Token Ring doesn't really have a link-level type field.
|
||||
* We assume that SSAP = SNAP is being used and pick
|
||||
* out the encapsulated Ethernet type.
|
||||
* We set "off_linktype" to the offset of the LLC header.
|
||||
*
|
||||
* To check for Ethernet types, we assume that SSAP = SNAP
|
||||
* is being used and pick out the encapsulated Ethernet type.
|
||||
* XXX - should we generate code to check for SNAP?
|
||||
*
|
||||
* XXX - the header is actually variable-length.
|
||||
|
@ -629,7 +638,7 @@ init_linktype(type)
|
|||
* the 16-bit value at an offset of 14 (shifted right
|
||||
* 8 - figure out which byte that is).
|
||||
*/
|
||||
off_linktype = 20;
|
||||
off_linktype = 14;
|
||||
off_nl = 22;
|
||||
return;
|
||||
|
||||
|
@ -702,10 +711,6 @@ gen_linktype(proto)
|
|||
{
|
||||
struct block *b0, *b1;
|
||||
|
||||
/* If we're not using encapsulation, we're done */
|
||||
if (off_linktype == -1)
|
||||
return gen_true();
|
||||
|
||||
switch (linktype) {
|
||||
|
||||
case DLT_EN10MB:
|
||||
|
@ -718,6 +723,9 @@ gen_linktype(proto)
|
|||
case LLC_ISO_LSAP:
|
||||
/*
|
||||
* 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_gt(off_linktype, BPF_H, ETHERMTU);
|
||||
gen_not(b0);
|
||||
|
@ -767,11 +775,125 @@ gen_linktype(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 that the frame is an 802.2 frame
|
||||
* (i.e., that the length/type field is
|
||||
* a length field, <= ETHERMTU) and
|
||||
* then check the DSAP.
|
||||
*/
|
||||
b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
|
||||
gen_not(b0);
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DLT_FDDI:
|
||||
case DLT_IEEE802:
|
||||
case DLT_ATM_RFC1483:
|
||||
case DLT_ATM_CLIP:
|
||||
/*
|
||||
* XXX - handle token-ring variable-length header.
|
||||
*/
|
||||
switch (proto) {
|
||||
|
||||
case LLC_ISO_LSAP:
|
||||
return gen_cmp(off_linktype, BPF_H, (long)
|
||||
((LLC_ISO_LSAP << 8) | LLC_ISO_LSAP));
|
||||
|
||||
case ETHERTYPE_ATALK:
|
||||
/*
|
||||
* 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).
|
||||
*
|
||||
* XXX - check for an organization code of
|
||||
* encapsulated Ethernet as well?
|
||||
*/
|
||||
return gen_snap(0x080007, ETHERTYPE_ATALK,
|
||||
off_linktype);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (proto <= ETHERMTU) {
|
||||
/*
|
||||
* This is an LLC SAP value, so check
|
||||
* the DSAP.
|
||||
*/
|
||||
return gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)proto);
|
||||
} else {
|
||||
/*
|
||||
* This is an Ethernet type; we assume
|
||||
* that it's unlikely that it'll
|
||||
* appear in the right place at random,
|
||||
* and therefore check only the
|
||||
* location that would hold the Ethernet
|
||||
* type in a SNAP frame with an organization
|
||||
* code of 0x000000 (encapsulated Ethernet).
|
||||
*
|
||||
* XXX - if we were to check for the SNAP DSAP
|
||||
* and LSAP, as per XXX, and were also to check
|
||||
* for an organization code of 0x000000
|
||||
* (encapsulated Ethernet), we'd do
|
||||
*
|
||||
* return gen_snap(0x000000, proto,
|
||||
* off_linktype);
|
||||
*
|
||||
* here; for now, we don't, as per the above.
|
||||
* I don't know whether it's worth the
|
||||
* extra CPU time to do the right check
|
||||
* or not.
|
||||
*/
|
||||
return gen_cmp(off_linktype+6, BPF_H,
|
||||
(bpf_int32)proto);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DLT_SLIP:
|
||||
return gen_false();
|
||||
case DLT_SLIP_BSDOS:
|
||||
case DLT_RAW:
|
||||
/*
|
||||
* These types don't provide any type field; packets
|
||||
* are always IP.
|
||||
*
|
||||
* XXX - for IPv4, check for a version number of 4, and,
|
||||
* for IPv6, check for a version number of 6?
|
||||
*/
|
||||
switch (proto) {
|
||||
|
||||
case ETHERTYPE_IP:
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
#endif
|
||||
return gen_true(); /* always true */
|
||||
|
||||
default:
|
||||
return gen_false(); /* always false */
|
||||
}
|
||||
break;
|
||||
|
||||
case DLT_PPP:
|
||||
case DLT_PPP_SERIAL:
|
||||
|
@ -911,6 +1033,24 @@ gen_linktype(proto)
|
|||
}
|
||||
return (gen_cmp(0, BPF_W, (bpf_int32)proto));
|
||||
}
|
||||
|
||||
/*
|
||||
* All the types that have no encapsulation should either be
|
||||
* handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if
|
||||
* all packets are IP packets, or should be handled in some
|
||||
* special case, if none of them are (if some are and some
|
||||
* aren't, the lack of encapsulation is a problem, as we'd
|
||||
* have to find some other way of determining the packet type).
|
||||
*
|
||||
* Therefore, if "off_linktype" is -1, there's an error.
|
||||
*/
|
||||
if (off_linktype == -1)
|
||||
abort();
|
||||
|
||||
/*
|
||||
* Any type not handled above should always have an Ethernet
|
||||
* type at an offset of "off_linktype".
|
||||
*/
|
||||
return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
|
||||
}
|
||||
|
||||
|
@ -1332,6 +1472,9 @@ gen_host(addr, mask, proto, dir)
|
|||
case Q_CLNP:
|
||||
bpf_error("'clnp' modifier applied to host");
|
||||
|
||||
case Q_STP:
|
||||
bpf_error("'stp' modifier applied to host");
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
@ -1424,6 +1567,9 @@ gen_host6(addr, mask, proto, dir)
|
|||
case Q_CLNP:
|
||||
bpf_error("'clnp' modifier applied to host");
|
||||
|
||||
case Q_STP:
|
||||
bpf_error("'stp' modifier applied to host");
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
@ -1626,6 +1772,10 @@ gen_proto_abbrev(proto)
|
|||
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
|
||||
break;
|
||||
|
||||
case Q_STP:
|
||||
b1 = gen_linktype(LLC_STP_LSAP);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
@ -2282,6 +2432,9 @@ gen_proto(v, proto, dir)
|
|||
case Q_ESP:
|
||||
bpf_error("'ah proto' is bogus");
|
||||
|
||||
case Q_STP:
|
||||
bpf_error("'stp proto' is bogus");
|
||||
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.47 2000-11-04 10:09:55 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.48 2001-01-14 04:34:51 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
/* Address qualifiers. */
|
||||
|
@ -65,6 +65,8 @@
|
|||
#define Q_ISIS 24
|
||||
#define Q_CLNP 25
|
||||
|
||||
#define Q_STP 26
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
#define Q_SRC 1
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.64 2000-10-28 10:18:40 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.65 2001-01-14 04:34:52 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -118,6 +118,7 @@ pcap_parse()
|
|||
%token IPV6 ICMPV6 AH ESP
|
||||
%token VLAN
|
||||
%token ISO ESIS ISIS CLNP
|
||||
%token STP
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
|
@ -263,6 +264,7 @@ pname: LINK { $$ = Q_LINK; }
|
|||
| ESIS { $$ = Q_ESIS; }
|
||||
| ISIS { $$ = Q_ISIS; }
|
||||
| CLNP { $$ = Q_CLNP; }
|
||||
| STP { $$ = Q_STP; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.70 2000-10-28 10:18:40 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.71 2001-01-14 04:34:52 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -197,6 +197,8 @@ isis return ISIS;
|
|||
is-is return ISIS;
|
||||
clnp return CLNP;
|
||||
|
||||
stp return STP;
|
||||
|
||||
host return HOST;
|
||||
net return NET;
|
||||
mask return MASK;
|
||||
|
|
Reference in New Issue