linux 程序 源代码,linux下的ping程序源代码

今天没事就照着书上,用C++写了ping的实现,期间遇到段错误,百思不得其解。用了几条printf测试输出,终于找到了根源所在, 原来是memcpy(packet, icmp , icmplen);的时候icmplen的值不对,照成了内存访问越界。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#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;

}

uint16_t ICMP::checksum(uint16_t *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)

{

memcpy(packet->icmp_data, buf, len);

packet->icmp_cksum =0;

packet->icmp_cksum = checksum((uint16_t *)packet, ICMPHEAD + 6);

int err = send(packet, MAXICMPLEN, host);

return err;

}

int ICMP:: recv_icmp(sockaddr *from)

{

char buf[MAXICMPLEN + 100];

int hlen1, icmplen;

struct ip *ip;

struct icmp *icmp;

if( Error() )

{

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

return -1;

}

socklen_t addrlen = 0;

int len = receive(buf, MAXICMPLEN+100, from , &addrlen);

if ( len == -1)

{

cout<

return -1;

}

ip = (struct ip *)buf;

hlen1 = ip->ip_hl << 2;

icmp = (struct icmp *) (buf + hlen1);

if( (icmplen = len -hlen1) < 8)

{

cout<

return -1;

}

memcpy(packet, icmp , icmplen);

// printf("11111\n");

return 0;

}

main(int argc, char *argv[])

{

ICMP icmp;

struct sockaddr from;

char *host;

int count;

if(argc < 2)

{

printf("can shu you wu\n");

exit(1);

}

if(argc == 2)

{

host = argv[1];

count = 5;

}

if( argc == 3)

{

host = argv[1];

count = 3;

}

for( int i=0; i<=count; i++)

{

icmp.setId(getpid());

icmp.setSeq(i);

char *test_data = "abcde";

icmp.send_icmp(host, test_data, strlen(test_data));

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

}

int num = 1;

while(1)

{

if(icmp.recv_icmp(&from) < 0)

continue;

if(icmp.packet->icmp_type == ICMP_ECHOREPLY)

{

if( icmp.packet->icmp_id == getpid())

{

printf("%d bypes form %s: seq=%u, data=%s\n",

icmp.length, host, icmp.packet->icmp_seq, icmp.packet->icmp_data);

num++;

if(num > count)

break;

}

}

}

}

(jingxshi)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值