ping的源码 在著名的Network Programming for Microsoft Windows 2nd上有
原始套接字搞的
Ping example performs the following steps.
1.Creates a socket of address family AF_INET, type SOCK_RAW, and protocol IPPROTO_ICMP. For IPv6, the address family is AF_INET6, type SOCK_RAW, and protocol value 58.
2.Creates and initializes the ICMP header.
3.Calls sendto or WSASendTo to send the ICMP request to the remote host.
4.Calls recvfrom or WSARecvFrom to receive any ICMP responses.
// Define the ICMP header
typedef struct icmp_hdr
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
unsigned short icmp_id;
unsigned short icmp_sequence;
unsigned long icmp_timestamp;
} ICMP_HDR, *PICMP_HDR, FAR *LPICMP_HDR;
icmp = (ICMP_HDR *)buf;
icmp->icmp_type = 8; // echo request type
icmp->icmp_code = 0;
icmp->icmp_id = GetCurrentProcessId();
icmp->icmp_checksum = 0; // zero field before computing checksum
icmp->icmp_sequence = 0;
icmp->icmp_timestamp = GetTickCount();
// Fill in the payload with a random character
memset(&buf[sizeof(ICMP_HDR)], '@', 32);
// Compute the checksum over the ICMP header and payload
// The checksum() function computes the 16-bit one's
// complement on the specified buffer. See the Ping
// code sample on the companion CD for its implementation.
icmp->icmp_checksum = checksum(buf, sizeof(ICMP_HDR)+32);
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
// Initialize the destination SOCKADDR_STORAGE
((SOCKADDR_IN *)&dest)->sin_family = AF_INET;
((SOCKADDR_IN *)&dest)->sin_port = htons(0);
// port is ignored for ICMP
((SOCKADDR_IN *)&dest)->sin_addr.s_addr = inet_addr("1.2.3.4");