Module Name: src
Committed By: spz
Date: Thu Jul 19 21:52:29 UTC 2012
Modified Files:
src/sys/net/npf: npf.h npf_alg_icmp.c npf_impl.h npf_inet.c npf_instr.c
npf_ncode.h npf_processor.c npf_session.c
src/usr.sbin/npf/npfctl: npf_build.c npf_data.c npf_disassemble.c
npf_ncgen.c npf_parse.y npf_scan.l npf_var.h npfctl.h
Log Message:
teach npf ipv6-icmp
reviewed by rmind@
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/net/npf/npf.h
cvs rdiff -u -r1.10 -r1.11 src/sys/net/npf/npf_alg_icmp.c
cvs rdiff -u -r1.18 -r1.19 src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.14 -r1.15 src/sys/net/npf/npf_inet.c
cvs rdiff -u -r1.13 -r1.14 src/sys/net/npf/npf_instr.c
cvs rdiff -u -r1.9 -r1.10 src/sys/net/npf/npf_ncode.h
cvs rdiff -u -r1.11 -r1.12 src/sys/net/npf/npf_processor.c
cvs rdiff -u -r1.15 -r1.16 src/sys/net/npf/npf_session.c
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/npf/npfctl/npf_build.c
cvs rdiff -u -r1.15 -r1.16 src/usr.sbin/npf/npfctl/npf_data.c
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/npf/npfctl/npf_disassemble.c
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npf_ncgen.c
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/npf/npfctl/npf_parse.y
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/npf/npfctl/npf_var.h
cvs rdiff -u -r1.17 -r1.18 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.h
diff -u src/sys/net/npf/npf.h:1.19 src/sys/net/npf/npf.h:1.20
--- src/sys/net/npf/npf.h:1.19 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf.h Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.h,v 1.19 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.20 2012/07/19 21:52:29 spz 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.10 src/sys/net/npf/npf_alg_icmp.c:1.11
--- src/sys/net/npf/npf_alg_icmp.c:1.10 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf_alg_icmp.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_alg_icmp.c,v 1.10 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf_alg_icmp.c,v 1.11 2012/07/19 21:52:29 spz 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.10 2012/07/15 00:23:00 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.11 2012/07/19 21:52:29 spz 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.18 src/sys/net/npf/npf_impl.h:1.19
--- src/sys/net/npf/npf_impl.h:1.18 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf_impl.h Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_impl.h,v 1.18 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf_impl.h,v 1.19 2012/07/19 21:52:29 spz 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.14 src/sys/net/npf/npf_inet.c:1.15
--- src/sys/net/npf/npf_inet.c:1.14 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf_inet.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_inet.c,v 1.14 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf_inet.c,v 1.15 2012/07/19 21:52:29 spz 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.14 2012/07/15 00:23:00 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.15 2012/07/19 21:52:29 spz Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -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_instr.c
diff -u src/sys/net/npf/npf_instr.c:1.13 src/sys/net/npf/npf_instr.c:1.14
--- src/sys/net/npf/npf_instr.c:1.13 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf_instr.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_instr.c,v 1.13 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf_instr.c,v 1.14 2012/07/19 21:52:29 spz 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.13 2012/07/15 00:23:00 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.14 2012/07/19 21:52:29 spz 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.9 src/sys/net/npf/npf_ncode.h:1.10
--- src/sys/net/npf/npf_ncode.h:1.9 Sun Jul 1 23:21:06 2012
+++ src/sys/net/npf/npf_ncode.h Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_ncode.h,v 1.9 2012/07/01 23:21:06 rmind Exp $ */
+/* $NetBSD: npf_ncode.h,v 1.10 2012/07/19 21:52:29 spz 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.11 src/sys/net/npf/npf_processor.c:1.12
--- src/sys/net/npf/npf_processor.c:1.11 Sun Jul 1 23:21:06 2012
+++ src/sys/net/npf/npf_processor.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_processor.c,v 1.11 2012/07/01 23:21:06 rmind Exp $ */
+/* $NetBSD: npf_processor.c,v 1.12 2012/07/19 21:52:29 spz 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.11 2012/07/01 23:21:06 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_processor.c,v 1.12 2012/07/19 21:52:29 spz 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_session.c
diff -u src/sys/net/npf/npf_session.c:1.15 src/sys/net/npf/npf_session.c:1.16
--- src/sys/net/npf/npf_session.c:1.15 Sun Jul 15 00:23:00 2012
+++ src/sys/net/npf/npf_session.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_session.c,v 1.15 2012/07/15 00:23:00 rmind Exp $ */
+/* $NetBSD: npf_session.c,v 1.16 2012/07/19 21:52:29 spz 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.15 2012/07/15 00:23:00 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.16 2012/07/19 21:52:29 spz 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/usr.sbin/npf/npfctl/npf_build.c
diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.11 src/usr.sbin/npf/npfctl/npf_build.c:1.12
--- src/usr.sbin/npf/npfctl/npf_build.c:1.11 Sun Jul 15 00:22:58 2012
+++ src/usr.sbin/npf/npfctl/npf_build.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_build.c,v 1.11 2012/07/15 00:22:58 rmind Exp $ */
+/* $NetBSD: npf_build.c,v 1.12 2012/07/19 21:52:29 spz Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.11 2012/07/15 00:22:58 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.12 2012/07/19 21:52:29 spz 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.15 src/usr.sbin/npf/npfctl/npf_data.c:1.16
--- src/usr.sbin/npf/npfctl/npf_data.c:1.15 Sun Jul 15 00:22:59 2012
+++ src/usr.sbin/npf/npfctl/npf_data.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_data.c,v 1.15 2012/07/15 00:22:59 rmind Exp $ */
+/* $NetBSD: npf_data.c,v 1.16 2012/07/19 21:52:29 spz Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_data.c,v 1.15 2012/07/15 00:22:59 rmind Exp $");
+__RCSID("$NetBSD: npf_data.c,v 1.16 2012/07/19 21:52:29 spz Exp $");
#include <sys/types.h>
#include <sys/null.h>
@@ -41,6 +41,8 @@ __RCSID("$NetBSD: npf_data.c,v 1.15 2012
#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;
- 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/npf_disassemble.c
diff -u src/usr.sbin/npf/npfctl/npf_disassemble.c:1.7 src/usr.sbin/npf/npfctl/npf_disassemble.c:1.8
--- src/usr.sbin/npf/npfctl/npf_disassemble.c:1.7 Sun Jul 15 00:22:59 2012
+++ src/usr.sbin/npf/npfctl/npf_disassemble.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_disassemble.c,v 1.7 2012/07/15 00:22:59 rmind Exp $ */
+/* $NetBSD: npf_disassemble.c,v 1.8 2012/07/19 21:52:29 spz Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_disassemble.c,v 1.7 2012/07/15 00:22:59 rmind Exp $");
+__RCSID("$NetBSD: npf_disassemble.c,v 1.8 2012/07/19 21:52:29 spz 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.12 src/usr.sbin/npf/npfctl/npf_ncgen.c:1.13
--- src/usr.sbin/npf/npfctl/npf_ncgen.c:1.12 Sun Jul 15 00:22:59 2012
+++ src/usr.sbin/npf/npfctl/npf_ncgen.c Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_ncgen.c,v 1.12 2012/07/15 00:22:59 rmind Exp $ */
+/* $NetBSD: npf_ncgen.c,v 1.13 2012/07/19 21:52:29 spz Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_ncgen.c,v 1.12 2012/07/15 00:22:59 rmind Exp $");
+__RCSID("$NetBSD: npf_ncgen.c,v 1.13 2012/07/19 21:52:29 spz 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.10 src/usr.sbin/npf/npfctl/npf_parse.y:1.11
--- src/usr.sbin/npf/npfctl/npf_parse.y:1.10 Sun Jul 15 00:22:59 2012
+++ src/usr.sbin/npf/npfctl/npf_parse.y Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_parse.y,v 1.10 2012/07/15 00:22:59 rmind Exp $ */
+/* $NetBSD: npf_parse.y,v 1.11 2012/07/19 21:52:29 spz 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.4 src/usr.sbin/npf/npfctl/npf_scan.l:1.5
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.4 Sun Jul 1 23:21:07 2012
+++ src/usr.sbin/npf/npfctl/npf_scan.l Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_scan.l,v 1.4 2012/07/01 23:21:07 rmind Exp $ */
+/* $NetBSD: npf_scan.l,v 1.5 2012/07/19 21:52:29 spz 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.2 src/usr.sbin/npf/npfctl/npf_var.h:1.3
--- src/usr.sbin/npf/npfctl/npf_var.h:1.2 Sun Feb 26 21:50:05 2012
+++ src/usr.sbin/npf/npfctl/npf_var.h Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_var.h,v 1.2 2012/02/26 21:50:05 christos Exp $ */
+/* $NetBSD: npf_var.h,v 1.3 2012/07/19 21:52:29 spz 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.17 src/usr.sbin/npf/npfctl/npfctl.h:1.18
--- src/usr.sbin/npf/npfctl/npfctl.h:1.17 Sun Jul 15 00:22:59 2012
+++ src/usr.sbin/npf/npfctl/npfctl.h Thu Jul 19 21:52:29 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npfctl.h,v 1.17 2012/07/15 00:22:59 rmind Exp $ */
+/* $NetBSD: npfctl.h,v 1.18 2012/07/19 21:52:29 spz 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);