在linux写了ping命令,但是有些地方编译不出来?急!

weixin_38071610 2009-04-14 01:31:51

/*
* 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
   
命令提示符就停在那里了·····

这是怎么回事····不懂,我写了很详细的注释,望各位高手解答下!不甚感激!
...全文
15 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

477

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