Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/npf/npfctl npfctl:
details: https://anonhg.NetBSD.org/src/rev/1c8d3a80da3e
branches: trunk
changeset: 350755:1c8d3a80da3e
user: rmind <rmind%NetBSD.org@localhost>
date: Thu Jan 19 20:18:17 2017 +0000
description:
npfctl:
- Add protocol filter option for "map".
- Print user-friendly error if table contains an entry with invalid netmask.
- Add support for inline ports.
diffstat:
usr.sbin/npf/npfctl/npf.conf.5 | 18 ++++---
usr.sbin/npf/npfctl/npf_build.c | 19 ++++---
usr.sbin/npf/npfctl/npf_data.c | 91 ++++++++++++++++++++++++++++------------
usr.sbin/npf/npfctl/npf_parse.y | 26 +++++++----
usr.sbin/npf/npfctl/npfctl.h | 8 +-
5 files changed, 106 insertions(+), 56 deletions(-)
diffs (truncated from 429 to 300 lines):
diff -r 33a583a60d0d -r 1c8d3a80da3e usr.sbin/npf/npfctl/npf.conf.5
--- a/usr.sbin/npf/npfctl/npf.conf.5 Thu Jan 19 19:09:06 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf.conf.5 Thu Jan 19 20:18:17 2017 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: npf.conf.5,v 1.46 2017/01/03 01:29:49 rmind Exp $
+.\" $NetBSD: npf.conf.5,v 1.47 2017/01/19 20:18:17 rmind Exp $
.\"
.\" Copyright (c) 2009-2017 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -228,11 +228,15 @@
.Bd -literal
procedure "someproc" {
log: npflog0
- normalize: "random-id", "min-ttl" 64
+ normalize: "random-id", "min-ttl" 64, "max-mss" 1432
}
.Ed
.Pp
In this case, the procedure calls the logging and normalisation modules.
+Traffic normalisation has a set of different mechanisms.
+In the example above, the normalisation procedure has arguments which
+apply the following mechanisms: IPv4 ID randomisation, Don't Fragment (DF)
+flag cleansing, minimum TTL enforcement and TCP MSS "clamping".
.Ss Misc
Text after a hash
.Pq Sq #
@@ -275,9 +279,9 @@
; Mapping for address translation.
map = "map" interface
- ( "static" [ "algo" algorithm ] | "dynamic" )
+ ( "static" [ "algo" algorithm ] | "dynamic" ) [ proto ]
net-seg ( "->" | "<-" | "<->" ) net-seg
- [ "pass" filt-opts ]
+ [ "pass" [ proto ] filt-opts ]
; Rule procedure definition. The name should be in the double quotes.
;
@@ -295,8 +299,7 @@
group-opts = name-string [ "in" | "out" ] [ "on" interface ]
rule-list = [ rule new-line ] rule-list
-npf-filter = [ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
- ( "all" | filt-opts )
+npf-filter = [ "family" family-opt ] [ proto ] ( "all" | filt-opts )
static-rule = ( "block" [ block-opts ] | "pass" )
[ "stateful" | "stateful-ends" ]
[ "in" | out" ] [ "final" ] [ "on" interface ]
@@ -306,6 +309,7 @@
dynamic-ruleset = "ruleset" group-opts
rule = static-rule | dynamic-ruleset
+proto = "proto" protocol [ proto-opts ]
block-opts = "return-rst" | "return-icmp" | "return"
family-opt = "inet4" | "inet6"
proto-opts = "flags" tcp-flags [ "/" tcp-flag-mask ] |
@@ -345,7 +349,7 @@
# Note: if $ext_if has multiple IP address (e.g. IPv6 as well),
# then the translation address has to be specified explicitly.
map $ext_if dynamic 10.1.1.0/24 -> $ext_if
-map $ext_if dynamic 10.1.1.2 port 22 <- $ext_if port 9022
+map $ext_if dynamic proto tcp 10.1.1.2 port 22 <- $ext_if port 9022
procedure "log" {
# Note: npf_ext_log kernel module should be loaded, if not built-in.
diff -r 33a583a60d0d -r 1c8d3a80da3e usr.sbin/npf/npfctl/npf_build.c
--- a/usr.sbin/npf/npfctl/npf_build.c Thu Jan 19 19:09:06 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c Thu Jan 19 20:18:17 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_build.c,v 1.43 2017/01/03 01:29:49 rmind Exp $ */
+/* $NetBSD: npf_build.c,v 1.44 2017/01/19 20:18:17 rmind Exp $ */
/*-
* Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.43 2017/01/03 01:29:49 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.44 2017/01/19 20:18:17 rmind Exp $");
#include <sys/types.h>
#include <sys/mman.h>
@@ -586,9 +586,9 @@
*/
static nl_nat_t *
npfctl_build_nat(int type, const char *ifname, const addr_port_t *ap,
- const filt_opts_t *fopts, u_int flags)
+ const opt_proto_t *op, const filt_opts_t *fopts, u_int flags)
{
- const opt_proto_t op = { .op_proto = -1, .op_opts = NULL };
+ const opt_proto_t def_op = { .op_proto = -1, .op_opts = NULL };
fam_addr_mask_t *am = npfctl_get_singlefam(ap->ap_netaddr);
in_port_t port;
nl_nat_t *nat;
@@ -600,10 +600,13 @@
} else {
port = 0;
}
+ if (!op) {
+ op = &def_op;
+ }
nat = npf_nat_create(type, flags, ifname, am->fam_family,
&am->fam_addr, am->fam_mask, port);
- npfctl_build_code(nat, am->fam_family, &op, fopts);
+ npfctl_build_code(nat, am->fam_family, op, fopts);
npf_nat_insert(npf_conf, nat, NPF_PRI_LAST);
return nat;
}
@@ -613,7 +616,7 @@
*/
void
npfctl_build_natseg(int sd, int type, const char *ifname,
- const addr_port_t *ap1, const addr_port_t *ap2,
+ const addr_port_t *ap1, const addr_port_t *ap2, const opt_proto_t *op,
const filt_opts_t *fopts, u_int algo)
{
fam_addr_mask_t *am1 = NULL, *am2 = NULL;
@@ -692,12 +695,12 @@
if (type & NPF_NATIN) {
memset(&imfopts, 0, sizeof(filt_opts_t));
memcpy(&imfopts.fo_to, ap2, sizeof(addr_port_t));
- nt1 = npfctl_build_nat(NPF_NATIN, ifname, ap1, fopts, flags);
+ nt1 = npfctl_build_nat(NPF_NATIN, ifname, ap1, op, fopts, flags);
}
if (type & NPF_NATOUT) {
memset(&imfopts, 0, sizeof(filt_opts_t));
memcpy(&imfopts.fo_from, ap1, sizeof(addr_port_t));
- nt2 = npfctl_build_nat(NPF_NATOUT, ifname, ap2, fopts, flags);
+ nt2 = npfctl_build_nat(NPF_NATOUT, ifname, ap2, op, fopts, flags);
}
if (algo == NPF_ALGO_NPT66) {
diff -r 33a583a60d0d -r 1c8d3a80da3e usr.sbin/npf/npfctl/npf_data.c
--- a/usr.sbin/npf/npfctl/npf_data.c Thu Jan 19 19:09:06 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf_data.c Thu Jan 19 20:18:17 2017 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: npf_data.c,v 1.27 2016/12/27 22:35:33 rmind Exp $ */
+/* $NetBSD: npf_data.c,v 1.28 2017/01/19 20:18:17 rmind Exp $ */
/*-
- * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2017 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_data.c,v 1.27 2016/12/27 22:35:33 rmind Exp $");
+__RCSID("$NetBSD: npf_data.c,v 1.28 2017/01/19 20:18:17 rmind Exp $");
#include <stdlib.h>
#include <stddef.h>
@@ -129,6 +129,12 @@
}
}
+/*
+ * npfctl_parse_fam_addr: parse a given a string and return the address
+ * family with the actual address as npf_addr_t.
+ *
+ * => Return true on success; false otherwise.
+ */
static bool
npfctl_parse_fam_addr(const char *name, sa_family_t *fam, npf_addr_t *addr)
{
@@ -154,41 +160,65 @@
return true;
}
+/*
+ * npfctl_parse_mask: parse a given string which represents a mask and
+ * can either be in quad-dot or CIDR block notation; validates the mask
+ * given the family.
+ *
+ * => Returns true if mask is valid (or is NULL); false otherwise.
+ */
static bool
npfctl_parse_mask(const char *s, sa_family_t fam, npf_netmask_t *mask)
{
+ unsigned max_mask = NPF_MAX_NETMASK;
char *ep = NULL;
npf_addr_t addr;
uint8_t *ap;
- if (s) {
- errno = 0;
- *mask = (npf_netmask_t)strtol(s, &ep, 0);
- if (*ep == '\0' && s != ep && errno != ERANGE)
- return true;
- if (!npfctl_parse_fam_addr(s, &fam, &addr))
- return false;
- }
-
assert(fam == AF_INET || fam == AF_INET6);
- *mask = NPF_NO_NETMASK;
- if (ep == NULL) {
+ if (!s) {
+ /* No mask. */
+ *mask = NPF_NO_NETMASK;
return true;
}
+ errno = 0;
+ *mask = (npf_netmask_t)strtol(s, &ep, 0);
+ if (*ep == '\0' && s != ep && errno != ERANGE) {
+ /* Just a number -- CIDR notation. */
+ goto check;
+ }
+
+ /* Other characters: try to parse a full address. */
+ if (!npfctl_parse_fam_addr(s, &fam, &addr)) {
+ return false;
+ }
+
+ /* Convert the address to CIDR block number. */
ap = addr.word8 + (*mask / 8) - 1;
while (ap >= addr.word8) {
for (int j = 8; j > 0; j--) {
if (*ap & 1)
- return true;
+ goto check;
*ap >>= 1;
(*mask)--;
if (*mask == 0)
- return true;
+ goto check;
}
ap--;
}
+ *mask = NPF_NO_NETMASK;
return true;
+check:
+ switch (fam) {
+ case AF_INET:
+ max_mask = 32;
+ break;
+ case AF_INET6:
+ max_mask = 128;
+ break;
+ }
+ return *mask <= max_mask;
}
/*
@@ -202,6 +232,7 @@
unsigned long *nummask)
{
fam_addr_mask_t fam;
+ char buf[32];
memset(&fam, 0, sizeof(fam));
@@ -209,12 +240,14 @@
return NULL;
/*
- * Note: both mask and nummask may be NULL. In such case,
- * npfctl_parse_mask() will handle and will set full mask.
+ * Mask may be NULL. In such case, "no mask" value will be set.
*/
if (nummask) {
- fam.fam_mask = *nummask;
- } else if (!npfctl_parse_mask(mask, fam.fam_family, &fam.fam_mask)) {
+ /* Let npfctl_parse_mask() validate the number. */
+ snprintf(buf, sizeof(buf), "%lu", *nummask);
+ mask = buf;
+ }
+ if (!npfctl_parse_mask(mask, fam.fam_family, &fam.fam_mask)) {
return NULL;
}
return npfvar_create_element(NPFVAR_FAM, &fam, sizeof(fam));
@@ -249,17 +282,16 @@
}
npfvar_t *
-npfctl_parse_port_range_variable(const char *v)
+npfctl_parse_port_range_variable(const char *v, npfvar_t *vp)
{
- npfvar_t *vp = npfvar_lookup(v);
size_t count = npfvar_get_count(vp);
npfvar_t *pvp = npfvar_create();
port_range_t *pr;
- in_port_t p;
for (size_t i = 0; i < count; i++) {
int type = npfvar_get_type(vp, i);
void *data = npfvar_get_data(vp, type, i);
+ in_port_t p;
switch (type) {
case NPFVAR_IDENTIFIER:
@@ -277,8 +309,13 @@
npfvar_add_elements(pvp, npfctl_parse_port_range(p, p));
break;
default:
- yyerror("wrong variable '%s' type '%s' for port range",
Home |
Main Index |
Thread Index |
Old Index