資源簡介
traceroute(路由跟蹤)用于查找傳輸數據所經過的路由地址
代碼片段和文件信息
#include?
#include?
#define?_WINSOCK_DEPRECATED_NO_WARNINGS
#include?
#include?
using?namespace?std;
#pragma?comment(lib?“Ws2_32.lib“)
//IP報頭
typedef?struct?IP_HEADER
{
unsigned?char?hdr_len?:?4;???????//4位頭部長度
unsigned?char?version?:?4;???????//4位版本號
unsigned?char?tos;?????????????//8位服務類型
unsigned?short?total_len;??????//16位總長度
unsigned?short?identifier;?????//16位標識符
unsigned?short?frag_and_flags;?//3位標志加13位片偏移
unsigned?char?ttl;?????????????//8位生存時間
unsigned?char?protocol;????????//8位上層協議號
unsigned?short?checksum;???????//16位校驗和
unsigned?long?sourceIP;????????//32位源IP地址
unsigned?long?destIP;??????????//32位目的IP地址
}?IP_HEADER;
//ICMP報頭
typedef?struct?ICMP_HEADER
{
BYTE?type;????//8位類型字段
BYTE?code;????//8位代碼字段
USHORT?cksum;?//16位校驗和
USHORT?id;????//16位標識符
USHORT?seq;???//16位序列號
}?ICMP_HEADER;
//報文解碼結構
typedef?struct?DECODE_RESULT
{
USHORT?usSeqNo;????????//序列號
DWORD?dwRoundTripTime;?//往返時間
in_addr?dwIPaddr;??????//返回報文的IP地址
}DECODE_RESULT;
//計算網際校驗和函數
/**
1、把校驗和字段置為0;
2、對IP頭部中的每16bit進行二進制求和;
3、如果和的高16bit不為0,則將和的高16bit和低16bit反復相加,直到和的高16bit為0,從而獲得一個16bit的值;
4、將該16bit的值取反,存入校驗和字段。
*/
USHORT?checksum(USHORT?*pBuf?int?iSize)
{
unsigned?long?cksum?=?0;
//每16位相加
while?(iSize?>?1)
{
cksum?+=?*pBuf++;
iSize?-=?sizeof(USHORT);
}
if?(iSize)//如果?iSize?為正,即為奇數個字節
{
cksum?+=?*(UCHAR?*)pBuf;?//則在末尾補上一個字節,使之有偶數個字節
}
cksum?=?(cksum?>>?16)?+?(cksum?&?0xffff);?//將高16位與低16位相加
cksum?+=?(cksum?>>?16);?//將進位到高位的16位與低16位相加,確保高16位為0
return?(USHORT)(~cksum);?//最后將結果取反,得到checksum
}
//對數據包進行解碼
BOOL?DecodeIcmpResponse(char?*pBuf?int?iPacketSize?DECODE_RESULT?&DecodeResult
BYTE?ICMP_ECHO_REPLY?BYTE?ICMP_TIMEOUT)
{
//檢查數據報大小的合法性
IP_HEADER?*pIpHdr?=?(IP_HEADER?*)pBuf;
int?iIpHdrLen?=?pIpHdr->hdr_len?*?4;????//ip報頭的長度是以4字節為單位的
//若數據包大小?小于?IP報頭?+?ICMP報頭,則數據報大小不合法
if?(iPacketSize?(int)(iIpHdrLen?+?sizeof(ICMP_HEADER)))
return?FALSE;
//根據ICMP報文類型提取ID字段和序列號字段
ICMP_HEADER?*pIcmpHdr?=?(ICMP_HEADER?*)(pBuf?+?iIpHdrLen);//ICMP報頭?=?接收到的緩沖數據?+?IP報頭
USHORT?usID?usSquNo;
if?(pIcmpHdr->type?==?ICMP_ECHO_REPLY)????//ICMP回顯應答報文
{
usID?=?pIcmpHdr->id;????????//報文ID
usSquNo?=?pIcmpHdr->seq;????//報文序列號
}
else?if?(pIcmpHdr->type?==?ICMP_TIMEOUT)??//ICMP超時差錯報文
{
char?*pInnerIpHdr?=?pBuf?+?iIpHdrLen?+?sizeof(ICMP_HEADER);?//載荷中的IP頭
int?iInnerIPHdrLen?=?((IP_HEADER?*)pInnerIpHdr)->hdr_len?*?4;?//載荷中的IP頭長
ICMP_HEADER?*pInnerIcmpHdr?=?(ICMP_HEADER?*)(pInnerIpHdr?+?iInnerIPHdrLen);//載荷中的ICMP頭
usID?=?pInnerIcmpHdr->id;????????//報文ID
usSquNo?=?pInnerIcmpHdr->seq;????//序列號
}
else
{
return?false;
}
//檢查ID和序列號以確定收到期待數據報
if?(usID?!=?(USHORT)GetCurrentProcessId()?||?usSquNo?!=?DecodeResult.usSeqNo)
{
return?false;
}
//記錄IP地址并計算往返時間
DecodeResult.dwIPaddr.s_addr?=?pIpHdr->sourceIP;
DecodeResult.dwRoundTripTime?=?GetTickCount()?-?DecodeResult.dwRoundTripTime;
評論
共有 條評論