国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

TCP/IP 網(wǎng)絡(luò)中故障節(jié)點的診斷方法

2008-07-14 10:05于長虹張偉鋒
電腦知識與技術(shù) 2008年18期

于長虹 張偉鋒

摘要:本文描述了一種在TCP/IP網(wǎng)絡(luò)中進行故障節(jié)點診斷的程序?qū)崿F(xiàn),該方法基于VxWorks操作系統(tǒng)的網(wǎng)絡(luò)測試儀環(huán)境,但此程序算法的實現(xiàn),并不依賴于底層的操作系統(tǒng)及硬件環(huán)境,經(jīng)過少量修改可以在任何提供TCP/IP協(xié)議棧的操作系統(tǒng)中實現(xiàn),比如Linux,Windows等。

關(guān)鍵詞:ICMP;TCP;UDP;路由追蹤

中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2008)18-2pppp-0c

1 背景

網(wǎng)路故障的一般表現(xiàn)是網(wǎng)速變慢或者無法訪問互聯(lián)網(wǎng)或內(nèi)網(wǎng)服務(wù)器,在現(xiàn)場進行網(wǎng)絡(luò)故障診斷時,往往需要借助各種工具軟件如Sniffer、ping、traceroute等進行逐步排查,最后經(jīng)過分析,選擇懷疑的網(wǎng)絡(luò)節(jié)點,然后在局端或現(xiàn)場對懷疑的網(wǎng)絡(luò)節(jié)點進行各種連通性、替代性測試,方法步驟繁雜,而且往往無法準確診斷。

經(jīng)過分析,故障診斷的過程,可以使用專用的設(shè)備,并編寫相應(yīng)的診斷程序,自動完成網(wǎng)絡(luò)故障節(jié)點的測試和判斷。

2 算法和設(shè)計

當(dāng)測試節(jié)點到達目的網(wǎng)絡(luò)位置的鏈路存在問題時,一般可能是:物理鏈路斷開(線纜或節(jié)點設(shè)備故障);目的地址的相應(yīng)端口沒有開放,或者中間鏈路經(jīng)過的設(shè)備(交換機,路由器等)禁止了協(xié)議或端口;終端設(shè)備故障。故,處理流程首先是找到測試節(jié)點到達連接服務(wù)器節(jié)點的路徑,確定經(jīng)過的網(wǎng)絡(luò)節(jié)點位置,然后對節(jié)點中的各個位置實施連通性測試,最后根據(jù)測試結(jié)果判斷故障節(jié)點位置和原因。

2.1 網(wǎng)絡(luò)路由的查詢

該部分的功能類似于Linux系統(tǒng)中提供的命令traceroute,不同的是,該部分功能進行路由診斷依賴的協(xié)議不僅僅是ICMP。

ICMP的原理是鏈路上的節(jié)點設(shè)備都要在轉(zhuǎn)發(fā)該 ICMP 回顯請求報文之前將報文頭部的 TTL 值減 1,當(dāng)報文的 TTL 值減少到 0 時,節(jié)點設(shè)備向源發(fā)回 ICMP 超時信息。該診斷實用程序通過向目的地發(fā)送具有不同生存時間 (TTL) 的 ICMP報文,確定至目的地的路由。通過發(fā)送 TTL 為 1 的第一個回顯報文并且在隨后的發(fā)送中每次將 TTL 值加 1,直到目標響應(yīng)或達到最大 TTL 值,可以確定鏈路經(jīng)過的路由。通過檢查鏈路中間節(jié)點設(shè)備發(fā)回的 ICMP 超時信息,可以確定故障節(jié)點。

如果使用ICMP協(xié)議無法完成測試,則改為使用UDP協(xié)議和TCP協(xié)議分別進行路由偵測。源發(fā)出UDP數(shù)據(jù)包,源端口使用隨機的大于32768的高段端口號,目的端口從33434開始依此遞增,直至33434+29,同時TTL從1開始依此遞增,直至1+29=30。節(jié)點設(shè)備送回的 ICMP超時報文,使得源可以偵測到鏈路上每一個節(jié)點。

2.2 網(wǎng)絡(luò)節(jié)點診斷

向節(jié)點發(fā)送TCP握手信號,如果該節(jié)點可以通過connect連接成功,表示節(jié)點可以正常連接,如果回應(yīng)RST,表示該節(jié)點禁止了該端口的訪問,如果該節(jié)點長時間不回復(fù)SYN,也可以認為該節(jié)點禁止端口。

