-
November 24th, 2010, 01:10 PM
#1
ICMP pings not being received
I am working on a traceroute program and have run into problems when it comes to receiving the echo request replies.
This is the code that I have:
Code:
int main(int argc, char* argv[]){
int bytes, result, SockAddrSize;
SOCKET sock;
struct sockaddr_in send_addr, recv_addr;
struct hostent *remote;
u_char send_buf[MAX_ICMP_SIZE];
class ICMPHeader *icmp = (ICMPHeader*) send_buf;
char rec_buf[MAX_REPLY_SIZE];
IPHeader *router_ip_hdr = (IPHeader *)rec_buf;
ICMPHeader *router_icmp_hdr = (ICMPHeader*) (router_ip_hdr + 1);
IPHeader *orig_ip_hdr = (IPHeader*) (router_icmp_hdr + 1);
ICMPHeader *orig_icmp_hdr = (ICMPHeader *)(orig_ip_hdr + 1);
char* address = argv[1];
//Initialize WinSock
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
printf("WSAStartup error %d\n", WSAGetLastError ());
WSACleanup();
return 1;
}
//create socket
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(sock == INVALID_SOCKET){
cout<<"Unable to create a raw socket: "<<WSAGetLastError()<<endl;
WSACleanup();
return 1;
}
send_addr.sin_family = AF_INET;
send_addr.sin_addr.S_un.S_addr = inet_addr(address);
send_addr.sin_port = htons(27015);
// first assume that the string is an IP address
DWORD IP = inet_addr (address);
if (IP == INADDR_NONE)
{
// if not a valid IP, then do a DNS lookup
if ((remote = gethostbyname(address)) == NULL)
{
printf ("Invalid string: neither FQDN, nor IP address\n");
return 1;
}
else // take the first IP address and copy into sin_addr
memcpy((char *)&(send_addr.sin_addr), remote->h_addr, remote->h_length);
}
else
{
// if a valid IP, directly drop its binary version into sin_addr
send_addr.sin_addr.S_un.S_addr = IP;
}
cout<<"Tracerouting to "<<send_addr.sin_addr<<"..."<<endl;
// set up the echo request
// no need to flip the byte order since fields are 1 byte each
icmp->type = ICMP_ECHO_REQUEST;
icmp->code = 0;
// set up optional fields as needed
icmp->id = (u_short) GetCurrentProcessId();
icmp->checksum = 0;
icmp->seq = 0;
/* calculate the checksum */
int packet_size = sizeof(ICMPHeader);
icmp->checksum = ip_checksum((u_short*) send_buf, packet_size);
//set proper TTL
int ttl = 1;
// need Ws2tcpip.h for IP_TTL
if(setsockopt(sock, IPPROTO_IP, IP_TTL, (const char*) &ttl,
sizeof(ttl)) == SOCKET_ERROR){
perror("setsockopt failed\n");
closesocket(sock);
WSACleanup();
return 1;
}
// use regular sendto on the above socket
if(sendto (sock, (const char*) send_buf, MAX_ICMP_SIZE, 0, (struct sockaddr*) &send_addr, sizeof(send_addr)) == SOCKET_ERROR){
printf("Error sending to receiver.\n");
return 1;
}
//receive from the socket into buffer rec_buf
HANDLE dataReady = CreateEvent (NULL, false, false, NULL);
WSAEventSelect(sock, dataReady, FD_READ);
result = WaitForSingleObject(dataReady, 5000);
if(result == WAIT_TIMEOUT){
cout<<"timed out"<<endl;
return 1;
}
else {
cout<<"received packet"<<endl;
SockAddrSize = sizeof(struct sockaddr_in);
bytes = recvfrom(sock, rec_buf, sizeof(rec_buf), 0, (struct sockaddr*) &send_addr, &SockAddrSize);
}
return 0;
}
I eventually have will send out more than one request, but right now I'm just trying to get one working. It always times out at the WaitForSingleObject(). I'm not getting any compilation errors.
I'm running Windows Vista. I have turned off my Symantec because it was blocking packets and I have turned off my firewall. I also allowed ICMP echo requests through my firewall and am using a HughesNet network, but still it times out every single time.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|