Linux用ICMP协议实现简单Ping网络监测功能
- #include <stdio.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <netdb.h>
- #define PACKET_SIZE 4096
- #define ERROR 0
- #define SUCCESS 1
- //效验算法(百度下有注释,但是还是看不太明白)
- unsigned short cal_chksum(unsigned short *addr, int len)
- {
- int nleft=len;
- int sum=0;
- unsigned short *w=addr;
- unsigned short answer=0;
- while(nleft > 1)
- {
- sum += *w++;
- nleft -= 2;
- }
- if( nleft == 1)
- {
- *(unsigned char *)(&answer) = *(unsigned char *)w;
- sum += answer;
- }
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- answer = ~sum;
- return answer;
- }
- // Ping函数
- int ping( char *ips, int timeout)
- {
- struct timeval *tval;
- int maxfds = 0;
- fd_set readfds;
- struct sockaddr_in addr;
- struct sockaddr_in from;
- // 设定Ip信息
- bzero(&addr,sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(ips);
- int sockfd;
- // 取得socket
- sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- if (sockfd < 0)
- {
- printf("ip:%s,socket error\n",ips);
- return ERROR;
- }
- struct timeval timeo;
- // 设定TimeOut时间
- timeo.tv_sec = timeout / 1000;
- timeo.tv_usec = timeout % 1000;
- if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) == -1)
- {
- printf("ip:%s,setsockopt error\n",ips);
- return ERROR;
- }
- char sendpacket[PACKET_SIZE];
- char recvpacket[PACKET_SIZE];
- // 设定Ping包
- memset(sendpacket, 0, sizeof(sendpacket));
- pid_t pid;
- // 取得PID,作为Ping的Sequence ID
- pid=getpid();
- struct ip *iph;
- struct icmp *icmp;
- icmp=(struct icmp*)sendpacket;
- icmp->icmp_type=ICMP_ECHO; //回显请求
- icmp->icmp_code=0;
- icmp->icmp_cksum=0;
- icmp->icmp_seq=0;
- icmp->icmp_id=pid;
- tval= (struct timeval *)icmp->icmp_data;
- gettimeofday(tval,NULL);
- icmp->icmp_cksum=cal_chksum((unsigned short *)icmp,sizeof(struct icmp)); //校验
- int n;
- // 发包
- n = sendto(sockfd, (char *)&sendpacket, sizeof(struct icmp), 0, (struct sockaddr *)&addr, sizeof(addr));
- if (n < 1)
- {
- printf("ip:%s,sendto error\n",ips);
- return ERROR;
- }
- // 接受
- // 由于可能接受到其他Ping的应答消息,所以这里要用循环
- while(1)
- {
- // 设定TimeOut时间,这次才是真正起作用的
- FD_ZERO(&readfds);
- FD_SET(sockfd, &readfds);
- maxfds = sockfd + 1;
- n = select(maxfds, &readfds, NULL, NULL, &timeo);
- if (n <= 0)
- {
- printf("ip:%s,Time out error\n",ips);
- close(sockfd);
- return ERROR;
- }
- // 接受
- memset(recvpacket, 0, sizeof(recvpacket));
- int fromlen = sizeof(from);
- n = recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen);
- if (n < 1) {
- break;
- }
- char *from_ip = (char *)inet_ntoa(from.sin_addr);
- // 判断是否是自己Ping的回复
- if (strcmp(from_ip,ips) != 0)
- {
- printf("NowPingip:%s Fromip:%s\nNowPingip is not same to Fromip,so ping wrong!\n",ips,from_ip);
- return ERROR;
- }
- iph = (struct ip *)recvpacket;
- icmp=(struct icmp *)(recvpacket + (iph->ip_hl<<2));
- printf("ip:%s\n,icmp->icmp_type:%d\n,icmp->icmp_id:%d\n",ips,icmp->icmp_type,icmp->icmp_id);
- // 判断Ping回复包的状态
- if (icmp->icmp_type == ICMP_ECHOREPLY && icmp->icmp_id == pid) //ICMP_ECHOREPLY回显应答
- {
- // 正常就退出循环
- break;
- }
- else
- {
- // 否则继续等
- continue;
- }
- }
- int main()
- {
- char cPing[16];
- printf("Please input ping IP:");
- scanf("%s",cPing);
- if(ping(cPing,10000))
- {
- printf("Ping succeed!\n");
- }
- else
- {
- printf("Ping wrong!\n");
- }
- }
测试结果:
Please input ping IP:192.168.1.155
Nowip:192.168.1.155 Fromip:192.168.1.133
Nowip is not same to Fromip,so ping wrong!
Ping wrong!
root@an-virtual-machine:~/wyz/test# ./testping
Please input ping IP:192.168.1.188
ip:192.168.1.188
,icmp->icmp_type:0
,icmp->icmp_id:27865
Ping succeed!
Linux用ICMP协议实现简单Ping网络监测功能的更多相关文章
- ICMP 协议仿真及ping命令用途
1.实验目的 加深对 IPv4 协议首部各定义域的理解,掌握路由表的结构和基本配置命令,熟悉 ICMP 的调试操作. 2.实验原理 IPv4 协议定义,网络层协议的相关 RFC 定义和描述. 3.实验 ...
- 002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)
一.大致流程: 将ICMP头和时间数据设置好后,通过创建好的原始套接字socket发出去.目的主机计算效验和后会将数据原样返回,用当前时间和返回的数据结算时间差,计算出rtt. 二.数据结构: ICM ...
- ICMP协议、DNS、ARP协议、ping、DHCP协议
1.ICMP协议 1)ICMP协议,即:网络控制消息协议(Internet Control Message Protocol) 2)ICMP是网络层协议,因为ICMP报文是装在IP数据报中,作为它的数 ...
- 三、ARP协议和ICMP协议
一.ARP协议 网络设备有数据要发送到另一台网络设备时,必须要知道对方的网络层地址(IP).IP地址由网络层来提供,但是仅有IP地址是不够的,IP数据报文必须封装成帧才能通过数据链路进行发送.数据帧必 ...
- (转)协议森林06 瑞士军刀 (ICMP协议)
协议森林06 瑞士军刀 (ICMP协议) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 到现在为止,我们讲解了网络层中最重要的I ...
- UNIX网络编程——利用ARP和ICMP协议解释ping命令
一.MTU 以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit) ...
- 【网络协议】ICMP协议、Ping、Traceroute
ICMP协议 ICMP常常被觉得是IP层的一个组成部分,它是网络层的一个协议.它传递差错报文以及其它须要注意的信息.ICMP报文通常被IP层或更高层(TCP.UDP等)使用,它是在IP数据报内 ...
- PING的原理以及ICMP协议
主要内容: 1.ping的原理以及工作过程 2.ICMP协议 3.ICMP的应用:ping,traceroute 1.ping的原理以及工作过程 ping的原理 ping 程序是用来探测主机到主机 ...
- 4.ICMP协议,ping和Traceroute
1.IMCP协议介绍 前面讲到了,IP协议并不是一个可靠的协议,它不保证数据被送达,那么,自然的,保证数据送达的工作应该由其他的模块来完成.其中一个重要的模块就是ICMP(网络控制报文)协议. 当传送 ...
随机推荐
- 原根&离散对数简单总结
原根&离散对数 1.原根 1.定义: 定义\(Ord_m(a)\)为使得\(a^d\equiv1\;(mod\;m)\)成立的最小的d(其中a和m互质) 由欧拉定理可知: \(Ord\le\P ...
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
题目 有一个n个点的无向图,给出m条边,每条边的信息形如\(<x,y,c,r>\) 给出q组询问形如\(<u,v,l,r>\) 接下来解释询问以及边的意义 询问表示,一开始你在 ...
- CNN简略总结
https://blog.csdn.net/real_myth/article/details/51824193 池化层的作用: 感受野变化...?? 1*1卷积核的作用 1. 实现跨通道的交互和信息 ...
- mongodb .net 版本
1.现下载驱动 再 引用dll 2.https://www.cnblogs.com/zxtceq/p/7692200.html mongodb .net 版本 https://www.cnbl ...
- 51 Nod 1134 最长递增子序列(经典问题回顾)
1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元 ...
- CodeForces 557C Arthur and Table STL的使用
题意:一个桌子有n条腿,每条腿有一定的长度l,和砍下的花费w,现在规定,桌子稳的条件是长度最长的腿(可多个)的数量大于长度小于它的桌子腿数量,且不存在比他还长的桌子腿,求让桌子腿稳定的最小的花费 #i ...
- jQuery_复制操作
复制操作代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- Linux任务计划及周期性任务执行:at、crontab命令
一.概述 未来的某时间点执行一次某任务:at, batch 周期性运行某任务:crontab 这两个任务的执行结果:会通过邮件发送给用户 (本地终端用户之间的邮件通知) centos 5,6,7默认开 ...
- R_Studio(关联)使用apriori函数简单查看数据存在多少条关联规则,并按支持度降序排序输出
查看数据menu_orders.txt文件存在多少条关联规则,并按支持度降序排序输出 #导入arules包 install.packages("arules") library ( ...
- [CSP-S模拟测试]:硬币(博弈论+DP+拓展域并查集)
题目传送门(内部题135) 输入格式 第一行包含一个整数$T$,表示数据组数. 对于每组数据,第一行两个整数$h,w$,表示棋盘大小. 接下来$h$行,每行一个长度为$w$的字符串,每个位置由为$o, ...