路由追踪的实现

    今天小编将给大家分享我在东北大学上研究生的时候学到的关于路由追踪的实现,希望大家看完小编的这篇博文后能够对windows 下的tracert命令有一定的了解。

    1. 实验目的

    Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据报访问目标所采取的路径。Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由。

    2. 实验环境

    一台具有登陆外网功能的电脑和连通的网络。

    3. 实验内容和要求

    Windows 系统环境
    CMD命令tracert www.baidu.com

    4. 实验原理

   通过向目标发送不同 IP 生存时间 (TTL) 值的“Internet 控制消息协议 (ICMP)”回应数据包,Tracert诊断程序确定到目标所采取的路由。要求路径上的每个路由器在转发数据包之前至少将数据包上的 TTL 递减 1。数据包上的 TTL 减为 0 时,路由器应该将“ICMP 已超时”的消息发回源系统。
Tracert 先发送 TTL 为 1 的回应数据包,并在随后的每次发送过程将 TTL 递增 1,直到目标响应或 TTL 达到最大值,从而确定路由。通过检查中间路由器发回的“ICMP 已超时”的消息确定路由。某些路由器不经询问直接丢弃 TTL 过期的数据包,这在 Tracert 实用程序中看不到。
Tracert 命令按顺序打印出返回“ICMP 已超时”消息的路径中的近端路由器接口列表。如果使用 -d 选项,则 Tracert 实用程序不在每个 IP 地址上查询 DNS。

    5.探测方式

    tracert是Windows下常用的命令行工具,UNIX下与之对应的是traceroute。若想知道自己的电脑到www.aorb. org 经过了多少个路由器,可在命令行下输入tracert www.aorb. org进行探测,返回结果也许会与ping -R相同,但它是以另一种方式实现的。这种方式并没有像Record route options探测技术中使用IP协议包的Options字段,而是利用了IP协议包中的TTL字段。
    基本思路是这样的:www.aorb. org这台服务器即卖茄子(提供HTTP服务),也卖黄瓜(提供FTP服务),但不卖土豆(未监听的UDP端口)。有位买家,为了知道一封信到达蔬菜供应商www.aorb. org中间需要经过几个邮局(路由器),于是写信给www.aorb. org询问土豆的价格。
    第一步,买家在信封的TTL位置写上数字1,当这封信到达与自己相邻的第一个邮局时,邮局的人把TTL值减1,于是TTL为0,邮局章程规定,把TTL值为0的信丢到垃圾桶里,然后给买家发一封名曰超时的信,信上写了丢信邮局的名字,以告诉买家信被谁丢掉了。
    第二步,买家在信封的TTL位置写上数字2,当这封信到达与自己相邻的第一个邮局时,邮局的人把TTL值减1,现在TTL值为1,邮局章程规定, TTL值不为0的数据报需要继续转发给下一个邮局,于是这封信又被转发到了下一个邮局。当下一个邮局收到这封信时,邮局的人把TTL值减1,于是TTL为 0,邮局章程规定,把TTL值为0的信丢到垃圾桶里,然后给买家发一封名曰超时的信,信上写了丢信邮局的名字,以告诉买家信被谁丢掉了。
通过第一步,买家知道了第一个中转路由器。通过第二步,买家知道了第二个中转路由器。那么买家只需要不断的把TTL值加1,便可根据如上步骤探测出中间经过了哪些路由器。
    第三步,我们假设中间只经过两个邮局信便到达目的地了。接着第二步,买家选在把TTL值设置为3,当这封信到达与自己相邻的第一个邮局时,邮局的人把TTL值减1,现在TTL值为2,邮局章程规定,TTL值不为0的数据报需要继续转发给下一个邮局,于是这封信又被转发到了下一个邮局。当下一个邮局收到这封信时,邮局的人把TTL值减1,于是TTL为1,邮局章程规定,TTL值不为0的数据报需要继续转发给下一个邮局,于是这封信又被转发到了下一个邮局,但下一个邮局已经就是最终目的地www.aorb .org了,尽管www.aorb .org把TTL减1的结果为0,但却不会丢弃它,因为目的地就是 www.aorb. org呀!于是www.aorb .org把这个IP层邮递员送来的信交付给负责卖土豆人,但我们开始说了,www.aorb .org并不卖土豆,于是就回送一个名曰终点不可达(ICMP类型为3,代码为3)的信给买家。
    第四步,当买家收到类型为终点不可达的信时,就不再把那封问土豆价格的信上的TTL加1了,因为他已经知道了到达目的地的全部路由。

    6.源代码

