Linux下用ICMP协议,进行路由多端口尝试探测
2015-03-18 09:27
399 查看
路由器通常会有多个端口,而多个端口的ip可能又处在不同的网段中,以实现不同网段间的数据转发。对于特定路由拓扑的发现,探测路由的端口还是有一定价值的。
编程思路:
在已经知道路由的某个端口下,构造一个udp数据包
将数据包发送到路由的某个不可用的高端口(使路由回复端口不可达的icmp数据包)
接收数据包,分析是否有端口不可达的icmp数据包
如果有,则检测是否是同一ip返回的数据,如果ip不同,则很大程度上认为此不同的ip即为另一端口(可以多次测量,并保证数据请求的单一性)
当然此种方法存在着很大的不足:
通常情况下,路由的路径相对稳定,返回的icmp通常也就是原来的路由端口(已知)
代码说明:
只简易的实现了基本流程,没有对接收时的等待时间作限制,容易在此处卡掉
对于路由高端口的选择,也只是随机得挑了一个
这种测试方法,一般会对同一路由进行多次探测,而代码仅有一次流程
代码仅作参考
编程思路:
在已经知道路由的某个端口下,构造一个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 packet int check_packet(u_char *databuf,int buflen); int main(int argc,char* argv[]) { struct sockaddr_in hostaddr; //aim host address struct sockaddr_in localaddr; //local host address int sendsock,recvsock; //two socket if(argc!=2) { printf("this programe need one argument:host ip\n"); return 0; } //fill aim host address bzero(&hostaddr,sizeof(hostaddr)); hostaddr.sin_family=AF_INET; hostaddr.sin_port=htons(55555); //TEST port hostaddr.sin_addr.s_addr=inet_addr(argv[1]); //fill local host address bzero(&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 socket if((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 socket if((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 send char buf[40]; ///test memset(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 packet if((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 backdata if(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 packet int check_packet(u_char *databuf,int buflen) { struct ip *ip=(struct ip *)databuf; int hlen=ip->ip_hl<<2; //total ip header length if(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; } }
相关文章推荐
- Linux 环境下部署Hadoop 2.x,建议尝试64位系统下进行本地编译的安装方式
- linux下,调用ping指令和traceroute指令进行路由验证。
- SUSE iptable 和如何采用LINUX进行简单路由
- Linux下利用PC机进行路由转发将Linux变成一台路由器
- Linux 环境下部署Hadoop 2.x,建议尝试64位系统下进行本地编译的安装方式
- 配置电信网通双线双IP的解决办法(Linux Ip Route2,基于源地址进行路由选择)
- 通过探测邮件服务器进行Email地址有效性检验
- 基于Linux核心的汉字显示的尝试
- 对Linux系统进行配置应该养成做备份的习惯--个人总结
- Linux下利用ppp-on脚本进行GPRS拨号上网
- linux 多线程用信号量进行同步例子
- 政府和微软正在进行着一场暧昧的游戏,在这场游戏中,Linux的角色就是那个用来敲打“蝴蝶”的苍蝇拍
- linux解决南北网络访问速度慢的问题!双线路自动路由!
- adsl在linux下的路由
- 在linux下设置永久路由的方法
- 对 Linux 内核进行压力测试
- [原创]Linux下进行Java开发的一些小技巧
- 在LINUX下挂载WINDOWS分区和听MP3的尝试
- 微软称不需要借助Longhorn与Linux进行竞争
- Linux策略性路由应用及深入分析