uclibc 0.9.29: setsockopt + recvmsg

joerg jungermann joju at math.uni-paderborn.de
Sun Aug 31 15:47:23 UTC 2008


Hi !

I compiled udp-broadcast-relay-0.3 on two platforms
Debian/etch/i386/libc and Openwrt/mipsel/uclbc-0.9.29.
You can get from http://www.joachim-breitner.de/udp-broadcast-relay/ .

I found some odd, different behavior between the two generated binaries.

The Debian/etch/i386/libc binary works like described on the homepage.

The uclibc binary shows the oddity:
./udp-broadcast-relay -d 1 6111 br-lan wl0

This stopps after line 334:
        if (ttlptr == NULL) {
            perror("TTL not found on incoming packet\n");
            exit(1);
        }

I've done some investigation:

The receiving socket rcv is setup this way after line 242:
/* Create our broadcast receiving socket */
    if((rcv=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
    {
        perror("socket");
        exit(1);
    };

    x = 1;
    if(setsockopt(rcv, SOL_SOCKET, SO_BROADCAST, (char*) &x,
sizeof(int))<0){
        perror("SO_BROADCAST on rcv");
        exit(1);
    };
    if(setsockopt(rcv, SOL_IP, IP_RECVTTL, (char*) &x, sizeof(int))<0){
        perror("IP_RECVTTL on rcv");
        exit(1);
    };
    if(setsockopt(rcv, SOL_IP, IP_PKTINFO, (char*) &x, sizeof(int))<0){
        perror("IP_PKTINFO on rcv");
        exit(1);
    };

As for as I understand the docs/manpages relevant for getting the TTL of
a received packet is line 254 to 257:
    if(setsockopt(rcv, SOL_IP, IP_RECVTTL, (char*) &x, sizeof(int))<0){
        perror("IP_RECVTTL on rcv");
        exit(1);
    };

In uclibc this seems to ignore this.

In line 319 to 332 packets are received but in uclibc IP_TTL (value 2)
message type is not in the ancillary data. Only IP_RECVHDR (value 12) is
found as requested in line 258.

/* Receive a broadcast packet */
        len = recvmsg(rcv,&rcv_msg,0);
        if (len <= 0) continue; /* ignore broken packets */

        /* Find the ttl and the reveicing interface */
        ttlptr=NULL;
        if (rcv_msg.msg_controllen>0)
          for
(cmsg=CMSG_FIRSTHDR(&rcv_msg);cmsg;cmsg=CMSG_NXTHDR(&rcv_msg,cmsg)) {
            if (cmsg->cmsg_type==IP_TTL) {
              ttlptr = (int *)CMSG_DATA(cmsg);
            }
            if (cmsg->cmsg_type==IP_PKTINFO) {
              rcv_ifindex=((struct in_pktinfo
*)CMSG_DATA(cmsg))->ipi_ifindex;
            }
          }

        if (ttlptr == NULL) {
            perror("TTL not found on incoming packet\n");
            exit(1);
        }
        if (*ttlptr == ttl) {
            DPRINT ("Got local packge (TTL %i) on interface
%i\n",*ttlptr,rcv_ifindex);
            continue;
        }

AFAIK the program does setup al neccesary things to get IP_TTL. But I am
not deep involved if this is wanted behaviour in uclibc.

If its not a bug please give me a pointer, where I can read an fixup the
program.

regards
 joerg





More information about the uClibc mailing list