From e5ff19c718a7f8106479296f9aa531519e06c0f7 Mon Sep 17 00:00:00 2001 From: jca Date: Mon, 27 Jun 2016 16:33:48 +0000 Subject: [PATCH] Implement IPV6_MINHOPCOUNT support. 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 | 12 ++++++++++-- sys/kern/kern_pledge.c | 3 ++- sys/netinet/in_pcb.h | 3 ++- sys/netinet/tcp_input.c | 16 +++++++++++++--- sys/netinet6/in6.h | 3 ++- sys/netinet6/ip6_output.c | 15 ++++++++++++++- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index f378d8d7c03..da89a961f31 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -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 diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 7130310e04e..1a3a9e51395 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -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 @@ -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: diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index cdf3393c2fa..db841e327ed 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -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; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 688d12d412b..83f4a7e2f1b 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -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) diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index dc72a346da8..8ba57fecae5 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -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 */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index d3936180d7c..3dbf220bf48 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -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; -- 2.20.1