ping功能实现(ICMP)
简单记录下项目中ping功能实现
笔记:ping功能实现
void Handler::handlePingDepot(const char *ip)
{
int mSize=50*1024;
bzero(&mDestAddr,sizeof(mDestAddr));
mDestAddr.sin_family = AF_INET;
mDestAddr.sin_addr.s_addr = inet_addr(ip);
if( (mSockFd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) < 0){
LogE("socket error\n");
return;
}
::setsockopt(mSockFd,SOL_SOCKET,SO_RCVBUF,&mSize,sizeof(mSize) );
mPid=getpid();
recvICMPPacket();
}
void Handler::sendICMPPacket()
{
int mPacketSize = 0;
mSend++;
int n;
mPacketSize = setICMPHander(mSend);
if((n = ::sendto(mSockFd, mSendPacket,mPacketSize, 0,(struct sockaddr *)&mDestAddr, sizeof(mDestAddr))) < 0){
LogE("send icmp packet error\n");
return;
}
}
int Handler::setICMPHander(int mSeq)
{
int mPackSize;
struct icmp *icmp;
icmp = (struct icmp*)mSendPacket;
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_seq = mSeq;
icmp->icmp_id = mPid;
mPackSize = 8 + dataLen;
icmp->icmp_cksum = calCheckSum( (unsigned short *)icmp,mPackSize);
return mPackSize;
}
void Handler::recvICMPPacket()
{
int n;
mPingTag = true;
socklen_t mFromLen;
int mMaxFds = 0;
fd_set mReadFds;
struct timeval mTimeout;
mFromLen = sizeof(struct sockaddr_in);
while(1){
sendICMPPacket();
mTimeout.tv_sec = mConfig->mSCUTimeout;
mTimeout.tv_usec = 0;
FD_ZERO(&mReadFds);
FD_SET(mSockFd,&mReadFds);
mMaxFds = mSockFd + 1;
n = select(mMaxFds, &mReadFds, NULL, NULL, &mTimeout);
if(n <= 0 ){
LogE("ping %s icmp packet error\n",inet_ntoa(mDestAddr.sin_addr));
mPingTag = false;
break;
}else{
memset(mRecvPacket, 0, sizeof(mRecvPacket));
if((n = ::recvfrom(mSockFd, mRecvPacket, sizeof(mRecvPacket), 0, (struct sockaddr *)&mFrom, &mFromLen)) < 0){
LogE("recv icmp packet error\n");
return;
}
if(parseICMPPacket(mRecvPacket, n) == true){
mIPCall->sendDepotMsg(mFlag);
mRecvPandown = true;
mSend = 0;
break;
}
}
}
}
bool Handler::parseICMPPacket(char *buf, int len)
{
int mIpHdrLen;
struct ip *mIP;
struct icmp *mICMP;
mIP = (struct ip *)buf;
mIpHdrLen = mIP->ip_hl << 2;
mICMP = (struct icmp *)(buf + mIpHdrLen);
len -= mIpHdrLen;
if( len < 8){
LogE("ICMP packets's length is less than 8\n");
return false;
}
if( (mICMP->icmp_type == ICMP_ECHOREPLY) && (mICMP->icmp_id == mPid) ) {
LogE("%d byte from %s: icmp_seq=%u ttl=%d sucess\n",
len,
inet_ntoa(mFrom.sin_addr),
mICMP->icmp_seq,
mIP->ip_ttl);
return true;
}else{
return false;
}
}
unsigned short Handler::calCheckSum(unsigned short *addr,int len)
{
int mLeft = len;
int sum=0;
unsigned short *w = addr;
unsigned short answer = 0;
while(mLeft > 1){
sum += *w++;
mLeft -= 2;
}
if( mLeft == 1){
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer =~ sum;
return answer;
}
ping功能实现(ICMP)的更多相关文章
- Linux下实现ping功能
实现ping功能,就肯定要用到ping命令,那么在Linux下ping命令为: ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...
- Java实现ping功能的三种方法及Linux的区分
前大半部份转自:https://blog.csdn.net/futudeniaodan/article/details/52317650 检测设备的运行状态,有的是使用ping的方式来检测的.所以需要 ...
- 你知道PING功能是怎么实现的吗
以太网的协议有层,而每层都包含有更多的协议.所谓协议,通俗的讲就是通信双方约定的规则. 今天我们介绍一些一个听起来陌生却有很常用的协议,ICMP协议. ICMP是(Internet Control ...
- 如何开放 Azure 虚拟机 Ping 功能
前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...
- 【虚拟机-网络IP】如何开放 Azure 虚拟机 Ping 功能
前言 文章<使用 PsPing & PaPing 进行 TCP 端口连通性测试>中提到,ICMP 协议的数据包无法通过 Azure 的防火墙和负载均衡器,所以不能直接使用 Ping ...
- ping 原理与ICMP协议[转]
原文:http://blog.csdn.net/inject2006/article/details/2139149 ping 的原理 ping 程序是用来探测主机到主机之间是否可通信,如果不 ...
- ping 原理与ICMP协议
ping 的原理 ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接.ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机 ...
- VB6之ICMP实现ping功能
代码备忘 'code by lichmama from cnblogs.com Private Type IPAddr ip1 As Byte ip2 As Byte ip3 As Byte ip4 ...
- C++实现ping功能
今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...
- C++实现ping功能<转>
今天接到需求要实现ping的功能,然后网上查了一些资料,对网络编程的一些函数熟悉了一下,虽然还有一些细节不清楚,但是慢慢积累. 要实现这样的功能: 基础知识 ping的过程是向目的IP发送一个type ...
随机推荐
- python高阶编程(一)
1.生成器 通过列表⽣成式,我们可以直接创建⼀个列表.但是,受到内存限制,列表容量肯定是有限的.⽽且,创建⼀个包 含100万个元素的列表,不仅占⽤很⼤的存储空间,如果我们仅仅需要访问前⾯⼏个元素,那后 ...
- 并发QPS公式估算
一.经典公式1: 一般来说,利用以下经验公式进行估算系统的平均并发用户数和峰值数据 1)平均并发用户数为 C = nL/T 2)并发用户数峰值 C' = C + 3*根号C C是平均并发用户数,n是l ...
- [C#]协变Covariance案例
协变参考代码1: using System; using System.Collections.Generic; using System.Linq; namespace CovarianceSoOn ...
- TiSpark 初级应用
目前正在使用tispark 进行离线计算,简单记录一下操作过程 一.技术验证 场景:计算每次充电过程中单体最高电压的变化速率 解决方案: 使用tispark 直接访问tidb的数据,采用sp ...
- windows远程linux桌面
TigerVNC是一个高性能.平台无关的虚拟网络计算(Virtual Network Computing,VNC)实现,是一个客户端/服务器应用程序,允许用户在远程机器上启动并与图形应用程序进行交互. ...
- python3判断ip类型
利用socket库附带的校验功能实现校验.
- LVS负载均衡 2022年4月
1. 负载均衡技术简介 2 1.1 负载均衡类型3 1.2 LVS简介4 1.3 Keepalived简介5 2. 负载均衡搭建主要步骤 6 2.1 LVS+Keepalived的负载均衡系统搭建6 ...
- NET 实现 Cron 定时任务执行,告别第三方组件
原文连接: (96条消息) NET 实现 Cron 定时任务执行,告别第三方组件_.net 定时任务_Phil Arist的博客-CSDN博客 代码: using System.Globalizati ...
- python实例1(石头 剪刀 布)
#random .randint 模块导入 import random #定义一个用户需要输入的数据内容入口 user = int(input("请输入(石头1,剪刀2,布3 ...
- 求pi
参考自:https://www.zhihu.com/question/402311979 由 \[\frac{\pi^4}{90}={\textstyle \sum_{n=1}^{\infty }} ...