ping3.c
e75179f41c5d50dd62c60f572182b8178ed03e94
· 2.7 KB · 110 lines
raw
| 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <unistd.h> |
| 4 | #include <sys/types.h> |
| 5 | #include <sys/socket.h> |
| 6 | #include <netdb.h> |
| 7 | #include <netinet/in.h> |
| 8 | #include <netinet/in_systm.h> |
| 9 | #include <netinet/ip.h> |
| 10 | #include <netinet/ip_icmp.h> |
| 11 | #include <string.h> |
| 12 | #include <arpa/inet.h> |
| 13 | #include <sys/select.h> |
| 14 | |
| 15 | unsigned short cksum(unsigned short *addr, int len); |
| 16 | |
| 17 | int main(int argc, char *argv[]) { |
| 18 | int sock; |
| 19 | char send_buf[400], src_ip[15], dst_ip[15], src_name[256]; |
| 20 | struct ip *ip = (struct ip *)send_buf; |
| 21 | struct icmp *icmp = (struct icmp *)(ip + 1); |
| 22 | struct hostent *src_hp, *dst_hp; |
| 23 | struct sockaddr_in src, dst; |
| 24 | int on = 1; |
| 25 | memset(send_buf, 0, sizeof(send_buf)); |
| 26 | |
| 27 | if (argc < 2) { |
| 28 | printf("Need arg. I\n"); |
| 29 | exit(EXIT_FAILURE); |
| 30 | } |
| 31 | |
| 32 | /**if (getuid() == 0) { |
| 33 | fprintf(stderr, "Need to elevate\n"); |
| 34 | exit(EXIT_FAILURE); |
| 35 | } **/ |
| 36 | |
| 37 | gethostname(src_name, sizeof(src_name)); |
| 38 | printf("%s\n", src_name); |
| 39 | src_hp = gethostbyname(src_name); |
| 40 | ip->ip_src = (*(struct in_addr *)src_hp->h_addr_list[0]); |
| 41 | |
| 42 | dst_hp = gethostbyname(argv[1]); |
| 43 | ip->ip_dst = (*(struct in_addr *)dst_hp->h_addr); |
| 44 | dst.sin_addr = (*(struct in_addr *)dst_hp->h_addr); |
| 45 | |
| 46 | sprintf(src_ip, "%s", inet_ntoa(ip->ip_src)); |
| 47 | sprintf(dst_ip, "%s", inet_ntoa(ip->ip_dst)); |
| 48 | printf("Src: %s -- Dst: %s\n", src_ip, dst_ip); |
| 49 | |
| 50 | // Create socket |
| 51 | sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); |
| 52 | |
| 53 | setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)); |
| 54 | |
| 55 | // IP Structure |
| 56 | ip->ip_v = 4; |
| 57 | ip->ip_hl = 5; |
| 58 | ip->ip_tos = 0; |
| 59 | ip->ip_len = htons(sizeof(send_buf)); |
| 60 | ip->ip_id = htons(321); |
| 61 | ip->ip_off = htons(0); |
| 62 | ip->ip_ttl = 255; |
| 63 | ip->ip_p = IPPROTO_ICMP; |
| 64 | ip->ip_sum = 0; |
| 65 | |
| 66 | // ICMP Structure |
| 67 | icmp->icmp_type = 2; |
| 68 | icmp->icmp_code = 0; |
| 69 | |
| 70 | dst.sin_family = AF_INET; |
| 71 | |
| 72 | ip->ip_sum = cksum((unsigned short *)send_buf, ip->ip_hl); |
| 73 | icmp->icmp_cksum = cksum((unsigned short *)icmp, sizeof(send_buf) - sizeof(struct icmp)); |
| 74 | |
| 75 | int dst_addr_len = sizeof(dst); |
| 76 | int bytes_sent; |
| 77 | |
| 78 | if((bytes_sent = sendto(sock, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&dst, dst_addr_len)) < 0) { |
| 79 | perror("send err"); |
| 80 | fflush(stdout); |
| 81 | } |
| 82 | else { |
| 83 | printf("Sent %d bytes\n", bytes_sent); |
| 84 | } |
| 85 | |
| 86 | |
| 87 | } |
| 88 | |
| 89 | unsigned short cksum(unsigned short *addr, int len) { |
| 90 | int nleft = len; |
| 91 | int sum = 0; |
| 92 | unsigned short *w = addr; |
| 93 | unsigned short answer = 0; |
| 94 | |
| 95 | while (nleft > 1) { |
| 96 | sum += *w++; |
| 97 | nleft -= 2; |
| 98 | } |
| 99 | |
| 100 | if (nleft == 1) { |
| 101 | *(unsigned char *)(&answer) = *(unsigned char *)w; |
| 102 | sum += answer; |
| 103 | } |
| 104 | |
| 105 | sum = (sum >> 16) + (sum & 0xffff); |
| 106 | sum += (sum >> 16); |
| 107 | answer = ~sum; |
| 108 | |
| 109 | return answer; |
| 110 | } |