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(网络控制报文)协议. 当传送 ...
随机推荐
- npoi 导入
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CusImport.aspx ...
- Resttemplate请求失败如何获取返回的json
参考:https://blog.csdn.net/u011974797/article/details/82424004 https://www.cnblogs.com/liumz0323/p/106 ...
- 大视频上传T级别解决方案
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- [LOJ6433][PKUSC2018]最大前缀和:状压DP
分析 我们让每个数列在第一个取到最大前缀和的位置被统计到. 假设一个数列在\(pos\)处第一次取到最大前缀和,分析性质,有: 下标在\([1,pos]\)之间的数形成的数列的每个后缀和(不包括整个数 ...
- 【转】【Linux经验】Codeblocks 13.12自动补全 、缩进解决
最近使用Xubuntu 14.04学习C语言编程,发现了Codeblocks这款比较方便简单.适合我这种新手的IDE.之前用过Codeblocks10.04,它的代码自动补全和自动缩进让我眼前一亮.但 ...
- codefroces Round #201.a--Difference Row
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description You wa ...
- R_Studio(决策树算法)鸢尾花卉数据集Iris是一类多重变量分析的数据集【精】
鸢尾花卉数据集Iris是一类多重变量分析的数据集 通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类 针对 ...
- RedisTemplate与zset
Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有 ...
- STS(Spring tool suite)集成配置jdk,maven和Tomcat
STS是spring官网的一个集成开发工具,最近在学springboot,所以用了. 在本文中将介绍如下内容: 搭建开发的 JDK(1.8) 环境. 配置 Maven 环境. 配置 Tomcat 环境 ...
- ajax异步加载查询数据库
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...