summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/gencode.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/gencode.c')
-rw-r--r--contrib/libpcap/gencode.c451
1 files changed, 348 insertions, 103 deletions
diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c
index 12879f2..1ed1e7b 100644
--- a/contrib/libpcap/gencode.c
+++ b/contrib/libpcap/gencode.c
@@ -21,10 +21,6 @@
*
* $FreeBSD$
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.309 2008-12-23 20:13:29 guy Exp $ (LBL)";
-#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -86,7 +82,7 @@ static const char rcsid[] _U_ =
#include "pcap/sll.h"
#include "pcap/ipnet.h"
#include "arcnet.h"
-#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
#include <linux/types.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
@@ -143,9 +139,7 @@ static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
#endif
/* XXX */
-#ifdef PCAP_FDDIPAD
static int pcap_fddipad;
-#endif
/* VARARGS */
void
@@ -402,38 +396,30 @@ syntax()
static bpf_u_int32 netmask;
static int snaplen;
int no_optimize;
-#ifdef WIN32
-static int
-pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
- const char *buf, int optimize, bpf_u_int32 mask);
int
pcap_compile(pcap_t *p, struct bpf_program *program,
const char *buf, int optimize, bpf_u_int32 mask)
{
- int result;
-
- EnterCriticalSection(&g_PcapCompileCriticalSection);
-
- result = pcap_compile_unsafe(p, program, buf, optimize, mask);
-
- LeaveCriticalSection(&g_PcapCompileCriticalSection);
-
- return result;
-}
-
-static int
-pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
- const char *buf, int optimize, bpf_u_int32 mask)
-#else /* WIN32 */
-int
-pcap_compile(pcap_t *p, struct bpf_program *program,
- const char *buf, int optimize, bpf_u_int32 mask)
-#endif /* WIN32 */
-{
extern int n_errors;
const char * volatile xbuf = buf;
u_int len;
+ int rc;
+
+ /*
+ * XXX - single-thread this code path with pthread calls on
+ * UN*X, if the platform supports pthreads? If that requires
+ * a separate -lpthread, we might not want to do that.
+ */
+#ifdef WIN32
+ extern int wsockinit (void);
+ static int done = 0;
+
+ if (!done)
+ wsockinit();
+ done = 1;
+ EnterCriticalSection(&g_PcapCompileCriticalSection);
+#endif
/*
* If this pcap_t hasn't been activated, it doesn't have a
@@ -442,13 +428,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
if (!p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"not-yet-activated pcap_t passed to pcap_compile");
- return (-1);
+ rc = -1;
+ goto quit;
}
no_optimize = 0;
n_errors = 0;
root = NULL;
bpf_pcap = p;
init_regs();
+
if (setjmp(top_ctx)) {
#ifdef INET6
if (ai != NULL) {
@@ -458,7 +446,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
#endif
lex_cleanup();
freechunks();
- return (-1);
+ rc = -1;
+ goto quit;
}
netmask = mask;
@@ -467,7 +456,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
if (snaplen == 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snaplen of 0 rejects all packets");
- return -1;
+ rc = -1;
+ goto quit;
}
lex_init(xbuf ? xbuf : "");
@@ -491,7 +481,16 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
lex_cleanup();
freechunks();
- return (0);
+
+ rc = 0; /* We're all okay */
+
+quit:
+
+#ifdef WIN32
+ LeaveCriticalSection(&g_PcapCompileCriticalSection);
+#endif
+
+ return (rc);
}
/*
@@ -596,7 +595,7 @@ finish_parse(p)
* worth the effort.
*/
insert_compute_vloffsets(p->head);
-
+
/*
* For DLT_PPI captures, generate a check of the per-packet
* DLT value to make sure it's DLT_IEEE802_11.
@@ -878,6 +877,7 @@ static u_int off_proto;
* These are offsets for the MTP2 fields.
*/
static u_int off_li;
+static u_int off_li_hsl;
/*
* These are offsets for the MTP3 fields.
@@ -927,9 +927,7 @@ init_linktype(p)
pcap_t *p;
{
linktype = pcap_datalink(p);
-#ifdef PCAP_FDDIPAD
pcap_fddipad = p->fddipad;
-#endif
/*
* Assume it's not raw ATM with a pseudo-header, for now.
@@ -951,6 +949,7 @@ init_linktype(p)
* And assume we're not doing SS7.
*/
off_li = -1;
+ off_li_hsl = -1;
off_sio = -1;
off_opc = -1;
off_dpc = -1;
@@ -1066,13 +1065,9 @@ init_linktype(p)
* XXX - should we generate code to check for SNAP?
*/
off_linktype = 13;
-#ifdef PCAP_FDDIPAD
off_linktype += pcap_fddipad;
-#endif
off_macpl = 13; /* FDDI MAC header length */
-#ifdef PCAP_FDDIPAD
off_macpl += pcap_fddipad;
-#endif
off_nl = 8; /* 802.2+SNAP */
off_nl_nosnap = 3; /* 802.2 */
return;
@@ -1136,7 +1131,7 @@ init_linktype(p)
return;
case DLT_PPI:
- /*
+ /*
* At the moment we treat PPI the same way that we treat
* normal Radiotap encoded packets. The difference is in
* the function that generates the code at the beginning
@@ -1343,6 +1338,13 @@ init_linktype(p)
off_nl_nosnap = -1; /* no 802.2 LLC */
return;
+ case DLT_BACNET_MS_TP:
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
case DLT_JUNIPER_SERVICES:
off_linktype = 12;
off_macpl = -1; /* L3 proto location dep. on cookie type */
@@ -1383,6 +1385,7 @@ init_linktype(p)
case DLT_MTP2:
off_li = 2;
+ off_li_hsl = 4;
off_sio = 3;
off_opc = 4;
off_dpc = 4;
@@ -1395,6 +1398,7 @@ init_linktype(p)
case DLT_MTP2_WITH_PHDR:
off_li = 6;
+ off_li_hsl = 8;
off_sio = 7;
off_opc = 8;
off_dpc = 8;
@@ -1407,6 +1411,7 @@ init_linktype(p)
case DLT_ERF:
off_li = 22;
+ off_li_hsl = 24;
off_sio = 23;
off_opc = 24;
off_dpc = 24;
@@ -2301,7 +2306,7 @@ gen_load_radiotap_llprefixlen()
return (NULL);
}
-/*
+/*
* At the moment we treat PPI as normal Radiotap encoded
* packets. The difference is in the function that generates
* the code at the beginning to compute the header length.
@@ -2314,7 +2319,7 @@ static struct slist *
gen_load_ppi_llprefixlen()
{
struct slist *s1, *s2;
-
+
/*
* Generate code to load the length of the radiotap header
* into the register assigned to hold that length, if one has
@@ -2404,7 +2409,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
* slist of instructions
*/
no_optimize = 1;
-
+
/*
* If "s" is non-null, it has code to arrange that the X register
* contains the length of the prefix preceding the link-layer
@@ -2455,7 +2460,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
sjset_data_frame_1->s.k = 0x08;
sappend(s, sjset_data_frame_1);
-
+
/*
* If b3 is set, test b2, otherwise go to the first statement of
* the rest of the program.
@@ -2474,7 +2479,7 @@ gen_load_802_11_header_len(struct slist *s, struct slist *snext)
sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
sjset_qos->s.k = 0x80; /* QoS bit */
sappend(s, sjset_qos);
-
+
/*
* If it's set, add 2 to reg_off_macpl, to skip the QoS
* field.
@@ -2745,7 +2750,7 @@ gen_radiotap_llprefixlen(void)
return s;
}
-/*
+/*
* At the moment we treat PPI as normal Radiotap encoded
* packets. The difference is in the function that generates
* the code at the beginning to compute the header length.
@@ -2899,6 +2904,7 @@ gen_linktype(proto)
register int proto;
{
struct block *b0, *b1, *b2;
+ const char *description;
/* are we checking MPLS-encapsulated packets? */
if (label_stack_depth > 0) {
@@ -2906,12 +2912,12 @@ gen_linktype(proto)
case ETHERTYPE_IP:
case PPP_IP:
/* FIXME add other L3 proto IDs */
- return gen_mpls_linktype(Q_IP);
+ return gen_mpls_linktype(Q_IP);
case ETHERTYPE_IPV6:
case PPP_IPV6:
/* FIXME add other L3 proto IDs */
- return gen_mpls_linktype(Q_IPV6);
+ return gen_mpls_linktype(Q_IPV6);
default:
bpf_error("unsupported protocol over mpls");
@@ -2983,7 +2989,7 @@ gen_linktype(proto)
case DLT_FDDI:
/*
- * XXX - check for asynchronous frames, as per RFC 1103.
+ * XXX - check for LLC frames.
*/
return gen_llc_linktype(proto);
/*NOTREACHED*/
@@ -3195,8 +3201,7 @@ gen_linktype(proto)
* Then we run it through "htonl()", and
* generate code to compare against the result.
*/
- if (bpf_pcap->sf.rfile != NULL &&
- bpf_pcap->sf.swapped)
+ if (bpf_pcap->rfile != NULL && bpf_pcap->swapped)
proto = SWAPLONG(proto);
proto = htonl(proto);
}
@@ -3351,6 +3356,9 @@ gen_linktype(proto)
*/
return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
+ case DLT_BACNET_MS_TP:
+ return gen_mcmp(OR_LINK, 0, BPF_W, 0x55FF0000, 0xffff0000);
+
case DLT_IPNET:
return gen_ipnet_linktype(proto);
@@ -3406,26 +3414,43 @@ gen_linktype(proto)
case DLT_AX25_KISS:
bpf_error("AX.25 link-layer type filtering not implemented");
- }
- /*
- * 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 == (u_int)-1)
- abort();
+ case DLT_NFLOG:
+ /* Using the fixed-size NFLOG header it is possible to tell only
+ * the address family of the packet, other meaningful data is
+ * either missing or behind TLVs.
+ */
+ bpf_error("NFLOG link-layer type filtering not implemented");
- /*
- * Any type not handled above should always have an Ethernet
- * type at an offset of "off_linktype".
- */
- return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+ default:
+ /*
+ * Does this link-layer header type have a field
+ * indicating the type of the next protocol? If
+ * so, off_linktype will be the offset of that
+ * field in the packet; if not, it will be -1.
+ */
+ if (off_linktype != (u_int)-1) {
+ /*
+ * Yes; assume it's an Ethernet type. (If
+ * it's not, it needs to be handled specially
+ * above.)
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+ } else {
+ /*
+ * No; report an error.
+ */
+ description = pcap_datalink_val_to_description(linktype);
+ if (description != NULL) {
+ bpf_error("%s link-layer type filtering not implemented",
+ description);
+ } else {
+ bpf_error("DLT %u link-layer type filtering not implemented",
+ linktype);
+ }
+ }
+ break;
+ }
}
/*
@@ -3454,6 +3479,178 @@ gen_snap(orgcode, ptype)
}
/*
+ * Generate code to match frames with an LLC header.
+ */
+struct block *
+gen_llc(void)
+{
+ struct block *b0, *b1;
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ /*
+ * We check for an Ethernet type field less than
+ * 1500, which means it's an 802.3 length field.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * Now check for the purported DSAP and SSAP not being
+ * 0xFF, to rule out NetWare-over-802.3.
+ */
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
+ gen_not(b1);
+ gen_and(b0, b1);
+ return b1;
+
+ case DLT_SUNATM:
+ /*
+ * We check for LLC traffic.
+ */
+ b0 = gen_atmtype_abbrev(A_LLC);
+ return b0;
+
+ case DLT_IEEE802: /* Token Ring */
+ /*
+ * XXX - check for LLC frames.
+ */
+ return gen_true();
+
+ case DLT_FDDI:
+ /*
+ * XXX - check for LLC frames.
+ */
+ return gen_true();
+
+ case DLT_ATM_RFC1483:
+ /*
+ * For LLC encapsulation, these are defined to have an
+ * 802.2 LLC header.
+ *
+ * For VC encapsulation, they don't, but there's no
+ * way to check for that; the protocol used on the VC
+ * is negotiated out of band.
+ */
+ return gen_true();
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_PPI:
+ /*
+ * Check that we have a data frame.
+ */
+ b0 = gen_check_802_11_data_frame();
+ return b0;
+
+ default:
+ bpf_error("'llc' not supported for linktype %d", linktype);
+ /* NOTREACHED */
+ }
+}
+
+struct block *
+gen_llc_i(void)
+{
+ struct block *b0, *b1;
+ struct slist *s;
+
+ /*
+ * Check whether this is an LLC frame.
+ */
+ b0 = gen_llc();
+
+ /*
+ * Load the control byte and test the low-order bit; it must
+ * be clear for I frames.
+ */
+ s = gen_load_a(OR_MACPL, 2, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01;
+ b1->stmts = s;
+ gen_not(b1);
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_llc_s(void)
+{
+ struct block *b0, *b1;
+
+ /*
+ * Check whether this is an LLC frame.
+ */
+ b0 = gen_llc();
+
+ /*
+ * Now compare the low-order 2 bit of the control byte against
+ * the appropriate value for S frames.
+ */
+ b1 = gen_mcmp(OR_MACPL, 2, BPF_B, LLC_S_FMT, 0x03);
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_llc_u(void)
+{
+ struct block *b0, *b1;
+
+ /*
+ * Check whether this is an LLC frame.
+ */
+ b0 = gen_llc();
+
+ /*
+ * Now compare the low-order 2 bit of the control byte against
+ * the appropriate value for U frames.
+ */
+ b1 = gen_mcmp(OR_MACPL, 2, BPF_B, LLC_U_FMT, 0x03);
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_llc_s_subtype(bpf_u_int32 subtype)
+{
+ struct block *b0, *b1;
+
+ /*
+ * Check whether this is an LLC frame.
+ */
+ b0 = gen_llc();
+
+ /*
+ * Now check for an S frame with the appropriate type.
+ */
+ b1 = gen_mcmp(OR_MACPL, 2, BPF_B, subtype, LLC_S_CMD_MASK);
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_llc_u_subtype(bpf_u_int32 subtype)
+{
+ struct block *b0, *b1;
+
+ /*
+ * Check whether this is an LLC frame.
+ */
+ b0 = gen_llc();
+
+ /*
+ * Now check for a U frame with the appropriate type.
+ */
+ b1 = gen_mcmp(OR_MACPL, 2, BPF_B, subtype, LLC_U_CMD_MASK);
+ gen_and(b0, b1);
+ return b1;
+}
+
+/*
* Generate code to match a particular packet type, for link-layer types
* using 802.2 LLC headers.
*
@@ -3705,18 +3902,10 @@ gen_fhostop(eaddr, dir)
switch (dir) {
case Q_SRC:
-#ifdef PCAP_FDDIPAD
return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
-#else
- return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr);
-#endif
case Q_DST:
-#ifdef PCAP_FDDIPAD
return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
-#else
- return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr);
-#endif
case Q_AND:
b0 = gen_fhostop(eaddr, Q_SRC);
@@ -4411,7 +4600,7 @@ gen_mpls_linktype(proto)
b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0);
gen_and(b0, b1);
return b1;
-
+
case Q_IPV6:
/* match the bottom-of-stack bit */
b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
@@ -4419,7 +4608,7 @@ gen_mpls_linktype(proto)
b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
gen_and(b0, b1);
return b1;
-
+
default:
abort();
}
@@ -4577,6 +4766,9 @@ gen_host6(addr, mask, proto, dir, type)
case Q_DEFAULT:
return gen_host6(addr, mask, Q_IPV6, dir, type);
+ case Q_LINK:
+ bpf_error("link-layer modifier applied to ip6 %s", typestr);
+
case Q_IP:
bpf_error("'ip' modifier applied to ip6 %s", typestr);
@@ -5223,7 +5415,7 @@ gen_portrangeatom(off, v1, v2)
b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1);
b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2);
- gen_and(b1, b2);
+ gen_and(b1, b2);
return b2;
}
@@ -5325,7 +5517,7 @@ gen_portrangeatom6(off, v1, v2)
b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1);
b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2);
- gen_and(b1, b2);
+ gen_and(b1, b2);
return b2;
}
@@ -5775,7 +5967,7 @@ gen_check_802_11_data_frame()
b0 = new_block(JMP(BPF_JSET));
b0->s.k = 0x08;
b0->stmts = s;
-
+
s = gen_load_a(OR_LINK, 0, BPF_B);
b1 = new_block(JMP(BPF_JSET));
b1->s.k = 0x04;
@@ -6251,7 +6443,7 @@ gen_scode(name, q)
if (proto != Q_DEFAULT &&
proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
bpf_error("illegal qualifier of 'portrange'");
- if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
+ if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
bpf_error("unknown port in range '%s'", name);
if (proto == Q_UDP) {
if (real_proto == IPPROTO_TCP)
@@ -6278,7 +6470,7 @@ gen_scode(name, q)
bpf_error("port in range '%s' is tcp", name);
else
/* override PROTO_UNDEF */
- real_proto = IPPROTO_SCTP;
+ real_proto = IPPROTO_SCTP;
}
if (port1 < 0)
bpf_error("illegal port number %d < 0", port1);
@@ -7535,14 +7727,14 @@ gen_inbound(dir)
* check it, otherwise give up as this link-layer type
* has nothing in the packet data.
*/
-#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
/*
- * We infer that this is Linux with PF_PACKET support.
+ * This is Linux with PF_PACKET support.
* If this is a *live* capture, we can look at
* special meta-data in the filter expression;
* if it's a savefile, we can't.
*/
- if (bpf_pcap->sf.rfile != NULL) {
+ if (bpf_pcap->rfile != NULL) {
/* We have a FILE *, so this is a savefile */
bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
linktype);
@@ -7556,12 +7748,12 @@ gen_inbound(dir)
/* to filter on inbound traffic, invert the match */
gen_not(b0);
}
-#else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
bpf_error("inbound/outbound not supported on linktype %d",
linktype);
b0 = NULL;
/* NOTREACHED */
-#endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
}
return (b0);
}
@@ -7970,22 +8162,22 @@ gen_mpls(label_num)
* etc.
*/
switch (linktype) {
-
+
case DLT_C_HDLC: /* fall through */
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
b0 = gen_linktype(ETHERTYPE_MPLS);
break;
-
+
case DLT_PPP:
b0 = gen_linktype(PPP_MPLS_UCAST);
break;
-
+
/* FIXME add other DLT_s ...
* for Frame-Relay/and ATM this may get messy due to SNAP headers
* leave it for now */
-
+
default:
bpf_error("no MPLS support for data link type %d",
linktype);
@@ -8021,9 +8213,10 @@ gen_pppoed()
}
struct block *
-gen_pppoes()
+gen_pppoes(sess_num)
+ int sess_num;
{
- struct block *b0;
+ struct block *b0, *b1;
/*
* Test against the PPPoE session link-layer type.
@@ -8063,6 +8256,14 @@ gen_pppoes()
orig_nl = off_nl;
is_pppoes = 1;
+ /* If a specific session is requested, check PPPoE session id */
+ if (sess_num >= 0) {
+ b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W,
+ (bpf_int32)sess_num, 0x0000ffff);
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+
/*
* The "network-layer" protocol is PPPoE, which has a 6-byte
* PPPoE header, followed by a PPP packet.
@@ -8247,11 +8448,12 @@ gen_atmtype_abbrev(type)
return b1;
}
-/*
+/*
* Filtering for MTP2 messages based on li value
* FISU, length is null
* LSSU, length is 1 or 2
* MSU, length is 3 or more
+ * For MTP2_HSL, sequences are on 2 bytes, and length on 9 bits
*/
struct block *
gen_mtp2type_abbrev(type)
@@ -8288,6 +8490,33 @@ gen_mtp2type_abbrev(type)
b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
break;
+ case MH_FISU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'hfisu' supported only on MTP2_HSL");
+ /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
+ b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0);
+ break;
+
+ case MH_LSSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'hlssu' supported only on MTP2_HSL");
+ b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100);
+ b1 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0);
+ gen_and(b1, b0);
+ break;
+
+ case MH_MSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'hmsu' supported only on MTP2_HSL");
+ b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100);
+ break;
+
default:
abort();
}
@@ -8303,9 +8532,17 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
{
struct block *b0;
bpf_u_int32 val1 , val2 , val3;
+ u_int newoff_sio=off_sio;
+ u_int newoff_opc=off_opc;
+ u_int newoff_dpc=off_dpc;
+ u_int newoff_sls=off_sls;
switch (mtp3field) {
+ case MH_SIO:
+ newoff_sio += 3; /* offset for MTP2_HSL */
+ /* FALLTHROUGH */
+
case M_SIO:
if (off_sio == (u_int)-1)
bpf_error("'sio' supported only on SS7");
@@ -8313,10 +8550,12 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
if(jvalue > 255)
bpf_error("sio value %u too big; max value = 255",
jvalue);
- b0 = gen_ncmp(OR_PACKET, off_sio, BPF_B, 0xffffffff,
+ b0 = gen_ncmp(OR_PACKET, newoff_sio, BPF_B, 0xffffffff,
(u_int)jtype, reverse, (u_int)jvalue);
break;
+ case MH_OPC:
+ newoff_opc+=3;
case M_OPC:
if (off_opc == (u_int)-1)
bpf_error("'opc' supported only on SS7");
@@ -8333,10 +8572,14 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
val3 = jvalue & 0x00000003;
val3 = val3 <<22;
jvalue = val1 + val2 + val3;
- b0 = gen_ncmp(OR_PACKET, off_opc, BPF_W, 0x00c0ff0f,
+ b0 = gen_ncmp(OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f,
(u_int)jtype, reverse, (u_int)jvalue);
break;
+ case MH_DPC:
+ newoff_dpc += 3;
+ /* FALLTHROUGH */
+
case M_DPC:
if (off_dpc == (u_int)-1)
bpf_error("'dpc' supported only on SS7");
@@ -8351,10 +8594,12 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
val2 = jvalue & 0x00003f00;
val2 = val2 << 8;
jvalue = val1 + val2;
- b0 = gen_ncmp(OR_PACKET, off_dpc, BPF_W, 0xff3f0000,
+ b0 = gen_ncmp(OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000,
(u_int)jtype, reverse, (u_int)jvalue);
break;
+ case MH_SLS:
+ newoff_sls+=3;
case M_SLS:
if (off_sls == (u_int)-1)
bpf_error("'sls' supported only on SS7");
@@ -8365,7 +8610,7 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
/* the following instruction is made to convert jvalue
* to the forme used to write sls in an ss7 message*/
jvalue = jvalue << 4;
- b0 = gen_ncmp(OR_PACKET, off_sls, BPF_B, 0xf0,
+ b0 = gen_ncmp(OR_PACKET, newoff_sls, BPF_B, 0xf0,
(u_int)jtype,reverse, (u_int)jvalue);
break;
OpenPOWER on IntegriCloud