[PATCH] Add IP_MINTTL socket option

Hasso Tepper hasso at estpak.ee
Mon Apr 2 13:46:31 PDT 2007


On Monday 02 April 2007 Matthew Dillon wrote:
>     Looks good, except the conditionals need to be rearranged a bit to make
>     them more readable and there is also no need to check for 0.  For
>     example:
> 
> 	if (last && last->inp_ip_minttl && last->inp_ip_minttl > ip->ip_ttl) {
> 
>     Can just be:
> 
> 	if (last && ip->ip_ttl < last->inp_ip_minttl) {

Right.
 
>     The code logic in raw_ip.c doesn't look quite right.  I think you are
>     missing an 'else' clause:
> 
>         } 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--;
> +       }
> +
> 	^^^^^^ needs an else clause to chain into the unmodified code that
> 	       occurs afterwords?
> 	if (last) {

Yes, my bad. Updated version is attached.


Thanks.

-- 
Hasso Tepper
# HG changeset patch
# User Hasso Tepper <hasso at estpak.ee>
# Date 1175536105 -10800
# Node ID c6710beed361a5b212950d4a7b53b669f492e7f9
# 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 c6710beed361 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 20:48:25 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 c6710beed361 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 20:48:25 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 c6710beed361 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 20:48:25 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 c6710beed361 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 20:48:25 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 c6710beed361 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 20:48:25 2007 +0300
@@ -225,7 +225,11 @@ rip_input(struct mbuf *m, ...)
 		/* do not inject data to pcb */
 	} else
 #endif /*FAST_IPSEC*/
-	if (last) {
+	/* Check the minimum TTL for socket. */
+	if (last && ip->ip_ttl < last->inp_ip_minttl) {
+		m_freem(opts);
+		ipstat.ips_delivered--;
+	} else if (last) {
 		if (last->inp_flags & INP_CONTROLOPTS ||
 		    last->inp_socket->so_options & SO_TIMESTAMP)
 			ip_savecontrol(last, &opts, ip, m);
diff -r bb9e64772dc1 -r c6710beed361 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 20:48:25 2007 +0300
@@ -804,6 +804,9 @@ findpcb:
 			goto drop;
 	}
 #endif
+	/* Check the minimum TTL for socket. */
+	if (ip->ip_ttl < inp->inp_ip_minttl)
+		goto drop;
 
 	tp = intotcpcb(inp);
 	if (tp == NULL) {
diff -r bb9e64772dc1 -r c6710beed361 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 20:48:25 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 (ip->ip_ttl < inp->inp_ip_minttl)
+		goto bad;
 
 	/*
 	 * Construct sockaddr format source address.




More information about the Submit mailing list