因此,依據(jù)上述現(xiàn)象可以很容易判斷當(dāng)前故障節(jié)點——離測試者最近的故障點,可以被認定為當(dāng)前網(wǎng)絡(luò)故障點。

2.3 故障節(jié)點位置的判斷策略

如果路由尋找完整,一般能夠找到節(jié)點。在所有不回應(yīng)SYN包或者回應(yīng)RST包的

節(jié)點中,應(yīng)該是離源最近跳數(shù)的節(jié)點設(shè)備將端口關(guān)閉。

如果路由尋找不完整,有可能找不到所找的故障點。如果在找到的n個節(jié)點中,只有非最遠離源的一個節(jié)點不回應(yīng),或回應(yīng)RST包,則不能確定故障節(jié)點;如果是包括最遠離源在內(nèi)的一個或多個節(jié)點不回應(yīng)或回應(yīng)RST包,則最右端節(jié)點可能為故障節(jié)點,但并不能確定在整個路由中的故障節(jié)點所在,因為路由不完整。

2.4 不能覆蓋的異常情況

如果使用ICMP和UDP都無法尋找到完整路由,則有可能找不到故障節(jié)點,但這種情況非常少,因為根據(jù)UDP的測試原理,除非中間節(jié)點將大于32768的端口全部封掉,否則都可以得到完整的路由路徑。

3 代碼片段和程序流程

3.1 整體框架代碼

int f_procon_scan_showerr(char *re_info)

{char err_node[16];

inet_ntoa_b(info_scan.node[info_scan.err_num],err_node);

if(err_tcpscan == ERR_PORTSCAN_ROUTE_HALF){

sprintf(re_info,"路由信息不完整,故障點可能是:%s",err_node);

}else if(err_tcpscan == ERR_PORTSCAN_ROUTE_NO){

sprintf(re_info,"未找到達到目的地址的路徑,無法診斷故障");

}else{

sprintf(re_info,"路由信息完整,故障點是:%s",err_node);

}

return OK;

}

static int quitflag=0;

int f_procon_scan_tcp(void)

{char * re_info; /* 測試完后返回的信息 */

int re_find;

int i,rv;

char buf[512];

int numBytes,count;

int on,len;

int ctrlSock;

struct sockaddr_in ctrlAddr;

struct router_node bak_router_node;

sprintf(buf,"正在使用ICMP獲取路由信息...");

server_virtual_display_output(buf,0);

bzero((char *)&info_scan,sizeof(info_scan));

re_find = find_node(0);/*使用ICMP協(xié)議*/

if(info_scan.number == 0){/* 沒有正確找到到目的地址的路由信息,嘗試使用udp協(xié)議查找*/

sprintf(buf,"正在使用UDP獲取路由信息...");

server_virtual_display_output(buf,0);

bzero((char *)&info_scan,sizeof(info_scan));

re_find = find_node(1);/*使用UDP協(xié)議*/

if(info_scan.number == 0){

err_tcpscan = ERR_PORTSCAN_ROUTE_NO;

return OK;

}

}else if(re_find == ERROR){/*獲取不完整路徑,嘗試用udp獲取*/

sprintf(buf,"正在使用UDP獲取路由信息...");

server_virtual_display_output(buf,0);

memcpy(&bak_router_node,&info_scan,sizeof(info_scan));

bzero((char *)&info_scan,sizeof(info_scan));

re_find = find_node(1);/*使用UDP協(xié)議*/

if(info_scan.number == 0){/*udp沒有獲取到路徑,則恢復(fù)icmp的路徑*/

memcpy(&info_scan,&bak_router_node,sizeof(bak_router_node));

re_find=ERROR;

}else if(re_find == ERROR){/*udp獲取的也是不完整路徑,則進行比較,選最多的*/

if(info_scan.number

memcpy(&info_scan,&bak_router_node,sizeof(bak_router_node));

}

}

}

if(re_find == ERROR){

err_tcpscan = ERR_PORTSCAN_ROUTE_HALF;

}else{

err_tcpscan = ERR_PORTSCAN_ROUTE_OK;

}

quitflag=1;

info_scan.node[info_scan.number].s_addr=self_ip;

for(i=info_scan.number-1;i>=0;i--){

/*創(chuàng)建socket*/

ctrlSock = socket (AF_INET, SOCK_STREAM, 0);

if (ctrlSock < 0){

sprintf(buf,"無法創(chuàng)建socket");

server_virtual_display_output(buf,0);

return (ERROR);

}

/*設(shè)置socket為非阻塞模式*/

on=TRUE;

if(ioctl(ctrlSock,FIONBIO,(int)&on)<0){

printf("set socket to no block is error ");

}

ctrlAddr.sin_family= AF_INET;

ctrlAddr.sin_addr.s_addr = info_scan.node[i].s_addr;

ctrlAddr.sin_port= htons(s_procon_info.port);

if(connect(ctrlSock,(struct sockaddr *)&ctrlAddr, sizeof (ctrlAddr))< 0){

if(!((errno==EINPROGRESS) || (errno==EALREADY))){

shutdown(ctrlSock,2);

close(ctrlSock);

continue;

}

}

rv=server_wait_for_write_timeout(ctrlSock,&quitflag);

if(rv!=0){

shutdown(ctrlSock,2);

close(ctrlSock);

break;

}

shutdown(ctrlSock,2);

close(ctrlSock);

}

if(i<0){/*沒有一個通的,或最近的也不通,則認為是最近的有問題*/

i=0;

}else if(i!=info_scan.number-1){/*不是最后一個不同,則認為就是他了*/

i++;

}else if(err_tcpscan == ERR_PORTSCAN_ROUTE_OK){/*最后一個竟然也是通的,則認為是服務(wù)器本身了*/

i++;

}

info_scan.err_num=i;

return OK;

}

