linux编译ping指令,Linux C++实现ping指令

//#include "ping.h"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PACKET_SIZE 4096

#define SEND_DATA_LEN 56

#define ERROR -1

#define SUCCESS 1

#define MAX_WAIT_TIME 3

#define MAX_NO_PACKETS 4

#define NULL 0

using namespace std;

class Cping

{

public:

Cping(const char * ip, int timeout);

Cping(const Cping& org);

virtual ~Cping();

private:

std::string m_strIp;

std::string m_copy_Ip;

int m_nSend;

int m_nRecv;

struct sockaddr_in m_dest_addr;

struct sockaddr_in m_from_addr;

char m_sendpacket[PACKET_SIZE];

char m_recvpacket[PACKET_SIZE];

struct timeval m_tvrecv;

struct timeval m_begin_tvrecv;

struct timeval m_end_tvrecv;

double m_dTotalResponseTimes;

int m_nSocketfd;

int m_nMaxTimeWait;

public:

bool ping(int times);

bool CreateSocket();

bool CloseSocket();

void send_packet(void);

void recv_packet(void);

int pack(int pack_no);

int unpack(char *buf, int len);

void tv_sub(struct timeval *out, struct timeval *in);

void statistics(int sig);

static unsigned short cal_chksum(unsigned short *addr, int len);

};

Cping::Cping(const char *ip, int timeout)

{

m_strIp = ip;

m_copy_Ip = ip;

m_nSend = 0;

m_nRecv = 0;

m_dTotalResponseTimes = 0;

if(timeout > MAX_WAIT_TIME)

{

m_nMaxTimeWait = MAX_WAIT_TIME;

}

else

{

m_nMaxTimeWait = timeout;

}

}

Cping::~Cping()

{

if(!CloseSocket())

{

cout << "CloseSocket failed!" << endl;

}

}

bool Cping::ping(int times)

{

if(!CreateSocket())

{

printf("CreateSocket failed!!!\n");

return false;

}

printf("PING %s(%s): %d bytes data in ICMP packets.\n", m_strIp.c_str(),

m_copy_Ip.c_str(), SEND_DATA_LEN);

while(times--)

{

send_packet();

recv_packet();

sleep(1);

}

statistics(SIGINT);

return true;

}

bool Cping::CreateSocket()

{

char buf[2048];

int errnop = 0;

unsigned long inaddr;

struct hostent hostinfo, *dest_phost;

struct protoent *protocol = NULL;

if((protocol = getprotobyname("icmp")) == NULL)

{

perror("getprotobyname()");

printf("CreateSocket : getprotobyname failed:%d\n",errnop);

return false;

}

if(-1 == (m_nSocketfd = socket(AF_INET,SOCK_RAW,protocol->p_proto)))

{

perror("socket");

printf("CreateSocket: create socket failed:%d\n", m_nSocketfd);

return false;

}

setuid(getuid());

m_dest_addr.sin_family = AF_INET;

bzero(&(m_dest_addr.sin_zero),8);

if((inaddr = inet_addr(m_strIp.c_str())) == INADDR_NONE)

{

//if(getprotobyname_r(m_strIp.c_str(), &hostinfo, buf, sizeof(buf), &dest_phost, &errnop))

//{

//printf("CreateSocket: getprotobyname error %s failed:%d\n", m_strIp.c_str(),errnop);

//return false;

//}

//else

//{

m_dest_addr.sin_addr = *((struct in_addr *)dest_phost->h_addr);

//}

}

else

{

m_dest_addr.sin_addr.s_addr = inaddr;

}

m_copy_Ip = inet_ntoa(m_dest_addr.sin_addr);

return true;

}

bool Cping::CloseSocket()

{

bool flag = false;

if(m_nSocketfd)

{

close(m_nSocketfd);

flag = true;

}

return flag;

}

void Cping::send_packet(void)

{

int packetsize;

packetsize = pack(m_nSend);

if((sendto(m_nSocketfd, m_sendpacket, packetsize, 0 ,(const struct sockaddr*)&m_dest_addr, sizeof(m_dest_addr))) < 0)

{

printf("send_packet: send error :\n");

}

m_nSend++;

}

void Cping::recv_packet(void)

