Jump to content
  • Advertisement
Sign in to follow this  
Brocketino

icmp

This topic is 4770 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm building a ping-alike app using raw sockets and the icmp protocol. Everything works fine as long as the ICMP message isn't fragmented. Here's some code, would be really nice if someone could tell me how to solve this problem.
struct stIPHDR 
{
  u_char  h_len:4;
  u_char  ver:4;
  u_char  tos;
  u_short totlen;
  u_short id;
  u_short offset;
  u_char  ttl;
  u_char  proto;
  u_short checksum;
  u_int srcIP;
  u_int destIP;
};

struct stICMPHDR
{
  u_char type;
  u_char code;
  u_short sum;
  u_short id;
  u_long tstamp;
}

SOCKET g_socket = INVALID_SOCKET;
SOCKADDR_IN g_dst;
SOCKADDR_IN g_src;

int send_icmp_package(int size)
{
  // Clean the buffer
  static char outpkt[65500];
  memset(outpkt,0,65500);
  // Setup ip header
  stIPHDR * pIP = (stIPHDR*) outpkt;
  pIP->ver = 4;
  pIP->offset = 0;
  pIP->tos = 0;
  pIP->proto = IPPROTO_ICMP;
  pIP->totlen = htons(sizeof(stIPHDR)+sizeof(stICMPHDR));
  pIP->h_len = sizeof(IpHeader)/4;
  pIP->destIP = g_dst.sin_addr.s_addr;
  pIP->srcIP = g_src.sin_addr.s_addr;
  pIP->checksum = 0;
  pIP->ttl = 128;
  pIP->id = htonl(GetCurrentProcessId() & 0xffff);
  pIP->checksum = checksum((u_short*)ip,sizeof(stIPHDR)+sizeof(stICMPHDR));
  // Setup icmp header
  stICMPHDR * pICMP = (stICMPHDR*)(outpkt + sizeof(stIPHDR));
  pICMP->type = ICMP_ECHO;
  pICMP->code = 0;
  pICMP->sum = 0;
  pICMP->tstamp = GetTickCount();
  pICMP->id = GetCurrentProcessId();
  pICMP->sum = checksum((u_short*)pICMP,sizeof(stICMPHDR)+size);
  // Send the package
  int iret = sendto(g_socket,outpkt,sizeof(stIPHDR)+sizeof(stICMPHDR)+size,0,@g_dst,sizeof(g_dst));
  return iret; 
}

int main(char argv[])
{
  WSADATA wsadata;
  WSAStartup(0x0202,&wsadata);
  // Create a raw socket
  g_socket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
  // Set options for socket
  BOOL option = 4;
  setsockopt(g_socket,IPPROTO_IP,IP_HDRINCL,(char*)&option,sizeof(option));
  // Setup address
  memset(g_dst,0,sizeof(g_dst));
  g_dst.sin_family = AF_INET;
  g_dst.sin_port = htons(0);
  g_dst.sin_addr.s_addr = inet_addr('a_valid_ip_address');
  memset(g_src,0,sizeof(g_src));
  g_src.sin_family = AF_INET;
  g_src.sin_port = htons(0);
  g_src.sin_addr.s_addr = inet_addr('local_ip_address');
  

  int num_echos = 5;
  char inpkt[65500];

  while(num_echos > 0)
  {
     int iRet = send_icmp_package(5000); // datasize
     
     fd_set read;
     read.fd_count = 1;
     read.fd_array[0] = g_socket;
     TIMEVAL timeout = { 3, 0 };
     if((iRet = select(1,&read,NULL,NULL,&timeout)) == SOCKET_ERROR)
     { 
     } else
     if(iRet == 0) 
     {
       // Timeout
     } else
     {
       iRet = recvfrom(g_socket,g_inpkt,65500,0,(sockaddr*)&g_dst,&addrlen);  
     }
     
     
     if(--num_echos == 0)
       break;  
  }

  closesocket(g_socket);
  WSACleanup();
  return 0;
  
}




Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Quote:
Original post by Brocketino
I'm building a ping-alike app using raw sockets and the icmp protocol. Everything works fine as long as the ICMP message isn't fragmented.
Here's some code, would be really nice if someone could tell me how to solve this problem.

*** Source Snippet Removed ***


There is flag for do not fragment in TCP/IP. How you would go about setting it, I am not sure.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by Brocketino
I'm building a ping-alike app using raw sockets and the icmp protocol. Everything works fine as long as the ICMP message isn't fragmented.
Here's some code, would be really nice if someone could tell me how to solve this problem.

*** Source Snippet Removed ***


There is flag for do not fragment in TCP/IP. How you would go about setting it, I am not sure.


I think the flags for fragmentation are set by the kernel if u don't set them yourself, so that shouldn't be the problem. I checked my outgoing package using
Ethereal and they looked ok. The reply package from the other peer also has the MORE_FRAGMENTS flag set by I only receive one single package?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!