Permalink
Browse files

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.
  • Loading branch information...
yuguy committed Jan 14, 2001
1 parent 90018eb commit 2b3dac284e25434f15da7f9d7f1d66cbecb1df88
Showing with 174 additions and 15 deletions.
  1. +165 −12 gencode.c
  2. +3 −1 gencode.h
  3. +3 −1 grammar.y
  4. +3 −1 scanner.l
View
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 */
View
@@ -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
View
@@ -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); }
View
@@ -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;

0 comments on commit 2b3dac2

Please sign in to comment.