Module Name: src Committed By: jdc Date: Wed Jul 25 20:45:24 UTC 2012
Modified Files: src/sys/net/npf [netbsd-6]: npf.h npf_alg_icmp.c npf_impl.h npf_inet.c npf_instr.c npf_ncode.h npf_processor.c npf_session.c npf_state.c npf_state_tcp.c src/usr.sbin/npf/npfctl [netbsd-6]: npf_build.c npf_data.c npf_disassemble.c npf_ncgen.c npf_parse.y npf_scan.l npf_var.h npfctl.c npfctl.h src/usr.sbin/npf/npftest [netbsd-6]: npfstream.c src/usr.sbin/npf/npftest/libnpftest [netbsd-6]: npf_test_subr.c Log Message: Pull up revisions: src/usr.sbin/npf/npfctl/npfctl.c revisions 1.16,1.17 src/sys/net/npf/npf.h revision 1.20 src/sys/net/npf/npf_alg_icmp.c revision 1.11 src/sys/net/npf/npf_impl.h revision 1.19 src/sys/net/npf/npf_inet.c revisions 1.15,1.16 src/sys/net/npf/npf_instr.c revision 1.14 src/sys/net/npf/npf_ncode.h revision 1.10 src/sys/net/npf/npf_processor.c revision 1.12 src/sys/net/npf/npf_session.c revision 1.16 src/usr.sbin/npf/npfctl/npf_build.c revision 1.12 src/usr.sbin/npf/npfctl/npf_data.c revisions 1.16,1.17 src/usr.sbin/npf/npfctl/npf_disassemble.c revision 1.8 src/usr.sbin/npf/npfctl/npf_ncgen.c revision 1.13 src/usr.sbin/npf/npfctl/npf_parse.y revision 1.11 src/usr.sbin/npf/npfctl/npf_scan.l revision 1.5 src/usr.sbin/npf/npfctl/npf_var.h revision 1.3 src/usr.sbin/npf/npfctl/npfctl.h revision 1.18 src/sys/net/npf/npf_state.c revision 1.10 src/sys/net/npf/npf_state_tcp.c revision 1.10 src/usr.sbin/npf/npftest/npfstream.c revision 1.2 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c revision 1.2 (requested by rmind in ticket #435). Add missing __dead. teach npf ipv6-icmp reviewed by rmind@ - npfctl_print_stats: beautification a la French style. - npfctl_icmpcode: fix the build break. - npf_fetch_tcpopts: fix off-by-one when validating TCP option length against the maximum allowed. - npf_tcp_inwindow: be more liberal with npf_fetch_tcpopts(). - Few minor improvements to npftest. To generate a diff of this commit: cvs rdiff -u -r1.14.2.5 -r1.14.2.6 src/sys/net/npf/npf.h cvs rdiff -u -r1.8.4.2 -r1.8.4.3 src/sys/net/npf/npf_alg_icmp.c cvs rdiff -u -r1.10.2.5 -r1.10.2.6 src/sys/net/npf/npf_impl.h cvs rdiff -u -r1.10.4.4 -r1.10.4.5 src/sys/net/npf/npf_inet.c \ src/sys/net/npf/npf_session.c cvs rdiff -u -r1.9.2.4 -r1.9.2.5 src/sys/net/npf/npf_instr.c cvs rdiff -u -r1.5.6.3 -r1.5.6.4 src/sys/net/npf/npf_ncode.h cvs rdiff -u -r1.9.2.2 -r1.9.2.3 src/sys/net/npf/npf_processor.c cvs rdiff -u -r1.6.4.3 -r1.6.4.4 src/sys/net/npf/npf_state.c cvs rdiff -u -r1.3.2.4 -r1.3.2.5 src/sys/net/npf/npf_state_tcp.c cvs rdiff -u -r1.4.2.4 -r1.4.2.5 src/usr.sbin/npf/npfctl/npf_build.c cvs rdiff -u -r1.10.2.3 -r1.10.2.4 src/usr.sbin/npf/npfctl/npf_data.c \ src/usr.sbin/npf/npfctl/npfctl.c cvs rdiff -u -r1.3.2.5 -r1.3.2.6 src/usr.sbin/npf/npfctl/npf_disassemble.c cvs rdiff -u -r1.7.2.4 -r1.7.2.5 src/usr.sbin/npf/npfctl/npf_ncgen.c cvs rdiff -u -r1.3.2.4 -r1.3.2.5 src/usr.sbin/npf/npfctl/npf_parse.y cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/usr.sbin/npf/npfctl/npf_scan.l cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/usr.sbin/npf/npfctl/npf_var.h cvs rdiff -u -r1.11.2.4 -r1.11.2.5 src/usr.sbin/npf/npfctl/npfctl.h cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/usr.sbin/npf/npftest/npfstream.c cvs rdiff -u -r1.1.2.2 -r1.1.2.3 \ src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.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/npf.h diff -u src/sys/net/npf/npf.h:1.14.2.5 src/sys/net/npf/npf.h:1.14.2.6 --- src/sys/net/npf/npf.h:1.14.2.5 Mon Jul 16 22:13:26 2012 +++ src/sys/net/npf/npf.h Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf.h,v 1.14.2.5 2012/07/16 22:13:26 riz Exp $ */ +/* $NetBSD: npf.h,v 1.14.2.6 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -74,6 +74,7 @@ typedef struct npf_rproc npf_rproc_t; #include <netinet/tcp.h> #include <netinet/udp.h> #include <netinet/ip_icmp.h> +#include <netinet/icmp6.h> #define NPC_IP4 0x01 /* Indicates fetched IPv4 header. */ #define NPC_IP6 0x02 /* Indicates IPv6 header. */ @@ -104,9 +105,10 @@ typedef struct { } npc_ip; /* TCP, UDP, ICMP. */ union { - struct tcphdr tcp; - struct udphdr udp; - struct icmp icmp; + struct tcphdr tcp; + struct udphdr udp; + struct icmp icmp; + struct icmp6_hdr icmp6; } npc_l4; } npf_cache_t; Index: src/sys/net/npf/npf_alg_icmp.c diff -u src/sys/net/npf/npf_alg_icmp.c:1.8.4.2 src/sys/net/npf/npf_alg_icmp.c:1.8.4.3 --- src/sys/net/npf/npf_alg_icmp.c:1.8.4.2 Mon Jul 16 22:13:26 2012 +++ src/sys/net/npf/npf_alg_icmp.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_alg_icmp.c,v 1.8.4.2 2012/07/16 22:13:26 riz Exp $ */ +/* $NetBSD: npf_alg_icmp.c,v 1.8.4.3 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.8.4.2 2012/07/16 22:13:26 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.8.4.3 2012/07/25 20:45:23 jdc Exp $"); #include <sys/param.h> #include <sys/module.h> @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp #include <netinet/tcp.h> #include <netinet/udp.h> #include <netinet/ip_icmp.h> +#include <netinet/icmp6.h> #include <net/pfil.h> #include "npf_impl.h" @@ -156,54 +157,102 @@ npfa_icmp_match(npf_cache_t *npc, nbuf_t static bool npf_icmp_uniqid(const int type, npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr) { - struct icmp *ic; - u_int offby; - - /* Per RFC 792. */ - switch (type) { - case ICMP_UNREACH: - case ICMP_SOURCEQUENCH: - case ICMP_REDIRECT: - case ICMP_TIMXCEED: - case ICMP_PARAMPROB: - /* Should contain original IP header. */ - offby = offsetof(struct icmp, icmp_ip); - if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) { - return false; - } - /* Fetch into the cache. */ - if (!npf_fetch_ip(npc, nbuf, n_ptr)) { - return false; - } - switch (npf_cache_ipproto(npc)) { - case IPPROTO_TCP: - return npf_fetch_tcp(npc, nbuf, n_ptr); - case IPPROTO_UDP: - return npf_fetch_udp(npc, nbuf, n_ptr); + struct icmp *ic; + struct icmp6_hdr *ic6; + u_int offby; + + if (npf_iscached(npc, NPC_IP4)) { + /* Per RFC 792. */ + switch (type) { + case ICMP_UNREACH: + case ICMP_SOURCEQUENCH: + case ICMP_REDIRECT: + case ICMP_TIMXCEED: + case ICMP_PARAMPROB: + /* Should contain original IP header. */ + offby = offsetof(struct icmp, icmp_ip); + if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) { + return false; + } + /* Fetch into the cache. */ + if (!npf_fetch_ip(npc, nbuf, n_ptr)) { + return false; + } + switch (npf_cache_ipproto(npc)) { + case IPPROTO_TCP: + return npf_fetch_tcp(npc, nbuf, n_ptr); + case IPPROTO_UDP: + return npf_fetch_udp(npc, nbuf, n_ptr); + default: + return false; + } + return true; + + case ICMP_ECHOREPLY: + case ICMP_ECHO: + case ICMP_TSTAMP: + case ICMP_TSTAMPREPLY: + case ICMP_IREQ: + case ICMP_IREQREPLY: + /* Should contain ICMP query ID. */ + ic = &npc->npc_l4.icmp; + offby = offsetof(struct icmp, icmp_id); + if (nbuf_advfetch(&nbuf, &n_ptr, offby, + sizeof(uint16_t), &ic->icmp_id)) { + return false; + } + npc->npc_info |= NPC_ICMP_ID; + return true; default: - return false; + break; } - return true; - - case ICMP_ECHOREPLY: - case ICMP_ECHO: - case ICMP_TSTAMP: - case ICMP_TSTAMPREPLY: - case ICMP_IREQ: - case ICMP_IREQREPLY: - /* Should contain ICMP query ID. */ - ic = &npc->npc_l4.icmp; - offby = offsetof(struct icmp, icmp_id); - if (nbuf_advfetch(&nbuf, &n_ptr, offby, - sizeof(uint16_t), &ic->icmp_id)) { - return false; + /* No unique IDs. */ + return false; + } + if (npf_iscached(npc, NPC_IP6)) { + switch (type) { + /* Per RFC 4443. */ + case ICMP6_DST_UNREACH: + case ICMP6_PACKET_TOO_BIG: + case ICMP6_TIME_EXCEEDED: + case ICMP6_PARAM_PROB: + /* Should contain original IP header. */ + offby = sizeof(struct icmp6_hdr); + if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) { + return false; + } + /* Fetch into the cache. */ + if (!npf_fetch_ip(npc, nbuf, n_ptr)) { + return false; + } + switch (npf_cache_ipproto(npc)) { + case IPPROTO_TCP: + return npf_fetch_tcp(npc, nbuf, n_ptr); + case IPPROTO_UDP: + return npf_fetch_udp(npc, nbuf, n_ptr); + default: + return false; + } + return true; + + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + /* Should contain ICMP query ID. */ + ic6 = &npc->npc_l4.icmp6; + offby = offsetof(struct icmp6_hdr, icmp6_id); + if (nbuf_advfetch(&nbuf, &n_ptr, offby, + sizeof(uint16_t), &ic6->icmp6_id)) { + return false; + } + npc->npc_info |= NPC_ICMP_ID; + return true; + default: + break; } - npc->npc_info |= NPC_ICMP_ID; - return true; - default: - break; + /* No unique IDs. */ + return false; } - /* No unique IDs. */ + /* Whatever protocol that may have been ... */ return false; } Index: src/sys/net/npf/npf_impl.h diff -u src/sys/net/npf/npf_impl.h:1.10.2.5 src/sys/net/npf/npf_impl.h:1.10.2.6 --- src/sys/net/npf/npf_impl.h:1.10.2.5 Mon Jul 16 22:13:27 2012 +++ src/sys/net/npf/npf_impl.h Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_impl.h,v 1.10.2.5 2012/07/16 22:13:27 riz Exp $ */ +/* $NetBSD: npf_impl.h,v 1.10.2.6 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -208,6 +208,7 @@ int npf_match_tcp_ports(npf_cache_t *, int npf_match_udp_ports(npf_cache_t *, nbuf_t *, void *, const int, const uint32_t); int npf_match_icmp4(npf_cache_t *, nbuf_t *, void *, uint32_t); +int npf_match_icmp6(npf_cache_t *, nbuf_t *, void *, uint32_t); int npf_match_tcpfl(npf_cache_t *, nbuf_t *, void *, uint32_t); /* Tableset interface. */ Index: src/sys/net/npf/npf_inet.c diff -u src/sys/net/npf/npf_inet.c:1.10.4.4 src/sys/net/npf/npf_inet.c:1.10.4.5 --- src/sys/net/npf/npf_inet.c:1.10.4.4 Mon Jul 16 22:13:25 2012 +++ src/sys/net/npf/npf_inet.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_inet.c,v 1.10.4.4 2012/07/16 22:13:25 riz Exp $ */ +/* $NetBSD: npf_inet.c,v 1.10.4.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.10.4.4 2012/07/16 22:13:25 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.10.4.5 2012/07/25 20:45:23 jdc Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -277,7 +277,7 @@ next: if (nbuf_advfetch(&nbuf, &n_ptr, 1, sizeof(val), &val)) { return false; } - if (val < 2 || val >= topts_len) { + if (val < 2 || val > topts_len) { return false; } topts_len -= val; @@ -463,14 +463,18 @@ npf_fetch_icmp(npf_cache_t *npc, nbuf_t if (!npf_iscached(npc, NPC_IP46) && !npf_fetch_ip(npc, nbuf, n_ptr)) { return false; } - if (npf_cache_ipproto(npc) != IPPROTO_ICMP) { + if (npf_cache_ipproto(npc) != IPPROTO_ICMP && + npf_cache_ipproto(npc) != IPPROTO_ICMPV6) { return false; } ic = &npc->npc_l4.icmp; hlen = npf_cache_hlen(npc); /* Fetch basic ICMP header, up to the "data" point. */ - iclen = offsetof(struct icmp, icmp_data); + CTASSERT(offsetof(struct icmp, icmp_void) == + offsetof(struct icmp6_hdr, icmp6_data32)); + + iclen = offsetof(struct icmp, icmp_void); if (nbuf_advfetch(&nbuf, &n_ptr, hlen, iclen, ic)) { return false; } @@ -503,6 +507,7 @@ npf_cache_all(npf_cache_t *npc, nbuf_t * (void)npf_fetch_udp(npc, nbuf, n_ptr); break; case IPPROTO_ICMP: + case IPPROTO_ICMPV6: (void)npf_fetch_icmp(npc, nbuf, n_ptr); break; } Index: src/sys/net/npf/npf_session.c diff -u src/sys/net/npf/npf_session.c:1.10.4.4 src/sys/net/npf/npf_session.c:1.10.4.5 --- src/sys/net/npf/npf_session.c:1.10.4.4 Mon Jul 16 22:13:25 2012 +++ src/sys/net/npf/npf_session.c Wed Jul 25 20:45:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_session.c,v 1.10.4.4 2012/07/16 22:13:25 riz Exp $ */ +/* $NetBSD: npf_session.c,v 1.10.4.5 2012/07/25 20:45:24 jdc Exp $ */ /*- * Copyright (c) 2010-2012 The NetBSD Foundation, Inc. @@ -80,7 +80,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.10.4.4 2012/07/16 22:13:25 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.10.4.5 2012/07/25 20:45:24 jdc Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -495,7 +495,15 @@ npf_session_inspect(npf_cache_t *npc, nb senkey.se_dst_id = ic->icmp_id; break; } - /* FALLTHROUGH */ + return NULL; + case IPPROTO_ICMPV6: + if (npf_iscached(key, NPC_ICMP_ID)) { + const struct icmp6_hdr *ic6 = &key->npc_l4.icmp6; + senkey.se_src_id = ic6->icmp6_id; + senkey.se_dst_id = ic6->icmp6_id; + break; + } + return NULL; default: /* Unsupported protocol. */ return NULL; @@ -636,7 +644,18 @@ npf_session_establish(const npf_cache_t fw->se_dst_id = ic->icmp_id; break; } - /* FALLTHROUGH */ + ok = false; + goto out; + case IPPROTO_ICMPV6: + if (npf_iscached(npc, NPC_ICMP_ID)) { + /* ICMP query ID. */ + const struct icmp6_hdr *ic6 = &npc->npc_l4.icmp6; + fw->se_src_id = ic6->icmp6_id; + fw->se_dst_id = ic6->icmp6_id; + break; + } + ok = false; + goto out; default: /* Unsupported. */ ok = false; Index: src/sys/net/npf/npf_instr.c diff -u src/sys/net/npf/npf_instr.c:1.9.2.4 src/sys/net/npf/npf_instr.c:1.9.2.5 --- src/sys/net/npf/npf_instr.c:1.9.2.4 Mon Jul 16 22:13:26 2012 +++ src/sys/net/npf/npf_instr.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_instr.c,v 1.9.2.4 2012/07/16 22:13:26 riz Exp $ */ +/* $NetBSD: npf_instr.c,v 1.9.2.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.9.2.4 2012/07/16 22:13:26 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.9.2.5 2012/07/25 20:45:23 jdc Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -237,6 +237,37 @@ npf_match_icmp4(npf_cache_t *npc, nbuf_t } /* + * npf_match_icmp6: match ICMPv6 packet. + */ +int +npf_match_icmp6(npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr, uint32_t tc) +{ + struct icmp6_hdr *ic6 = &npc->npc_l4.icmp6; + + if (!npf_iscached(npc, NPC_ICMP)) { + if (!npf_fetch_icmp(npc, nbuf, n_ptr)) { + return -1; + } + KASSERT(npf_iscached(npc, NPC_ICMP)); + } + + /* Match code/type, if required. */ + if ((1 << 31) & tc) { + const uint8_t type = (tc >> 8) & 0xff; + if (type != ic6->icmp6_type) { + return -1; + } + } + if ((1 << 30) & tc) { + const uint8_t code = tc & 0xff; + if (code != ic6->icmp6_code) { + return -1; + } + } + return 0; +} + +/* * npf_match_tcpfl: match TCP flags. */ int Index: src/sys/net/npf/npf_ncode.h diff -u src/sys/net/npf/npf_ncode.h:1.5.6.3 src/sys/net/npf/npf_ncode.h:1.5.6.4 --- src/sys/net/npf/npf_ncode.h:1.5.6.3 Thu Jul 5 17:48:42 2012 +++ src/sys/net/npf/npf_ncode.h Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ncode.h,v 1.5.6.3 2012/07/05 17:48:42 riz Exp $ */ +/* $NetBSD: npf_ncode.h,v 1.5.6.4 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2010 The NetBSD Foundation, Inc. @@ -118,6 +118,7 @@ int npf_ncode_validate(const void *, siz #define NPF_OPCODE_TABLE 0x91 #define NPF_OPCODE_ICMP4 0x92 #define NPF_OPCODE_IP6MASK 0x93 +#define NPF_OPCODE_ICMP6 0x94 #define NPF_OPCODE_TCP_PORTS 0xa0 #define NPF_OPCODE_UDP_PORTS 0xa1 @@ -139,7 +140,7 @@ int npf_ncode_validate(const void *, siz # define NPF_OPERAND_SUBNET 9 # define NPF_OPERAND_LENGTH 10 # define NPF_OPERAND_TABLE_ID 11 -# define NPF_OPERAND_ICMP4_TYPE_CODE 12 +# define NPF_OPERAND_ICMP_TYPE_CODE 12 # define NPF_OPERAND_TCP_FLAGS_MASK 13 # define NPF_OPERAND_PORT_RANGE 14 # define NPF_OPERAND_PROTO 15 @@ -330,7 +331,13 @@ static const struct npf_instruction { [NPF_OPCODE_ICMP4] = { .name = "icmp4", .op = { - [0] = NPF_OPERAND_ICMP4_TYPE_CODE, + [0] = NPF_OPERAND_ICMP_TYPE_CODE, + }, + }, + [NPF_OPCODE_ICMP6] = { + .name = "icmp6", + .op = { + [0] = NPF_OPERAND_ICMP_TYPE_CODE, }, }, [NPF_OPCODE_IP6MASK] = { Index: src/sys/net/npf/npf_processor.c diff -u src/sys/net/npf/npf_processor.c:1.9.2.2 src/sys/net/npf/npf_processor.c:1.9.2.3 --- src/sys/net/npf/npf_processor.c:1.9.2.2 Thu Jul 5 17:48:42 2012 +++ src/sys/net/npf/npf_processor.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_processor.c,v 1.9.2.2 2012/07/05 17:48:42 riz Exp $ */ +/* $NetBSD: npf_processor.c,v 1.9.2.3 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2010 The NetBSD Foundation, Inc. @@ -50,7 +50,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_processor.c,v 1.9.2.2 2012/07/05 17:48:42 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_processor.c,v 1.9.2.3 2012/07/25 20:45:23 jdc Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -316,6 +316,11 @@ cisc_like: i_ptr = nc_fetch_word(i_ptr, &n); cmpval = npf_match_icmp4(npc, nbuf, n_ptr, n); break; + case NPF_OPCODE_ICMP6: + /* ICMP type/code. */ + i_ptr = nc_fetch_word(i_ptr, &n); + cmpval = npf_match_icmp6(npc, nbuf, n_ptr, n); + break; case NPF_OPCODE_PROTO: i_ptr = nc_fetch_word(i_ptr, &n); cmpval = npf_match_proto(npc, nbuf, n_ptr, n); @@ -480,6 +485,7 @@ jmp_check: error = nc_ptr_check(&iptr, nc, sz, 1, NULL, 0); break; case NPF_OPCODE_ICMP4: + case NPF_OPCODE_ICMP6: error = nc_ptr_check(&iptr, nc, sz, 1, NULL, 0); break; case NPF_OPCODE_PROTO: Index: src/sys/net/npf/npf_state.c diff -u src/sys/net/npf/npf_state.c:1.6.4.3 src/sys/net/npf/npf_state.c:1.6.4.4 --- src/sys/net/npf/npf_state.c:1.6.4.3 Thu Jul 5 17:48:42 2012 +++ src/sys/net/npf/npf_state.c Wed Jul 25 20:45:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_state.c,v 1.6.4.3 2012/07/05 17:48:42 riz Exp $ */ +/* $NetBSD: npf_state.c,v 1.6.4.4 2012/07/25 20:45:24 jdc Exp $ */ /*- * Copyright (c) 2010-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.6.4.3 2012/07/05 17:48:42 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.6.4.4 2012/07/25 20:45:24 jdc Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -107,6 +107,7 @@ npf_state_init(const npf_cache_t *npc, n default: ret = false; } + NPF_TCP_STATE_SAMPLE(nst, ret); return ret; } Index: src/sys/net/npf/npf_state_tcp.c diff -u src/sys/net/npf/npf_state_tcp.c:1.3.2.4 src/sys/net/npf/npf_state_tcp.c:1.3.2.5 --- src/sys/net/npf/npf_state_tcp.c:1.3.2.4 Mon Jul 16 22:13:25 2012 +++ src/sys/net/npf/npf_state_tcp.c Wed Jul 25 20:45:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_state_tcp.c,v 1.3.2.4 2012/07/16 22:13:25 riz Exp $ */ +/* $NetBSD: npf_state_tcp.c,v 1.3.2.5 2012/07/25 20:45:24 jdc Exp $ */ /*- * Copyright (c) 2010-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.3.2.4 2012/07/16 22:13:25 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.3.2.5 2012/07/25 20:45:24 jdc Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -300,7 +300,7 @@ npf_tcp_inwindow(const npf_cache_t *npc, const struct tcphdr * const th = &npc->npc_l4.tcp; const int tcpfl = th->th_flags; npf_tcpstate_t *fstate, *tstate; - int tcpdlen, wscale, ackskew; + int tcpdlen, ackskew; tcp_seq seq, ack, end; uint32_t win; @@ -359,11 +359,9 @@ npf_tcp_inwindow(const npf_cache_t *npc, * Handle TCP Window Scaling (RFC 1323). Both sides may * send this option in their SYN packets. */ - if (npf_fetch_tcpopts(npc, nbuf, NULL, &wscale)) { - fstate->nst_wscale = wscale; - } else { - fstate->nst_wscale = 0; - } + fstate->nst_wscale = 0; + (void)npf_fetch_tcpopts(npc, nbuf, NULL, &fstate->nst_wscale); + tstate->nst_wscale = 0; /* Done. */ @@ -377,12 +375,12 @@ npf_tcp_inwindow(const npf_cache_t *npc, fstate->nst_end = end; fstate->nst_maxend = end + 1; fstate->nst_maxwin = win; + fstate->nst_wscale = 0; /* Handle TCP Window Scaling (must be ignored if no SYN). */ if (tcpfl & TH_SYN) { - fstate->nst_wscale = - npf_fetch_tcpopts(npc, nbuf, NULL, &wscale) ? - wscale : 0; + (void)npf_fetch_tcpopts(npc, nbuf, NULL, + &fstate->nst_wscale); } } Index: src/usr.sbin/npf/npfctl/npf_build.c diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.4 src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.5 --- src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.4 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npf_build.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_build.c,v 1.4.2.4 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npf_build.c,v 1.4.2.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_build.c,v 1.4.2.4 2012/07/16 22:13:28 riz Exp $"); +__RCSID("$NetBSD: npf_build.c,v 1.4.2.5 2012/07/25 20:45:23 jdc Exp $"); #include <sys/types.h> #include <sys/ioctl.h> @@ -246,6 +246,21 @@ npfctl_build_proto(nc_ctx_t *nc, sa_fami npfctl_gennc_icmp(nc, *icmp_type, *icmp_code); nop = false; break; + case IPPROTO_ICMPV6: + /* + * Build ICMP block. + */ + if (!nop) { + goto invop; + } + assert(npfvar_get_count(popts) == 2); + + int *icmp6_type, *icmp6_code; + icmp6_type = npfvar_get_data(popts, NPFVAR_ICMP6, 0); + icmp6_code = npfvar_get_data(popts, NPFVAR_ICMP6, 1); + npfctl_gennc_icmp6(nc, *icmp6_type, *icmp6_code); + nop = false; + break; case -1: pflag = NC_MATCH_TCP | NC_MATCH_UDP; nop = false; Index: src/usr.sbin/npf/npfctl/npf_data.c diff -u src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.3 src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.4 --- src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.3 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npf_data.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_data.c,v 1.10.2.3 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npf_data.c,v 1.10.2.4 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_data.c,v 1.10.2.3 2012/07/16 22:13:28 riz Exp $"); +__RCSID("$NetBSD: npf_data.c,v 1.10.2.4 2012/07/25 20:45:23 jdc Exp $"); #include <sys/types.h> #include <sys/null.h> @@ -41,6 +41,8 @@ __RCSID("$NetBSD: npf_data.c,v 1.10.2.3 #include <netinet/ip.h> #define ICMP_STRINGS #include <netinet/ip_icmp.h> +#define ICMP6_STRINGS +#include <netinet/icmp6.h> #include <netinet/tcp.h> #include <net/if.h> @@ -440,71 +442,142 @@ npfctl_parse_tcpflag(const char *s) } uint8_t -npfctl_icmptype(const char *type) +npfctl_icmptype(int proto, const char *type) { - for (uint8_t ul = 0; icmp_type[ul]; ul++) - if (strcmp(icmp_type[ul], type) == 0) - return ul; + uint8_t ul; + + switch (proto) { + case IPPROTO_ICMP: + for (ul = 0; icmp_type[ul]; ul++) + if (strcmp(icmp_type[ul], type) == 0) + return ul; + break; + case IPPROTO_ICMPV6: + for (ul = 0; icmp6_type_err[ul]; ul++) + if (strcmp(icmp6_type_err[ul], type) == 0) + return ul; + for (ul = 0; icmp6_type_info[ul]; ul++) + if (strcmp(icmp6_type_info[ul], type) == 0) + return (ul+128); + break; + default: + assert(false); + } + + yyerror("unknown icmp-type %s", type); return ~0; } uint8_t -npfctl_icmpcode(uint8_t type, const char *code) +npfctl_icmpcode(int proto, uint8_t type, const char *code) { - const char **arr; + const char * const *arr; - switch (type) { - case ICMP_ECHOREPLY: - case ICMP_SOURCEQUENCH: - case ICMP_ALTHOSTADDR: - case ICMP_ECHO: - case ICMP_ROUTERSOLICIT: - case ICMP_TSTAMP: - case ICMP_TSTAMPREPLY: - case ICMP_IREQ: - case ICMP_IREQREPLY: - case ICMP_MASKREQ: - case ICMP_MASKREPLY: - arr = icmp_code_none; - break; - case ICMP_ROUTERADVERT: - arr = icmp_code_routeradvert; - break; - case ICMP_UNREACH: - arr = icmp_code_unreach; - break; - case ICMP_REDIRECT: - arr = icmp_code_redirect; - break; - case ICMP_TIMXCEED: - arr = icmp_code_timxceed; - break; - case ICMP_PARAMPROB: - arr = icmp_code_paramprob; + switch (proto) { + case IPPROTO_ICMP: + switch (type) { + case ICMP_ECHOREPLY: + case ICMP_SOURCEQUENCH: + case ICMP_ALTHOSTADDR: + case ICMP_ECHO: + case ICMP_ROUTERSOLICIT: + case ICMP_TSTAMP: + case ICMP_TSTAMPREPLY: + case ICMP_IREQ: + case ICMP_IREQREPLY: + case ICMP_MASKREQ: + case ICMP_MASKREPLY: + arr = icmp_code_none; + break; + case ICMP_ROUTERADVERT: + arr = icmp_code_routeradvert; + break; + case ICMP_UNREACH: + arr = icmp_code_unreach; + break; + case ICMP_REDIRECT: + arr = icmp_code_redirect; + break; + case ICMP_TIMXCEED: + arr = icmp_code_timxceed; + break; + case ICMP_PARAMPROB: + arr = icmp_code_paramprob; + break; + case ICMP_PHOTURIS: + arr = icmp_code_photuris; + break; + default: + yyerror("unknown icmp-type %d while parsing code %s", + type, code); + return ~0; + } break; - case ICMP_PHOTURIS: - arr = icmp_code_photuris; + case IPPROTO_ICMPV6: + switch (type) { + case ICMP6_DST_UNREACH: + arr = icmp6_code_unreach; + break; + case ICMP6_TIME_EXCEEDED: + arr = icmp6_code_timxceed; + break; + case ICMP6_PARAM_PROB: + arr = icmp6_code_paramprob; + break; + case ICMP6_PACKET_TOO_BIG: + /* code-less info ICMPs */ + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + case MLD_LISTENER_QUERY: + case MLD_LISTENER_REPORT: + case MLD_LISTENER_DONE: + case ND_ROUTER_SOLICIT: + case ND_ROUTER_ADVERT: + case ND_NEIGHBOR_SOLICIT: + case ND_NEIGHBOR_ADVERT: + case ND_REDIRECT: + arr = icmp6_code_none; + break; + /* XXX TODO: info ICMPs with code values */ + default: + yyerror("unknown icmp-type %d while parsing code %s", + type, code); + return ~0; + } break; default: - return ~0; + assert(false); } for (uint8_t ul = 0; arr[ul]; ul++) { if (strcmp(arr[ul], code) == 0) return ul; } + yyerror("unknown code %s for icmp-type %d", code, type); return ~0; } npfvar_t * -npfctl_parse_icmp(int type, int code) +npfctl_parse_icmp(int proto, int type, int code) { - npfvar_t *vp = npfvar_create(".icmp"); + npfvar_t *vp=npfvar_create(".icmp"); + int varnum; + + switch (proto) { + case IPPROTO_ICMP: + varnum = NPFVAR_ICMP; + break; + case IPPROTO_ICMPV6: + varnum = NPFVAR_ICMP6; + break; + default: + assert(false); + } - if (!npfvar_add_element(vp, NPFVAR_ICMP, &type, sizeof(type))) + if (!npfvar_add_element(vp, varnum, &type, sizeof(type))) goto out; - if (!npfvar_add_element(vp, NPFVAR_ICMP, &code, sizeof(code))) + if (!npfvar_add_element(vp, varnum, &code, sizeof(code))) goto out; return vp; @@ -512,3 +585,4 @@ out: npfvar_destroy(vp); return NULL; } + Index: src/usr.sbin/npf/npfctl/npfctl.c diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.10.2.3 src/usr.sbin/npf/npfctl/npfctl.c:1.10.2.4 --- src/usr.sbin/npf/npfctl/npfctl.c:1.10.2.3 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npfctl.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.c,v 1.10.2.3 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npfctl.c,v 1.10.2.4 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npfctl.c,v 1.10.2.3 2012/07/16 22:13:28 riz Exp $"); +__RCSID("$NetBSD: npfctl.c,v 1.10.2.4 2012/07/25 20:45:23 jdc Exp $"); #include <sys/ioctl.h> #include <sys/stat.h> @@ -171,48 +171,64 @@ npfctl_parsecfg(const char *cfg) static int npfctl_print_stats(int fd) { + static const struct stats_s { + /* Note: -1 indicates a new section. */ + int index; + const char * name; + } stats[] = { + { -1, "Packets passed" }, + { NPF_STAT_PASS_DEFAULT, "default pass" }, + { NPF_STAT_PASS_RULESET, "ruleset pass" }, + { NPF_STAT_PASS_SESSION, "session pass" }, + + { -1, "Packets blocked" }, + { NPF_STAT_BLOCK_DEFAULT, "default block" }, + { NPF_STAT_BLOCK_RULESET, "ruleset block" }, + + { -1, "Session and NAT entries" }, + { NPF_STAT_SESSION_CREATE, "session allocations" }, + { NPF_STAT_SESSION_DESTROY, "session destructions" }, + { NPF_STAT_NAT_CREATE, "NAT entry allocations" }, + { NPF_STAT_NAT_DESTROY, "NAT entry destructions"}, + + { -1, "Invalid packet state cases" }, + { NPF_STAT_INVALID_STATE, "cases in total" }, + { NPF_STAT_INVALID_STATE_TCP1, "TCP case I" }, + { NPF_STAT_INVALID_STATE_TCP2, "TCP case II" }, + { NPF_STAT_INVALID_STATE_TCP3, "TCP case III" }, + + { -1, "Packet race cases" }, + { NPF_STAT_RACE_NAT, "NAT association race" }, + { NPF_STAT_RACE_SESSION, "duplicate session race"}, + + { -1, "Rule procedure cases" }, + { NPF_STAT_RPROC_LOG, "packets logged" }, + { NPF_STAT_RPROC_NORM, "packets normalised" }, + + { -1, "Fragmentation" }, + { NPF_STAT_FRAGMENTS, "fragments" }, + { NPF_STAT_REASSEMBLY, "reassembled" }, + { NPF_STAT_REASSFAIL, "failed reassembly" }, + + { -1, "Other" }, + { NPF_STAT_ERROR, "unexpected errors" }, + }; uint64_t *st = zalloc(NPF_STATS_SIZE); if (ioctl(fd, IOC_NPF_STATS, &st) != 0) { err(EXIT_FAILURE, "ioctl(IOC_NPF_STATS)"); } - printf("Packets passed:\n\t%"PRIu64" default pass\n\t" - "%"PRIu64 " ruleset pass\n\t%"PRIu64" session pass\n\n", - st[NPF_STAT_PASS_DEFAULT], st[NPF_STAT_PASS_RULESET], - st[NPF_STAT_PASS_SESSION]); - - printf("Packets blocked:\n\t%"PRIu64" default block\n\t" - "%"PRIu64 " ruleset block\n\n", st[NPF_STAT_BLOCK_DEFAULT], - st[NPF_STAT_BLOCK_RULESET]); - - printf("Session and NAT entries:\n\t%"PRIu64" session allocations\n\t" - "%"PRIu64" session destructions\n\t%"PRIu64" NAT entry allocations\n\t" - "%"PRIu64" NAT entry destructions\n\n", st[NPF_STAT_SESSION_CREATE], - st[NPF_STAT_SESSION_DESTROY], st[NPF_STAT_NAT_CREATE], - st[NPF_STAT_NAT_DESTROY]); - - printf("Invalid packet state cases:\n\t%"PRIu64" cases in total\n\t" - "%"PRIu64" TCP case I\n\t%"PRIu64" TCP case II\n\t%"PRIu64 - " TCP case III\n\n", st[NPF_STAT_INVALID_STATE], - st[NPF_STAT_INVALID_STATE_TCP1], st[NPF_STAT_INVALID_STATE_TCP2], - st[NPF_STAT_INVALID_STATE_TCP3]); - - printf("Packet race cases:\n\t%"PRIu64" NAT association race\n\t" - "%"PRIu64" duplicate session race\n\n", st[NPF_STAT_RACE_NAT], - st[NPF_STAT_RACE_SESSION]); - - printf("Rule processing procedure cases:\n" - "\t%"PRIu64" packets logged\n\t%"PRIu64" packets normalized\n\n", - st[NPF_STAT_RPROC_LOG], st[NPF_STAT_RPROC_NORM]); - - printf("Fragmentation:\n" - "\t%"PRIu64" fragments\n\t%"PRIu64" reassembled\n" - "\t%"PRIu64" failed reassembly\n\n", - st[NPF_STAT_FRAGMENTS], st[NPF_STAT_REASSEMBLY], - st[NPF_STAT_REASSFAIL]); - - printf("Unexpected error cases:\n\t%"PRIu64"\n", st[NPF_STAT_ERROR]); + for (unsigned i = 0; i < __arraycount(stats); i++) { + const char *sname = stats[i].name; + int sidx = stats[i].index; + + if (sidx == -1) { + printf("%s:\n", sname); + } else { + printf("\t%"PRIu64" %s\n", st[sidx], sname); + } + } free(st); return 0; @@ -243,7 +259,7 @@ npfctl_print_error(const nl_error_t *ne) } } -static void +__dead static void npfctl_table(int fd, char **argv) { static const struct tblops_s { Index: src/usr.sbin/npf/npfctl/npf_disassemble.c diff -u src/usr.sbin/npf/npfctl/npf_disassemble.c:1.3.2.5 src/usr.sbin/npf/npfctl/npf_disassemble.c:1.3.2.6 --- src/usr.sbin/npf/npfctl/npf_disassemble.c:1.3.2.5 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npf_disassemble.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_disassemble.c,v 1.3.2.5 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npf_disassemble.c,v 1.3.2.6 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_disassemble.c,v 1.3.2.5 2012/07/16 22:13:28 riz Exp $"); +__RCSID("$NetBSD: npf_disassemble.c,v 1.3.2.6 2012/07/25 20:45:23 jdc Exp $"); #include <stdio.h> #include <stdlib.h> @@ -232,7 +232,7 @@ npfctl_ncode_operand(nc_inf_t *ni, char snprintf(buf, bufsiz, "id=%d", op); break; - case NPF_OPERAND_ICMP4_TYPE_CODE: { + case NPF_OPERAND_ICMP_TYPE_CODE: { uint8_t type = (op & 31) ? op >> 8 : 0; uint8_t code = (op & 30) ? op & 0xff : 0; Index: src/usr.sbin/npf/npfctl/npf_ncgen.c diff -u src/usr.sbin/npf/npfctl/npf_ncgen.c:1.7.2.4 src/usr.sbin/npf/npfctl/npf_ncgen.c:1.7.2.5 --- src/usr.sbin/npf/npfctl/npf_ncgen.c:1.7.2.4 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npf_ncgen.c Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ncgen.c,v 1.7.2.4 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npf_ncgen.c,v 1.7.2.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_ncgen.c,v 1.7.2.4 2012/07/16 22:13:28 riz Exp $"); +__RCSID("$NetBSD: npf_ncgen.c,v 1.7.2.5 2012/07/25 20:45:23 jdc Exp $"); #include <stdlib.h> #include <stddef.h> @@ -343,6 +343,26 @@ npfctl_gennc_icmp(nc_ctx_t *ctx, int typ } /* + * npfctl_gennc_icmp6: fragment to match ICMPV6 type and code. + */ +void +npfctl_gennc_icmp6(nc_ctx_t *ctx, int type, int code) +{ + uint32_t *nc = npfctl_ncgen_getptr(ctx, 4 /* words */); + + /* OP, code, type (2 words) */ + *nc++ = NPF_OPCODE_ICMP6; + *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); + + /* + 4 words. */ + npfctl_ncgen_putptr(ctx, nc); +} + +/* * npfctl_gennc_tbl: fragment to match IPv4 source/destination address of * the packet against table specified by ID. */ Index: src/usr.sbin/npf/npfctl/npf_parse.y diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.4 src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.5 --- src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.4 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npf_parse.y Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_parse.y,v 1.3.2.4 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npf_parse.y,v 1.3.2.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -120,7 +120,8 @@ yyerror(const char *fmt, ...) %token TO %token TREE %token TYPE -%token ICMP +%token <num> ICMP +%token <num> ICMP6 %token <num> HEX %token <str> IDENTIFIER @@ -471,6 +472,11 @@ opt_proto $$.op_proto = IPPROTO_ICMP; $$.op_opts = $3; } + | PROTO ICMP6 icmp_type_and_code + { + $$.op_proto = IPPROTO_ICMPV6; + $$.op_opts = $3; + } | PROTO some_name { $$.op_proto = npfctl_protono($2); @@ -633,24 +639,24 @@ port icmp_type_and_code : ICMPTYPE icmp_type { - $$ = npfctl_parse_icmp($2, -1); + $$ = npfctl_parse_icmp($<num>0, $2, -1); } | ICMPTYPE icmp_type CODE NUM { - $$ = npfctl_parse_icmp($2, $4); + $$ = npfctl_parse_icmp($<num>0, $2, $4); } | ICMPTYPE icmp_type CODE IDENTIFIER { - $$ = npfctl_parse_icmp($2, npfctl_icmpcode($2, $4)); + $$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, $4)); } | ICMPTYPE icmp_type CODE VAR_ID { char *s = npfvar_expand_string(npfvar_lookup($4)); - $$ = npfctl_parse_icmp($2, npfctl_icmpcode($2, s)); + $$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, s)); } | { - $$ = npfctl_parse_icmp(-1, -1); + $$ = npfctl_parse_icmp($<num>0, -1, -1); } ; @@ -675,11 +681,11 @@ tcp_flags icmp_type : NUM { $$ = $1; } - | IDENTIFIER { $$ = npfctl_icmptype($1); } + | IDENTIFIER { $$ = npfctl_icmptype($<num>-1, $1); } | VAR_ID { char *s = npfvar_expand_string(npfvar_lookup($1)); - $$ = npfctl_icmptype(s); + $$ = npfctl_icmptype($<num>-1, s); } ; Index: src/usr.sbin/npf/npfctl/npf_scan.l diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.2 src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.3 --- src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.2 Thu Jul 5 17:48:44 2012 +++ src/usr.sbin/npf/npfctl/npf_scan.l Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_scan.l,v 1.1.2.2 2012/07/05 17:48:44 riz Exp $ */ +/* $NetBSD: npf_scan.l,v 1.1.2.3 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -85,7 +85,9 @@ inet return INET; proto return PROTO; family return FAMILY; tcp return TCP; -icmp return ICMP; +icmp { yylval.num = IPPROTO_ICMP; return ICMP; } +ipv6-icmp { yylval.num = IPPROTO_ICMPV6; return ICMP6; } +\"ipv6-icmp\" { yylval.num = IPPROTO_ICMPV6; return ICMP6; } return-rst return RETURNRST; return-icmp return RETURNICMP; return return RETURN; Index: src/usr.sbin/npf/npfctl/npf_var.h diff -u src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.1 src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.2 --- src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.1 Tue Jun 26 00:07:20 2012 +++ src/usr.sbin/npf/npfctl/npf_var.h Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_var.h,v 1.1.2.1 2012/06/26 00:07:20 riz Exp $ */ +/* $NetBSD: npf_var.h,v 1.1.2.2 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -48,11 +48,12 @@ #define NPFVAR_ICMP 8 #define NPFVAR_PROC_OP 9 #define NPFVAR_MODULE_ARG 10 +#define NPFVAR_ICMP6 11 #ifdef _NPFVAR_PRIVATE static const char *npfvar_types[ ] = { "string", "identifier", "var_id", "num", "table", "fam", "port_range", - "tcpflag", "icmp", "proc_op", "module_arg" + "tcpflag", "icmp", "proc_op", "module_arg", "icmp6" }; #endif Index: src/usr.sbin/npf/npfctl/npfctl.h diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.4 src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.5 --- src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.4 Mon Jul 16 22:13:28 2012 +++ src/usr.sbin/npf/npfctl/npfctl.h Wed Jul 25 20:45:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.h,v 1.11.2.4 2012/07/16 22:13:28 riz Exp $ */ +/* $NetBSD: npfctl.h,v 1.11.2.5 2012/07/25 20:45:23 jdc Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -99,13 +99,12 @@ void npfctl_print_error(const nl_error_ bool npfctl_table_exists_p(const char *); int npfctl_protono(const char *); in_port_t npfctl_portno(const char *); -uint8_t npfctl_icmpcode(uint8_t, const char *); -uint8_t npfctl_icmptype(const char *); +uint8_t npfctl_icmpcode(int, uint8_t, const char *); +uint8_t npfctl_icmptype(int, const char *); unsigned long npfctl_find_ifindex(const char *); 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(int, int); +npfvar_t * npfctl_parse_icmp(int, 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 *); @@ -125,6 +124,7 @@ typedef struct nc_ctx nc_ctx_t; #define NC_MATCH_TCP 0x04 #define NC_MATCH_UDP 0x08 #define NC_MATCH_ICMP 0x10 +#define NC_MATCH_ICMP6 0x20 nc_ctx_t * npfctl_ncgen_create(void); void * npfctl_ncgen_complete(nc_ctx_t *, size_t *); @@ -139,6 +139,7 @@ void npfctl_gennc_v6cidr(nc_ctx_t *, in const npf_netmask_t); void npfctl_gennc_ports(nc_ctx_t *, int, in_port_t, in_port_t); void npfctl_gennc_icmp(nc_ctx_t *, int, int); +void npfctl_gennc_icmp6(nc_ctx_t *, int, int); void npfctl_gennc_tbl(nc_ctx_t *, int, u_int); void npfctl_gennc_tcpfl(nc_ctx_t *, uint8_t, uint8_t); void npfctl_gennc_proto(nc_ctx_t *ctx, uint8_t, uint8_t); Index: src/usr.sbin/npf/npftest/npfstream.c diff -u src/usr.sbin/npf/npftest/npfstream.c:1.1.2.2 src/usr.sbin/npf/npftest/npfstream.c:1.1.2.3 --- src/usr.sbin/npf/npftest/npfstream.c:1.1.2.2 Tue Jun 26 00:07:17 2012 +++ src/usr.sbin/npf/npftest/npfstream.c Wed Jul 25 20:45:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfstream.c,v 1.1.2.2 2012/06/26 00:07:17 riz Exp $ */ +/* $NetBSD: npfstream.c,v 1.1.2.3 2012/07/25 20:45:24 jdc Exp $ */ /* * NPF stream processor. @@ -67,7 +67,7 @@ process_tcpip(const void *data, size_t l forw = (initial_ip.s_addr == ip->ip_src.s_addr); packetno = forw ? ++snd_packet_no : ++rcv_packet_no; - int64_t result[9]; + int64_t result[11]; memset(result, 0, sizeof(result)); len = ntohs(ip->ip_len); @@ -76,7 +76,7 @@ process_tcpip(const void *data, size_t l fprintf(fp, "%s%2x %5d %3d %11u %11u %11u %11u %12lx", forw ? ">" : "<", (th->th_flags & (TH_SYN | TH_ACK | TH_FIN)), packetno, error, (u_int)seq, (u_int)ntohl(th->th_ack), - (u_int)(seq + tcpdlen), ntohs(th->th_win), (uintptr_t)result[0]); + tcpdlen, ntohs(th->th_win), (uintptr_t)result[0]); for (unsigned i = 1; i < __arraycount(result); i++) { fprintf(fp, "%11" PRIu64 " ", result[i]); @@ -101,9 +101,12 @@ process_stream(const char *input, const if (fp == NULL) { err(EXIT_FAILURE, "fopen"); } - fprintf(fp, "# %5s %3s %11s %11s %11s %11s %11s %11s %11s\n", + fprintf(fp, "#FL %5s %3s %11s %11s %11s %11s %11s %11s %11s " + "%11s %11s %11s %5s %11s %11s %11s %5s\n", "No", "Err", "Seq", "Ack", "TCP Len", "Win", - "Stream", "RetVal", "State"); + "Stream", "RetVal", "State", + "F.END", "F.MAXEND", "F.MAXWIN", "F.WSC", + "T.END", "T.MAXEND", "T.MAXWIN", "T.WSC"); while (pcap_next_ex(pcap, &phdr, &data) > 0) { if (phdr->len != phdr->caplen) { warnx("process_stream: truncated packet"); Index: src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c diff -u src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.1.2.2 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.1.2.3 --- src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.1.2.2 Tue Jun 26 00:07:19 2012 +++ src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c Wed Jul 25 20:45:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_test_subr.c,v 1.1.2.2 2012/06/26 00:07:19 riz Exp $ */ +/* $NetBSD: npf_test_subr.c,v 1.1.2.3 2012/07/25 20:45:24 jdc Exp $ */ /* * NPF initialisation and handler routines. @@ -65,10 +65,12 @@ npf_test_handlepkt(const void *data, siz result[i++] = fstate->nst_end; result[i++] = fstate->nst_maxend; result[i++] = fstate->nst_maxwin; + result[i++] = fstate->nst_wscale; result[i++] = tstate->nst_end; result[i++] = tstate->nst_maxend; result[i++] = tstate->nst_maxwin; + result[i++] = tstate->nst_wscale; return 0; }