#pragma pack(4)
#pragma comment(lib, "ws2_32.lib")#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>#include <stdio.h>
#include <stdlib.h>//
// ICMP 消息类型
//
#define ICMP_ECHOREPLY      0
#define ICMP_DESTUNREACH    3
#define ICMP_SRCQUENCH      4
#define ICMP_REDIRECT       5
#define ICMP_ECHO           8
#define ICMP_TIMEOUT       11
#define ICMP_PARMERR       12#define MAX_HOPS           30#define ICMP_MIN 8    //ICMP报文最小长度(仅仅头部)//
// IP分组头部
//
typedef struct iphdr
{unsigned int   h_len : 4;        // Length of the headerunsigned int   version : 4;      // Version of IPunsigned char  tos;            // Type of serviceunsigned short total_len;      // Total length of the packetunsigned short ident;          // Unique identifierunsigned short frag_and_flags; // Flagsunsigned char  ttl;            // Time to liveunsigned char  proto;          // Protocol (TCP, UDP etc)unsigned short checksum;       // IP checksumunsigned int   sourceIP;       // Source IPunsigned int   destIP;         // Destination IP
} IpHeader;//
// ICMP 数据报头部
//
typedef struct _ihdr
{BYTE   i_type;               // ICMP message typeBYTE   i_code;               // Sub codeUSHORT i_cksum;USHORT i_id;                 // Unique idUSHORT i_seq;                // Sequence number// This is not the std header, but we reserve space for timeULONG timestamp;
} IcmpHeader;#define DEF_PACKET_SIZE         32
#define MAX_PACKET            1024
//打印用户信息
void usage(char *progname)
{printf("usage: %s host-name [max-hops]\n", progname);getchar();ExitProcess(-1);
}
// 设置存活时间
int set_ttl(SOCKET s, int nTimeToLive)
{int     nRet;nRet = setsockopt(s, IPPROTO_IP, IP_TTL, (LPSTR)&nTimeToLive,sizeof(int));if (nRet == SOCKET_ERROR){printf("setsockopt(IP_TTL) failed: %d\n",WSAGetLastError());return 0;}return 1;
}// 对回应尽心编译
int decode_resp(char *buf, int bytes, SOCKADDR_IN *from, int ttl)
{IpHeader       *iphdr = NULL;			//ip头部IcmpHeader     *icmphdr = NULL;			//icmp头部unsigned short  iphdrlen;				//ip头部长度struct hostent *lpHostent = NULL;		//host实体struct in_addr  inaddr = from->sin_addr;//ipv4 网络地址iphdr = (IpHeader *)buf;// Number of 32-bit words * 4 = bytesiphdrlen = iphdr->h_len * 4;if (bytes < iphdrlen + ICMP_MIN)		//ip分组长度过段printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));icmphdr = (IcmpHeader*)(buf + iphdrlen);switch (icmphdr->i_type){case ICMP_ECHOREPLY:     // Response from destinationlpHostent = gethostbyaddr((const char *)&from->sin_addr,AF_INET, sizeof(struct in_addr));if (lpHostent != NULL)printf("%2d  %s (%s)", ttl, lpHostent->h_name,inet_ntoa(inaddr));return 1;break;case ICMP_TIMEOUT:      // Response from router along the wayprintf("%2d  %s/n", ttl, inet_ntoa(inaddr));return 0;break;case ICMP_DESTUNREACH:  // Can't reach the destination at allprintf("%2d  %s  reports: Host is unreachable\n", ttl,inet_ntoa(inaddr));return 1;break;default:printf("non-echo type %d recvd\n", icmphdr->i_type);return 1;break;}return 0;
}//检测和
USHORT checksum(USHORT *buffer, int size)
{unsigned long cksum = 0;while (size > 1){cksum += *buffer++;size -= sizeof(USHORT);}if (size)cksum += *(UCHAR*)buffer;cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >> 16);return (USHORT)(~cksum);
}//填充ICMP数据
void fill_icmp_data(char * icmp_data, int datasize)
{IcmpHeader *icmp_hdr;char       *datapart;icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO;icmp_hdr->i_code = 0;icmp_hdr->i_id = (USHORT)GetCurrentProcessId();icmp_hdr->i_cksum = 0;icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader);//// Place some junk in the buffer. Don't care about the data...//memset(datapart, 'E', datasize - sizeof(IcmpHeader));
}//
// Function: main
// 
int main(int argc, char **argv)
{WSADATA         wsd;SOCKET          sockRaw;HOSTENT         *hp = NULL;SOCKADDR_IN     dest, from;int     ret;int     datasize;int     fromlen = sizeof(from);int     timeout;int     done = 0;int     maxhops;int     ttl = 1;char    *icmp_data;char    *recvbuf;BOOL    bOpt;USHORT  seq_no = 0;// Initialize the Winsock2 DLL//if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){printf("WSAStartup() failed: %d\n", GetLastError());return -1;}if (argc < 2)usage(argv[0]);if (argc == 3)maxhops = atoi(argv[2]);elsemaxhops = MAX_HOPS;sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP,NULL, 0, WSA_FLAG_OVERLAPPED);if (sockRaw == INVALID_SOCKET){printf("WSASocket() failed: %d\n", WSAGetLastError());ExitProcess(-1);}timeout = 1000;ret = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO,(char *)&timeout, sizeof(timeout));if (ret == SOCKET_ERROR){printf("setsockopt(SO_RCVTIMEO) failed: %d\n",WSAGetLastError());return -1;}timeout = 1000;ret = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO,(char *)&timeout, sizeof(timeout));if (ret == SOCKET_ERROR){printf("setsockopt(SO_SNDTIMEO) failed: %d\n",WSAGetLastError());return -1;}ZeroMemory(&dest, sizeof(dest));dest.sin_family = AF_INET;if ((dest.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE){hp = gethostbyname(argv[1]);if (hp)memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);else{printf("Unable to resolve %s\n", argv[1]);ExitProcess(-1);}}datasize = DEF_PACKET_SIZE;datasize += sizeof(IcmpHeader);icmp_data = (char *)(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET));recvbuf = (char *)(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET));if ((!icmp_data) || (!recvbuf)){printf("HeapAlloc() failed %d\n", GetLastError());return -1;}bOpt = TRUE;if (setsockopt(sockRaw, SOL_SOCKET, SO_DONTROUTE, (char *)&bOpt,sizeof(BOOL)) == SOCKET_ERROR)printf("setsockopt(SO_DONTROUTE) failed: %d\n",WSAGetLastError());memset(icmp_data, 0, MAX_PACKET);fill_icmp_data(icmp_data, datasize);printf("/nTracing route to %s over a maximum of %d hops:\n\n",argv[1], maxhops);for (ttl = 1; ((ttl < maxhops) && (!done)); ttl++){int bwrote;((IcmpHeader*)icmp_data)->i_cksum = 0;((IcmpHeader*)icmp_data)->timestamp = GetTickCount();((IcmpHeader*)icmp_data)->i_seq = seq_no++;((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,datasize);bwrote = sendto(sockRaw, icmp_data, datasize, 0,(SOCKADDR *)&dest, sizeof(dest));if (bwrote == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT){printf("%2d  Send request timed out. \n", ttl);continue;}printf("sendto() failed: %d\n", WSAGetLastError());return -1;}ret = recvfrom(sockRaw, recvbuf, MAX_PACKET, 0,(struct sockaddr*)&from, &fromlen);if (ret == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT){printf("%2d  Receive Request timed out. \n", ttl);continue;}printf("recvfrom() failed: %d \n", WSAGetLastError());return -1;}done = decode_resp(recvbuf, ret, &from, ttl);Sleep(1000);}HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data);getchar();return 0;
}

    7.实验结果

    

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/256638.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

