Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src teach npf ipv6-icmp



details:   https://anonhg.NetBSD.org/src/rev/82153a655b9f
branches:  trunk
changeset: 780306:82153a655b9f
user:      spz <spz%NetBSD.org@localhost>
date:      Thu Jul 19 21:52:29 2012 +0000

description:
teach npf ipv6-icmp
reviewed by rmind@

diffstat:

 sys/net/npf/npf.h                     |   10 +-
 sys/net/npf/npf_alg_icmp.c            |  139 ++++++++++++++++++++---------
 sys/net/npf/npf_impl.h                |    3 +-
 sys/net/npf/npf_inet.c                |   13 +-
 sys/net/npf/npf_instr.c               |   35 +++++++-
 sys/net/npf/npf_ncode.h               |   13 ++-
 sys/net/npf/npf_processor.c           |   10 +-
 sys/net/npf/npf_session.c             |   27 ++++-
 usr.sbin/npf/npfctl/npf_build.c       |   19 +++-
 usr.sbin/npf/npfctl/npf_data.c        |  158 ++++++++++++++++++++++++---------
 usr.sbin/npf/npfctl/npf_disassemble.c |    6 +-
 usr.sbin/npf/npfctl/npf_ncgen.c       |   24 ++++-
 usr.sbin/npf/npfctl/npf_parse.y       |   24 +++-
 usr.sbin/npf/npfctl/npf_scan.l        |    6 +-
 usr.sbin/npf/npfctl/npf_var.h         |    5 +-
 usr.sbin/npf/npfctl/npfctl.h          |   11 +-
 16 files changed, 371 insertions(+), 132 deletions(-)

diffs (truncated from 944 to 300 lines):

diff -r a9c0bce0983b -r 82153a655b9f sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Thu Jul 19 21:08:42 2012 +0000
+++ b/sys/net/npf/npf.h Thu Jul 19 21:52:29 2012 +0000
@@ -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 @@
 #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 @@
        } 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;
 
diff -r a9c0bce0983b -r 82153a655b9f sys/net/npf/npf_alg_icmp.c
--- a/sys/net/npf/npf_alg_icmp.c        Thu Jul 19 21:08:42 2012 +0000
+++ b/sys/net/npf/npf_alg_icmp.c        Thu Jul 19 21:52:29 2012 +0000
@@ -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 @@
 #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 @@
 static bool
 npf_icmp_uniqid(const int type, npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr)
 {
-       struct icmp *ic;
-       u_int offby;
+       struct icmp      *ic;
+       struct icmp6_hdr *ic6;
+       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;
+       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:
+                       break;
                }
-               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;
+               /* 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 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;
+               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;
 }
 
diff -r a9c0bce0983b -r 82153a655b9f sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h    Thu Jul 19 21:08:42 2012 +0000
+++ b/sys/net/npf/npf_impl.h    Thu Jul 19 21:52:29 2012 +0000
@@ -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_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. */
diff -r a9c0bce0983b -r 82153a655b9f sys/net/npf/npf_inet.c
--- a/sys/net/npf/npf_inet.c    Thu Jul 19 21:08:42 2012 +0000
+++ b/sys/net/npf/npf_inet.c    Thu Jul 19 21:52:29 2012 +0000
@@ -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 @@
        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 @@
                (void)npf_fetch_udp(npc, nbuf, n_ptr);
                break;
        case IPPROTO_ICMP:
+       case IPPROTO_ICMPV6:
                (void)npf_fetch_icmp(npc, nbuf, n_ptr);
                break;
        }
diff -r a9c0bce0983b -r 82153a655b9f sys/net/npf/npf_instr.c
--- a/sys/net/npf/npf_instr.c   Thu Jul 19 21:08:42 2012 +0000
+++ b/sys/net/npf/npf_instr.c   Thu Jul 19 21:52:29 2012 +0000
@@ -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_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;
+               }



Home | Main Index | Thread Index | Old Index