npfctl_build_code: generate TCP/UDP check for ports case when other blocks
do not imply L4 check; add an assert in npfctl_bpf_proto() and elsewhere.
This commit is contained in:
parent
7429e1daf1
commit
410bae3ffd
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_bpf_comp.c,v 1.5 2014/05/15 02:34:29 rmind Exp $ */
|
||||
/* $NetBSD: npf_bpf_comp.c,v 1.6 2014/05/31 22:41:37 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_bpf_comp.c,v 1.5 2014/05/15 02:34:29 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_bpf_comp.c,v 1.6 2014/05/31 22:41:37 rmind Exp $");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -62,7 +62,8 @@ __RCSID("$NetBSD: npf_bpf_comp.c,v 1.5 2014/05/15 02:34:29 rmind Exp $");
|
|||
* something other than L4 header offset. Generally, when BPF_LDX is used.
|
||||
*/
|
||||
#define FETCHED_L3 0x01
|
||||
#define X_EQ_L4OFF 0x02
|
||||
#define CHECKED_L4 0x02
|
||||
#define X_EQ_L4OFF 0x04
|
||||
|
||||
struct npf_bpf {
|
||||
/*
|
||||
|
@ -283,8 +284,8 @@ fetch_l3(npf_bpf_t *ctx, sa_family_t af, u_int flags)
|
|||
}
|
||||
|
||||
/*
|
||||
* Fetch L3 information. The coprocessor populates the following
|
||||
* words in the scratch memory store:
|
||||
* Call NPF_COP_L3 to fetch L3 information. The coprocessor
|
||||
* populates the following words in the scratch memory store:
|
||||
* - BPF_MW_IPVER: IP version (4 or 6).
|
||||
* - BPF_MW_L4OFF: L4 header offset.
|
||||
* - BPF_MW_L4PROTO: L4 protocol.
|
||||
|
@ -369,6 +370,7 @@ npfctl_bpf_proto(npf_bpf_t *ctx, sa_family_t af, int proto)
|
|||
|
||||
uint32_t mwords[] = { BM_PROTO, 1, proto };
|
||||
done_block(ctx, mwords, sizeof(mwords));
|
||||
ctx->flags |= CHECKED_L4;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -471,6 +473,7 @@ npfctl_bpf_ports(npf_bpf_t *ctx, u_int opts, in_port_t from, in_port_t to)
|
|||
/* TCP and UDP port offsets are the same. */
|
||||
assert(sport_off == offsetof(struct tcphdr, th_sport));
|
||||
assert(dport_off == offsetof(struct tcphdr, th_dport));
|
||||
assert(ctx->flags & CHECKED_L4);
|
||||
|
||||
assert(((opts & MATCH_SRC) != 0) ^ ((opts & MATCH_DST) != 0));
|
||||
off = (opts & MATCH_SRC) ? sport_off : dport_off;
|
||||
|
@ -516,11 +519,12 @@ void
|
|||
npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask, bool checktcp)
|
||||
{
|
||||
const u_int tcpfl_off = offsetof(struct tcphdr, th_flags);
|
||||
const bool usingmask = tf_mask != tf;
|
||||
|
||||
/* X <- IP header length */
|
||||
fetch_l3(ctx, AF_UNSPEC, X_EQ_L4OFF);
|
||||
if (checktcp) {
|
||||
const u_int jf = (tf_mask != tf) ? 3 : 2;
|
||||
const u_int jf = usingmask ? 3 : 2;
|
||||
assert(ctx->ingroup == false);
|
||||
|
||||
/* A <- L4 protocol; A == TCP? If not, jump out. */
|
||||
|
@ -529,6 +533,8 @@ npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask, bool checktcp)
|
|||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, jf),
|
||||
};
|
||||
add_insns(ctx, insns_tcp, __arraycount(insns_tcp));
|
||||
} else {
|
||||
assert(ctx->flags & CHECKED_L4);
|
||||
}
|
||||
|
||||
struct bpf_insn insns_tf[] = {
|
||||
|
@ -537,7 +543,7 @@ npfctl_bpf_tcpfl(npf_bpf_t *ctx, uint8_t tf, uint8_t tf_mask, bool checktcp)
|
|||
};
|
||||
add_insns(ctx, insns_tf, __arraycount(insns_tf));
|
||||
|
||||
if (tf_mask != tf) {
|
||||
if (usingmask) {
|
||||
/* A <- (A & mask) */
|
||||
struct bpf_insn insns_mask[] = {
|
||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, tf_mask),
|
||||
|
@ -567,6 +573,7 @@ npfctl_bpf_icmp(npf_bpf_t *ctx, int type, int code)
|
|||
const u_int type_off = offsetof(struct icmp, icmp_type);
|
||||
const u_int code_off = offsetof(struct icmp, icmp_code);
|
||||
|
||||
assert(ctx->flags & CHECKED_L4);
|
||||
assert(offsetof(struct icmp6_hdr, icmp6_type) == type_off);
|
||||
assert(offsetof(struct icmp6_hdr, icmp6_code) == code_off);
|
||||
assert(type != -1 || code != -1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_build.c,v 1.37 2014/05/15 02:34:29 rmind Exp $ */
|
||||
/* $NetBSD: npf_build.c,v 1.38 2014/05/31 22:41:37 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_build.c,v 1.37 2014/05/15 02:34:29 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_build.c,v 1.38 2014/05/31 22:41:37 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
@ -293,10 +293,10 @@ static bool
|
|||
npfctl_build_code(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
|
||||
const filt_opts_t *fopts)
|
||||
{
|
||||
bool noproto, noaddrs, noports, need_tcpudp = false;
|
||||
const addr_port_t *apfrom = &fopts->fo_from;
|
||||
const addr_port_t *apto = &fopts->fo_to;
|
||||
const int proto = op->op_proto;
|
||||
bool noproto, noaddrs, noports;
|
||||
npf_bpf_t *bc;
|
||||
size_t len;
|
||||
|
||||
|
@ -317,7 +317,9 @@ npfctl_build_code(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
|
|||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
case IPPROTO_UDP:
|
||||
break;
|
||||
case -1:
|
||||
need_tcpudp = true;
|
||||
break;
|
||||
default:
|
||||
yyerror("invalid filter options for protocol %d", proto);
|
||||
|
@ -344,6 +346,13 @@ npfctl_build_code(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
|
|||
npfctl_build_vars(bc, family, apto->ap_netaddr, MATCH_DST);
|
||||
|
||||
/* Build port-range blocks. */
|
||||
if (need_tcpudp) {
|
||||
/* TCP/UDP check for the ports. */
|
||||
npfctl_bpf_group(bc);
|
||||
npfctl_bpf_proto(bc, AF_UNSPEC, IPPROTO_TCP);
|
||||
npfctl_bpf_proto(bc, AF_UNSPEC, IPPROTO_UDP);
|
||||
npfctl_bpf_endgroup(bc);
|
||||
}
|
||||
npfctl_build_vars(bc, family, apfrom->ap_portrange, MATCH_SRC);
|
||||
npfctl_build_vars(bc, family, apto->ap_portrange, MATCH_DST);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_show.c,v 1.14 2014/05/31 22:41:37 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_show.c,v 1.13 2014/03/14 11:29:45 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_show.c,v 1.14 2014/05/31 22:41:37 rmind Exp $");
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -248,7 +248,7 @@ static const struct mark_keyword_mapent {
|
|||
u_int fwords;
|
||||
} mark_keyword_map[] = {
|
||||
{ BM_IPVER, "family %s", NULL, print_family, 1 },
|
||||
{ BM_PROTO, "proto %s", NULL, print_proto, 1 },
|
||||
{ BM_PROTO, "proto %s", ", ", print_proto, 1 },
|
||||
{ BM_TCPFL, "flags %s", NULL, print_tcpflags, 2 },
|
||||
{ BM_ICMP_TYPE, "icmp-type %s", NULL, print_number, 1 },
|
||||
{ BM_ICMP_CODE, "code %s", NULL, print_number, 1 },
|
||||
|
|
Loading…
Reference in New Issue