Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Wiktor Garbarek 291963
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <strings.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include "sender.h"
- #include "receiver.h"
- #define UNDEF -1
- #define TIMEOUT 1
- #define REACHED 2
- #define RECEIVED 3
- #define N 3
- #define handle_error(msg) \
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
- void set_timeout(struct timeval *tv){
- tv->tv_sec = 1; tv->tv_usec = 0;
- }
- struct icmphdr* get_icmp_header(struct iphdr* ip_header){
- return (void*)ip_header + 4*ip_header->ihl;
- }
- struct iphdr* get_inner_ip_header(struct icmphdr* icmp_header){
- return (void*)icmp_header + 8;
- }
- void write_unique_ips(const char *ip1, const char *ip2, const char* ip3, char* dst){
- if (strcmp(ip1, ip2) != 0){
- if(strcmp(ip2, ip3) != 0 && strcmp(ip1, ip3) != 0){
- sprintf(dst, "%s %s %s", ip1, ip2, ip3);
- }
- if(strcmp(ip2, ip3) != 0 && strcmp(ip1, ip3) == 0){
- sprintf(dst, "%s %s", ip1, ip2);
- }
- if(strcmp(ip2, ip3) == 0){
- sprintf(dst, "%s %s", ip1, ip2);
- }
- }
- if (strcmp(ip1, ip2) == 0){
- if (strcmp(ip2, ip3) == 0){
- sprintf(dst, "%s", ip1);
- }
- if (strcmp(ip2, ip3) != 0){
- sprintf(dst, "%s %s", ip1, ip3);
- }
- }
- }
- void send_icmp(int sockfd, const char *addr, int ttl){
- struct icmphdr icmp_header;
- fill_icmp_header(&icmp_header, ttl);
- struct sockaddr_in recipient;
- bzero (&recipient, sizeof(recipient));
- recipient.sin_family = AF_INET;
- inet_pton(AF_INET, addr, &recipient.sin_addr);
- if (inet_pton(AF_INET, addr, &recipient.sin_addr) != 1){
- handle_error("inet_pton");
- }
- if (setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)) == -1){
- handle_error("setsockopt");
- }
- if(sendto(sockfd, &icmp_header, sizeof(icmp_header), 0,
- (struct sockaddr*) &recipient, sizeof(recipient)) < 0){
- handle_error("sendto");
- }
- }
- int receive_icmp(int sockfd, uint16_t ttl, struct timeval *timedelta, uint16_t *received_id, uint16_t *received_ttl, char *ip){
- struct sockaddr_in sender;
- socklen_t sender_len = sizeof(sender);
- u_int8_t buffer[IP_MAXPACKET];
- fd_set descriptors;
- FD_ZERO (&descriptors);
- FD_SET (sockfd, &descriptors);
- int ready = select(sockfd+1, &descriptors, NULL, NULL, timedelta);
- if (ready < 0){
- handle_error("select");
- }
- if (ready == 0){
- return TIMEOUT;
- }
- ssize_t packet_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0,
- (struct sockaddr*)&sender, &sender_len);
- char sender_ip_str[20];
- inet_ntop(AF_INET, &(sender.sin_addr), sender_ip_str, sizeof(sender_ip_str));
- //strcpy(ip, sender_ip_str);
- sprintf(ip, "%s", sender_ip_str);
- //fprintf(stderr,"********from %s to %s at ptr %p\n", sender_ip_str, ip, &ip);
- struct iphdr* ip_header = (struct iphdr*) buffer;
- struct icmphdr* icmp_header = get_icmp_header(ip_header);
- //fprintf(stderr,"*******%d %d %d %d\n", icmp_header->type, icmp_header->code, icmp_header->un.echo.id, icmp_header->un.echo.sequence);
- *received_id = icmp_header->un.echo.id;
- *received_ttl = icmp_header->un.echo.sequence;
- if (icmp_header->type == ICMP_TIME_EXCEEDED){
- struct iphdr* ip_header2 = get_inner_ip_header(icmp_header);
- struct icmphdr* icmp_header2 = get_icmp_header(ip_header2);
- // fprintf(stderr,"11: %d %d %d %d\n", icmp_header2->type, icmp_header2->code, icmp_header2->un.echo.id, icmp_header2->un.echo.sequence);
- *received_id = icmp_header2->un.echo.id;
- *received_ttl = icmp_header2->un.echo.sequence;
- }
- // assert(*received_id == getpid());
- // if (sequence == ttl){
- // // fprintf(stderr," %s \n", sender_ip_str);
- // }
- if (icmp_header->type == ICMP_ECHOREPLY){
- return REACHED;
- }
- return RECEIVED;
- }
- int main(int argc, char *argv[]){
- if(argc != 2){
- fprintf(stderr, "Invalid parameters or missing ip address\n");
- exit(EXIT_FAILURE);
- }
- struct in_addr addr;
- if (inet_aton(argv[1], &addr) == 0) {
- fprintf(stderr, "Invalid address - expected form: x.x.x.x \n");
- exit(EXIT_FAILURE);
- }
- uint16_t pid = getpid();
- int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
- for(int ttl=1; ttl <= 30; ttl++){
- int status = UNDEF;
- for(int i = 0; i < N; i++){
- send_icmp(sockfd, argv[1], ttl);
- }
- char ip[N][20];
- struct timeval start_time, timedelta, end_time;
- struct timeval waiting_time[N];
- gettimeofday(&start_time, NULL);
- set_timeout(&timedelta);
- timeradd(&start_time, &timedelta, &end_time);
- printf("%ld.%06ld\n", start_time.tv_sec, start_time.tv_usec);
- fprintf(stderr,"%d. ", ttl);
- int received_responses = 0;
- for(int i = 0; i < N; i++){
- uint16_t received_id = -1, received_ttl = -1;
- //fprintf(stderr,"%p for ip[%d]\n", ip[i], i );
- while((received_id != (uint16_t) getpid() || received_ttl != ttl) && status != TIMEOUT){
- status = receive_icmp(sockfd, ttl, &timedelta, &received_id, &received_ttl, ip[i]);
- //fprintf(stderr, "got id, ttl = %d, %d ... status = %d \n", received_id, received_ttl, status == TIMEOUT);
- }
- received_responses += (status != TIMEOUT)?1:0;
- if (status == TIMEOUT){
- break;
- }
- gettimeofday(&waiting_time[i], NULL);
- timersub(&waiting_time[i], &start_time, &waiting_time[i]);
- //if(status==TIMEOUT){
- // fprintf(stderr, "timeouted %f\n", );
- //}
- //if (timercmp(&timedelta, &waiting_time[i], <=)){
- // fprintf(stderr,"???");
- // break;
- //}
- timersub(&timedelta, &waiting_time[i], &timedelta);
- }
- // for (int a = 0; a < 60; a++){
- // if (a == 20 || a == 40){
- // fprintf(stderr,"20 v 40!\n");
- // }
- // fprintf(stderr,"%c - %d \n", ip[a/20][a % 20], ip[a/20][a % 20]);
- // }
- // fprintf(stderr,"\n");
- char unique_ips[63];
- if (received_responses == 3){
- 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 );
- }
- else if (received_responses == 0){
- fprintf(stderr, "* \n");
- }
- else{
- fprintf(stderr, "weeelllp %s %s %s ???\n", ip[0], ip[1], ip[2]);
- }
- if(status==REACHED){
- fprintf(stderr, "reached\n");
- break;
- }
- }
- fprintf(stderr,"*|* %d *|*\n", getpid());
- close(sockfd);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement