#include "libping.h" /* From Stevens, UNP2ev1 */ unsigned short in_cksum(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); } // Computing the internet checksum (RFC 1071). // Note that the internet checksum does not preclude collisions. uint16_t ip_checksum (uint16_t *addr, int len) { int count = len; register uint32_t sum = 0; uint16_t answer = 0; // Sum up 2-byte values until none or only one byte left. while (count > 1) { sum += *(addr++); count -= 2; } // Add left-over byte, if any. if (count > 0) { sum += *(uint8_t *) addr; } // Fold 32-bit sum into 16 bits; we lose information by doing this, // increasing the chances of a collision. // sum = (lower 16 bits) + (upper 16 bits shifted right 16 bits) while (sum >> 16) { sum = (sum & 0xffff) + (sum >> 16); } // Checksum is one's compliment of sum. answer = ~sum; return (answer); } int icmp_eth_init( icmp_pckt_t *icmp ) { uint8_t dest[] = {0x00,0x22,0x43,0x68,0xe5,0xab}; uint8_t src[] = {0x6c,0x88,0x14,0x0a,0x89,0x58}; memcpy( icmp->eth_dest, dest, 6 ); memcpy( icmp->eth_src, src, 6 ); icmp->eth_type = 0x0008; return 0; } int icmp_eth_dest( icmp_pckt_t *icmp, uint8_t *mac ) { memcpy( icmp->eth_dest, mac, 6 ); return 0; } int icmp_eth_src( icmp_pckt_t *icmp, uint8_t *mac ) { memcpy( icmp->eth_src, mac, 6 ); return 0; } int icmp_eth_len( icmp_pckt_t *icmp ) { return 14; } int icmp_ip_init( icmp_pckt_t *icmp ) { icmp->head_hlength = 0x45; //ip4,header size 20 byte icmp->tos = 0x00; icmp->ip_length = htons(20+8+ICMP_MAX_DATA); //ip4 header + icmp message icmp->ip_ident = htons(0xfbea); icmp->flags_fragment_off = 0x0040; icmp->ttl = 64; icmp->protocol = 1; //ICMP icmp->source_addr = inet_addr("127.0.0.1"); icmp->dest_addr = inet_addr("127.0.0.1"); return 0; } int icmp_ip_chksum( icmp_pckt_t *icmp ) { uint16_t chk; icmp->ip_chksum = 0; chk = ip_checksum( (uint16_t *)icmp+7, 20 ); icmp->ip_chksum = chk; return 0; } int icmp_ip_dest( icmp_pckt_t *icmp, uint32_t dest ) { uint32_t s = dest; uint8_t a,b,c,d; a = s; b = s>>8; c = s>>16; d = s>>24; uint32_t aa = a; uint32_t bb = b; uint32_t cc = c; uint32_t dd = d; printf("%d.%d.%d.%d\n",a,b,c,d); s = 0x0; s = aa + (bb<<8) + (cc<<16) + (dd<<24); icmp->dest_addr = s; return 0; } int icmp_ip_src( icmp_pckt_t *icmp, uint32_t src ) { uint32_t s = src; uint8_t a,b,c,d; a = s; b = s>>8; c = s>>16; d = s>>24; uint32_t aa = a; uint32_t bb = b; uint32_t cc = c; uint32_t dd = d; printf("%d.%d.%d.%d\n",a,b,c,d); s = 0x0; s = aa + (bb<<8) + (cc<<16) + (dd<<24); icmp->source_addr = s; return 0; } int icmp_ip_ident( icmp_pckt_t *icmp, uint16_t ident ) { icmp->ip_ident = htons(ident); //icmp->ip_ident = ident; return 0; } int icmp_ip_ttl( icmp_pckt_t *icmp, uint8_t ttl ) { icmp->ttl = ttl; return 0; } int icmp_ip_len( icmp_pckt_t *icmp ) { return 20; } int icmp_icmp_init( icmp_pckt_t *icmp ) { int i = 0; icmp->type = ICMP_TREQUEST; icmp->code = 0; icmp->icmp_ident = 0x4062; icmp->seq_num = 0x0001; //icmp->timestamp = 0x5749aae7;//0xe7aa4957; for (i=0;idata[i] = 0; } return 0; } int icmp_icmp_set_chks( icmp_pckt_t *icmp ) { uint16_t chk=0x0; uint16_t offset=0x0; icmp->icmp_check_sum = 0x0000; //fot ICMP header offset = icmp_eth_len(icmp) + icmp_ip_len(icmp); printf("offset %d len %d\n", offset, icmp_icmp_len(icmp)); chk = ip_checksum( ((uint16_t *)icmp)+offset/2, icmp_icmp_len(icmp) ); icmp->icmp_check_sum = chk; return 0; } int icmp_icmp_set_code( icmp_pckt_t *icmp, uint8_t code ) { return 0; } int icmp_icmp_set_type( icmp_pckt_t *icmp, uint8_t type ) { icmp->type = type; return 0; } int icmp_icmp_len( icmp_pckt_t *icmp ) { return 8+ICMP_MAX_DATA; } int icmp_icmp_ident( icmp_pckt_t *icmp, uint16_t ident ) { icmp->icmp_ident = htons(ident); return 0; } int icmp_icmp_seq( icmp_pckt_t *icmp, uint16_t seq) { icmp->seq_num = htons(seq); return 0; } int icmp_total_len( icmp_pckt_t *icmp ) { int ret=0; ret = icmp_eth_len(icmp) +icmp_ip_len(icmp) +icmp_icmp_len(icmp); return ret; } int icmp_icmp_ts( icmp_pckt_t *icmp, uint64_t timestamp ) { //icmp->timestamp = timestamp; return 0; } int icmp_dump( icmp_pckt_t *icmp ) { int i=0,j=0,m=0; printf("Etherenet header\n"); for (i=0;idata, data, size ); return 0; }