Linux下的ping程序源代码

Linux下用C++写了ping的源代码,期间遇到段错误,百思不得其解。用了几条printf测试输出,终于找到了根源所在, 原来是memcpy(packet, icmp , icmplen);的时候icmplen的值不对,照成了内存访问越界。
#include<iostream>
#include<string.h>
#include<errno.h>
#include<signal.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdio.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<netdb.h>
#include<netinet/in_systm.h>
#include<netinet/ip.h>
#include<netinet/ip_icmp.h>
#include<sys/types.h>

#define ICMPHEAD 8
#define MAXICMPLEN 200
//typedef unsigned int socklen_t;

using namespace std;


class RawSock
{
    public:
    int sock;
    int error;
    RawSock(int protocol =0);
    virtual ~RawSock();
    int send(const void* msg, int msglen, struct sockaddr* addr, unsigned int len);
    int send(const void* msg, int msglen, char *addr);
    int receive(void *buf, int buflen, sockaddr *from, socklen_t *len);
    int Error() { return error; }
};

class ICMP : public RawSock
{
    public:
    struct icmp *packet;
    int max_len;
    int length;

uint16_t checksum(uint16_t *addr, int len);
    ICMP();
    ICMP(int len);
    ~ICMP();
    int send_icmp(char *to, void *buf, int len);
    int recv_icmp(sockaddr *from);
    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; }
};

RawSock:: RawSock(int protocol )
{
    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, struct sockaddr* to, unsigned int len)
{
    if (error )
    return -1;
    int length = sendto(sock, msg, msglen, 0, (const struct 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;
    if(error)
    return -1;

if(hostname)
    {
    hostent *hostnm = gethostbyname(hostname);
    if( hostnm == (struct hostent *)0)
    {
        return -1;
    }
    sin.sin_addr = *((struct in_addr *)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, socklen_t *len)
{
    if(error) return -1;
    while(1)
    {
    int length =recvfrom(sock, buf, buflen, 0, from, len);
    if(length == -1)
        if( error == EINTR ) continue;
        else {
        error = 3;
        return -1;
        }
    return length;
    }
}

/********************
* ICMP 瀹炵幇
*
*
* ********************/

ICMP::ICMP() : RawSock(IPPROTO_ICMP)
{
    max_len = MAXICMPLEN;
    packet = (struct 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)
{
    max_len = len;
    packet = (struct 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;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpdwp.html