[PATCH] Add IP_RECVTTL socket option support

Hasso Tepper hasso at estpak.ee
Mon Apr 2 03:35:48 PDT 2007


# HG changeset patch
# User Hasso Tepper <hasso at estpak.ee>
# Date 1175495001 -10800
# Node ID bb9e64772dc17d5e6155ed7d2ad98545cd65d794
# Parent  3a99304a032fccb41f8423112e3274bf329d7d96
Add IP_RECVTTL socket option support.

When set, userland receives the incoming packet's TTL as ancillary data
with recvmsg(2) call. It allows to implement security mechanisms described
in RFC3682 (GTSM).

Obtained from FreeBSD.

diff -r 3a99304a032f -r bb9e64772dc1 share/man/man4/ip.4
--- a/share/man/man4/ip.4	Sun Apr 01 22:58:14 2007 +0300
+++ b/share/man/man4/ip.4	Mon Apr 02 09:23:21 2007 +0300
@@ -137,6 +137,28 @@ cmsg_type = IP_RECVDSTADDR
 cmsg_type = IP_RECVDSTADDR
 .Ed
 .Pp
+If the
+.Dv IP_RECVTTL
+option is enabled on a
+.Dv SOCK_DGRAM
+socket, the
+.Xr recvmsg 2
+call will return the
+.Tn IP
+.Tn TTL
+(time to live) field for a
+.Tn UDP
+datagram.
+The msg_control field in the msghdr structure points to a buffer
+that contains a cmsghdr structure followed by the
+.Tn TTL .
+The cmsghdr fields have the following values:
+.Bd -literal
+cmsg_len = sizeof(u_char)
+cmsg_level = IPPROTO_IP
+cmsg_type = IP_RECVTTL
+.Ed
+.Pp
 .Dv IP_PORTRANGE
 may be used to set the port range used for selecting a local port number
 on a socket with an unspecified (zero) port number.
diff -r 3a99304a032f -r bb9e64772dc1 sys/netinet/in.h
--- a/sys/netinet/in.h	Sun Apr 01 22:58:14 2007 +0300
+++ b/sys/netinet/in.h	Mon Apr 02 09:23:21 2007 +0300
@@ -355,6 +355,8 @@ struct sockaddr_in {
 #define	IP_DUMMYNET_FLUSH	62   /* flush dummynet */
 #define	IP_DUMMYNET_GET		64   /* get entire dummynet pipes */
 
+#define	IP_RECVTTL		65   /* bool; receive IP TTL w/dgram */
+
 /*
  * Defaults and limits for options
  */
diff -r 3a99304a032f -r bb9e64772dc1 sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h	Sun Apr 01 22:58:14 2007 +0300
+++ b/sys/netinet/in_pcb.h	Mon Apr 02 09:23:21 2007 +0300
@@ -327,8 +327,10 @@ struct inpcbinfo {		/* XXX documentation
 #define	IN6P_RTHDRDSTOPTS	0x200000 /* receive dstoptions before rthdr */
 #define IN6P_AUTOFLOWLABEL	0x800000 /* attach flowlabel automatically */
 
+#define	INP_RECVTTL		0x80000000 /* receive incoming IP TTL */
+
 #define	INP_CONTROLOPTS		(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
-					INP_RECVIF|\
+					INP_RECVIF|INP_RECVTTL|\
 				 IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
 				 IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
 				 IN6P_AUTOFLOWLABEL)
diff -r 3a99304a032f -r bb9e64772dc1 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c	Sun Apr 01 22:58:14 2007 +0300
+++ b/sys/netinet/ip_input.c	Mon Apr 02 09:23:21 2007 +0300
@@ -2171,6 +2171,12 @@ ip_savecontrol(struct inpcb *inp, struct
 		if (*mp)
 			mp = &(*mp)->m_next;
 	}
+	if (inp->inp_flags & INP_RECVTTL) {
+		*mp = sbcreatecontrol((caddr_t) &ip->ip_ttl,
+		    sizeof(u_char), IP_RECVTTL, IPPROTO_IP);
+		if (*mp)
+			mp = &(*mp)->m_next;
+	}
 #ifdef notyet
 	/* XXX
 	 * Moving these out of udp_input() made them even more broken
diff -r 3a99304a032f -r bb9e64772dc1 sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c	Sun Apr 01 22:58:14 2007 +0300
+++ b/sys/netinet/ip_output.c	Mon Apr 02 09:23:21 2007 +0300
@@ -1413,6 +1413,7 @@ ip_ctloutput(struct socket *so, struct s
 		case IP_RECVRETOPTS:
 		case IP_RECVDSTADDR:
 		case IP_RECVIF:
+		case IP_RECVTTL:
 		case IP_FAITH:
 			error = sooptcopyin(sopt, &optval, sizeof optval,
 					    sizeof optval);
@@ -1447,6 +1448,10 @@ ip_ctloutput(struct socket *so, struct s
 
 			case IP_RECVIF:
 				OPTSET(INP_RECVIF);
+				break;
+
+			case IP_RECVTTL:
+				OPTSET(INP_RECVTTL);
 				break;
 
 			case IP_FAITH:
@@ -1541,6 +1546,7 @@ ip_ctloutput(struct socket *so, struct s
 		case IP_RECVOPTS:
 		case IP_RECVRETOPTS:
 		case IP_RECVDSTADDR:
+		case IP_RECVTTL:
 		case IP_RECVIF:
 		case IP_PORTRANGE:
 		case IP_FAITH:
@@ -1566,6 +1572,10 @@ ip_ctloutput(struct socket *so, struct s
 
 			case IP_RECVDSTADDR:
 				optval = OPTBIT(INP_RECVDSTADDR);
+				break;
+
+			case IP_RECVTTL:
+				optval = OPTBIT(INP_RECVTTL);
 				break;
 
 			case IP_RECVIF:





More information about the Submit mailing list