• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

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

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

      于長(zhǎng)虹 張偉鋒

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

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

      中圖分類號(hào):TP393文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)18-2pppp-0c

      1 背景

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

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

      2 算法和設(shè)計(jì)

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

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

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

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

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

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

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

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

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

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

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

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

      2.4 不能覆蓋的異常情況

      如果使用ICMP和UDP都無法尋找到完整路由,則有可能找不到故障節(jié)點(diǎn),但這種情況非常少,因?yàn)楦鶕?jù)UDP的測(cè)試原理,除非中間節(jié)點(diǎn)將大于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,"路由信息不完整,故障點(diǎn)可能是:%s",err_node);

      }else if(err_tcpscan == ERR_PORTSCAN_ROUTE_NO){

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

      }else{

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

      }

      return OK;

      }

      static int quitflag=0;

      int f_procon_scan_tcp(void)

      {char * re_info; /* 測(cè)試完后返回的信息 */

      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獲取的也是不完整路徑,則進(jìn)行比較,選最多的*/

      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){/*沒有一個(gè)通的,或最近的也不通,則認(rèn)為是最近的有問題*/

      i=0;

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

      i++;

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

      i++;

      }

      info_scan.err_num=i;

      return OK;

      }

      3.2 查找路由節(jié)點(diǎn)函數(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)超時(shí)找不到路由情況,如果是,終止測(cè)試 */

      /* 如果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é)點(diǎn)總數(shù) 如果為0,表示未找到路由*/

      int err_num; /* 詢查所有節(jié)點(diǎn),最后一個(gè)對(duì)端口無回應(yīng)的節(jié)點(diǎn)序號(hào)*/

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

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

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

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

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

      }info_scan;

      錯(cuò)誤狀態(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é)點(diǎn)發(fā)送SYN同步包出錯(cuò)

      4 應(yīng)用案例

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

      首先,通過用戶界面,填入多媒體點(diǎn)播系統(tǒng)的IP地址(如202.102.249.174)極其端口號(hào)(1026),然后點(diǎn)擊測(cè)試,診斷軟件首先查找從局域網(wǎng)絡(luò)到達(dá)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ù)算法,從最后一個(gè)節(jié)點(diǎn)開始診斷,發(fā)現(xiàn)直到hn.kd.ny.adsl時(shí),1026端口的連接測(cè)試不能通過,從而確定,問題是因?yàn)閔n.kd.ny.adsl設(shè)備禁止了1026端口。向局端工程師確認(rèn),并修改多媒體登錄系統(tǒng)的端口為其它端口(8080),可以登錄,問題解決。

      5 后記

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

      參考文獻(xiàn):

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

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

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

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

      收稿日期:2008-03-10

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

      涟源市| 锡林郭勒盟| 寿阳县| 靖边县| 西丰县| 视频| 新蔡县| 广灵县| 江北区| 资溪县| 茶陵县| 桑日县| 天台县| 中江县| 屏东市| 岚皋县| 泽州县| 利辛县| 宁明县| 五家渠市| 巴里| 博野县| 金湖县| 日喀则市| 邢台市| 进贤县| 吉木萨尔县| 营口市| 成都市| 余干县| 朝阳区| 皮山县| 临沂市| 府谷县| 隆尧县| 芦溪县| 武宣县| 朝阳县| 娱乐| 保亭| 马山县|