当前位置:网站首页>Principle and implementation of Ping
Principle and implementation of Ping
2022-07-23 05:33:00 【CAir2】
Ping The basic principle of depends on ICMP agreement .ICMP Baotou is as follows :
The type and code The definition is as follows :

design idea
- Definition IP Head structure
- Definition ICMP Head structure
- structure ICPM Message and calculate ICMP Checksum
- adopt sendto and recvfrom Send and receive ICMP message
The code is as follows
Define the communication packet header NetStruct.h
// Network byte order , Big end
//unsigned char header_len : 4;
// Why not define a bit pattern , Because byte order processing is required
#pragma pack(push,1)
typedef struct IPHeader
{
private:
unsigned char version_headerlen;// edition (4) ipv4-4 ipv6-6 The length of the first (4) 32(4 byte ) Bit is a cell in calculation max=60(15*4) byte
public:
unsigned char tos;// Service type
unsigned short total_len;// Unit byte ,IP Head + Data section
unsigned short flag;// identification
private:
unsigned short flag_sep_offset;// identification 3: The offset 13
public:
unsigned char ttl;
unsigned char proto_type;//1-icmp 2-igmp 6-tcp 17-udp
unsigned short check_sum;// Head checksums
unsigned int src_ip;
unsigned int dest_ip;
unsigned char version()
{
return (version_headerlen >>2) & 0x0f;
}
unsigned char header_len()
{
return version_headerlen & 0x0f;
}
}IPHeader, *PIPHeader;
typedef struct ICMPHeader
{
unsigned char type;
unsigned char code;
unsigned short check_sum;
unsigned short flag;
unsigned short seq;
unsigned char data[0];// Data section
}ICMPHeader, *PICMPHeader;
#pragma pack(pop)
structure ICMP Message and calculate the checksum Ping.cpp
unsigned short CalcCheckSum(unsigned short *pdata,int nSize)
{
unsigned long check_sum = 0;
while (nSize > 1)
{
check_sum += *pdata++;
nSize -= sizeof(unsigned short);
}
if (nSize)
{
check_sum += *(unsigned short *)pdata;
}
check_sum = (check_sum >> 16) + (check_sum & 0xffff);
check_sum += (check_sum >> 16);
unsigned short result = (unsigned short)(~check_sum);
return result;
}
PICMPHeader NewIcmpPack(const void *icmpData, int &len)
{
unsigned int pack_len = sizeof(ICMPHeader) + len;
char *pack_buffer = new char[pack_len];
memset(pack_buffer, 0, pack_len);
PICMPHeader pHeader = (PICMPHeader)pack_buffer;
memcpy(pHeader->data, icmpData, len);
pHeader->type = 8;
pHeader->code = 0;
pHeader->flag = 0x1234;
pHeader->seq = 0;
pHeader->check_sum = CalcCheckSum((unsigned short *)pack_buffer, pack_len);
len = pack_len;
return pHeader;
}
void DeleteIcmpPack(PICMPHeader p)
{
if(p != NULL)
{
delete [](char *)p;
}
}
// analysis icmp Data packets
PICMPHeader parseIcmpReply(char *pdata, unsigned int date_len)
{
PIPHeader pIpHeader = (PIPHeader)pdata;
unsigned short iHeaderLen = pIpHeader->header_len() * 4;
//icmp Incomplete data
if (date_len < iHeaderLen + sizeof(ICMPHeader))
{
cout << "ICMP pack data error" << endl;
return NULL;
}
PICMPHeader pIcmpHeader = (PICMPHeader)pIpHeader->data;
return pIcmpHeader;
}
Send and receive ICMP message
bool ping(const char *szIp, unsigned int timeout)
{
SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock == INVALID_SOCKET)
{
cout << "socket create failed:" << WSAGetLastError() << endl;
return false;
}
// If it is linux be timeout by struct timeval
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
sockaddr_in sock_dst = {
0};
sock_dst.sin_family = AF_INET;
sock_dst.sin_addr.S_un.S_addr = inet_addr(szIp);
int data_len = 6;
PICMPHeader pIcmpPack = NewIcmpPack("Hellow", data_len);
if (SOCKET_ERROR == sendto(sock, (const char *)pIcmpPack, data_len, 0, (sockaddr*)&sock_dst, sizeof(sock_dst)))
{
cout << "sendto data failed:" << WSAGetLastError() << endl;
closesocket(sock);
DeleteIcmpPack(pIcmpPack );
return false;
}
DeleteIcmpPack(pIcmpPack );
while (true)
{
char recv_buf[1024] = "";
int ret = recvfrom(sock, recv_buf, 1024, 0, NULL, NULL);
if (ret == SOCKET_ERROR)
{
cout << "WSAStartup failed:" << WSAGetLastError() << endl;
}
else
{
PICMPHeader pIcmpReplay = parseIcmpReply(recv_buf, ret);
// Deal with according to the agreement icmp The reply
}
break;
}
closesocket(sock);
return true;
}
The test program , adopt winshark Grab the bag and see the result
ping("192.168.34.187", 3000);

边栏推荐
猜你喜欢
随机推荐
打印字符串数组中的所有词——指针与字符串的故事
Super detailed - how to understand the expression while (scanf ("%d", & Num)! = EOF) in C language?
Operation on December 1
With only 5000 lines of code, AI rendered 100 million landscape paintings on Quanzhi v853
代码随想录笔记_数组_977有序数组的平方
代码随想录笔记_链表_206反转链表
Code random notes_ Array_ 59 spiral matrix II
Notes and reflection notes
C语言求质数的几种简单易懂方法
Leetcode-646. longest number pair chain
如何用C语言实现无头单向非循环链表Single List ?
leetcode-343. 整数拆分
My first blog | records the original intention and goal of the programming road
大一暑假实习day7总结
leetcode-53. 最大子数组和
Leetcode-415. string addition
leetcode-326. 3的幂
理解OOP以及常见面试题
leetcode-188. 买卖股票的最佳时机 IV
Code random notes_ Array_ 704 binary search