{

int fromlen, packetsize, n;

while(m_nRecv < m_nSend)

{

struct timeval timeout;

fd_set readfd;

FD_ZERO(&readfd);

FD_SET(m_nSocketfd, &readfd);

int maxfd = m_nSocketfd + 1;

timeout.tv_sec = m_nMaxTimeWait;

timeout.tv_usec = 0;

n = select(maxfd, &readfd, NULL, NULL, &timeout);

switch(n)

{

case 0:

printf("recv_packet: select time out: \n");

break;

case -1:

printf("recv_packet: select error: \n");

break;

default:

if(FD_ISSET(m_nSocketfd, &readfd))

{

if((packetsize = recvfrom(m_nSocketfd, m_recvpacket, sizeof(m_recvpacket), 0,(struct sockaddr *)&m_from_addr,(socklen_t*)&fromlen)) < 0)

{

printf("packetsize = %d\n", packetsize);

//printf("recv_packet: recv error: %d\n", errno);

return ;

}

gettimeofday(&m_tvrecv, NULL);

m_end_tvrecv.tv_usec = m_tvrecv.tv_usec;

m_end_tvrecv.tv_sec = m_tvrecv.tv_sec;

if(unpack(m_recvpacket, packetsize) == -1)

{

continue;

}

m_nRecv++;

}

break;

}

}

}

int Cping::pack(int pack_number)

{

int packsize;

struct icmp *pIcmp;

struct timeval *pTime;

pIcmp = (struct icmp*)m_sendpacket;

pIcmp->icmp_type = ICMP_ECHO;

pIcmp->icmp_code = 0;

pIcmp->icmp_cksum = 0;

pIcmp->icmp_seq = pack_number;

pIcmp->icmp_id = getpid();

packsize = 8 + SEND_DATA_LEN;

pTime = (struct timeval *)pIcmp->icmp_data;

gettimeofday(pTime, NULL);

if(m_nSend == 0)

{

m_begin_tvrecv.tv_usec = pTime->tv_usec;

m_begin_tvrecv.tv_sec = pTime->tv_sec;

}

pIcmp->icmp_cksum = cal_chksum((unsigned short*)pIcmp, packsize);

return packsize;

}

int Cping::unpack(char *buf, int len)

{

int i, iphdrlen;

struct icmp *pIcmp;

struct timeval *tvsend;

struct ip* recv_ip = (struct ip*)buf;

double rtt;

iphdrlen = recv_ip->ip_hl << 2;

pIcmp = (struct icmp*)(buf + iphdrlen);

len -= iphdrlen;

if(len < 8)

{

printf("ICMP packets's length is less than 8'");

return -1;

}

if((pIcmp->icmp_type == ICMP_ECHOREPLY) && (m_copy_Ip == inet_ntoa(m_from_addr.sin_addr)) && (pIcmp->icmp_id = getpid()) )

{

tvsend = (struct timeval *)pIcmp->icmp_data;

tv_sub(&m_tvrecv, tvsend);

rtt = m_tvrecv.tv_sec * 1000 + (double)m_tvrecv.tv_usec / 1000;

printf("%d byte from %s : icmp_seq=%u ttl=%d time=%.3fms\n",

len,

inet_ntoa(m_from_addr.sin_addr),

pIcmp->icmp_seq,

recv_ip->ip_ttl,

rtt);

}

else

{

printf("throw away the old package %d\tbyte from %s\t: icmp_seq=%u\t: icmp_seq=%u\t ttl=%u\trtt=%.3f\tms",

len,

inet_ntoa(m_from_addr.sin_addr),

pIcmp->icmp_seq,

recv_ip->ip_ttl,

rtt);

return -1;

}

return 1;

}

void Cping::tv_sub(struct timeval *out, struct timeval *in)

{

if((out->tv_usec -= in->tv_usec) < 0)

{

--out->tv_sec;

out->tv_usec += 10000000;

}

out->tv_sec -= in->tv_sec;

}

void Cping::statistics(int sig)

{

tv_sub(&m_end_tvrecv, &m_begin_tvrecv);

m_dTotalResponseTimes = m_end_tvrecv.tv_sec * 1000 + (double)m_end_tvrecv.tv_usec / 1000;

printf("--------statistics----------\n");

printf("%d packets transmitted, %d received, %d%% lost, time: %.3lfms\n", m_nSend, m_nRecv,(m_nSend - m_nRecv) / m_nSend*100, m_dTotalResponseTimes);

close(m_nSocketfd);

}

unsigned short Cping::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;

}

int main(int argc, char *argv[])

{

Cping Ping(argv[1], 20);

Ping.ping(3);

}

命名为 myping.cpp

编译命令:sudo g++ -o myping myping.cpp

修改权限:sudo chmod u+s myping

使用:./myping 192.168.1.222

标签:addr,int,ping,C++,tv,Linux,Cping,icmp,struct

来源: https://blog.csdn.net/CCCCxq/article/details/97925553

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值