diff options
Diffstat (limited to 'contrib/libpcap/gencode.c')
-rw-r--r-- | contrib/libpcap/gencode.c | 451 |
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; |