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 ...
随机推荐
- 优先使用C++的别名声明(using)来替换typedef
C++98中,我们如果想用简写的方式表达一个类型,那么可以使用typedef关键字: typedef std::unique_ptr<std::unordered_map<std::str ...
- 论zzy的苏州话
乘地铁(ceng) - 盛饭(seng) 无法无天 - 12345 掀被子 - 先干嘛,再干嘛 ?待更新
- Unity泛型单例模式
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Singleto ...
- 什么是5G垂直行业?
什么是垂直行业呢? 感觉"垂直行业"这个词在太多地方遇到,但是这个词的涵盖范围到底是什么呢? 垂直这一概念源于两条直线(或平面)的直角交叉,两条直线是相互作为参照物的.比如,我们可 ...
- c++中文编码格式
c++程序中涉及到中文字符的输入输出以及其他操作经常会出现乱码.乱码主要是由于程序的源文件编码.可执行文件编码以及程序运行环境的编码不匹配导致.比如,c++源程序文件编码为GB18030, 在源程序中 ...
- python内置函数range()—对象创建函数
range()函数 介绍 range()函数实际上表示一个不可变的数字序列类型,通常用于在for循环中指定特定的次数. range()的格式: range(stop) range(start, sto ...
- VsCode里面运行mvn命令显示The JAVA_HOME environment variable is not defined correctly
问题描述 关于这个问题,就是环境配置出了问题!!! 问题解决 在settings.json里面,配置的环境的路径不能出错,我就是在配置的时候,名为Environments的文件夹写成Environme ...
- git clone的时候出现 fatal: unable to access 'https://github.com/...':OpenSSL SSL_read: Connection was reset, errno 10054解决方法
git clone的时候出现fatal: unable to access 'https://github.com/...':OpenSSL SSL_read: Connection was rese ...
- 做bad apple第一步:超级好用的you-get下载各大网站音频!!!!
1 安装在cmd中输入pip3 install you-get 就行了 2 简单用法下载视频: 超级暴力,直接 you-get + "网站" 就没了,会下载到当前路径.我想下载到哪 ...
- 使用cmd命令行安装 windows系统
条件:Microsoft WindowsPE 或其他第三方 WindowsPE 1. 使用 diskpart 分区: list disk:列出所有磁盘 select disk 编号:选择某块磁盘 c ...