31.traceroute命令进行路由跟踪

路由跟踪功能是用来识别一个设备到另一个设备的网络路径。在一个简单的网络上&#xff0c;这个网络路径可能只经过一个路由器&#xff0c;甚至一个都不经过。但是在复杂的网络中&#xff0c;数据包可能要经过数十个路由器才会到达最终目的地。在通信过程中&#xff0c;可以通过…

路由追踪traceroute分析

原文 &#xff1a; http://www.freebuf.com/articles/network/118221.html 一、路由追踪程序traceroute/tracert Traceroute是Linux和Mac OS等系统默认提供的路由追踪小程序&#xff0c;Tracert是Windows系统默认提供的路由追踪小程序。二者的功能相同&#xff0c;都能探测数据…

路由跟踪(tracert、traceroute)简析

WINDOWS平台命令&#xff1a; tracert LINUX平台命令&#xff1a; traceroute 简介&#xff1a; Tracert&#xff08;traceroute&#xff09; 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由。用来跟踪到目的IP所经过路径 原理简…

【Rust 日报】2023-05-28 一个构建在TCP上的聊天工具

tcp-chat&#xff1a;构建在TCP上的简单快速轻量的聊天工具 tcp-chat通过TCP进行通信&#xff0c;该项目的目的是了解并行性和底层网络通信。 前端工具&#xff1a;Solid、Tauri、Vite 后端工具&#xff1a;Rust、Tokio、Serde GitHub: https://github.com/gatomod/tcp-chat ez…

