Implement IPV6_MINHOPCOUNT support.
authorjca <jca@openbsd.org>
Mon, 27 Jun 2016 16:33:48 +0000 (16:33 +0000)
committerjca <jca@openbsd.org>
Mon, 27 Jun 2016 16:33:48 +0000 (16:33 +0000)
Useful to implement GTSM support in daemons such as bgpd(8). Diff from
2013 revived by renato@.  Input from bluhm@, ok bluhm@ deraadt@

share/man/man4/ip6.4
sys/kern/kern_pledge.c
sys/netinet/in_pcb.h
sys/netinet/tcp_input.c
sys/netinet6/in6.h
sys/netinet6/ip6_output.c

index f378d8d..da89a96 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ip6.4,v 1.37 2016/05/19 21:02:21 jmc Exp $
+.\"    $OpenBSD: ip6.4,v 1.38 2016/06/27 16:33:48 jca Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -26,7 +26,7 @@
 .\" 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.
-.Dd $Mdocdate: May 19 2016 $
+.Dd $Mdocdate: June 27 2016 $
 .Dt IP6 4
 .Os
 .Sh NAME
@@ -144,6 +144,14 @@ The following socket options are supported:
 Get or set the default hop limit header field for outgoing unicast
 datagrams sent on this socket.
 A value of \-1 resets to the default value.
+.It Dv IPV6_MINHOPCOUNT Fa "int *"
+Get or set the minimum hop limit header field for incoming unicast
+datagrams received on this
+.Dv SOCK_STREAM
+socket.
+This can be used to implement the
+.Em Generalized TTL Security Mechanism (GTSM)
+according to RFC 5082.
 .It Dv IPV6_MULTICAST_IF Fa "u_int *"
 Get or set the interface from which multicast packets will be sent.
 For hosts with multiple interfaces, each multicast transmission is sent
index 7130310..1a3a9e5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_pledge.c,v 1.170 2016/06/07 01:31:54 tedu Exp $  */
+/*     $OpenBSD: kern_pledge.c,v 1.171 2016/06/27 16:33:48 jca Exp $   */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -1434,6 +1434,7 @@ pledge_sockopt(struct proc *p, int set, int level, int optname)
                switch (optname) {
                case IPV6_TCLASS:
                case IPV6_UNICAST_HOPS:
+               case IPV6_MINHOPCOUNT:
                case IPV6_RECVHOPLIMIT:
                case IPV6_PORTRANGE:
                case IPV6_RECVPKTINFO:
index cdf3393..db841e3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.h,v 1.99 2016/06/18 10:36:13 vgross Exp $      */
+/*     $OpenBSD: in_pcb.h,v 1.100 2016/06/27 16:33:48 jca Exp $        */
 /*     $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $     */
 
 /*
@@ -132,6 +132,7 @@ struct inpcb {
 #define SL_ESP_NETWORK    2             /* ESP network (encapsulation) level */
 #define SL_IPCOMP         3             /* Compression level */
        u_char  inp_ip_minttl;          /* minimum TTL or drop */
+#define inp_ip6_minhlim inp_ip_minttl  /* minimum Hop Limit or drop */
 #define        inp_flowinfo    inp_hu.hu_ipv6.ip6_flow
 
        int     inp_cksum6;
index 688d12d..83f4a7e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_input.c,v 1.321 2016/06/27 15:59:51 bluhm Exp $   */
+/*     $OpenBSD: tcp_input.c,v 1.322 2016/06/27 16:33:48 jca Exp $     */
 /*     $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $  */
 
 /*
@@ -633,8 +633,18 @@ findpcb:
        KASSERT(intotcpcb(inp) == NULL || intotcpcb(inp)->t_inpcb == inp);
 
        /* Check the minimum TTL for socket. */
-       if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
-               goto drop;
+       switch (af) {
+       case AF_INET:
+               if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
+                       goto drop;
+#ifdef INET6
+       case AF_INET6:
+               if (inp->inp_ip6_minhlim &&
+                   inp->inp_ip6_minhlim > ip6->ip6_hlim)
+                       goto drop;
+               break;
+#endif
+       }
 
        tp = intotcpcb(inp);
        if (tp == NULL)
index dc72a34..8ba57fe 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6.h,v 1.89 2016/06/01 11:11:44 jca Exp $    */
+/*     $OpenBSD: in6.h,v 1.90 2016/06/27 16:33:48 jca Exp $    */
 /*     $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $    */
 
 /*
@@ -346,6 +346,7 @@ struct route_in6 {
 #define IPV6_PIPEX             63   /* bool; using PIPEX */
 
 #define IPV6_RECVDSTPORT       64   /* bool; receive IP dst port w/dgram */
+#define IPV6_MINHOPCOUNT       65   /* int; minimum recv hop limit */
 
 #define IPV6_RTABLE            0x1021  /* int; routing table, see SO_RTABLE */
 
index d393618..3dbf220 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip6_output.c,v 1.209 2016/06/15 13:49:43 florian Exp $        */
+/*     $OpenBSD: ip6_output.c,v 1.210 2016/06/27 16:33:48 jca Exp $    */
 /*     $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $    */
 
 /*
@@ -1149,6 +1149,7 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname,
                                }
                                /* FALLTHROUGH */
                        case IPV6_UNICAST_HOPS:
+                       case IPV6_MINHOPCOUNT:
                        case IPV6_HOPLIMIT:
 
                        case IPV6_RECVPKTINFO:
@@ -1174,6 +1175,14 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname,
                                                inp->inp_hops = optval;
                                        }
                                        break;
+
+                               case IPV6_MINHOPCOUNT:
+                                       if (optval < 0 || optval > 255)
+                                               error = EINVAL;
+                                       else
+                                               inp->inp_ip6_minhlim = optval;
+                                       break;
+
 #define OPTSET(bit) \
 do { \
        if (optval) \
@@ -1477,6 +1486,10 @@ do { \
                                        optval = inp->inp_hops;
                                        break;
 
+                               case IPV6_MINHOPCOUNT:
+                                       optval = inp->inp_ip6_minhlim;
+                                       break;
+
                                case IPV6_RECVPKTINFO:
                                        optval = OPTBIT(IN6P_PKTINFO);
                                        break;