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