Module Name: src
Committed By: christos
Date: Tue Mar 12 20:47:48 UTC 2013
Modified Files:
src/sys/net/npf: files.npf
Added Files:
src/sys/net/npf: npf_ext_normalize.c
Removed Files:
src/sys/net/npf: npf_ext_normalise.c
Log Message:
normali{s,z}e
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/net/npf/files.npf
cvs rdiff -u -r1.4 -r0 src/sys/net/npf/npf_ext_normalise.c
cvs rdiff -u -r0 -r1.1 src/sys/net/npf/npf_ext_normalize.c
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/files.npf
diff -u src/sys/net/npf/files.npf:1.11 src/sys/net/npf/files.npf:1.12
--- src/sys/net/npf/files.npf:1.11 Sun Mar 10 16:51:44 2013
+++ src/sys/net/npf/files.npf Tue Mar 12 16:47:48 2013
@@ -1,4 +1,4 @@
-# $NetBSD: files.npf,v 1.11 2013/03/10 20:51:44 christos Exp $
+# $NetBSD: files.npf,v 1.12 2013/03/12 20:47:48 christos Exp $
#
# Public Domain.
#
@@ -31,7 +31,7 @@ file net/npf/npf_sendpkt.c npf
# Built-in extensions.
file net/npf/npf_ext_log.c npf
-file net/npf/npf_ext_normalise.c npf
+file net/npf/npf_ext_normalize.c npf
file net/npf/npf_ext_rndblock.c npf
# ALGs
Added files:
Index: src/sys/net/npf/npf_ext_normalize.c
diff -u /dev/null src/sys/net/npf/npf_ext_normalize.c:1.1
--- /dev/null Tue Mar 12 16:47:48 2013
+++ src/sys/net/npf/npf_ext_normalize.c Tue Mar 12 16:47:48 2013
@@ -0,0 +1,219 @@
+/* $NetBSD: npf_ext_normalize.c,v 1.1 2013/03/12 20:47:48 christos Exp $ */
+
+/*-
+ * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.1 2013/03/12 20:47:48 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/kmem.h>
+
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include "npf.h"
+#include "npf_impl.h"
+
+/*
+ * NPF extension module definition and the identifier.
+ */
+NPF_EXT_MODULE(npf_ext_normalize, "");
+
+#define NPFEXT_NORMALIZE_VER 1
+
+static void * npf_ext_normalize_id;
+
+/*
+ * Normalisation parameters.
+ */
+typedef struct {
+ u_int n_minttl;
+ u_int n_maxmss;
+ bool n_random_id;
+ bool n_no_df;
+} npf_normalize_t;
+
+/*
+ * npf_normalize_ctor: a constructor for the normalisation rule procedure
+ * with the given parameters.
+ */
+static int
+npf_normalize_ctor(npf_rproc_t *rp, prop_dictionary_t params)
+{
+ npf_normalize_t *np;
+
+ /* Create a structure for normalisation parameters. */
+ np = kmem_zalloc(sizeof(npf_normalize_t), KM_SLEEP);
+
+ /* IP ID randomisation and IP_DF flag cleansing. */
+ prop_dictionary_get_bool(params, "random-id", &np->n_random_id);
+ prop_dictionary_get_bool(params, "no-df", &np->n_no_df);
+
+ /* Minimum IP TTL and maximum TCP MSS. */
+ prop_dictionary_get_uint32(params, "min-ttl", &np->n_minttl);
+ prop_dictionary_get_uint32(params, "max-mss", &np->n_maxmss);
+
+ /* Assign the parameters for this rule procedure. */
+ npf_rproc_assign(rp, np);
+ return 0;
+}
+
+/*
+ * npf_normalize_dtor: a destructor for a normalisation rule procedure.
+ */
+static void
+npf_normalize_dtor(npf_rproc_t *rp, void *params)
+{
+ /* Free our meta-data, associated with the procedure. */
+ kmem_free(params, sizeof(npf_normalize_t));
+}
+
+/*
+ * npf_normalize_ip4: routine to normalize IPv4 header (randomise ID,
+ * clear "don't fragment" and/or enforce minimum TTL).
+ */
+static inline void
+npf_normalize_ip4(npf_cache_t *npc, npf_normalize_t *np)
+{
+ struct ip *ip = npc->npc_ip.v4;
+ uint16_t cksum = ip->ip_sum;
+ uint16_t ip_off = ip->ip_off;
+ uint8_t ttl = ip->ip_ttl;
+ u_int minttl = np->n_minttl;
+
+ KASSERT(np->n_random_id || np->n_no_df || minttl);
+
+ /* Randomise IPv4 ID. */
+ if (np->n_random_id) {
+ uint16_t oid = ip->ip_id, nid;
+
+ nid = htons(ip_randomid(ip_ids, 0));
+ cksum = npf_fixup16_cksum(cksum, oid, nid);
+ ip->ip_id = nid;
+ }
+
+ /* IP_DF flag cleansing. */
+ if (np->n_no_df && (ip_off & htons(IP_DF)) != 0) {
+ uint16_t nip_off = ip_off & ~htons(IP_DF);
+
+ cksum = npf_fixup16_cksum(cksum, ip_off, nip_off);
+ ip->ip_off = nip_off;
+ }
+
+ /* Enforce minimum TTL. */
+ if (minttl && ttl < minttl) {
+ cksum = npf_fixup16_cksum(cksum, ttl, minttl);
+ ip->ip_ttl = minttl;
+ }
+
+ /* Update IPv4 checksum. */
+ ip->ip_sum = cksum;
+}
+
+/*
+ * npf_normalize: the main routine to normalize IPv4 and/or TCP headers.
+ */
+static void
+npf_normalize(npf_cache_t *npc, nbuf_t *nbuf, void *params, int *decision)
+{
+ npf_normalize_t *np = params;
+ struct tcphdr *th = npc->npc_l4.tcp;
+ uint16_t cksum, mss, maxmss = np->n_maxmss;
+ int wscale;
+
+ /* Skip, if already blocking. */
+ if (*decision == NPF_DECISION_BLOCK) {
+ return;
+ }
+
+ /* Normalise IPv4. Nothing to do for IPv6. */
+ if (npf_iscached(npc, NPC_IP4) && (np->n_random_id || np->n_minttl)) {
+ npf_normalize_ip4(npc, np);
+ }
+
+ /*
+ * TCP Maximum Segment Size (MSS) "clamping". Only if SYN packet.
+ * Fetch MSS and check whether rewrite to lower is needed.
+ */
+ if (maxmss == 0 || !npf_iscached(npc, NPC_TCP) ||
+ (th->th_flags & TH_SYN) == 0) {
+ /* Not required; done. */
+ return;
+ }
+ mss = 0;
+ if (!npf_fetch_tcpopts(npc, nbuf, &mss, &wscale)) {
+ return;
+ }
+ if (ntohs(mss) <= maxmss) {
+ /* Nothing else to do. */
+ return;
+ }
+ maxmss = htons(maxmss);
+
+ /* Store new MSS, calculate TCP checksum and update it. */
+ if (npf_fetch_tcpopts(npc, nbuf, &maxmss, &wscale)) {
+ cksum = npf_fixup16_cksum(th->th_sum, mss, maxmss);
+ th->th_sum = cksum;
+ }
+}
+
+static int
+npf_ext_normalize_modcmd(modcmd_t cmd, void *arg)
+{
+ static const npf_ext_ops_t npf_normalize_ops = {
+ .version = NPFEXT_NORMALIZE_VER,
+ .ctx = NULL,
+ .ctor = npf_normalize_ctor,
+ .dtor = npf_normalize_dtor,
+ .proc = npf_normalize
+ };
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ /*
+ * Initialise normalisation module. Register the "normalize"
+ * extension and its calls.
+ */
+ npf_ext_normalize_id =
+ npf_ext_register("normalize", &npf_normalize_ops);
+ return npf_ext_normalize_id ? 0 : EEXIST;
+
+ case MODULE_CMD_FINI:
+ /* Unregister the normalisation rule procedure. */
+ return npf_ext_unregister(npf_ext_normalize_id);
+
+ case MODULE_CMD_AUTOUNLOAD:
+ return npf_autounload_p() ? 0 : EBUSY;
+
+ default:
+ return ENOTTY;
+ }
+ return 0;
+}