Linux下用ICMP协议,进行路由多端口尝试探测
来源:互联网 发布:像素画软件 编辑:程序博客网 时间:2024/06/07 14:29
路由器通常会有多个端口,而多个端口的ip可能又处在不同的网段中,以实现不同网段间的数据转发。对于特定路由拓扑的发现,探测路由的端口还是有一定价值的。
编程思路:
在已经知道路由的某个端口下,构造一个udp数据包
将数据包发送到路由的某个不可用的高端口(使路由回复端口不可达的icmp数据包)
接收数据包,分析是否有端口不可达的icmp数据包
如果有,则检测是否是同一ip返回的数据,如果ip不同,则很大程度上认为此不同的ip即为另一端口(可以多次测量,并保证数据请求的单一性)
当然此种方法存在着很大的不足:
通常情况下,路由的路径相对稳定,返回的icmp通常也就是原来的路由端口(已知)
代码说明:
只简易的实现了基本流程,没有对接收时的等待时间作限制,容易在此处卡掉
对于路由高端口的选择,也只是随机得挑了一个
这种测试方法,一般会对同一路由进行多次探测,而代码仅有一次流程
代码仅作参考
/** * date:2015-03-15 * author:zhang mou ren * purpose:use the udp and icmp to get router's names (IPs,ports); * * */#include <stdio.h>#include <string.h>#include <sys/time.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#include <netinet/udp.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#define MAXPACKET 65535 //MAX size of ip packetint check_packet(u_char *databuf,int buflen);int main(int argc,char* argv[]){struct sockaddr_in hostaddr; //aim host addressstruct sockaddr_in localaddr; //local host addressint sendsock,recvsock; //two socketif(argc!=2) {printf("this programe need one argument:host ip\n");return 0;}//fill aim host addressbzero(&hostaddr,sizeof(hostaddr));hostaddr.sin_family=AF_INET;hostaddr.sin_port=htons(55555); //TEST porthostaddr.sin_addr.s_addr=inet_addr(argv[1]); //fill local host addressbzero(&localaddr,sizeof(localaddr));localaddr.sin_family=AF_INET;localaddr.sin_port=htons(55551); //TEST port localaddr.sin_addr.s_addr=htonl(INADDR_ANY);//create send socketif((sendsock=socket(AF_INET,SOCK_DGRAM,0))==-1){printf("create send udp socket fail\n");return 0;} if(bind(sendsock,(struct sockaddr *)&localaddr,sizeof(localaddr))==-1){printf("create bind upd socket fail\n");return 0;}//create receive socketif((recvsock=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==-1){printf("create receive socket fail,raw socket need root\n");return 0;}//test a simple process//create a udp//receive the backdata//analyse the backdata//create a udp and sendchar buf[40]; ///testmemset(buf,0,sizeof(buf));int n;//int ttl=220; //test//set TTL //if(setsockopt(sendsock,IPPROTO_IP,IP_TTL,(char *)&ttl,sizeof(ttl))==-1)//{//printf("set ttl fail\n");//return 0;//}//send upd packetif((n=sendto(sendsock,buf,40,0,(struct sockaddr *)&hostaddr,sizeof(struct sockaddr_in)))==-1){printf("send packet fail\n");return 0;}if(n!=40){printf("send packet not complete\n");return 0;}//receive the backdata char databuf[MAXPACKET];struct sockaddr_in from;int len=sizeof(struct sockaddr_in);printf("start receive data\n");if((n=recvfrom(recvsock,databuf,MAXPACKET,0,(struct sockaddr *)&from,&len)) == -1){printf("receive packet fail\n");return 0;} //analyse the backdataif(check_packet(databuf,sizeof(databuf))==1) { printf("analyse the host ip\n"); printf("host ip:%s\n",inet_ntoa(from.sin_addr)); }return 0;}//check the icmp packetint check_packet(u_char *databuf,int buflen){struct ip *ip=(struct ip *)databuf;int hlen=ip->ip_hl<<2; //total ip header lengthif(ip->ip_p!=IPPROTO_ICMP){printf("not icmp packet\n");return 0;}struct icmp *icmp=(struct icmp *)(databuf+hlen);printf("receive ICMP tpye = %d \n",icmp->icmp_type);printf("receive ICMP code = %d \n",icmp->icmp_code); //the port is unreachable if(icmp->icmp_type==3 && icmp->icmp_code ==3) { printf("we get success!\n"); return 1; }}
0 0
- Linux下用ICMP协议,进行路由多端口尝试探测
- PING分组网间探测 ICMP协议
- Windows 7 环境下基于原始套接字和ICMP的路由探测开发的问题【1】
- Linux 下Jetty多端口启动
- lINUX iCmp协议
- 如何在同一Tomcat下进行多端口配置
- Linux下利用ICMP协议实现ping命令
- linux下apache配置多端口对应多个虚拟目录
- Linux下Apache 多端口多站点配置方法
- 构造ICMP数据包探测数据由主机到目标机的路由
- Linux用ICMP协议实现简单Ping网络监测功能
- Linux用ICMP协议实现简单Ping网络监测功能
- Linux用ICMP协议实现简单Ping网络监测功能
- MySQL 多端口 For Linux
- Linux服务器多端口配置
- linux上mysql多端口
- 透析ICMP协议(五): 应用篇路由追踪
- 透析ICMP协议(五): 应用篇路由追踪
- 手机/移动前端开发需要注意的20个要点
- 第1周项目5-时间类(2)
- C++中的string 类 简单介绍
- 竞态编程相关接口
- listview当选中某一个item时设置背景色其他的不变
- Linux下用ICMP协议,进行路由多端口尝试探测
- 第二周 项目二 长方柱类
- Linux下的 fork 函数
- 从最简单的实例学习ARM指令集
- 项目4-图书馆的书
- 设置背景图像平铺
- 第二周 程序阅读并回答问题
- 第一周实践:旱冰场造价
- 网络字节序、大端模式、小端模式