PDA

View Full Version : Help with ICMP


webmastermattd
04-20-2003, 01:18 PM
Have done some looking around, but have not come accross much that I can find of help.

Essentialy what I am trying to do is create a Ping class ( for implementation in a greate set of tools ).

Anyway the link to the files is
www.webmastermattd.net/progs/Ping-20030420.tar.bz2 (http://www.webmastermattd.net/progs/Ping-20030420.tar.bz2)

The problem that I am having is that I can send okay ( the send() function doesn't return an error ) though I don't recieve anything with the recv() function.

I have implemented a non-blocking socket in order to return from the function, though am not too sure if this is the right thing to do?

Anyway, any help would be greatly apreciated even if it is a link to another post or a particular faq. ( The examples from the raw socket faq only covered sending, which I have reimplemented in this function to the best of my understanding ).

Later,

RobSeace
04-20-2003, 07:00 PM
Well, one big problem I see is here:


// Now it is time to set up the buffer array
ipHeader = ( struct ip* )buffer;
bzero( ( char * )ipHeader, sizeof( struct ip ) );
icmpHeader = ( struct icmp* )( buffer + sizeof( ipHeader ) );
bzero( ( char * )icmpHeader, sizeof( struct ip ) );


There are a couple different problems... First, you don't want
"sizeof( ipHeader )" in line 4... "ipHeader" is a pointer, so its size
will always be whatever your native pointer size is (probably 4 bytes)...
You want "sizeof (struct ip)" (or "sizeof (*ipHeader)" would work, too)...
Also, in the last line, you don't want "sizeof( struct ip )" there; that would
overflow the buffer (if you had setup the location of the header correctly,
at least)... You want "sizeof (struct icmp)"...

I'm not sure if those are the only problems you have, but those are
certainly big ones which would prevent proper functioning...

webmastermattd
04-21-2003, 01:17 AM
Thanks Rob, that got it working.

I also had a problem with using recvfrom() instead of recv().
It kept on giving me a bad address error. Any idea why this would be?

Anyway, it now works and it is all good.
If anyone wants to get the semi completed code it is avaliable at
www.webmastermattd.net/progs/Ping-20030421.tar.bz2 (http://www.webmastermattd.net/progs/Ping-20030421.tar.bz2)

Later,

RobSeace
04-21-2003, 01:58 PM
It actually works with recv(), like that?? How odd... It shouldn't...
recv() should only work on connected sockets (typically TCP, or UDP
for which you've done the connect() kluge, to associate a single remote
address with them)... *shrug* Well, I guess recv() is just recvfrom()
with NULL for the last 2 args... So, I guess it'd probably work even with
an unconnected socket; it'd just throw away the remote address... I guess
it's only send() vs. sendto() where it's really a necessity to use the correct
one... *shrug*

However, looking at the former code, I see the problem with your
recvfrom():


if( recvfrom( sockfd, &recvBuffer, sizeof( recvBuffer ), 0, ( struct sockaddr * )&remoteAddress, ( socklen_t * )sizeof( remoteAddress ) ) == -1 )


That last arg needs to be a pointer to an actual variable for recvfrom()
to be able to fill in... Eg:


int len = sizeof (remoteAddress);
ecvfrom (sockfd, recvBuffer, sizeof (recvBuffer), 0, &remoteAddress, &len);

webmastermattd
04-21-2003, 02:18 PM
That got it working.

One other problem that I have been having is when I try to do IPv6 implementation of Ping, the send function returns an EINVAL error, which from what I can tell relates to the sockaddr that is being passed to it. ( yes it is a sockaddr_in6 ).

Anyway, the code is avaliable at
www.webmastermattd.net/progs/Ping6-20030420.tar.bz2 (http://www.webmastermattd.net/progs/Ping6-20030420.tar.bz2)

This problem has got me stumped.

Thanks heaps for your help with these obviously newbie questions.

As far as it working with recv() instead of recvfrom() it may be something to do with the linux implementation ( gcc 3.2.0 and kernel 2.4.20 )? ( doubt it though )

Later,

webmastermattd
04-27-2003, 09:20 AM
Have got a version of Ping6 working, though for some unknown reason ( unknown to me anyway ) when I get the echo reply message, the identifier field is zero.

Anyway, this is not a major problem, though it would be good to know that the echo reply ( or any other ICMPv6 packet ) that I am picking up is relevent to the one that I sent out.

the code is avaliable at http://www.webmastermattd.net/progs/Ping6-20030427.tar.bz2

The system that it is being built on is Slackware 9.0 with kernel 2.4.20 and GCC 3.2.0

Any help would be greate in figuring out this problem.

Thanks.