设计模式之~命令模式

定义&#xff1a; 命令模式&#xff08;Command&#xff09;&#xff0c;将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。 为什么需要命令模式? 在我们的软件开发系统中…

c++ 11标准模板(STL) std::map(九)

定义于头文件<map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class map;(1)namespace pmr { template <class Key, class T, clas…

Linux常用命令——gzexe命令

在线Linux命令查询工具 gzexe 用来压缩可执行文件 补充说明 gzexe命令用来压缩可执行文件&#xff0c;压缩后的文件仍然为可执行文件&#xff0c;在执行时进行自动解压缩。当您去执行被压缩过的执行文件时&#xff0c;该文件会自动解压然后继续执行&#xff0c;和使用一般的…

设计模式之~组合模式

组合模式&#xff1a; 将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 结构图&#xff1a; 实例&#xff1a; 透明方式&#xff1a; leaf中也有add和remove叫做透明方式&#xff0c;在component中声明所有用来管…

玩具租借小程序

玩具是儿童的必需品&#xff0c;家长每年都会给孩子购买少则几百多则几千的玩具&#xff0c;但是由于孩子对玩具喜新 厌旧&#xff0c;一个几百元的玩具几天就不感兴趣了&#xff0c;而市场上层出不穷的高价玩具及孩子对玩具永不满足的渴求&#xff0c;都在促使家长对"玩具…

租号网程序源码 无错版本完整无缺

介绍&#xff1a; 注意事项&#xff1a; 安装租号程序 需要WIN08服务器 iis7.0 sq2012 NET4.6 程序直接放入设置好的 网站根目录即可 (SA密码设置yixiaoka888) 网盘下载地址&#xff1a; http://kekewl.cc/tJoeIk6qPlJ 图片&#xff1a;

在线游戏租号声优陪玩网站源码+威客平台源码/亲测

正文: 由于标题太长了&#xff0c;所以本文标题简略写了&#xff0c;下方图片才是程序完整标题: 这系统界面美观&#xff0c;功能非常齐全&#xff0c;已对接支付&#xff0c;亲测可用&#xff0c;有详细的安装教程&#xff0c;全部放压缩包里了&#xff0c;有兴趣自己去看。 …

麒麟子出了一款免费3D角色虚拟摇杆控制器!这也太好用了

不需要编写代码&#xff0c;通过简单的拖拽和配置&#xff0c;就可以使你在手机上控制摄像机旋转和操作角色。 EasyJoystick EasyCamera EasyTouch 以上效果就 麒麟子 最近在 Cocos Store 分享的 KylinsEasyController 组件源码&#xff0c;它包含以下主要特性&#xff1a; 虚拟…

租赁小程序源码芝麻免押租机平台手机租赁代运营

租赁小程序 手机租赁 小程序代运营 租赁 免押租 代运营 上征信 银行风控 芝麻免押 支付宝服务商 支付宝租赁服务商 租赁平台源码 租赁小程序源码 租机平台源码 手机租赁源码 租赁小程序源码 芝麻免押租 租赁平台 小程序源码

如何在雷电模拟器里使用YiLu代理的动态ip?

1在易路“程序”页面里随意添加一个应用&#xff0c;请不要添加“雷电”到YiLu程序里&#xff1b; 2.YiLu设置&#xff1a; ① 点击YiLu“设置”页面&#xff1b; ② 选择“YiLu便携代理引擎”&#xff1b; ③ 选择“仅代理YiLu程序选项卡中的应用程序&#xff0c;其他通过您…

原神抢码,米游社抢码-首发

本文章仅供学习使用-侵权请联系删除_2023年3月14日08:17:06 本来在深渊12层打不过的我偶然在刷到了一个dy的直播间&#xff0c;看到主播在抢码上号帮忙打深渊还号称痛苦号打不满不送原石的旗号我就决定扫码试试&#xff0c;在直播间内使用了两部手机互相扫码在扫了一下午的码后…

腾讯大王卡扫号器

正文开始》》花莳王卡扫号器不做任何收益动作&#xff0c;要过年了坑逼多。该信息可以让你自行辨别是否交智商费《正文结束 --------------------------------------------------------------------------------------------------------------------------------------------…

剖析CPU性能火焰图生成的内部原理

关注开发内功修炼&#xff0c;掌握硬核技术原理 大家好&#xff0c;我是飞哥&#xff01; 在进行CPU性能优化的时候&#xff0c;我们经常先需要分析出来我们的应用程序中的CPU资源在哪些函数中使用的比较多&#xff0c;这样才能高效地优化。一个非常好的分析工具就是《性能之巅…

上号神器|王者扫码登录教程,苹果安卓通用扫码教程(建议收藏)

大家好&#xff0c;我是上号神器&#xff0c;很多玩王者的小伙伴都不知道怎么通过扫码进行登录王者&#xff0c;下面就为大家说下上号神器的使用教程&#xff0c;不用卸载微信也能登录王者号&#xff0c;十分地方便快捷&#xff01; 首先玩家需要进入上号神器地址&#xff08;…

多家游戏交易平台发声,禁止未成年人买号租号

游戏租号绕开防沉迷系统事件迎来下文。9 月7 日&#xff0c;DD3737、交易猫、5173 等游戏交易平台相继发布声明&#xff0c;已采取严格措施禁止任何未成年人利用游戏交易平台买卖和租赁游戏账号。 同时&#xff0c;上述游戏交易平台还呼吁&#xff1a;游戏出版、发行、运营、交…

app账号退不出去_怎么去和平精英租号平台APP上租号玩和平精英

怎么去和平精英租号平台APP上GG租号租玩和平精英了&#xff1f;首选给大家讲解下和平精英租号平台App的一些功能介绍。 租号平台app可以让用户在这个平台上&#xff0c;拥有武器和皮肤的软件平台&#xff0c;用户有了这款软件后&#xff0c;就在也不用充钱来购买武器和装备&…