]> The Tcpdump Group git mirrors - libpcap/blobdiff - gencode.c
The value pointed to by "gen_pf_ifname()"'s argument isn't modified, so
[libpcap] / gencode.c
index e8840ef58e289dc66a98ea7b0af60ce89d88522c..f8765fb5dcb96ccb32582ff6c49010c3b7e81880 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -21,7 +21,7 @@
  */
 #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
@@ -70,6 +70,7 @@ static const char rcsid[] =
 #include "ppp.h"
 #include "sll.h"
 #include "arcnet.h"
+#include "pf.h"
 #ifdef INET6
 #ifndef WIN32
 #include <netdb.h>     /* for "struct addrinfo" */
@@ -225,6 +226,8 @@ newchunk(n)
                        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)
@@ -736,6 +739,18 @@ init_linktype(type)
                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 */
@@ -864,10 +879,6 @@ init_linktype(type)
                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
@@ -993,6 +1004,9 @@ gen_ether_linktype(proto)
        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);
@@ -1012,6 +1026,9 @@ gen_ether_linktype(proto)
        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);
@@ -1243,6 +1260,9 @@ gen_linktype(proto)
                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)
@@ -1516,9 +1536,14 @@ gen_linktype(proto)
 
        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
@@ -1534,6 +1559,8 @@ gen_linktype(proto)
                 * 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) {
 
@@ -1556,7 +1583,7 @@ gen_linktype(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
@@ -1737,10 +1764,10 @@ gen_llc(proto)
         */
        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));
@@ -2734,7 +2761,7 @@ gen_proto_abbrev(proto)
        int proto;
 {
        struct block *b0;
-        struct block *b1;
+       struct block *b1;
 
        switch (proto) {
 
@@ -2920,7 +2947,7 @@ gen_proto_abbrev(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: 
@@ -3070,20 +3097,24 @@ gen_port(port, ip_proto, dir)
 {
        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:
@@ -3547,20 +3578,22 @@ gen_proto(v, proto, dir)
                /*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
@@ -3594,13 +3627,17 @@ gen_proto(v, proto, dir)
                        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);
@@ -3608,12 +3645,15 @@ gen_proto(v, proto, dir)
                        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");
@@ -4627,6 +4667,8 @@ gen_broadcast(proto)
                        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
@@ -4656,7 +4698,7 @@ gen_broadcast(proto)
                gen_and(b0, b2);
                return b2;
        }
-       bpf_error("only ether/ip broadcast filters supported");
+       bpf_error("only link-layer/IP broadcast filters supported");
 }
 
 /*
@@ -4834,6 +4876,11 @@ gen_multicast(proto)
                        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
@@ -4867,7 +4914,7 @@ gen_multicast(proto)
                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");
 }
 
 /*
@@ -4886,7 +4933,6 @@ gen_inbound(dir)
         */
        switch (linktype) {
        case DLT_SLIP:
-       case DLT_PPP:
                b0 = gen_relation(BPF_JEQ,
                          gen_load(Q_LINK, gen_loadi(0), 1),
                          gen_loadi(0),
@@ -4914,8 +4960,13 @@ gen_inbound(dir)
                }
                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 */
@@ -4923,6 +4974,58 @@ gen_inbound(dir)
        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;