Module Name: src Committed By: rmind Date: Fri Jun 15 23:24:08 UTC 2012
Modified Files: src/sys/net/npf: npf_ncode.h src/usr.sbin/npf/npfctl: npf.conf.5 npf_build.c npf_data.c npf_disassemble.c npf_ncgen.c npf_parse.y npf_scan.l npfctl.c npfctl.h Log Message: - Rework NPF NAT syntax to be more structured and support future additions of different types and configurations of NAT. - npfctl: improve disassemble and show-config command functionality. - Fix custom ICMP code and type filtering. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/net/npf/npf_ncode.h cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/npf/npfctl/npf.conf.5 \ src/usr.sbin/npf/npfctl/npfctl.c cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/npf/npfctl/npf_build.c cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npf_data.c cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/npf/npfctl/npf_disassemble.c cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/npf/npfctl/npf_ncgen.c cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/npf/npfctl/npf_parse.y cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/npf/npfctl/npf_scan.l cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/npf/npfctl/npfctl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/npf/npf_ncode.h diff -u src/sys/net/npf/npf_ncode.h:1.7 src/sys/net/npf/npf_ncode.h:1.8 --- src/sys/net/npf/npf_ncode.h:1.7 Sat Apr 14 19:01:21 2012 +++ src/sys/net/npf/npf_ncode.h Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ncode.h,v 1.7 2012/04/14 19:01:21 rmind Exp $ */ +/* $NetBSD: npf_ncode.h,v 1.8 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2009-2010 The NetBSD Foundation, Inc. @@ -143,9 +143,9 @@ int npf_ncode_validate(const void *, siz # define NPF_OPERAND_PORT_RANGE 14 static const struct npf_instruction { - const char *name; - uint8_t op[4]; -} npf_instructions[256] = { + const char * name; + uint8_t op[4]; +} npf_instructions[] = { [NPF_OPCODE_RET] = { .name = "ret", .op = { @@ -247,7 +247,8 @@ static const struct npf_instruction { [1] = NPF_OPERAND_REGISTER, }, }, - [NPF_OPCODE_DIV] = { .name = "div", + [NPF_OPCODE_DIV] = { + .name = "div", .op = { [0] = NPF_OPERAND_VALUE, [1] = NPF_OPERAND_REGISTER, Index: src/usr.sbin/npf/npfctl/npf.conf.5 diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.11 src/usr.sbin/npf/npfctl/npf.conf.5:1.12 --- src/usr.sbin/npf/npfctl/npf.conf.5:1.11 Wed May 30 22:00:44 2012 +++ src/usr.sbin/npf/npfctl/npf.conf.5 Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: npf.conf.5,v 1.11 2012/05/30 22:00:44 wiz Exp $ +.\" $NetBSD: npf.conf.5,v 1.12 2012/06/15 23:24:08 rmind Exp $ .\" .\" Copyright (c) 2009-2012 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 27, 2012 +.Dd June 14, 2012 .Dt NPF.CONF 5 .Os .Sh NAME @@ -132,7 +132,7 @@ There are two types of storage: "tree" ( .\" ----- .Sh GRAMMAR .Bd -literal -line = ( def | table | nat | group | rproc ) +line = ( def | table | map | group | rproc ) def = ( \*[Lt]name\*[Gt] "=" "{ a, b, ... }" | "\*[Lt]text\*[Gt]" | "$\*[Lt]interface\*[Gt]" ) iface = ( \*[Lt]interface\*[Gt] | def ) @@ -140,9 +140,9 @@ iface = ( \*[Lt]interface\*[Gt] | def ) table = "table" \*[Lt]tid\*[Gt] "type" ( "hash" | "tree" ) ( "dynamic" | "file" \*[Lt]path\*[Gt] ) -nat = "nat" iface filt-opts "->" \*[Lt]addr\*[Gt] -binat = "binat" iface filt-opts "->" \*[Lt]addr\*[Gt] -rdr = "rdr" iface filt-opts "->" \*[Lt]addr\*[Gt] port-opts +map-di = ( "->" | "<-" | "<->" ) +map-type = ( "static" | "dynamic" ) +map = "map" iface maptype \*[Lt]seg1\*[Gt] mapdi \*[Lt]seg2\*[Gt] [ "pass" filt-opts ] rproc = "procedure" \*[Lt]name\*[Gt] procs procs = "{" op1 \*[Lt]newline\*[Gt], op2 \*[Lt]newline\*[Gt], ... "}" @@ -179,13 +179,15 @@ default configuration file $ext_if = "wm0" $int_if = "wm1" -$services_tcp = { http, https, smtp, domain, 6000 } -$services_udp = { domain, ntp, 6000 } - table <1> type hash file "/etc/npf_blacklist" table <2> type tree dynamic -nat $ext_if from 192.168.0.0/24 to any -> $ext_if +$services_tcp = { http, https, smtp, domain, 6000, 9022 } +$services_udp = { domain, ntp, 6000 } +$localnet = { 10.1.1.0/24 } + +map $ext_if dynamic 10.1.1.0/24 -> $ext_if +map $ext_if dynamic 10.1.1.2 port 22 <- $ext_if 9022 procedure "log" { log: npflog0 @@ -196,9 +198,9 @@ procedure "rid" { } group (name "external", interface $ext_if) { - block in final from \*[Lt]1\*[Gt] pass stateful out final from $ext_if apply "rid" + block in final from \*[Lt]1\*[Gt] pass in final family inet proto tcp to $ext_if port ssh apply "log" pass in final proto tcp to $ext_if port $services_tcp pass in final proto udp to $ext_if port $services_udp Index: src/usr.sbin/npf/npfctl/npfctl.c diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.11 src/usr.sbin/npf/npfctl/npfctl.c:1.12 --- src/usr.sbin/npf/npfctl/npfctl.c:1.11 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npfctl.c Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.c,v 1.11 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npfctl.c,v 1.12 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npfctl.c,v 1.11 2012/05/30 21:30:07 rmind Exp $"); +__RCSID("$NetBSD: npfctl.c,v 1.12 2012/06/15 23:24:08 rmind Exp $"); #include <sys/ioctl.h> #include <sys/stat.h> @@ -338,14 +338,14 @@ main(int argc, char **argv) cmd = argv[1]; if (strcmp(cmd, "debug") == 0) { - const char *cfg = argc > 2 ? argv[2] : "npf.conf"; + const char *cfg = argc > 2 ? argv[2] : "/tmp/npf.conf"; npfctl_config_init(true); npfctl_parsecfg(cfg); npfctl_config_send(0); return EXIT_SUCCESS; } - /* Find and call the subroutine */ + /* Find and call the subroutine. */ for (int n = 0; operations[n].cmd != NULL; n++) { if (strcmp(cmd, operations[n].cmd) != 0) continue; Index: src/usr.sbin/npf/npfctl/npf_build.c diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.6 src/usr.sbin/npf/npfctl/npf_build.c:1.7 --- src/usr.sbin/npf/npfctl/npf_build.c:1.6 Sun Feb 26 21:50:05 2012 +++ src/usr.sbin/npf/npfctl/npf_build.c Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $ */ +/* $NetBSD: npf_build.c,v 1.7 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $"); +__RCSID("$NetBSD: npf_build.c,v 1.7 2012/06/15 23:24:08 rmind Exp $"); #include <sys/types.h> #include <sys/ioctl.h> @@ -90,10 +90,11 @@ npfctl_table_exists_p(const char *id) return npf_table_exists_p(npf_conf, atoi(id)); } -static in_port_t * +static in_port_t npfctl_get_singleport(const npfvar_t *vp) { port_range_t *pr; + in_port_t *port; if (npfvar_get_count(vp) > 1) { yyerror("multiple ports are not valid"); @@ -102,7 +103,8 @@ npfctl_get_singleport(const npfvar_t *vp if (pr->pr_start != pr->pr_end) { yyerror("port range is not valid"); } - return &pr->pr_start; + port = &pr->pr_start; + return *port; } static fam_addr_mask_t * @@ -247,13 +249,15 @@ static bool npfctl_build_ncode(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op, const filt_opts_t *fopts, bool invert) { + const addr_port_t *apfrom = &fopts->fo_from; + const addr_port_t *apto = &fopts->fo_to; nc_ctx_t *nc; void *code; size_t len; if (family == AF_UNSPEC && op->op_proto == -1 && - op->op_opts == NULL && !fopts->fo_from && !fopts->fo_to && - !fopts->fo_from_port_range && !fopts->fo_to_port_range) + op->op_opts == NULL && !apfrom->ap_netaddr && !apto->ap_netaddr && + !apfrom->ap_portrange && !apto->ap_portrange) return false; int srcflag = NC_MATCH_SRC; @@ -267,19 +271,19 @@ npfctl_build_ncode(nl_rule_t *rl, sa_fam nc = npfctl_ncgen_create(); /* Build IP address blocks. */ - npfctl_build_vars(nc, family, fopts->fo_from, srcflag); - npfctl_build_vars(nc, family, fopts->fo_to, dstflag); + npfctl_build_vars(nc, family, apfrom->ap_netaddr, srcflag); + npfctl_build_vars(nc, family, apto->ap_netaddr, dstflag); /* Build layer 4 protocol blocks. */ int pflag = npfctl_build_proto(nc, op); /* Build port-range blocks. */ - if (fopts->fo_from_port_range) { - npfctl_build_vars(nc, family, fopts->fo_from_port_range, + if (apfrom->ap_portrange) { + npfctl_build_vars(nc, family, apfrom->ap_portrange, srcflag | pflag); } - if (fopts->fo_to_port_range) { - npfctl_build_vars(nc, family, fopts->fo_to_port_range, + if (apto->ap_portrange) { + npfctl_build_vars(nc, family, apto->ap_portrange, dstflag | pflag); } @@ -289,7 +293,7 @@ npfctl_build_ncode(nl_rule_t *rl, sa_fam code = npfctl_ncgen_complete(nc, &len); if (npf_debug) { extern int yylineno; - printf("RULE AT LINE %d\n", yylineno - 1); + printf("RULE AT LINE %d\n", yylineno); npfctl_ncgen_print(code, len); } if (npf_rule_setcode(rl, NPF_CODE_NCODE, code, len) == -1) { @@ -430,64 +434,100 @@ npfctl_build_rule(int attr, u_int if_idx * given filter options. */ void -npfctl_build_nat(int type, u_int if_idx, const filt_opts_t *fopts, - npfvar_t *var1, npfvar_t *var2) +npfctl_build_nat(int sd, int type, u_int if_idx, const addr_port_t *ap1, + const addr_port_t *ap2, const filt_opts_t *fopts) { - opt_proto_t op = { .op_proto = -1, .op_opts = NULL }; + const opt_proto_t op = { .op_proto = -1, .op_opts = NULL }; + fam_addr_mask_t *am1, *am2; + filt_opts_t imfopts; + sa_family_t family; nl_nat_t *nat; - fam_addr_mask_t *ai; - assert(type != 0 && if_idx != 0); - assert(fopts != NULL && var1 != NULL); + if (sd == NPFCTL_NAT_STATIC) { + yyerror("static NAT is not yet supported"); + } + assert(sd == NPFCTL_NAT_DYNAMIC); + assert(if_idx != 0); + + family = AF_INET; + + if (type & NPF_NATIN) { + if (!ap1->ap_netaddr) { + yyerror("inbound network segment is not specified"); + } + am1 = npfctl_get_singlefam(ap1->ap_netaddr); + if (am1->fam_family != AF_INET) { + yyerror("IPv6 NAT is not supported"); + } + assert(am1 != NULL); + } - ai = npfctl_get_singlefam(var1); - assert(ai != NULL); - if (ai->fam_family != AF_INET) { - yyerror("IPv6 NAT is not supported"); + if (type & NPF_NATOUT) { + if (!ap2->ap_netaddr) { + yyerror("outbound network segment is not specified"); + } + am2 = npfctl_get_singlefam(ap2->ap_netaddr); + if (am2->fam_family != family) { + yyerror("IPv6 NAT is not supported"); + } + assert(am2 != NULL); + } + + /* + * If filter criteria is not specified explicitly, apply implicit + * filtering according to the given network segements. + */ + if (!fopts) { + memset(&imfopts, 0, sizeof(filt_opts_t)); + if (type & NPF_NATOUT) { + memcpy(&imfopts.fo_from, ap1, sizeof(addr_port_t)); + } + if (type & NPF_NATIN) { + memcpy(&imfopts.fo_to, ap2, sizeof(addr_port_t)); + } + fopts = &imfopts; } switch (type) { - case NPFCTL_RDR: { + case NPF_NATIN: { /* * Redirection: an inbound NAT with a specific port. */ - in_port_t *port = npfctl_get_singleport(var2); + if (!ap1->ap_portrange) { + yyerror("inbound port is not specified"); + } + in_port_t port = npfctl_get_singleport(ap1->ap_portrange); nat = npf_nat_create(NPF_NATIN, NPF_NAT_PORTS, - if_idx, &ai->fam_addr, ai->fam_family, *port); + if_idx, &am1->fam_addr, am1->fam_family, port); break; } - case NPFCTL_BINAT: { + case (NPF_NATIN | NPF_NATOUT): { /* * Bi-directional NAT: a combination of inbound NAT and * outbound NAT policies. Note that the translation address * is local IP and filter criteria is inverted accordingly. */ - fam_addr_mask_t *tai = npfctl_get_singlefam(var2); - assert(tai != NULL); - if (ai->fam_family != AF_INET) { - yyerror("IPv6 NAT is not supported"); - } nat = npf_nat_create(NPF_NATIN, 0, if_idx, - &tai->fam_addr, tai->fam_family, 0); - npfctl_build_ncode(nat, AF_INET, &op, fopts, true); + &am1->fam_addr, am1->fam_family, 0); + npfctl_build_ncode(nat, family, &op, fopts, true); npf_nat_insert(npf_conf, nat, NPF_PRI_NEXT); /* FALLTHROUGH */ } - case NPFCTL_NAT: { + case NPF_NATOUT: { /* * Traditional NAPT: an outbound NAT policy with port. - * If this is another hald for bi-directional NAT, then + * If this is another half for bi-directional NAT, then * no port translation with mapping. */ - nat = npf_nat_create(NPF_NATOUT, type == NPFCTL_NAT ? + nat = npf_nat_create(NPF_NATOUT, type == NPF_NATOUT ? (NPF_NAT_PORTS | NPF_NAT_PORTMAP) : 0, - if_idx, &ai->fam_addr, ai->fam_family, 0); + if_idx, &am2->fam_addr, am2->fam_family, 0); break; } default: assert(false); } - npfctl_build_ncode(nat, AF_INET, &op, fopts, false); + npfctl_build_ncode(nat, family, &op, fopts, false); npf_nat_insert(npf_conf, nat, NPF_PRI_NEXT); } Index: src/usr.sbin/npf/npfctl/npf_data.c diff -u src/usr.sbin/npf/npfctl/npf_data.c:1.12 src/usr.sbin/npf/npfctl/npf_data.c:1.13 --- src/usr.sbin/npf/npfctl/npf_data.c:1.12 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npf_data.c Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_data.c,v 1.12 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npf_data.c,v 1.13 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_data.c,v 1.12 2012/05/30 21:30:07 rmind Exp $"); +__RCSID("$NetBSD: npf_data.c,v 1.13 2012/06/15 23:24:08 rmind Exp $"); #include <sys/types.h> #include <sys/null.h> @@ -474,7 +474,7 @@ npfctl_icmpcode(uint8_t type, const char } npfvar_t * -npfctl_parse_icmp(uint8_t type, uint8_t code) +npfctl_parse_icmp(int type, int code) { npfvar_t *vp = npfvar_create(".icmp"); Index: src/usr.sbin/npf/npfctl/npf_disassemble.c diff -u src/usr.sbin/npf/npfctl/npf_disassemble.c:1.4 src/usr.sbin/npf/npfctl/npf_disassemble.c:1.5 --- src/usr.sbin/npf/npfctl/npf_disassemble.c:1.4 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npf_disassemble.c Fri Jun 15 23:24:08 2012 @@ -37,6 +37,7 @@ __RCSID("$NetBSD$"); #include <string.h> #include <unistd.h> #include <errno.h> +#include <assert.h> #include <err.h> #include <sys/socket.h> #include <netinet/in.h> @@ -60,55 +61,63 @@ enum { }; struct nc_inf { - npfvar_t * nci_vlist[NPF_SHOW_COUNT]; - bool nci_srcdst; + FILE * ni_fp; + const uint32_t * ni_buf; + size_t ni_left; + const uint32_t * ni_ipc; + const uint32_t * ni_pc; + + /* Jump target array, its size and current index. */ + const uint32_t ** ni_targs; + size_t ni_targsize; + size_t ni_targidx; + + /* Other meta-data. */ + npfvar_t * ni_vlist[NPF_SHOW_COUNT]; + int ni_proto; + bool ni_srcdst; }; -#define ADVANCE(n, rv) \ - do { \ - if (len < sizeof(*pc) * (n)) { \ - warnx("ran out of bytes"); \ - return rv; \ - } \ - pc += (n); \ - len -= sizeof(*pc) * (n); \ - } while (/*CONSTCOND*/0) - static size_t -npfctl_ncode_get_target(const uint32_t *pc, const uint32_t **t, size_t l) +npfctl_ncode_get_target(const nc_inf_t *ni, const uint32_t *pc) { - for (size_t i = 0; i < l; i++) - if (t[i] == pc) + for (size_t i = 0; i < ni->ni_targidx; i++) { + if (ni->ni_targs[i] == pc) return i; - return ~0; + } + return (size_t)-1; } static size_t -npfctl_ncode_add_target(const uint32_t *pc, const uint32_t ***t, size_t *l, - size_t *m) +npfctl_ncode_add_target(nc_inf_t *ni, const uint32_t *pc) { - size_t q = npfctl_ncode_get_target(pc, *t, *l); + size_t i = npfctl_ncode_get_target(ni, pc); - if (q != (size_t)~0) - return q; - - if (*l <= *m) { - *m += 10; - *t = xrealloc(*t, *m * sizeof(**t)); - } - q = *l; - (*t)[(*l)++] = pc; - return q; + /* If found, just return the index. */ + if (i != (size_t)-1) { + return i; + } + + /* Grow array, if needed, and add a new target. */ + if (ni->ni_targidx == ni->ni_targsize) { + ni->ni_targsize += 16; + ni->ni_targs = xrealloc(ni->ni_targs, + ni->ni_targsize * sizeof(uint32_t)); + } + assert(ni->ni_targidx < ni->ni_targsize); + i = ni->ni_targidx++; + ni->ni_targs[i] = pc; + return i; } static void -npfctl_ncode_add_vp(char *buf, nc_inf_t *nci, unsigned idx) +npfctl_ncode_add_vp(nc_inf_t *ni, char *buf, unsigned idx) { - npfvar_t *vl = nci->nci_vlist[idx]; + npfvar_t *vl = ni->ni_vlist[idx]; if (vl == NULL) { vl = npfvar_create(".list"); - nci->nci_vlist[idx] = vl; + ni->ni_vlist[idx] = vl; } npfvar_t *vp = npfvar_create(".string"); npfvar_add_element(vp, NPFVAR_STRING, buf, strlen(buf) + 1); @@ -116,56 +125,52 @@ npfctl_ncode_add_vp(char *buf, nc_inf_t } static const char * -npfctl_ncode_operand(char *buf, size_t bufsiz, uint8_t op, const uint32_t *st, - const uint32_t *ipc, const uint32_t **pcv, size_t *lenv, - const uint32_t ***t, size_t *l, size_t *m, nc_inf_t *nci) +npfctl_ncode_operand(nc_inf_t *ni, char *buf, size_t bufsiz, uint8_t operand) { - const uint32_t *pc = *pcv; - size_t len = *lenv; + const uint32_t op = *ni->ni_pc; struct sockaddr_storage ss; + unsigned advance; + + /* Advance by one is a default for most cases. */ + advance = 1; - switch (op) { + switch (operand) { case NPF_OPERAND_NONE: abort(); case NPF_OPERAND_REGISTER: - if (*pc & ~0x3) { + if (op & ~0x3) { warnx("invalid register operand 0x%x at offset %td", - *pc, pc - st); + op, ni->ni_pc - ni->ni_buf); return NULL; } - snprintf(buf, bufsiz, "R%d", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "R%d", op); break; case NPF_OPERAND_KEY: - snprintf(buf, bufsiz, "key=<0x%x>", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "key=<0x%x>", op); break; case NPF_OPERAND_VALUE: - snprintf(buf, bufsiz, "value=<0x%x>", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "value=<0x%x>", op); break; case NPF_OPERAND_SD: - if (*pc & ~0x1) { + if (op & ~0x1) { warnx("invalid src/dst operand 0x%x at offset %td", - *pc, pc - st); + op, ni->ni_pc - ni->ni_buf); return NULL; } - bool srcdst = (*pc == NPF_OPERAND_SD_SRC); - if (nci) { - nci->nci_srcdst = srcdst; + bool srcdst = (op == NPF_OPERAND_SD_SRC); + if (ni) { + ni->ni_srcdst = srcdst; } snprintf(buf, bufsiz, "%s", srcdst ? "SRC" : "DST"); - ADVANCE(1, NULL); break; case NPF_OPERAND_REL_ADDRESS: - snprintf(buf, bufsiz, "+%zu", - npfctl_ncode_add_target(ipc + *pc, t, l, m)); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "L%zu", + npfctl_ncode_add_target(ni, ni->ni_ipc + op)); break; case NPF_OPERAND_NET_ADDRESS4: { @@ -173,13 +178,13 @@ npfctl_ncode_operand(char *buf, size_t b sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; sin->sin_port = 0; - memcpy(&sin->sin_addr, pc, sizeof(sin->sin_addr)); + memcpy(&sin->sin_addr, ni->ni_pc, sizeof(sin->sin_addr)); sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)sin); - if (nci) { - npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ? + if (ni) { + npfctl_ncode_add_vp(ni, buf, ni->ni_srcdst ? NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR); } - ADVANCE(sizeof(sin->sin_addr) / sizeof(*pc), NULL); + advance = sizeof(sin->sin_addr) / sizeof(op); break; } case NPF_OPERAND_NET_ADDRESS6: { @@ -187,139 +192,172 @@ npfctl_ncode_operand(char *buf, size_t b sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; sin6->sin6_port = 0; - memcpy(&sin6->sin6_addr, pc, sizeof(sin6->sin6_addr)); + memcpy(&sin6->sin6_addr, ni->ni_pc, sizeof(sin6->sin6_addr)); sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)sin6); - if (nci) { - npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ? + if (ni) { + npfctl_ncode_add_vp(ni, buf, ni->ni_srcdst ? NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR); } - ADVANCE(sizeof(sin6->sin6_addr) / sizeof(*pc), NULL); + advance = sizeof(sin6->sin6_addr) / sizeof(op); break; } case NPF_OPERAND_ETHER_TYPE: - snprintf(buf, bufsiz, "ether=0x%x", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "ether=0x%x", op); break; case NPF_OPERAND_SUBNET: { - snprintf(buf, bufsiz, "/%d", *pc); - if (nci) { - npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ? + snprintf(buf, bufsiz, "/%d", op); + if (ni) { + npfctl_ncode_add_vp(ni, buf, ni->ni_srcdst ? NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR); } - ADVANCE(1, NULL); break; } case NPF_OPERAND_LENGTH: - snprintf(buf, bufsiz, "length=%d", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "length=%d", op); break; case NPF_OPERAND_TABLE_ID: - if (nci) { - snprintf(buf, bufsiz, "<%d>", *pc); - npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ? + if (ni) { + snprintf(buf, bufsiz, "<%d>", op); + npfctl_ncode_add_vp(ni, buf, ni->ni_srcdst ? NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR); } - snprintf(buf, bufsiz, "id=%d", *pc); - ADVANCE(1, NULL); + snprintf(buf, bufsiz, "id=%d", op); break; - case NPF_OPERAND_ICMP4_TYPE_CODE: - if (*pc & ~0xffff) { + case NPF_OPERAND_ICMP4_TYPE_CODE: { + uint8_t type = (op & 31) ? op >> 8 : 0; + uint8_t code = (op & 30) ? op & 0xff : 0; + + if (op & ~0xc000ffff) { warnx("invalid icmp/type operand 0x%x at offset %td", - *pc, pc - st); + op, ni->ni_pc - ni->ni_buf); return NULL; } - snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8, *pc & 0xff); - if (nci) { - npfctl_ncode_add_vp(buf, nci, NPF_SHOW_ICMP); + snprintf(buf, bufsiz, "type=%d, code=%d", type, code); + if (ni) { + ni->ni_proto |= NC_MATCH_ICMP; + if (type || code) { + snprintf(buf, bufsiz, + "icmp-type %d code %d", type, code); + npfctl_ncode_add_vp(ni, buf, NPF_SHOW_ICMP); + } } - ADVANCE(1, NULL); break; - - case NPF_OPERAND_TCP_FLAGS_MASK: - if (*pc & ~0xffff) { + } + case NPF_OPERAND_TCP_FLAGS_MASK: { + uint8_t tf = op >> 8, tf_mask = op & 0xff; + if (op & ~0xffff) { warnx("invalid flags/mask operand 0x%x at offset %td", - *pc, pc - st); + op, ni->ni_pc - ni->ni_buf); return NULL; } - snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8, *pc & 0xff); - if (nci) { - npfctl_ncode_add_vp(buf, nci, NPF_SHOW_TCPF); + snprintf(buf, bufsiz, "flags=0x%x, mask=%0xx", tf, tf_mask); + if (ni) { + ni->ni_proto |= NC_MATCH_TCP; + npfctl_ncode_add_vp(ni, buf, NPF_SHOW_TCPF); } - ADVANCE(1, NULL); break; - + } case NPF_OPERAND_PORT_RANGE: { - in_port_t p1 = ntohs(*pc >> 16), p2 = ntohs(*pc & 0xffff); + in_port_t p1 = ntohs(op >> 16), p2 = ntohs(op & 0xffff); if (p1 == p2) { snprintf(buf, bufsiz, "%d", p1); } else { snprintf(buf, bufsiz, "%d-%d", p1, p2); } - if (nci) { - npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ? + if (ni) { + npfctl_ncode_add_vp(ni, buf, ni->ni_srcdst ? NPF_SHOW_SRCPORT : NPF_SHOW_DSTPORT); } - ADVANCE(1, NULL); break; } default: - warnx("invalid operand %d at offset %td", op, pc - st); + warnx("invalid operand %d at offset %td", + operand, ni->ni_pc - ni->ni_buf); return NULL; } - *pcv = pc; - *lenv = len; + if (ni->ni_left < sizeof(op) * advance) { + warnx("ran out of bytes"); + return NULL; + } + ni->ni_pc += advance; + ni->ni_left -= sizeof(op) * advance; return buf; } +nc_inf_t * +npfctl_ncode_disinf(FILE *fp) +{ + nc_inf_t *ni = zalloc(sizeof(nc_inf_t)); + + memset(ni, 0, sizeof(nc_inf_t)); + ni->ni_fp = fp; + return ni; +} + int -npfctl_ncode_disassemble(FILE *fp, const void *v, size_t len, nc_inf_t *nci) +npfctl_ncode_disassemble(nc_inf_t *ni, const void *v, size_t len) { - const uint32_t *ipc, *pc = v; - const uint32_t *st = v; - const struct npf_instruction *ni; - char buf[256]; - const uint32_t **targ; - size_t tlen, mlen, target; + FILE *fp = ni->ni_fp; int error = -1; - targ = NULL; - mlen = tlen = 0; - while (len) { - /* Get the opcode */ - if (*pc & ~0xff) { - warnx("invalid opcode 0x%x at offset (%td)", *pc, - pc - st); + ni->ni_buf = v; + ni->ni_left = len; + ni->ni_pc = v; + + while (ni->ni_left) { + const struct npf_instruction *insn; + const uint32_t opcode = *ni->ni_pc; + size_t target; + + /* Get the opcode. */ + if (opcode & ~0xff) { + warnx("invalid opcode 0x%x at offset (%td)", + opcode, ni->ni_pc - ni->ni_buf); goto out; } - ni = &npf_instructions[*pc]; - if (ni->name == NULL) { - warnx("invalid opcode 0x%x at offset (%td)", *pc, - pc - st); + insn = &npf_instructions[opcode]; + if (insn->name == NULL) { + warnx("invalid opcode 0x%x at offset (%td)", + opcode, ni->ni_pc - ni->ni_buf); goto out; } - ipc = pc; - target = npfctl_ncode_get_target(pc, targ, tlen); + /* + * Lookup target array and prefix with the label, + * if this opcode is a jump target. + */ + ni->ni_ipc = ni->ni_pc; + target = npfctl_ncode_get_target(ni, ni->ni_pc); if (fp) { - if (target != (size_t)~0) - fprintf(fp, "%zu:", target); - fprintf(fp, "\t%s", ni->name); + if (target != (size_t)-1) { + fprintf(fp, "L%zu:", target); + } + fprintf(fp, "\t%s", insn->name); + } + if (ni->ni_left < sizeof(opcode)) { + warnx("ran out of bytes"); + return -1; } - ADVANCE(1, -1); + ni->ni_left -= sizeof(opcode); + ni->ni_pc++; - for (size_t i = 0; i < __arraycount(ni->op); i++) { + for (size_t i = 0; i < __arraycount(insn->op); i++) { + const uint8_t o = insn->op[i]; const char *op; - if (ni->op[i] == NPF_OPERAND_NONE) + char buf[256]; + + if (o == NPF_OPERAND_NONE) { break; - op = npfctl_ncode_operand(buf, sizeof(buf), ni->op[i], - st, ipc, &pc, &len, &targ, &tlen, &mlen, nci); - if (op == NULL) + } + op = npfctl_ncode_operand(ni, buf, sizeof(buf), o); + if (op == NULL) { goto out; + } if (fp) { fprintf(fp, "%s%s", i == 0 ? " " : ", ", op); } @@ -330,7 +368,7 @@ npfctl_ncode_disassemble(FILE *fp, const } error = 0; out: - free(targ); + free(ni->ni_targs); return error; } @@ -342,7 +380,7 @@ npfctl_show_fromto(const char *name, npf if (count == 0) { if (showany) { - printf("%s all ", name); + printf("%s any ", name); } return; } @@ -355,21 +393,47 @@ npfctl_show_fromto(const char *name, npf npfvar_destroy(vl); } -static void +static bool npfctl_show_ncode(const void *nc, size_t len) { - nc_inf_t nci; + nc_inf_t *ni = npfctl_ncode_disinf(NULL); + npfvar_t *vl; + bool any; - memset(&nci, 0, sizeof(nc_inf_t)); - - if (npfctl_ncode_disassemble(NULL, nc, len, (void *)&nci) == 0) { - npfctl_show_fromto("from", nci.nci_vlist[NPF_SHOW_SRCADDR], true); - npfctl_show_fromto("port", nci.nci_vlist[NPF_SHOW_SRCPORT], false); - npfctl_show_fromto("to", nci.nci_vlist[NPF_SHOW_DSTADDR], true); - npfctl_show_fromto("port", nci.nci_vlist[NPF_SHOW_DSTPORT], false); - } else { + if (npfctl_ncode_disassemble(ni, nc, len) != 0) { printf("<< ncode >> "); + return true; + } + + switch (ni->ni_proto) { + case NC_MATCH_TCP: + printf("proto tcp "); + break; + case NC_MATCH_ICMP: + printf("proto icmp "); + if ((vl = ni->ni_vlist[NPF_SHOW_ICMP]) != NULL) { + printf("%s ", npfvar_expand_string(vl)); + npfvar_destroy(vl); + } + break; + default: + break; + } + + any = false; + if (ni->ni_vlist[NPF_SHOW_SRCADDR] || ni->ni_vlist[NPF_SHOW_SRCPORT]) { + npfctl_show_fromto("from", ni->ni_vlist[NPF_SHOW_SRCADDR], true); + npfctl_show_fromto("port", ni->ni_vlist[NPF_SHOW_SRCPORT], false); + any = true; + } + if (ni->ni_vlist[NPF_SHOW_DSTADDR] || ni->ni_vlist[NPF_SHOW_DSTPORT]) { + npfctl_show_fromto("to", ni->ni_vlist[NPF_SHOW_DSTADDR], true); + npfctl_show_fromto("port", ni->ni_vlist[NPF_SHOW_DSTPORT], false); + any = true; } + + free(ni); + return any; } #define NPF_RSTICMP (NPF_RULE_RETRST | NPF_RULE_RETICMP) @@ -414,7 +478,7 @@ npfctl_show_rule(nl_rule_t *nrl, unsigne const char *rname = rg.rg_name; if (ingroup) { - puts("}"); + printf("}\n\n"); } ingroup = true; if (rg.rg_attr & NPF_RULE_DEFAULT) { @@ -450,12 +514,9 @@ npfctl_show_rule(nl_rule_t *nrl, unsigne } nc = _npf_rule_ncode(nrl, &nclen); - if (nc) { - npfctl_show_ncode(nc, nclen); - } else { + if (!nc || npfctl_show_ncode(nc, nclen)) { printf("all "); } - /* apply <rproc> */ if ((rproc = _npf_rule_rproc(nrl)) != NULL) { printf("apply \"%s\"", rproc); Index: src/usr.sbin/npf/npfctl/npf_ncgen.c diff -u src/usr.sbin/npf/npfctl/npf_ncgen.c:1.9 src/usr.sbin/npf/npfctl/npf_ncgen.c:1.10 --- src/usr.sbin/npf/npfctl/npf_ncgen.c:1.9 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npf_ncgen.c Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ncgen.c,v 1.9 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npf_ncgen.c,v 1.10 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_ncgen.c,v 1.9 2012/05/30 21:30:07 rmind Exp $"); +__RCSID("$NetBSD: npf_ncgen.c,v 1.10 2012/06/15 23:24:08 rmind Exp $"); #include <stdlib.h> #include <stddef.h> @@ -333,8 +333,8 @@ npfctl_gennc_icmp(nc_ctx_t *ctx, int typ /* OP, code, type (2 words) */ *nc++ = NPF_OPCODE_ICMP4; - *nc++ = (type == -1 ? 0 : (1 << 31) & (type & 0xff << 8)) | - (code == -1 ? 0 : (1 << 31) & (code & 0xff)); + *nc++ = (type == -1 ? 0 : (1 << 31) | ((type & 0xff) << 8)) | + (code == -1 ? 0 : (1 << 30) | (code & 0xff)); /* Comparison block (2 words). */ npfctl_ncgen_addjmp(ctx, &nc); @@ -388,5 +388,16 @@ npfctl_gennc_tcpfl(nc_ctx_t *ctx, uint8_ void npfctl_ncgen_print(const void *code, size_t len) { - npfctl_ncode_disassemble(stdout, code, len, NULL); +#if 0 + const uint32_t *op = code; + + while (len) { + printf("\t> |0x%02x|\n", (u_int)*op++); + len -= sizeof(*op); + } +#else + nc_inf_t *ni = npfctl_ncode_disinf(stdout); + npfctl_ncode_disassemble(ni, code, len); + free(ni); +#endif } Index: src/usr.sbin/npf/npfctl/npf_parse.y diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.7 src/usr.sbin/npf/npfctl/npf_parse.y:1.8 --- src/usr.sbin/npf/npfctl/npf_parse.y:1.7 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npf_parse.y Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_parse.y,v 1.7 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npf_parse.y,v 1.8 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -73,8 +73,9 @@ yyerror(const char *fmt, ...) %token ALL %token ANY %token APPLY -%token ARROW -%token BINAT +%token ARROWBOTH +%token ARROWLEFT +%token ARROWRIGHT %token BLOCK %token CURLY_CLOSE %token CURLY_OPEN @@ -83,6 +84,7 @@ yyerror(const char *fmt, ...) %token COMMA %token DEFAULT %token TDYNAMIC +%token TSTATIC %token EQ %token TFILE %token FLAGS @@ -95,8 +97,8 @@ yyerror(const char *fmt, ...) %token INET %token INET6 %token INTERFACE +%token MAP %token MINUS -%token NAT %token NAME %token ON %token OUT @@ -108,7 +110,6 @@ yyerror(const char *fmt, ...) %token PROTO %token FAMILY %token FINAL -%token RDR %token RETURN %token RETURNICMP %token RETURNRST @@ -136,10 +137,11 @@ yyerror(const char *fmt, ...) %type <str> opt_apply %type <num> ifindex, port, opt_final, on_iface %type <num> block_or_pass, rule_dir, block_opts, family, opt_family -%type <num> opt_stateful, icmp_type, table_type +%type <num> opt_stateful, icmp_type, table_type, map_sd, map_type %type <var> addr_or_iface, port_range, icmp_type_and_code %type <var> filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask %type <var> modulearg_opts, procs, proc_op, modulearg, moduleargs +%type <addrport> mapseg %type <filtopts> filt_opts, all_or_filt_opts %type <optproto> opt_proto %type <rulegroup> group_attr, group_opt @@ -147,6 +149,7 @@ yyerror(const char *fmt, ...) %union { char * str; unsigned long num; + addr_port_t addrport; filt_opts_t filtopts; npfvar_t * var; opt_proto_t optproto; @@ -167,7 +170,7 @@ lines line : def | table - | nat + | map | group | rproc | @@ -252,30 +255,34 @@ table_store | TFILE STRING { $$ = $2; } ; -nat - : natdef - | binatdef - | rdrdef +map_sd + : TSTATIC { $$ = NPFCTL_NAT_STATIC; } + | TDYNAMIC { $$ = NPFCTL_NAT_DYNAMIC; } + | { $$ = NPFCTL_NAT_DYNAMIC; } ; -natdef - : NAT ifindex filt_opts ARROW addr_or_iface - { - npfctl_build_nat(NPFCTL_NAT, $2, &$3, $5, NULL); - } +map_type + : ARROWBOTH { $$ = NPF_NATIN | NPF_NATOUT; } + | ARROWLEFT { $$ = NPF_NATIN; } + | ARROWRIGHT { $$ = NPF_NATOUT; } ; -binatdef - : BINAT ifindex filt_opts ARROW addr_or_iface +mapseg + : addr_or_iface port_range { - npfctl_build_nat(NPFCTL_BINAT, $2, &$3, $5, $3.fo_from); + $$.ap_netaddr = $1; + $$.ap_portrange = $2; } ; -rdrdef - : RDR ifindex filt_opts ARROW addr_or_iface port_range +map + : MAP ifindex map_sd mapseg map_type mapseg PASS filt_opts { - npfctl_build_nat(NPFCTL_RDR, $2, &$3, $5, $6); + npfctl_build_nat($3, $5, $2, &$4, &$6, &$8); + } + | MAP ifindex map_sd mapseg map_type mapseg + { + npfctl_build_nat($3, $5, $2, &$4, &$6, NULL); } ; @@ -490,10 +497,10 @@ opt_family all_or_filt_opts : ALL { - $$.fo_from = NULL; - $$.fo_from_port_range = NULL; - $$.fo_to = NULL; - $$.fo_to_port_range = NULL; + $$.fo_from.ap_netaddr = NULL; + $$.fo_from.ap_portrange = NULL; + $$.fo_to.ap_netaddr = NULL; + $$.fo_to.ap_portrange = NULL; } | filt_opts { $$ = $1; } ; @@ -518,24 +525,24 @@ block_opts filt_opts : FROM filt_addr port_range TO filt_addr port_range { - $$.fo_from = $2; - $$.fo_from_port_range = $3; - $$.fo_to = $5; - $$.fo_to_port_range = $6; + $$.fo_from.ap_netaddr = $2; + $$.fo_from.ap_portrange = $3; + $$.fo_to.ap_netaddr = $5; + $$.fo_to.ap_portrange = $6; } | FROM filt_addr port_range { - $$.fo_from = $2; - $$.fo_from_port_range = $3; - $$.fo_to = NULL; - $$.fo_to_port_range = NULL; + $$.fo_from.ap_netaddr = $2; + $$.fo_from.ap_portrange = $3; + $$.fo_to.ap_netaddr = NULL; + $$.fo_to.ap_portrange = NULL; } | TO filt_addr port_range { - $$.fo_from = NULL; - $$.fo_from_port_range = NULL; - $$.fo_to = $2; - $$.fo_to_port_range = $3; + $$.fo_from.ap_netaddr = NULL; + $$.fo_from.ap_portrange = NULL; + $$.fo_to.ap_netaddr = $2; + $$.fo_to.ap_portrange = $3; } ; @@ -606,11 +613,12 @@ port_range { $$ = npfctl_parse_port_range($2, $2); } - | PORT port MINUS port /* port from:to */ + | PORT port MINUS port /* port from-to */ { $$ = npfctl_parse_port_range($2, $4); } - | PORT VAR_ID { + | PORT VAR_ID + { $$ = npfctl_parse_port_range_variable($2); } | Index: src/usr.sbin/npf/npfctl/npf_scan.l diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.2 src/usr.sbin/npf/npfctl/npf_scan.l:1.3 --- src/usr.sbin/npf/npfctl/npf_scan.l:1.2 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npf_scan.l Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_scan.l,v 1.2 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npf_scan.l,v 1.3 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -53,14 +53,16 @@ table return TABLE; type return TYPE; hash return HASH; tree return TREE; +static return TSTATIC; dynamic return TDYNAMIC; file return TFILE; -nat return NAT; -binat return BINAT; -"->" return ARROW; +map return MAP; +"<->" return ARROWBOTH; +"<-" return ARROWLEFT; +"->" return ARROWRIGHT; "-" return MINUS; -rdr return RDR; procedure return PROCEDURE; +\\\n yylineno++; yycolumn = 0; \n yylineno++; yycolumn = 0; return SEPLINE; ; return SEPLINE; name return NAME; Index: src/usr.sbin/npf/npfctl/npfctl.h diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.14 src/usr.sbin/npf/npfctl/npfctl.h:1.15 --- src/usr.sbin/npf/npfctl/npfctl.h:1.14 Wed May 30 21:30:07 2012 +++ src/usr.sbin/npf/npfctl/npfctl.h Fri Jun 15 23:24:08 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.h,v 1.14 2012/05/30 21:30:07 rmind Exp $ */ +/* $NetBSD: npfctl.h,v 1.15 2012/06/15 23:24:08 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -57,11 +57,14 @@ typedef struct port_range { in_port_t pr_end; } port_range_t; +typedef struct addr_port { + npfvar_t * ap_netaddr; + npfvar_t * ap_portrange; +} addr_port_t; + typedef struct filt_opts { - npfvar_t * fo_from; - npfvar_t * fo_from_port_range; - npfvar_t * fo_to; - npfvar_t * fo_to_port_range; + addr_port_t fo_from; + addr_port_t fo_to; } filt_opts_t; typedef struct opt_proto { @@ -100,7 +103,7 @@ unsigned long npfctl_find_ifindex(cons npfvar_t * npfctl_parse_tcpflag(const char *); npfvar_t * npfctl_parse_table_id(const char *); npfvar_t * npfctl_parse_icmpcode(const char *); -npfvar_t * npfctl_parse_icmp(uint8_t, uint8_t); +npfvar_t * npfctl_parse_icmp(int, int); npfvar_t * npfctl_parse_iface(const char *); npfvar_t * npfctl_parse_port_range(in_port_t, in_port_t); npfvar_t * npfctl_parse_port_range_variable(const char *); @@ -119,6 +122,7 @@ typedef struct nc_ctx nc_ctx_t; #define NC_MATCH_TCP 0x04 #define NC_MATCH_UDP 0x08 +#define NC_MATCH_ICMP 0x10 nc_ctx_t * npfctl_ncgen_create(void); void * npfctl_ncgen_complete(nc_ctx_t *, size_t *); @@ -137,12 +141,20 @@ void npfctl_gennc_tbl(nc_ctx_t *, int, void npfctl_gennc_tcpfl(nc_ctx_t *, uint8_t, uint8_t); /* + * N-code disassembler. + */ + +typedef struct nc_inf nc_inf_t; + +nc_inf_t * npfctl_ncode_disinf(FILE *); +int npfctl_ncode_disassemble(nc_inf_t *, const void *, size_t); + +/* * Configuration building interface. */ -#define NPFCTL_RDR 1 -#define NPFCTL_BINAT 2 -#define NPFCTL_NAT 3 +#define NPFCTL_NAT_DYNAMIC 1 +#define NPFCTL_NAT_STATIC 2 void npfctl_config_init(bool); int npfctl_config_send(int); @@ -152,16 +164,8 @@ void npfctl_build_rproc(const char *, n void npfctl_build_group(const char *, int, u_int); void npfctl_build_rule(int, u_int, sa_family_t, const opt_proto_t *, const filt_opts_t *, const char *); -void npfctl_build_nat(int, u_int, const filt_opts_t *, - npfvar_t *, npfvar_t *); +void npfctl_build_nat(int, int, u_int, const addr_port_t *, + const addr_port_t *, const filt_opts_t *); void npfctl_build_table(const char *, u_int, const char *); -/* - * N-code disassembler. - */ -typedef struct nc_inf nc_inf_t; - -int npfctl_ncode_disassemble(FILE *, const void *, size_t, - nc_inf_t *); - #endif