[PATCH] Add IP_MINTTL socket option

Hasso Tepper hasso at estpak.ee
Mon Apr 2 03:20:11 PDT 2007


# HG changeset patch
# User Hasso Tepper <hasso at estpak.ee>
# Date 1175495151 -10800
# Node ID 90fca5ea7a10a682aed3b5238f44ad90d7cca115
# Parent  bb9e64772dc17d5e6155ed7d2ad98545cd65d794
Add IP_MINTTL socket option.

Used to set the minimum acceptable TTL a packet must have when received on
a socket.  All packets with a lower TTL are silently dropped.  Works on
already connected/connecting and listening sockets for RAW/UDP/TCP.

It allows to implement security mechanisms described in RFC3682 (GTSM).

Obtained from FreeBSD.

diff -r bb9e64772dc1 -r 90fca5ea7a10 share/man/man4/ip.4
--- a/share/man/man4/ip.4	Mon Apr 02 09:23:21 2007 +0300
+++ b/share/man/man4/ip.4	Mon Apr 02 09:25:51 2007 +0300
@@ -114,6 +114,13 @@ setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, 
 setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
 .Ed
 .Pp
+.Dv IP_MINTTL
+may be used to set the minimum acceptable TTL a packet must have when
+received on a socket.
+All packets with a lower TTL are silently dropped.
+Works on already connected/connecting and listening sockets for RAW/UDP/TCP.
+It allows to implement security mechanisms described in RFC3682 (GTSM).
+.Pp
 If the
 .Dv IP_RECVDSTADDR
 option is enabled on a
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/in.h
--- a/sys/netinet/in.h	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/in.h	Mon Apr 02 09:25:51 2007 +0300
@@ -356,6 +356,7 @@ struct sockaddr_in {
 #define	IP_DUMMYNET_GET		64   /* get entire dummynet pipes */
 
 #define	IP_RECVTTL		65   /* bool; receive IP TTL w/dgram */
+#define	IP_MINTTL		66   /* minimum TTL for packet or drop */
 
 /*
  * Defaults and limits for options
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/in_pcb.h	Mon Apr 02 09:25:51 2007 +0300
@@ -196,6 +196,7 @@ struct inpcb {
 #define	INP_IPV6	0x2
 	u_char	inp_ip_ttl;		/* time to live proto */
 	u_char	inp_ip_p;		/* protocol proto */
+	u_char	inp_ip_minttl;		/* minimum TTL or drop */
 
 	/* protocol dependent part; options */
 	struct {
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/ip_output.c	Mon Apr 02 09:25:51 2007 +0300
@@ -1409,6 +1409,7 @@ ip_ctloutput(struct socket *so, struct s
 
 		case IP_TOS:
 		case IP_TTL:
+		case IP_MINTTL:
 		case IP_RECVOPTS:
 		case IP_RECVRETOPTS:
 		case IP_RECVDSTADDR:
@@ -1427,6 +1428,12 @@ ip_ctloutput(struct socket *so, struct s
 
 			case IP_TTL:
 				inp->inp_ip_ttl = optval;
+				break;
+			case IP_MINTTL:
+				if (optval > 0 && optval <= MAXTTL)
+					inp->inp_ip_minttl = optval;
+				else
+					error = EINVAL;
 				break;
 #define	OPTSET(bit) \
 	if (optval) \
@@ -1543,6 +1550,7 @@ ip_ctloutput(struct socket *so, struct s
 
 		case IP_TOS:
 		case IP_TTL:
+		case IP_MINTTL:
 		case IP_RECVOPTS:
 		case IP_RECVRETOPTS:
 		case IP_RECVDSTADDR:
@@ -1558,6 +1566,9 @@ ip_ctloutput(struct socket *so, struct s
 
 			case IP_TTL:
 				optval = inp->inp_ip_ttl;
+				break;
+			case IP_MINTTL:
+				optval = inp->inp_ip_minttl;
 				break;
 
 #define	OPTBIT(bit)	(inp->inp_flags & bit ? 1 : 0)
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/raw_ip.c	Mon Apr 02 09:25:51 2007 +0300
@@ -225,6 +225,12 @@ rip_input(struct mbuf *m, ...)
 		/* do not inject data to pcb */
 	} else
 #endif /*FAST_IPSEC*/
+	/* Check the minimum TTL for socket. */
+	if (last && last->inp_ip_minttl && last->inp_ip_minttl > ip->ip_ttl) {
+		m_freem(opts);
+		ipstat.ips_delivered--;
+	}
+
 	if (last) {
 		if (last->inp_flags & INP_CONTROLOPTS ||
 		    last->inp_socket->so_options & SO_TIMESTAMP)
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/tcp_input.c	Mon Apr 02 09:25:51 2007 +0300
@@ -804,6 +804,9 @@ findpcb:
 			goto drop;
 	}
 #endif
+	/* Check the minimum TTL for socket. */
+	if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
+		goto drop;
 
 	tp = intotcpcb(inp);
 	if (tp == NULL) {
diff -r bb9e64772dc1 -r 90fca5ea7a10 sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c	Mon Apr 02 09:23:21 2007 +0300
+++ b/sys/netinet/udp_usrreq.c	Mon Apr 02 09:25:51 2007 +0300
@@ -474,6 +474,11 @@ udp_input(struct mbuf *m, ...)
 	if (ipsec4_in_reject(m, inp))
 		goto bad;
 #endif /*FAST_IPSEC*/
+	/*
+	 * Check the minimum TTL for socket.
+	 */
+	if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
+		goto bad;
 
 	/*
 	 * Construct sockaddr format source address.





More information about the Submit mailing list