Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit 2b3dac284e25434f15da7f9d7f1d66cbecb1df88 1 parent 90018eb
@yuguy yuguy authored
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
4 gencode.h
@@ -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
4 grammar.y
@@ -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
4 scanner.l
@@ -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;
Please sign in to comment.
Something went wrong with that request. Please try again.