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<<"Receive Failed\n";
return -1;
}
ip = (struct ip *)buf;
hlen1 = ip->ip_hl << 2;
icmp = (struct icmp *) (buf + hlen1);
if( (icmplen = len -hlen1) < 8)
{
cout<<"Receive Fail\n";
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;
}
}
}
}