Hello Bert, On 2/24/19 11:18 AM, bert hubert wrote: > Hi everyone, > > I need to get the TTL of UDP datagrams from userspace, so I set the > IP_RECVTTL socket option. And as promised by ip.7, I then get IP_TTL > messages from recvfrom. However, unlike what the manpage promises, the TTL > field gets passed as a 32 bit integer. > > The following userspace code works: > > uint32_t ttl32; > for (cmsg = CMSG_FIRSTHDR(msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(msgh,cmsg)) { > if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_TTL) && > CMSG_LEN(sizeof(ttl32)) == cmsg->cmsg_len) { > > memcpy(&ttl32, CMSG_DATA(cmsg), sizeof(ttl32)); > *ttl=ttl32; > return true; > } > else > cerr<<"Saw something else "<<(cmsg->cmsg_type == IP_TTL) <<", "<<(int)cmsg->cmsg_level<<", "<<cmsg->cmsg_len<<", "<<CMSG_LEN(1)<<endl; > } > > The 'else' field was used to figure out I go the length wrong. Reading the source code also seems to confirm this, from net/ipv4/ip_sockglue.c: [[ static void ip_cmsg_recv_ttl(struct msghdr *msg, struct sk_buff *skb) { int ttl = ip_hdr(skb)->ttl; put_cmsg(msg, SOL_IP, IP_TTL, sizeof(int), &ttl); } ]] > > Patch: > > diff --git a/man7/ip.7 b/man7/ip.7 > index 02dd47f2a..d664eddb1 100644 > --- a/man7/ip.7 > +++ b/man7/ip.7 > @@ -874,7 +874,7 @@ Expects a boolean integer flag. > When this flag is set, pass a > .B IP_TTL > control message with the time-to-live > -field of the received packet as a byte. > +field of the received packet as a 32 bit integer. > Not supported for > .B SOCK_STREAM > sockets. Thanks, Patch applied. Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/