3.2 查找路由節(jié)點函數(shù)

static int find_node(int flag)

{int dst_ip, gateway;

int i,num;

int result = OK;

S_TRACERT_INTERFACES info_tracert;

S_TRACERT_INTERS *intrs;

struct in_addr ip_tra;

dst_ip = s_procon_info.ip_remote.s_addr; /* tracert ip is test ip */

switch(s_netcon_info.mode){

case D_NETCON_MODE_STATIC_IP:

gateway = s_netcon_info.sta_ip.ip_router.s_addr;

self_ip = s_netcon_info.sta_ip.ip_local.s_addr;

break;

case D_NETCON_MODE_DHCPC:

gateway = s_netcon_info.dhcpc.ip_router[0].s_addr;

self_ip = s_netcon_info.dhcpc.ip_local.s_addr;

break;

case D_NETCON_MODE_PPPOEH:

gateway = s_netcon_info.pppoeh.ip_remote.s_addr;

self_ip = s_netcon_info.pppoeh.ip_local.s_addr;

break;

}

f_tracert_routine(dst_ip,gateway,flag); /* exec tracert for find node */

/* 如果tracert未結(jié)束,查看是否出現(xiàn)超時找不到路由情況,如果是,終止測試 */

/* 如果tracert停止,看是否追蹤到最終的路由 */

while(!v_tracert_end){

f_tracert_show((char *)&info_tracert); /* 取信息,判斷 */

for(i=0;i

intrs=&info_tracert.tracert_info[i];

ip_tra.s_addr = intrs->ip;

if(intrs->ip == 0){

info_tracert.number -= 1;

f_tracert_end();

result = ERROR;

}

}

taskDelay(sysClkRateGet()/2);

}

f_tracert_show((char *)&info_tracert);

info_scan.number = info_tracert.number;

/* save the node infomation to my struct */

for(i=0;i

intrs=&info_tracert.tracert_info[i];

info_scan.node[i].s_addr = intrs->ip;

}

num = info_scan.number - 1;

if(info_scan.node[num].s_addr == 0){

info_scan.number -= 1;

}

return result;

}

3.3 涉及到的數(shù)據(jù)結(jié)構(gòu)

保存狀態(tài)的結(jié)構(gòu)體。

static struct router_node{

int number; /* 到目的地址能找到的節(jié)點總數(shù) 如果為0,表示未找到路由*/

int err_num; /* 詢查所有節(jié)點,最后一個對端口無回應(yīng)的節(jié)點序號*/

struct in_addr node[31]; /* 用Tracert查到的路由節(jié)點地址 */

char f_send[30]; /* 向相應(yīng)節(jié)點成功發(fā)送TCP SYN包標志 ,成功置 1*/

charf_recv[30]; /* 成功接收各節(jié)點回復(fù)包標志,接收到置 1 */

int send_seq[30]; /* 發(fā)送的各SYN包的SEQ號,用來判斷接收包 */

unsigned char flag[30]; /* 如果接收返回包,保存返回包的TCP FLAG字段 */

}info_scan;

