# HG changeset patch
# User Hasso Tepper <[EMAIL PROTECTED]>
# 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.

Reply via email to