tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: IP_RECVTTL



At Wed, 8 Jul 2009 19:13:30 -0400,
matthew sporleder <msporleder%gmail.com@localhost> wrote:
> 
> While trying to compile liboping on netbsd I ran into a lack of
> IP_RECVTTL and noticed that freebsd did have this and a few other
> things defined in in.h:

I have the following diff in my local tree.  If it looks okay, I'll
commit it.

diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index bb7e9f7..d4f2f92 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -165,6 +165,26 @@ cmsg_len = sizeof(struct sockaddr_dl)
 cmsg_level = IPPROTO_IP
 cmsg_type = IP_RECVIF
 .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 TTL
+of the received datagram.
+The msg_control field in the msghdr structure points to a buffer
+that contains a cmsghdr structure followed by the
+.Tn TTL
+value.
+The cmsghdr fields have the following values:
+.Bd -literal
+cmsg_len = sizeof(uint8_t)
+cmsg_level = IPPROTO_IP
+cmsg_type = IP_RECVTTL
+.Ed
 .Ss MULTICAST OPTIONS
 .Tn IP
 multicasting is supported only on
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index dda7d62..3b20016 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -282,6 +282,7 @@ struct ip_opts {
 #if 1 /*IPSEC*/
 #define        IP_IPSEC_POLICY         22 /* struct; get/set security policy */
 #endif
+#define        IP_RECVTTL              23   /* bool; receive IP TTL w/dgram */
 
 /*
  * Defaults and limits for options
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 8e1d929..3c21403 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -108,8 +108,6 @@ struct inpcb {
 /* XXX should move to an UDP control block */
 #define INP_ESPINUDP           0x100   /* ESP over UDP for NAT-T */
 #define INP_ESPINUDP_NON_IKE   0x200   /* ESP over UDP for NAT-T */
-#define        INP_CONTROLOPTS         
(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
-                               INP_RECVIF)
 #define INP_ESPINUDP_ALL       (INP_ESPINUDP|INP_ESPINUDP_NON_IKE)
 #define INP_NOHEADER           0x400   /* Kernel removes IP header
                                         * before feeding a packet
@@ -118,6 +116,9 @@ struct inpcb {
                                         * not supply an IP header.
                                         * Cancels INP_HDRINCL.
                                         */
+#define        INP_RECVTTL             0x800   /* receive incoming IP TTL */
+#define        INP_CONTROLOPTS         
(INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\
+                               INP_RECVIF|INP_RECVTTL)
 
 #define        sotoinpcb(so)           ((struct inpcb *)(so)->so_pcb)
 
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 5a33fcc..7e0b77e 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -2118,6 +2118,12 @@ ip_savecontrol(struct inpcb *inp, struct mbuf **mp, 
struct ip *ip,
                if (*mp)
                        mp = &(*mp)->m_next;
        }
+       if (inp->inp_flags & INP_RECVTTL) {
+               *mp = sbcreatecontrol((void *) &ip->ip_ttl,
+                   sizeof(uint8_t), IP_RECVTTL, IPPROTO_IP);
+               if (*mp)
+                       mp = &(*mp)->m_next;
+       }
 }
 
 /*
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 34b5a8b..ec1d59c 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1227,6 +1227,7 @@ ip_ctloutput(int op, struct socket *so, struct sockopt 
*sopt)
                case IP_RECVRETOPTS:
                case IP_RECVDSTADDR:
                case IP_RECVIF:
+               case IP_RECVTTL:
                        error = sockopt_getint(sopt, &optval);
                        if (error)
                                break;
@@ -1260,6 +1261,10 @@ ip_ctloutput(int op, struct socket *so, struct sockopt 
*sopt)
                        case IP_RECVIF:
                                OPTSET(INP_RECVIF);
                                break;
+
+                       case IP_RECVTTL:
+                               OPTSET(INP_RECVTTL);
+                               break;
                        }
                break;
 #undef OPTSET
@@ -1334,6 +1339,7 @@ ip_ctloutput(int op, struct socket *so, struct sockopt 
*sopt)
                case IP_RECVRETOPTS:
                case IP_RECVDSTADDR:
                case IP_RECVIF:
+               case IP_RECVTTL:
                case IP_ERRORMTU:
                        switch (sopt->sopt_name) {
                        case IP_TOS:
@@ -1365,6 +1371,10 @@ ip_ctloutput(int op, struct socket *so, struct sockopt 
*sopt)
                        case IP_RECVIF:
                                optval = OPTBIT(INP_RECVIF);
                                break;
+
+                       case IP_RECVTTL:
+                               optval = OPTBIT(INP_RECVTTL);
+                               break;
                        }
                        error = sockopt_setint(sopt, optval);
                        break;

-- 
Min Sik Kim


Home | Main Index | Thread Index | Old Index