Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.13 KB | None | 0 0
  1. // Wiktor Garbarek 291963
  2.  
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8. #include <strings.h>
  9. #include <string.h>
  10.  
  11. #include <sys/socket.h>
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14.  
  15. #include <netinet/ip.h>
  16. #include <netinet/ip_icmp.h>
  17.  
  18. #include <sys/select.h>
  19. #include <sys/socket.h>
  20. #include <sys/time.h>
  21.  
  22. #include "sender.h"
  23. #include "receiver.h"
  24.  
  25. #define UNDEF -1
  26. #define TIMEOUT 1
  27. #define REACHED 2
  28. #define RECEIVED 3
  29. #define N 3
  30.  
  31. #define handle_error(msg) \
  32. do { perror(msg); exit(EXIT_FAILURE); } while (0)
  33.  
  34. void set_timeout(struct timeval *tv){
  35. tv->tv_sec = 1; tv->tv_usec = 0;
  36. }
  37.  
  38. struct icmphdr* get_icmp_header(struct iphdr* ip_header){
  39. return (void*)ip_header + 4*ip_header->ihl;
  40. }
  41.  
  42. struct iphdr* get_inner_ip_header(struct icmphdr* icmp_header){
  43. return (void*)icmp_header + 8;
  44. }
  45.  
  46. void write_unique_ips(const char *ip1, const char *ip2, const char* ip3, char* dst){
  47. if (strcmp(ip1, ip2) != 0){
  48. if(strcmp(ip2, ip3) != 0 && strcmp(ip1, ip3) != 0){
  49. sprintf(dst, "%s %s %s", ip1, ip2, ip3);
  50. }
  51. if(strcmp(ip2, ip3) != 0 && strcmp(ip1, ip3) == 0){
  52. sprintf(dst, "%s %s", ip1, ip2);
  53. }
  54. if(strcmp(ip2, ip3) == 0){
  55. sprintf(dst, "%s %s", ip1, ip2);
  56. }
  57. }
  58. if (strcmp(ip1, ip2) == 0){
  59. if (strcmp(ip2, ip3) == 0){
  60. sprintf(dst, "%s", ip1);
  61. }
  62. if (strcmp(ip2, ip3) != 0){
  63. sprintf(dst, "%s %s", ip1, ip3);
  64. }
  65. }
  66. }
  67.  
  68. void send_icmp(int sockfd, const char *addr, int ttl){
  69. struct icmphdr icmp_header;
  70. fill_icmp_header(&icmp_header, ttl);
  71.  
  72. struct sockaddr_in recipient;
  73. bzero (&recipient, sizeof(recipient));
  74. recipient.sin_family = AF_INET;
  75. inet_pton(AF_INET, addr, &recipient.sin_addr);
  76. if (inet_pton(AF_INET, addr, &recipient.sin_addr) != 1){
  77. handle_error("inet_pton");
  78. }
  79. if (setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)) == -1){
  80. handle_error("setsockopt");
  81. }
  82. if(sendto(sockfd, &icmp_header, sizeof(icmp_header), 0,
  83. (struct sockaddr*) &recipient, sizeof(recipient)) < 0){
  84. handle_error("sendto");
  85. }
  86. }
  87.  
  88. int receive_icmp(int sockfd, uint16_t ttl, struct timeval *timedelta, uint16_t *received_id, uint16_t *received_ttl, char *ip){
  89. struct sockaddr_in sender;
  90. socklen_t sender_len = sizeof(sender);
  91. u_int8_t buffer[IP_MAXPACKET];
  92.  
  93. fd_set descriptors;
  94. FD_ZERO (&descriptors);
  95. FD_SET (sockfd, &descriptors);
  96.  
  97. int ready = select(sockfd+1, &descriptors, NULL, NULL, timedelta);
  98. if (ready < 0){
  99. handle_error("select");
  100. }
  101. if (ready == 0){
  102. return TIMEOUT;
  103. }
  104.  
  105. ssize_t packet_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0,
  106. (struct sockaddr*)&sender, &sender_len);
  107.  
  108. char sender_ip_str[20];
  109. inet_ntop(AF_INET, &(sender.sin_addr), sender_ip_str, sizeof(sender_ip_str));
  110. //strcpy(ip, sender_ip_str);
  111. sprintf(ip, "%s", sender_ip_str);
  112. //fprintf(stderr,"********from %s to %s at ptr %p\n", sender_ip_str, ip, &ip);
  113.  
  114. struct iphdr* ip_header = (struct iphdr*) buffer;
  115. struct icmphdr* icmp_header = get_icmp_header(ip_header);
  116.  
  117. //fprintf(stderr,"*******%d %d %d %d\n", icmp_header->type, icmp_header->code, icmp_header->un.echo.id, icmp_header->un.echo.sequence);
  118. *received_id = icmp_header->un.echo.id;
  119. *received_ttl = icmp_header->un.echo.sequence;
  120. if (icmp_header->type == ICMP_TIME_EXCEEDED){
  121. struct iphdr* ip_header2 = get_inner_ip_header(icmp_header);
  122. struct icmphdr* icmp_header2 = get_icmp_header(ip_header2);
  123. // fprintf(stderr,"11: %d %d %d %d\n", icmp_header2->type, icmp_header2->code, icmp_header2->un.echo.id, icmp_header2->un.echo.sequence);
  124. *received_id = icmp_header2->un.echo.id;
  125. *received_ttl = icmp_header2->un.echo.sequence;
  126. }
  127. // assert(*received_id == getpid());
  128. // if (sequence == ttl){
  129. // // fprintf(stderr," %s \n", sender_ip_str);
  130. // }
  131. if (icmp_header->type == ICMP_ECHOREPLY){
  132. return REACHED;
  133. }
  134. return RECEIVED;
  135. }
  136.  
  137.  
  138. int main(int argc, char *argv[]){
  139. if(argc != 2){
  140. fprintf(stderr, "Invalid parameters or missing ip address\n");
  141. exit(EXIT_FAILURE);
  142. }
  143.  
  144. struct in_addr addr;
  145.  
  146. if (inet_aton(argv[1], &addr) == 0) {
  147. fprintf(stderr, "Invalid address - expected form: x.x.x.x \n");
  148. exit(EXIT_FAILURE);
  149. }
  150. uint16_t pid = getpid();
  151. int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
  152.  
  153. for(int ttl=1; ttl <= 30; ttl++){
  154. int status = UNDEF;
  155. for(int i = 0; i < N; i++){
  156. send_icmp(sockfd, argv[1], ttl);
  157. }
  158.  
  159. char ip[N][20];
  160. struct timeval start_time, timedelta, end_time;
  161. struct timeval waiting_time[N];
  162. gettimeofday(&start_time, NULL);
  163. set_timeout(&timedelta);
  164. timeradd(&start_time, &timedelta, &end_time);
  165. printf("%ld.%06ld\n", start_time.tv_sec, start_time.tv_usec);
  166.  
  167. fprintf(stderr,"%d. ", ttl);
  168. int received_responses = 0;
  169. for(int i = 0; i < N; i++){
  170. uint16_t received_id = -1, received_ttl = -1;
  171. //fprintf(stderr,"%p for ip[%d]\n", ip[i], i );
  172. while((received_id != (uint16_t) getpid() || received_ttl != ttl) && status != TIMEOUT){
  173. status = receive_icmp(sockfd, ttl, &timedelta, &received_id, &received_ttl, ip[i]);
  174. //fprintf(stderr, "got id, ttl = %d, %d ... status = %d \n", received_id, received_ttl, status == TIMEOUT);
  175. }
  176. received_responses += (status != TIMEOUT)?1:0;
  177. if (status == TIMEOUT){
  178. break;
  179. }
  180.  
  181. gettimeofday(&waiting_time[i], NULL);
  182. timersub(&waiting_time[i], &start_time, &waiting_time[i]);
  183. //if(status==TIMEOUT){
  184. // fprintf(stderr, "timeouted %f\n", );
  185. //}
  186. //if (timercmp(&timedelta, &waiting_time[i], <=)){
  187. // fprintf(stderr,"???");
  188. // break;
  189. //}
  190. timersub(&timedelta, &waiting_time[i], &timedelta);
  191. }
  192. // for (int a = 0; a < 60; a++){
  193. // if (a == 20 || a == 40){
  194. // fprintf(stderr,"20 v 40!\n");
  195. // }
  196. // fprintf(stderr,"%c - %d \n", ip[a/20][a % 20], ip[a/20][a % 20]);
  197. // }
  198. // fprintf(stderr,"\n");
  199. char unique_ips[63];
  200. if (received_responses == 3){
  201. fprintf(stderr,"%s %s %s %.0fms \n", ip[0], ip[1], ip[2], (waiting_time[0].tv_usec/1000.0 + waiting_time[1].tv_usec/1000.0 + waiting_time[2].tv_usec/1000.0)/3.0 );
  202. }
  203. else if (received_responses == 0){
  204. fprintf(stderr, "* \n");
  205. }
  206. else{
  207. fprintf(stderr, "weeelllp %s %s %s ???\n", ip[0], ip[1], ip[2]);
  208. }
  209.  
  210.  
  211. if(status==REACHED){
  212. fprintf(stderr, "reached\n");
  213. break;
  214. }
  215. }
  216. fprintf(stderr,"*|* %d *|*\n", getpid());
  217. close(sockfd);
  218.  
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement