ip.7: IP_RECVTTL error fixed

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.

Note from mtk:

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);
}
]]

Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
bert hubert 2019-02-24 11:18:11 +01:00 committed by Michael Kerrisk
parent c3a208e9d9
commit 2ca483cd4b
1 changed files with 1 additions and 1 deletions

View File

@ -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.