diff options
Diffstat (limited to 'gencode.c')
-rw-r--r-- | gencode.c | 99 |
1 files changed, 93 insertions, 6 deletions
@@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.141 2001-01-14 04:34:51 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.142 2001-01-14 05:30:07 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -662,7 +662,7 @@ init_linktype(type) return; case DLT_LINUX_SLL: /* fake header for Linux cooked socket */ - off_linktype = 2; + off_linktype = 14; off_nl = 16; return; } @@ -714,10 +714,6 @@ gen_linktype(proto) switch (linktype) { case DLT_EN10MB: - /* - * XXX - handle other LLC-encapsulated protocols here - * (IPX, OSI)? - */ switch (proto) { case LLC_ISO_LSAP: @@ -872,6 +868,97 @@ gen_linktype(proto) } break; + case DLT_LINUX_SLL: + switch (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); + b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32) + ((LLC_ISO_LSAP << 8) | LLC_ISO_LSAP)); + gen_and(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); + } + } + break; + case DLT_SLIP: case DLT_SLIP_BSDOS: case DLT_RAW: |