|
|
 |
 |
 |
 |
infinite loop with select
I'm having a problem using select with a Raw-Socket. I get a packet, change the IP address (for sending it to a tun device) and then I try to recalculate the IP-checksum. If I do so, it loops forever with the same packet. If I don't use either(!) ip->check = 0; or ip->check = in_cksum... the code works fine. Does anybody see what the problem is? thanks in advance, Andreas for( ;; ) { FD_ZERO( &read_fds ); FD_SET( sUDP, &read_fds ); ret_val = select( sUDP + 1, &read_fds, NULL, NULL, NULL ); if( ret_val < 0 ) break; if( ret_val > 0 ) { if ( FD_ISSET( sUDP, &read_fds ) ) { int lenInUDP = recvfrom(sUDP, ðBufferUDP, sizeof(ethBufferUDP), 0, 0, 0); ip = (struct iphdr *) ethBufferUDP; //change source address to interface address ip->saddr = inet_addr("172.16.1.20"); //change destination address to 134.2.173.55 ip->daddr = inet_addr("172.16.1.1"); /***************PROBLEM HERE*******************************************/ ip->check = 0; ip->check = in_cksum ((unsigned short *) ip, ip->ihl * (32 / 8)); } } }
here's the code for in_chksum: unsigned short in_cksum (unsigned short *addr, int count) { register long sum = 0; register unsigned short checksum; while (count > 1) { sum += *addr++; count -= 2; } if (count > 0) { sum += *(unsigned char *) addr; } while (sum >> 16) { sum = (sum & 0xffff) + (sum >> 16); } checksum = ~sum; return checksum;
}
In article <f43qmj$ta@newsserv.zdv.uni-tuebingen.de>, Andreas Mueller <m@amueller.org> wrote: >I'm having a problem using select with a Raw-Socket. >I get a packet, change the IP address (for sending it to a tun device) >and then I try to recalculate the IP-checksum. >If I do so, it loops forever with the same packet. If I don't use >either(!) ip->check = 0; or ip->check = in_cksum... the code works fine. >Does anybody see what the problem is?
For one thing, you're working with things not defined by the C language, which puts your question beyond the scope of comp.lang.c. Somewhere that discusses your platform and/or raw sockets would probably be a better place to ask. dave -- Dave Vandervies dj3va@csclub.uwaterloo.ca In fact, I go to considerable lengths to maintain the self-imposed delusion that I live in a fantasy world, one in which software is easy and fun to write, and works right the first time --Steve Summit in comp.lang.c
>In article <f43qmj$ta @newsserv.zdv.uni-tuebingen.de> >Andreas Mueller <m @amueller.org> wrote: >>I'm having a problem using select with a Raw-Socket. ... In article <f440hs$f6@rumours.uwaterloo.ca>, Dave Vandervies <dj3va @csclub.uwaterloo.ca> wrote: >For one thing, you're working with things not defined by the C language, >which puts your question beyond the scope of comp.lang.c. >Somewhere that discusses your platform and/or raw sockets would probably >be a better place to ask.
Indeed. However, there is one thing (well, two really) I can note here: >> //change destination address to 134.2.173.55 >> ip->daddr = inet_addr("172.16.1.1");
First, //-comments are C99-specific (and sometimes fail to survive Usenet, although these did). Second, the comment does not match the code. Why does one list one address, and the other use another? -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603 email: forget about it http://web.torek.net/torek/index.html Reading email is like searching for food in the garbage, thanks to spammers.
Andreas Mueller wrote: > I'm having a problem using select with a Raw-Socket. > I get a packet, change the IP address (for sending it to a tun device) > and then I try to recalculate the IP-checksum. > If I do so, it loops forever with the same packet. If I don't use > either(!) ip->check = 0; or ip->check = in_cksum... the code works fine. > Does anybody see what the problem is? > thanks in advance, > Andreas > for( ;; ) { > FD_ZERO( &read_fds ); > FD_SET( sUDP, &read_fds ); > ret_val = select( sUDP + 1, &read_fds, NULL, NULL, NULL ); > if( ret_val < 0 ) > break; > if( ret_val > 0 ) { > if ( FD_ISSET( sUDP, &read_fds ) ) { > int lenInUDP = recvfrom(sUDP, ðBufferUDP, > sizeof(ethBufferUDP), 0, 0, 0); > ip = (struct iphdr *) ethBufferUDP; > //change source address to interface address > ip->saddr = inet_addr("172.16.1.20"); > //change destination address to 134.2.173.55 > ip->daddr = inet_addr("172.16.1.1"); > /***************PROBLEM HERE*******************************************/ > ip->check = 0; > ip->check = in_cksum ((unsigned short *) ip, ip->ihl * (32 / 8)); > } > } > }
[...] Well, the use of sockets is beyond the scope of clc, but... What is "ethBufferUDP"? When you point ip (a pointer to "struct iphdr") there, are you certain that the buffer is large enough? Is it possible that ip->check points beyond the buffer? -- +-------------------------+--------------------+-----------------------+ | Kenneth J. Brody | www.hvcomputer.com | #include | | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> | +-------------------------+--------------------+-----------------------+ Don't e-mail me at: <mailto:ThisIsASpamT@gmail.com> |
 |
 |
 |
 |
|