From 54b2ab13c29b96c9d587a0fb348ae8a1caccf08f Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 28 Oct 2000 08:19:29 +0000 Subject: [PATCH] Patch from Monroe Williams , submitted with NetBSD PR #5228, to correctly check for Appletalk for EtherTalk phase II - they use 802.3 with LLC SNAP packets, rather than D/I/X Ethernet packets. His patch made "atalk" check for Appletalk ARP as well as other Appletalk packets; I've instead added a separate "aarp" packet type, leaving "atalk" checking only for ETHERTYPE_ATALK, so you can check for ETHERTYPE_ATALK, ETHERTYPE_AARP, or both. --- CREDITS | 1 + gencode.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++- gencode.h | 4 +- grammar.y | 5 ++- scanner.l | 3 +- 5 files changed, 117 insertions(+), 5 deletions(-) diff --git a/CREDITS b/CREDITS index 14017fe..24c76c0 100644 --- a/CREDITS +++ b/CREDITS @@ -19,6 +19,7 @@ Additional people who have contributed patches: Jefferson Ogata Juergen Schoenwaelder Love Hörnquist-Åstrand + Monroe Williams Peter Jeremy Rafal Maszkowski Rick Jones diff --git a/gencode.c b/gencode.c index 12706b6..615a258 100644 --- a/gencode.c +++ b/gencode.c @@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.126 2000-10-28 00:01:26 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.127 2000-10-28 08:19:29 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -124,12 +124,14 @@ static inline void syntax(void); static void backpatch(struct block *, struct block *); static void merge(struct block *, struct block *); static struct block *gen_cmp(u_int, u_int, bpf_int32); +static struct block *gen_cmp_gt(u_int, u_int, bpf_int32); static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32); static struct block *gen_bcmp(u_int, u_int, const u_char *); static struct block *gen_uncond(int); static inline struct block *gen_true(void); static inline struct block *gen_false(void); static struct block *gen_linktype(int); +static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int); static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int); #ifdef INET6 static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int); @@ -486,6 +488,24 @@ gen_cmp(offset, size, v) return b; } +static struct block * +gen_cmp_gt(offset, size, v) + u_int offset, size; + bpf_int32 v; +{ + struct slist *s; + struct block *b; + + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = offset; + + b = new_block(JMP(BPF_JGT)); + b->stmts = s; + b->s.k = v; + + return b; +} + static struct block * gen_mcmp(offset, size, v, mask) u_int offset, size; @@ -703,6 +723,57 @@ gen_linktype(proto) switch (linktype) { + case DLT_EN10MB: + /* + * XXX - handle other LLC-encapsulated protocols here + * (IPX, OSI)? + */ + switch (proto) { + + 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 an Ethernet type field less than + * 1500, which means it's an 802.3 length field. + */ + b0 = gen_cmp_gt(off_linktype, BPF_H, 1500); + gen_not(b0); + + /* + * 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, 14); + else /* proto == ETHERTYPE_AARP */ + b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14); + 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; + } + break; + case DLT_SLIP: return gen_false(); @@ -762,6 +833,32 @@ gen_linktype(proto) return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); } +/* + * Check for an LLC SNAP packet with a given organization code and + * protocol type; we check the entire contents of the 802.2 LLC and + * snap headers, checking for a DSAP of 0xAA, an SSAP of 0xAA, and + * a control field of 0x03 in the LLC header, and for the specified + * organization code and protocol type in the SNAP header. + */ +static struct block * +gen_snap(orgcode, ptype, offset) + bpf_u_int32 orgcode; + bpf_u_int32 ptype; + u_int offset; +{ + u_char snapblock[8]; + + snapblock[0] = 0xAA; /* DSAP = SNAP */ + snapblock[1] = 0xAA; /* SSAP = SNAP */ + snapblock[2] = 0x03; /* control = UI */ + snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */ + snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */ + snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */ + snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ + snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ + return gen_bcmp(offset, 8, snapblock); +} + static struct block * gen_hostop(addr, mask, dir, proto, src_off, dst_off) bpf_u_int32 addr; @@ -1107,6 +1204,9 @@ gen_host(addr, mask, proto, dir) case Q_ATALK: bpf_error("ATALK host filtering not implemented"); + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + case Q_DECNET: return gen_dnhostop(addr, dir, off_nl); @@ -1185,6 +1285,9 @@ gen_host6(addr, mask, proto, dir) case Q_ATALK: bpf_error("ATALK host filtering not implemented"); + case Q_AARP: + bpf_error("AARP host filtering not implemented"); + case Q_DECNET: bpf_error("'decnet' modifier applied to ip6 host"); @@ -1340,6 +1443,10 @@ gen_proto_abbrev(proto) b1 = gen_linktype(ETHERTYPE_ATALK); break; + case Q_AARP: + b1 = gen_linktype(ETHERTYPE_AARP); + break; + case Q_DECNET: b1 = gen_linktype(ETHERTYPE_DN); break; diff --git a/gencode.h b/gencode.h index 96c2bde..d022d90 100644 --- a/gencode.h +++ b/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.43 2000-10-28 00:01:27 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.44 2000-10-28 08:19:29 guy Exp $ (LBL) */ /* Address qualifiers. */ @@ -58,6 +58,8 @@ #define Q_PIM 20 +#define Q_AARP 21 + /* Directional qualifiers. */ #define Q_SRC 1 diff --git a/grammar.y b/grammar.y index 9932f42..f441ad3 100644 --- a/grammar.y +++ b/grammar.y @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.61 2000-10-22 04:15:56 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.62 2000-10-28 08:19:30 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -107,7 +107,7 @@ pcap_parse() %token DST SRC HOST GATEWAY %token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE %token ARP RARP IP TCP UDP ICMP IGMP IGRP PIM -%token ATALK DECNET LAT SCA MOPRC MOPDL +%token ATALK AARP DECNET LAT SCA MOPRC MOPDL %token TK_BROADCAST TK_MULTICAST %token NUM INBOUND OUTBOUND %token LINK @@ -248,6 +248,7 @@ pname: LINK { $$ = Q_LINK; } | IGRP { $$ = Q_IGRP; } | PIM { $$ = Q_PIM; } | ATALK { $$ = Q_ATALK; } + | AARP { $$ = Q_AARP; } | DECNET { $$ = Q_DECNET; } | LAT { $$ = Q_LAT; } | SCA { $$ = Q_SCA; } diff --git a/scanner.l b/scanner.l index 03ea14e..98841c5 100644 --- a/scanner.l +++ b/scanner.l @@ -22,7 +22,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.67 2000-10-22 04:15:56 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.68 2000-10-28 08:19:30 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -183,6 +183,7 @@ ah return AH; esp return ESP; atalk return ATALK; +aarp return AARP; decnet return DECNET; lat return LAT; sca return SCA;