錯誤狀態(tài)如下:

#define ERR_PORTSCAN_ROUTE_NO 0x01

#define ERR_PORTSCAN_ROUTE_OK 0x02

#define ERR_PORTSCAN_ROUTE_HALF 0x03

#define ERR_PORTSCAN_SEND_SYN 0x11 //向網(wǎng)絡(luò)節(jié)點發(fā)送SYN同步包出錯

4 應(yīng)用案例

現(xiàn)有一計算機終端,無法登錄其開通的網(wǎng)絡(luò)多媒體點播服務(wù)系統(tǒng),但可以登錄其它網(wǎng)站,使用網(wǎng)絡(luò)測試儀的網(wǎng)絡(luò)故障診斷軟件來診斷該案例。

首先,通過用戶界面,填入多媒體點播系統(tǒng)的IP地址(如202.102.249.174)極其端口號(1026),然后點擊測試,診斷軟件首先查找從局域網(wǎng)絡(luò)到達202.102.249.174的路由如下:

1<1 ms<1 ms<1 ms192.168.15.1

2 *** Request timed out.

3 2 ms 1 ms 1 mshn.kd.ny.adsl [125.42.110.1]

4<1 ms<1 ms<1 mspc17.zz.ha.cn [61.168.254.17]

5<1 ms<1 ms<1 mspc58.zz.ha.cn [61.168.252.58]

6<1 ms<1 ms<1 ms202.102.249.174

然后,軟件將根據(jù)算法,從最后一個節(jié)點開始診斷,發(fā)現(xiàn)直到hn.kd.ny.adsl時,1026端口的連接測試不能通過,從而確定,問題是因為hn.kd.ny.adsl設(shè)備禁止了1026端口。向局端工程師確認,并修改多媒體登錄系統(tǒng)的端口為其它端口(8080),可以登錄,問題解決。

5 后記

使用該算法的網(wǎng)絡(luò)測試儀產(chǎn)品已經(jīng)研制成功,該產(chǎn)品同時具備了ping、sniffer等更多的網(wǎng)絡(luò)功能,可以更好的替代網(wǎng)絡(luò)維護人員隨聲攜帶的筆記本電腦和其它設(shè)備,簡便地進行網(wǎng)絡(luò)故障的診斷。

參考文獻:

[1](美)科默(Comer,D.E.),林瑤,蔣慧,等,譯.用TCP/IP進行網(wǎng)際互聯(lián)(第1卷):原理、協(xié)議與結(jié)構(gòu).北京:電子工業(yè)出版社,2001,5.

[2](美)W.Richard Stevens,范建華,等,譯.TCP/IP詳解.北京:機械工業(yè)出版社,2000,4.

[3](美)DonnaL.Harrington,童小林,等,譯.CCNP實戰(zhàn)指南:故障排除.北京:人民郵電出版社,2003,12.

[4](美)史蒂文斯,(美)芬納,(美)魯?shù)婪?楊繼張,譯. UNIX網(wǎng)絡(luò)編程.北京:清華大學(xué)出版社,2006,1.

收稿日期:2008-03-10

作者簡介:于長虹(1982-),男,網(wǎng)絡(luò)工程師,主要研究方向:網(wǎng)絡(luò)管理技術(shù);張偉鋒,洛陽師范學(xué)院信息技術(shù)學(xué)院。

会理县| 阿尔山市| 山阳县| 广平县| 女性| 丰都县| 鄂伦春自治旗| 突泉县| 新丰县| 斗六市| 凉城县| 黑水县| 威海市| 靖西县| 都安| 嘉善县| 莱州市| 泌阳县| 石城县| 潍坊市| 宜丰县| 克山县| 饶河县| 健康| 贡嘎县| 德江县| 邵东县| 舒兰市| 大埔区| 宣汉县| 枞阳县| 汶川县| 林口县| 简阳市| 依安县| 儋州市| 靖宇县| 辉县市| 桃江县| 余江县| 侯马市|