设为首页 加入收藏

TOP

实现类似ping功能的C源代码(一)
2014-02-08 12:43:36 来源: 作者: 【 】 浏览:382
Tags:实现 类似 ping 功能 源代码

  早些年学习网络协议的时候折腾而写的代码,代码在后面。

  纯粹代码的意义不大,建议有兴趣学习的童鞋,要想学习ping,最好能了解一下 RFC 792 ICMP协议,这个比代码纯粹的代码有意义,当年咱学习的时候,可没人给这样的建议啊,这可是本人后来逐渐明白的,什么才是最重要的,在此点出来,明白的有缘人自然能明白。

  直接将以下代码存为文件xping.cpp或xping.c,用VC直接编译就可以(VC自己会提示生成工程),GCC编译也可以的

  //

  //xping

  //awzzz

  //2002/06/20

  //

  #include <STDIO.H>

  #include <STRING.H>

  #include <STDLIB.H>

  #include <TIME.H>

  #ifdef WIN32

  #define WIN32_LEAN_AND_MEAN

  #include <WINSOCK.H>

  #pragma comment(lib, "Wsock32.lib")

  #else

  #include <SYS types.h>

  #include <SYS socket.h>

  #include <NETINET in.h>

  #include <NETDB.H>

  #include <SYS ioctl.h>

  #include

  #include <UNISTD.H>

  #include <NETINET ip.h>

  #include <NETINET ip_icmp.h>

  #endif

  #define ICMP_ECHO 8

  #define ICMP_ECHOREPLY 0

  //#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)

  #define ICMP_MIN (8 + 4) // minimum 8 byte icmp packet (just header + timestamp)

  // IP header

  typedef struct _tagX_iphdr

  {

  unsigned char h_len:4;           // length of the header

  unsigned char version:4;         // Version of IP

  unsigned char tos;              // Type of service

  unsigned short total_len;       // total length of the packet

  unsigned short ident;           // unique identifier

  unsigned short frag_and_flags; // flags

  unsigned char ttl;     // ttl

  unsigned char proto;            // protocol (TCP, UDP etc)

  unsigned short checksum;        // IP checksum

  unsigned int sourceIP;

  unsigned int destIP;

  }XIpHeader;

  // ICMP header

  typedef struct _tagX_icmphdr

  {

  unsigned char i_type;

  unsigned char i_code;

  unsigned short i_cksum;

  unsigned short i_id;

  unsigned short i_seq;

  unsigned long i_timestamp;

  }XIcmpHeader;

  //puclic code

  //网际校验和生产算法

  //网际校验和是被校验数据16位值的反码和(ones-complement sum)

  unsigned short in_cksum(unsigned short* addr, int len)

  {

  int   nleft = len;

  int   sum = 0;

  unsigned short* w = addr;

  unsigned short answer = 0;

  while(nleft > 1) {

  sum += *w++;

  nleft -= 2;

  }

  if(nleft == 1) {

  *(unsigned char*)(&answer) = *(unsigned char*)w;

  sum += answer;

  }

  sum = (sum 》 16) + (sum & 0xffff);

  sum += (sum 》 16);

  answer = ~sum;

  return (answer);

  }

  void fill_IpHeader(char *buf)

  {

  // XIpHeader *ip_hdr = (XIpHeader *)buf;

  }

  void fill_IcmpData(char *buf, int datasize)

  {

  if (buf)

  {

  char ch = 0;

  char* icmpdata = buf + sizeof(XIcmpHeader);

  fprintf(stdout, "(IcmpData)\r\n");

  for (int i = 0; i < datasize; i++)

  {

  ch = 'A' + i%('z' - 'A');

  *(icmpdata + i) = ch;

  fprintf(stdout, "%c", ch);

  }

  fprintf(stdout, "\r\n");

  }

  }

  void fill_IcmpHeader(char *buf, int datasize)

  {

  static unsigned short seq_no = 0;

  XIcmpHeader *icmp_hdr = (XIcmpHeader *)buf;

  if (icmp_hdr)

  {

  icmp_hdr->i_type = ICMP_ECHO;

  icmp_hdr->i_code = 0;

  icmp_hdr->i_cksum = 0;

  #ifdef WIN32

  icmp_hdr->i_id = (unsigned short)GetCurrentProcessId();

  #else

  icmp_hdr->i_id = (unsigned short)getpid();

  #endif

  icmp_hdr->i_seq = seq_no++;

  #ifdef WIN32

  icmp_hdr->i_timestamp = (unsigned long)::GetTickCount();

  #else

  icmp_hdr->i_timestamp = (unsigned long)time(NULL);

  #endif

  icmp_hdr->i_cksum = in_cksum((unsigned short*)buf, sizeof(XIcmpHeader) + datasize);

  fprintf(stdout, "(IcmpHeader)\r\n");

  fprintf(stdout, "%02X%02X%04X\r\n", icmp_hdr->i_type, icmp_hdr->i_code, icmp_hdr->i_cksum);

  fprintf(stdout, "%04X%04X\r\n", icmp_hdr->i_id, icmp_hdr->i_seq);

  fprintf(stdout, "%08X\r\n", icmp_hdr->i_timestamp);

  }

  }

  // decode

  void decode_IpIcmp(char *buf, int size)

  {

  XIpHeader *ip_hdr = (XIpHeader *)buf;

  unsigned short iphdrlen;

  if (ip_hdr)

  {

  fprintf(stdout, "(IpHeader)\r\n");

  fprintf(stdout, "%01X%01X%02X%04X\r\n", ip_hdr->version, ip_hdr->h_len, ip_hdr->tos, ip_hdr->total_len);

  fprintf(stdout, "%04X%04X\r\n", ip_hdr->ident, ip_hdr->frag_and_flags);

  fprintf(stdout, "%02X%02X%04X\r\n", ip_hdr->ttl, ip_hdr->proto, ip_hdr->checksum);

  //iphdrlen = ip_hdr->h_len * 4; // number of 32-bit words *4 = bytes

  iphdrlen = ip_hdr->h_len 《 2; // number of 32-bit words *4 = bytes

  fprintf(stdout, "(IcmpHeader)\r\n");

  if (size < iphdrlen + ICMP_MIN)

  {

   

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇使用C语言实现“泛型”链表 下一篇C不确定参数个数的函数的实现

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: