原理簡(jiǎn)介:
--------
用RAW Socket實(shí)現(xiàn)的ping可能比上一節(jié)的應(yīng)用ICMP.DLL的程序龐大些, 但是這才是我們需要關(guān)注的東西, 我的觀點(diǎn)真正想做網(wǎng)絡(luò)開(kāi)發(fā)的程序員應(yīng)該靜下心來(lái)讀讀這篇文章, 相信你會(huì)從中獲益頗多. 中間我也會(huì)講解一些東西為后一章的路由追蹤做一些鋪墊.
另一個(gè)重要的要講的東西, 微軟公布隨時(shí)不支持上節(jié)講的ping用到的開(kāi)發(fā)接口, 但是本節(jié)的講的是更一般的東西. 所以它不會(huì)過(guò)時(shí), 甚至做很小的改動(dòng)就可以移植到別的系統(tǒng)上去. 系統(tǒng)移植不是我們的講的重點(diǎn). 但是微軟的長(zhǎng)期支持足以引起我們充分的重視.
如何少作變動(dòng)來(lái)使的這個(gè)程序?qū)崿F(xiàn)追蹤路由的功能, 這里只是拋磚引玉. 將ICMP包中IP包的包頭該為特定的值就能得到那個(gè)路由器的IP(要求到達(dá)目的地的跳數(shù)大于你設(shè)的特定值).
這個(gè)程序需要windows2k/WindowsXP/WindowsNT平臺(tái)和系統(tǒng)治理員的權(quán)限.
具體實(shí)現(xiàn):
--------
這段源代碼大部分來(lái)自:
http://tangentsoft.net/wskfaq/examples/rawping.Html
[bugfree]只做了少量修改,給出了大量的注釋, 最后結(jié)合經(jīng)驗(yàn)給出了自己的建議.
----------
/*
* 程序名: rawping_driver.cpp
* 說(shuō)明:;
*;;;;驅(qū)動(dòng)程序,也是主函數(shù)
*/
#include
#include "rawping.h"
#define DEFAULT_PACKET_SIZE 32// 默認(rèn)ICMP包字節(jié)數(shù)
#define DEFAULT_TTL 30// 默認(rèn)TTL值
#define MAX_PING_DATA_SIZE 1024; // 最大數(shù)據(jù)塊
#define MAX_PING_PACKET_SIZE (MAX_PING_DATA_SIZEsizeof(IPHeader)) //最大ICMP包長(zhǎng)度
/* 為 send_buf 和 recv_buf 分配內(nèi)存
* send_buf大小為 packet_size
* recv_buf大小為 MAX_PING_PACKET_SIZE, 保證大于send_buf
*/
int allocate_buffers(ICMPHeader*& send_buf, IPHeader*& recv_buf,
int packet_size);
///////////////////////////////////////////////////////////////////////
// Program entry point
int main(int argc, char* argv[])
{
int seq_no = 0;//用在發(fā)送和接受的ICMP包頭中
ICMPHeader* send_buf = 0;
IPHeader* recv_buf = 0;
// 判定命令行是否合法
if (argc < 2) {
cerr << "usage: " << argv[0] << "[data_size] [ttl]" <<
endl;
cerr << "tdata_size can be up to " << MAX_PING_DATA_SIZE <<
" bytes.; Default is " << DEFAULT_PACKET_SIZE << "." <<
endl;
cerr << "tttl should be 255 or lower.; Default is " <<
DEFAULT_TTL << "." << endl;
return 1;
}
;// 處理命令行參數(shù)
int packet_size = DEFAULT_PACKET_SIZE;
int ttl = DEFAULT_TTL;
if (argc > 2) {
int temp = atoi(argv[2]);
if (temp != 0) {
packet_size = temp;
}
if (argc > 3) {
temp = atoi(argv[3]);
if ((temp >= 0) && (temp <= 255)) {
ttl = temp;
}
}
}
packet_size = max(sizeof(ICMPHeader),
min(MAX_PING_DATA_SIZE, (unsigned int)packet_size));
// 啟動(dòng) Winsock
WSAData wsaData;
if (WSAStartup(MAKEWord(2, 1), &wsaData) != 0) {
cerr << "Failed to find Winsock 2.1 or better." << endl;
return 1;
}
SOCKET sd; // RAW Socket句柄
sockaddr_in dest, source;
// 三個(gè)任務(wù)(創(chuàng)建sd, 設(shè)置ttl, 初試dest的值)
if (setup_for_ping(argv[1], ttl, sd, dest) < 0) {
goto cleanup; //釋放資源并退出
}
// 為send_buf和recv_buf分配內(nèi)存
if (allocate_buffers(send_buf, recv_buf, packet_size) < 0) {
goto cleanup;
}
// 初試化IMCP數(shù)據(jù)包(type=8,code=0)
init_ping_packet(send_buf, packet_size, seq_no);
// 發(fā)送ICMP數(shù)據(jù)包
if (send_ping(sd, dest, send_buf, packet_size) >= 0) {
while (1) {
// 接受回應(yīng)包
if (recv_ping(sd, source, recv_buf, MAX_PING_PACKET_SIZE)
推薦閱讀
- 哪個(gè)四字成語(yǔ)第二個(gè)字是圓
- 哪個(gè)四字詞語(yǔ)形容人迷茫
- 二 透析ICMP協(xié)議: Windows Socket簡(jiǎn)介
- 三 透析ICMP協(xié)議: 應(yīng)用篇ping(ICMP.dll)
- 哪個(gè)網(wǎng)絡(luò)電視軟件更新電影快
- 一 透析ICMP協(xié)議: 協(xié)議原理
- 亞運(yùn)會(huì)幾年舉辦一次 亞洲亞運(yùn)會(huì)幾年舉辦一次
- 楷書(shū)四大家 楷書(shū)四大家分別指的是
- 高考祝福,高考祝福語(yǔ)四個(gè)字
- 明代四大奇書(shū) 明代四大奇書(shū)指的是
