*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.184 2003-01-23 07:24:51 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.191 2003-05-02 08:37:43 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "ppp.h"
#include "sll.h"
#include "arcnet.h"
+#include "pf.h"
#ifdef INET6
#ifndef WIN32
#include <netdb.h> /* for "struct addrinfo" */
bpf_error("out of memory");
size = CHUNK0SIZE << k;
cp->m = (void *)malloc(size);
+ if (cp->m == NULL)
+ bpf_error("out of memory");
memset((char *)cp->m, 0, size);
cp->n_left = size;
if (n > size)
off_nl_nosnap = 4; /* no 802.2 LLC */
return;
+ case DLT_ENC:
+ off_linktype = 0;
+ off_nl = 12;
+ off_nl_nosnap = 12; /* no 802.2 LLC */
+ return;
+
+ case DLT_PFLOG:
+ off_linktype = 0;
+ off_nl = 28;
+ off_nl_nosnap = 28; /* no 802.2 LLC */
+ return;
+
case DLT_PPP:
case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
return;
case DLT_ATM_RFC1483:
- off_linktype = 0;
- off_nl = 4; /* FIXME SNAP */
- return;
-
case DLT_ATM_CLIP: /* Linux ATM defines this */
/*
* assume routed, non-ISO PDUs
case LLCSAP_ISONS:
/*
* OSI protocols always use 802.2 encapsulation.
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP?
*/
b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
gen_not(b0);
case LLCSAP_NETBEUI:
/*
* NetBEUI always uses 802.2 encapsulation.
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP?
*/
b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
gen_not(b0);
case LLCSAP_ISONS:
/*
* 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(off_linktype, BPF_H, LINUX_SLL_P_802_2);
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
case DLT_NULL:
case DLT_LOOP:
+ case DLT_ENC:
+ case DLT_PFLOG:
/*
* For DLT_NULL, the link-layer header is a 32-bit
- * word containing an AF_ value in *host* byte order.
+ * word containing an AF_ value in *host* byte order,
+ * and for DLT_ENC, the link-layer header begins
+ * with a 32-bit work containing an AF_ value in
+ * host byte order.
*
* In addition, if we're reading a saved capture file,
* the host byte order in the capture may not be the
* This means that, when reading a capture file, just
* checking for our AF_INET6 value won't work if the
* capture file came from another OS.
+ *
+ * XXX - what's the byte order for DLT_PFLOG?
*/
switch (proto) {
return gen_false();
}
- if (linktype == DLT_NULL) {
+ if (linktype == DLT_NULL || linktype == DLT_ENC) {
/*
* The AF_ value is in host byte order, but
* the BPF interpreter will convert it to
*/
switch (proto) {
- case LLCSAP_IP:
+ case LLCSAP_IP:
return gen_cmp(off_linktype, BPF_H, (long)
((LLCSAP_IP << 8) | LLCSAP_IP));
-
+
case LLCSAP_ISONS:
return gen_cmp(off_linktype, BPF_H, (long)
((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
int proto;
{
struct block *b0;
- struct block *b1;
+ struct block *b1;
switch (proto) {
b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
gen_or(b0, b1);
b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
- gen_or(b0, b1);
+ gen_or(b0, b1);
break;
case Q_ISIS_LSP:
{
struct block *b0, *b1, *tmp;
- switch (linktype) {
- case DLT_IEEE802_11:
- case DLT_PRISM_HEADER:
- case DLT_IEEE802_11_RADIO:
- case DLT_FDDI:
- case DLT_IEEE802:
- case DLT_ATM_RFC1483:
- case DLT_ATM_CLIP:
- b0 = gen_linktype(LLCSAP_IP);
- break;
- default:
- b0 = gen_linktype(ETHERTYPE_IP);
- break;
- }
+ /*
+ * ether proto ip
+ *
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
switch (ip_proto) {
case IPPROTO_UDP:
/*FALLTHROUGH*/
#endif
case Q_IP:
- switch (linktype) {
- case DLT_IEEE802_11:
- case DLT_PRISM_HEADER:
- case DLT_IEEE802_11_RADIO:
- case DLT_FDDI:
- case DLT_IEEE802:
- case DLT_ATM_RFC1483:
- case DLT_ATM_CLIP:
- b0 = gen_linktype(LLCSAP_IP);
- break;
- default:
- b0 = gen_linktype(ETHERTYPE_IP);
- break;
- }
+ /*
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
#ifndef CHASE_CHAIN
b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
#else
return gen_cmp(2, BPF_H, (0x03<<8) | v);
break;
- case DLT_C_HDLC:
- /* Cisco uses an Ethertype lookalike - for OSI its 0xfefe */
- b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
- /* OSI in C-HDLC is stuffed with a fudge byte */
+ case DLT_C_HDLC:
+ /*
+ * Cisco uses an Ethertype lookalike - for OSI,
+ * it's 0xfefe.
+ */
+ b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
+ /* OSI in C-HDLC is stuffed with a fudge byte */
b1 = gen_cmp(off_nl_nosnap+1, BPF_B, (long)v);
gen_and(b0, b1);
- return b1;
+ return b1;
+
default:
b0 = gen_linktype(LLCSAP_ISONS);
b1 = gen_cmp(off_nl_nosnap, BPF_B, (long)v);
return b1;
}
- case Q_ISIS:
- b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
- /* 4 is the offset of the PDU type relative to the IS-IS header */
- b1 = gen_cmp(off_nl_nosnap+4, BPF_B, (long)v);
- gen_and(b0, b1);
- return b1;
+ case Q_ISIS:
+ b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ /*
+ * 4 is the offset of the PDU type relative to the IS-IS
+ * header.
+ */
+ b1 = gen_cmp(off_nl_nosnap+4, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
case Q_ARP:
bpf_error("arp does not encapsulate another protocol");
return gen_thostop(ebroadcast, Q_DST);
if (linktype == DLT_IEEE802_11)
return gen_wlanhostop(ebroadcast, Q_DST);
+ if (linktype == DLT_IP_OVER_FC)
+ return gen_ipfchostop(ebroadcast, Q_DST);
if (linktype == DLT_SUNATM && is_lane) {
/*
* Check that the packet doesn't begin with an
gen_and(b0, b2);
return b2;
}
- bpf_error("only ether/ip broadcast filters supported");
+ bpf_error("only link-layer/IP broadcast filters supported");
}
/*
return b0;
}
+ if (linktype == DLT_IP_OVER_FC) {
+ b0 = gen_mac_multicast(2);
+ return b0;
+ }
+
if (linktype == DLT_SUNATM && is_lane) {
/*
* Check that the packet doesn't begin with an
return b1;
#endif /* INET6 */
}
- bpf_error("only IP multicast filters supported on ethernet/FDDI");
+ bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
}
/*
*/
switch (linktype) {
case DLT_SLIP:
- case DLT_PPP:
b0 = gen_relation(BPF_JEQ,
gen_load(Q_LINK, gen_loadi(0), 1),
gen_loadi(0),
}
break;
+ case DLT_PFLOG:
+ b0 = gen_cmp(26, BPF_H,
+ (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
+ break;
+
default:
- bpf_error("inbound/outbound not supported on linktype %d\n",
+ bpf_error("inbound/outbound not supported on linktype %d",
linktype);
b0 = NULL;
/* NOTREACHED */
return (b0);
}
+/* PF firewall log matched interface */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ifname supported only for DLT_PFLOG");
+ /* NOTREACHED */
+ }
+ if (strlen(ifname) >= 16) {
+ bpf_error("ifname interface names can't be larger than 16 characters");
+ /* NOTREACHED */
+ }
+ return (gen_bcmp(4, strlen(ifname), (const u_char *)ifname));
+}
+
+
+/* PF firewall log rule number */
+struct block *
+gen_pf_rnr(int rnr)
+{
+ if (linktype != DLT_PFLOG) {
+ bpf_error("rnr supported only for DLT_PFLOG");
+ /* NOTREACHED */
+ }
+
+ return (gen_cmp(20, BPF_H, (bpf_int32)rnr));
+}
+
+/* PF firewall log reason code */
+struct block *
+gen_pf_reason(int reason)
+{
+ if (linktype != DLT_PFLOG) {
+ bpf_error("reason supported only for DLT_PFLOG");
+ /* NOTREACHED */
+ }
+
+ return (gen_cmp(22, BPF_H, (bpf_int32)reason));
+}
+
+/* PF firewall log action */
+struct block *
+gen_pf_action(int action)
+{
+ if (linktype != DLT_PFLOG) {
+ bpf_error("action supported only for DLT_PFLOG");
+ /* NOTREACHED */
+ }
+
+ return (gen_cmp(24, BPF_H, (bpf_int32)action));
+}
+
struct block *
gen_acode(eaddr, q)
register const u_char *eaddr;