VC++基于ICMP 遍历路由表
来源:互联网 发布:淘宝账户被冻结求解冻 编辑:程序博客网 时间:2024/06/10 05:33
ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
CMP协议是一种面向非连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,它对于网络安全具有极其重要的意义。
它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
ICMP原理ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型,并确定如何才能更好地重发失败的数据包。但是ICMP唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成。
我们在网络中经常会使用到ICMP协议,比如我们经常使用的用于检查网络通不通的Ping命令(Linux和Windows中均有),这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。
ICMP的全称是 Internet Control Message Protocol 。从技术角度来说,ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性﹐其功能主要有:
· 侦测远端主机是否存在。
· 建立及维护路由资料。
· 重导资料传送路径。
· 资料流量控制。 ICMP常用类型 ICMP常用类型ICMP在沟通之中,主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连线状况。常用的类别如下表所列﹕
ICMP 是个非常有用的协议﹐尤其是当我们要对网路连接状况进行判断的时候。下面让我们看看常用的 ICMP 实例,以更好了解 ICMP 的功能与作用。
ICMP协议对于网络安全具有极其重要的意义。ICMP协议本身的特点决定了它非常容易被用于攻击网络上的路由器和主机。例如,在1999年8月海信集团“悬赏”50万元人民币测试防火墙的过程中,其防火墙遭受到的ICMP攻击达334050次之多,占整个攻击总数的90%以上!可见,ICMP的重要性绝不可以忽视!
比如,可以利用操作系统规定的ICMP数据包最大尺寸不超过64KB这一规定,向主机发起“Ping of Death”(死亡之Ping)攻击。“Ping of Death” 攻击的原理是:如果ICMP数据包的尺寸超过64KB上限时,主机就会出现内存分配错误,导致TCP/IP堆栈崩溃,致使主机死机。(现在的操作系统已经取消了发送ICMP数据包的大小的限制,解决了这个漏洞)
此外,向目标主机长时间、连续、大量地发送ICMP数据包,也会最终使系统瘫痪。大量的ICMP数据包会形成“ICMP风暴”,使得目标主机耗费大量的CPU资源处理,疲于奔命。
请见代码
#include <stdio.h>CInitSock theSock;typedef struct icmp_hdr{ unsigned char icmp_type;// 消息类型 unsigned char icmp_code;// 代码 unsigned short icmp_checksum;// 校验和// 下面是回显头 unsigned short icmp_id;// 用来惟一标识此请求的ID号,通常设置为进程ID unsigned short icmp_sequence;// 序列号 unsigned long icmp_timestamp; // 时间戳} ICMP_HDR, *PICMP_HDR;void main(){char *szDestIp = "10.16.115.178"; // 210.181.18.12910.16.115.25 61.55.66.30char recvBuf[1024] = { 0 };// 创建用于接收ICMP封包的原始套节字,绑定到本地端口SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);sockaddr_in in;in.sin_family = AF_INET;in.sin_port = 0;in.sin_addr.S_un.S_addr = INADDR_ANY;if(::bind(sRaw, (sockaddr*)&in, sizeof(in)) == SOCKET_ERROR){printf(" bind() failed \n");return;}SetTimeout(sRaw, 5*1000);// 创建用于发送UDP封包的套节字SOCKET sSend = ::socket(AF_INET, SOCK_DGRAM, 0);SOCKADDR_IN destAddr;destAddr.sin_family = AF_INET;destAddr.sin_port = ::htons(22);destAddr.sin_addr.S_un.S_addr = ::inet_addr(szDestIp);int nTTL = 1;int nRet;ICMP_HDR *pICMPHdr;int nTick;SOCKADDR_IN recvAddr;do{// 设置UDP封包的TTL值SetTTL(sSend, nTTL);nTick = ::GetTickCount();// 发送这个UDP封包nRet = ::sendto(sSend, "hello", 5, 0, (sockaddr*)&destAddr, sizeof(destAddr));if(nRet == SOCKET_ERROR){printf(" sendto() failed \n");break;}// 等待接收路由器返回的ICMP报文int nLen = sizeof(recvAddr);nRet = ::recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&recvAddr, &nLen);if(nRet == SOCKET_ERROR){if(::WSAGetLastError() == WSAETIMEDOUT){printf(" time out \n");break;}else{printf(" recvfrom() failed \n");break;}}// 解析接收到的ICMP数据pICMPHdr = (ICMP_HDR*)&recvBuf[20]; // sizeof(IPHeader)if(pICMPHdr->icmp_type != 11 && pICMPHdr->icmp_type != 3 && pICMPHdr->icmp_code != 3){printf(" Unexpected Type: %d , code: %d \n",pICMPHdr->icmp_type, pICMPHdr->icmp_code);}else{char *szIP = ::inet_ntoa(recvAddr.sin_addr);printf(" 第%d个路由器,IP地址:%s \n", nTTL, szIP);printf(" 用时:%d毫秒 \n", ::GetTickCount() - nTick);}if(destAddr.sin_addr.S_un.S_addr == recvAddr.sin_addr.S_un.S_addr){printf("目标可达 \n");break;}printf("//------------------------------------// \n");}while(nTTL++ < 20);::closesocket(sRaw);::closesocket(sSend);}
- VC++基于ICMP 遍历路由表
- VC++获取路由表
- ICMP测试延迟!和路由!
- Windows 7 环境下基于原始套接字和ICMP的路由探测开发的问题【1】
- vc++ ICMP后门后门程序
- 基于ICMP木马的编写
- 基于ICMP木马的编写
- 基于icmp的ping函数
- VC++ 实现获取路由表信息
- VC模拟ping发送ICMP数据包
- VC++分析数据包实现ICMP协议分析
- VC模拟ping发送ICMP数据包
- VC动态添加路由
- VC++实现路由跟踪
- VC++实现路由跟踪
- 透析ICMP协议(五): 应用篇路由追踪
- 透析ICMP协议(五): 应用篇路由追踪
- 透析ICMP协议(五): 应用篇路由追踪
- hibernate的缓存机制
- 通才还是专才——由摩托裁员引发的讨论
- tomcat绿色版及安装版修改内存大小的方法
- 求子数组的最大和
- 关于JDBC(一)--- JDBC配置
- VC++基于ICMP 遍历路由表
- 19.Java序列化【草案一】
- 一个数据应用闭环
- 加多一個debug protocol去qemu是可能的
- VC++实现ARP协议
- 色彩立体模型软件的编写
- 缓存
- javaScript快速排序
- VC++获取路由表