在linux写了ping命令,但是有些地方编译不出来?急!
/*
* writing by hacktao
* 为开源做点事,特详细的ping源程序
* My blog:hacktao.cublog.cn/
*/
#include<iostream>
#include<string.h>
#include<errno.h>
#include<signal.h>
#include<stdlib.h>
#include<arpa/inet.h> /*inet_ntoa函数*/
#include<unistd.h> /*close函数*/
#include<stdio.h> /*基本输入输出*/
#include<sys/types.h> /*标准的系统的types*/
#include<netinet/in.h> /*internet address structures*/
#include<sys/socket.h> /*套接字接口定义*/
#include<netdb.h> /*host to ip*/
#include<netinet/in_systm.h>
#include<netinet/ip.h> /*icmp*/
#include<netinet/ip_icmp.h>/*icmp*/
#define ICMPHEAD 8 //ICMP 包头长度
#define MAXICMPLEN 200 //ICMP 最大长度
using namespace std;
/*******************************************
class:RawSock
定义RawSock类
作用:成员变量sock存放原始套接字,error
存放错误代码
*******************************************/
class RawSock
{
public:
int sock;
int error;
RawSock(int protocol);
virtual ~RawSock();
int send(const void*msg, int msglen, sockaddr* addr, unsigned int
len);
int send(const void*msg, int msglen, char* addr);
//send() 通过原始套接字发送数据
int receive(void* buf,int buflen,sockaddr* from,int* len);
//receive() 通过原始套接字来接收数据
int Error() { return error; }
};
RawSock::RawSock(int protocol=0) {
sock = socket(AF_INET, SOCK_RAW,protocol);
setuid(getuid());
if (sock == -1) error= 1;
else error = 0;
}
RawSock::~RawSock(){
close(sock);
}
int RawSock::send(const void* msg, int msglen,sockaddr* to , //这个事通过ip地址发
送的
unsigned int len)
{
if(error) return -1;
int length = sendto(sock,msg,msglen,0,(const sockaddr*)to,len);
if(length == -1){
error = 2;
return -1;}
return length;
}
int RawSock::send(const void* msg, int msglen, char* hostname)
//这种是通过域名发送的
{
sockaddr_in sin; // sock internet address
if(error) return -1;
if(hostname){
hostent *hostnm = gethostbyname(hostname);
if(hostnm == (struct hostent *)0) {
return -1;
}
sin.sin_addr.s_addr=*((unsigned long*)hostnm->h_addr);
}
else
return -1;
sin.sin_family = AF_INET;
return send(msg,msglen,(sockaddr*)&sin,sizeof(sin));
}
int RawSock::receive(void* buf,int buflen,sockaddr*from,int* len)
{
if(error) return -1;
while(1){
int length = recvfrom(sock,buf,buflen,0,from,(socklen_t*)len);
if(length == -1)
if(errno == EINTR) continue;
else{
error = 3;
return -1;
}
return length;
}
}
/******************************************
class:ICMP
定义ICMP类
作用:成员变量packet指向ICMP包,length
表示ICMP包长度
******************************************/
class ICMP:public RawSock
{
public:
struct icmp *packet;
int max_len;
int length;
unsigned short checksum(unsigned short *addr,int len);//计算校验和
ICMP();
ICMP(int len); //ICMP类的构造函数
~ICMP();
int send_icmp(char *to,void* buf,int len); //发送icmp响应请求包
int recv_icmp(sockaddr* from); //接收icmp响应应答包
void setCode(int c) { packet->icmp_code = c; } //设置代码
void setId(int i) { packet->icmp_id = i; } //设置标识
void setSeq(int s) { packet->icmp_seq = s; } //设置序列号
void setType(int t) { packet->icmp_type = t; } //设置类型
};
ICMP::ICMP(): RawSock(IPPROTO_ICMP) //实现ICMP类的构造函数 默认长度200
{
max_len = MAXICMPLEN;
packet = (icmp*) new char[max_len];
packet->icmp_code = 0;
packet->icmp_id = 0;
packet->icmp_seq =0;
packet->icmp_type = ICMP_ECHO;
}
ICMP::ICMP(int len): RawSock(IPPROTO_ICMP) //现ICMP类的构造函数 自定义包最大
长度
{
max_len = len;
packet = (icmp*) new char[max_len];
packet->icmp_code = 0;
packet->icmp_id = 0;
packet->icmp_seq =0;
packet->icmp_type = ICMP_ECHO;
}
ICMP::~ICMP()
{
delete[] (char*)packet;
}
unsigned short ICMP::checksum(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 ICMP::send_icmp(char *host, void* buf, int len) //实现send_icmp()函数
{
memcpy(packet->icmp_data,buf,len);
packet->icmp_cksum = 0;
packet->icmp_cksum =checksum((unsigned short *)packet, ICMPHEAD + 6);
//在包里加入加入校验和
int err = send(packet,MAXICMPLEN,host);
return err;
}
int ICMP::recv_icmp(sockaddr* from) //实现接受recv_icmp()函数
{
char buf[MAXICMPLEN+100]; //缓存
int hlen1,icmplen; //
struct ip *ip; //接收目标主机的ip包
struct icmp *icmp; //目标主机ip包里的icmp包
if(Error()) return -1;
int addrlen = 0;
int len = receive(buf,MAXICMPLEN+100,from,&addrlen); //接收目标主机的ip
包,返回该包长度
if(len == -1) { //异常处理
cout<<"Receiving Failed!\n";
return -1;
}
ip = (struct ip*) buf; //获得ip首部地址
hlen1 = ip->ip_hl << 2; //获得ip包头长度
icmp = (struct icmp*)(buf+hlen1); //获得icmp首地址
if((icmplen = len -hlen1) < {
cout<<"Receiving Fail!\n";
return -1;
}
length = len - hlen1;
memcpy(packet,icmp,length);
return 0;
}
/***********************************************
主程序入口
***********************************************/
int main(int argc,char *argv[])
{
ICMP icmp; //定
义一个icmp的对象
sockaddr from; //host的套接字地址
char *host; //目
标机器的ip地址
int cout; //发送包的数量
if(argc<2){
printf("Usage:%s <ip Address><try_number>\n",argv[0]);
exit(0);
}
if(argc==2){
host = argv[1];
cout = 5; //没有指定发包的数量的话,默认是发5个包
}
if(argc==3){
host = argv[1];
cout = atoi(argv[2]); //将字符数组转为整形数组
}
printf("22333"
// cout<<"22222";
for(int i = 0; i<cout; i++){ //循环发送
ICMP_ECHO包
icmp.setId(getpid()); //设置标识
icmp.setSeq(i); //设置序列号
char* test_data = "abcde"; //发生数据
icmp.send_icmp(host,test_data,strlen(test_data)); //发送
ICMP响应请求包
}
int num = 1;
// cout<<"3333";
while(1){
//循环等待接收ICMP_ECHOREPLY
if(icmp.recv_icmp(&from)<0) continue;
if(icmp.packet->icmp_type == ICMP_ECHOREPLY){
//检查其类型
if(icmp.packet->icmp_id == getpid()){
//检查其标识符是否是本进程的ID
printf("%d bytes from %s: seq=%u, data=%
s\n",
icmp.length,host,icmp.packet->icmp_seq,
icmp.packet->icmp_data);
num++;
if(num > cout) break;
//接收完毕,退出
}
}
}
return 0;
}
终端里敲入g++ -o Myping Myping.cpp
无错误,然后./Myping 127.0.0.1
命令提示符就停在那里了·····
这是怎么回事····不懂,我写了很详细的注释,望各位高手解答下!不甚感激!