BYTE ttl; // Time to live, 这个字段我在下一节中用来实现Tracert功能 BYTE proto; // Protocol number (TCP, UDP etc) USHORT checksum; // IP checksum ULONG source_ip; ULONG dest_ip; };
// ICMP 包头(实际的包不包括timestamp字段, // 作者用来计算包的回应时间,其实完全没有必要这样做) struct ICMPHeader { BYTE type; // ICMP packet type BYTE code; // Type sub code USHORT checksum; USHORT id; USHORT seq; ULONG timestamp; // not part of ICMP, but we need it };
extern USHORT ip_checksum(USHORT* buffer, int size); extern int setup_for_ping(char* host, int ttl, SOCKET& sd, sockaddr_in& dest); extern int send_ping(SOCKET sd, const sockaddr_in& dest, ICMPHeader* send_buf, int packet_size); extern int recv_ping(SOCKET sd, sockaddr_in& source, IPHeader* recv_buf, int packet_size); extern int decode_reply(IPHeader* reply, int bytes, sockaddr_in* from); extern void init_ping_packet(ICMPHeader* icmp_hdr, int packet_size, int seq_no);
/* * 程序名: rawping.cpp * 说明: * 主要函数库实现部分 */
include <winsock2.h> #include <ws2tcpip.h> #include <iostream.h> #include "rawping.h"
// 计算ICMP包的校验和的简单算法, 很多地方都有说明, 这里没有必要详细将 // 只是一点要提, 做校验之前, 务必将ICMP包头的checksum字段置为0 USHORT ip_checksum(USHORT* buffer, int size) { unsigned long cksum = 0;
// Sum all the words together, adding the final byte if size is odd while (size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } if (size) { cksum += *(UCHAR*)buffer; }
// Do a little shuffling cksum = (cksum >> 16) + (cksum & 0xffff);