aboutsummaryrefslogtreecommitdiff
path: root/Semestr 4/sieci/pracownia1/traceroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'Semestr 4/sieci/pracownia1/traceroute.c')
-rw-r--r--Semestr 4/sieci/pracownia1/traceroute.c88
1 files changed, 44 insertions, 44 deletions
diff --git a/Semestr 4/sieci/pracownia1/traceroute.c b/Semestr 4/sieci/pracownia1/traceroute.c
index 9281e4f..0e51c14 100644
--- a/Semestr 4/sieci/pracownia1/traceroute.c
+++ b/Semestr 4/sieci/pracownia1/traceroute.c
@@ -1,3 +1,8 @@
+/* Pracownia programistyczna nr 1 - traceroute
+ * ImiÄ™ i nazwisko: Franciszek Malinka
+ * Nr indeksu: 316093
+ */
+
#include <stdio.h>
#include <errno.h>
#include <netinet/ip.h>
@@ -23,6 +28,23 @@ void print_as_bytes (unsigned char* buff, ssize_t length)
printf ("%.2x ", *buff);
}
+void debug_received(uint8_t *buffer, struct sockaddr_in *sender, int packet_len) {
+ char ip_str[20];
+ inet_ntop(AF_INET, &(sender->sin_addr), ip_str, sizeof(ip_str));
+
+ printf("IP packet with ICMP content from: %s\n", ip_str);
+ struct ip* ip_header = (struct ip*) buffer;
+ ssize_t ip_header_len = 4 * ip_header->ip_hl;
+
+ printf ("IP header: ");
+ print_as_bytes (buffer, ip_header_len);
+ printf("\n");
+
+ printf ("IP data: ");
+ print_as_bytes (buffer + ip_header_len, packet_len - ip_header_len);
+ printf("\n\n");
+}
+
struct sockaddr_in get_sockaddr_from_ip(char *ip) {
struct sockaddr_in sock;
bzero(&sock, sizeof(sock));
@@ -71,7 +93,6 @@ void send_icmp_packet(int sockfd, struct sockaddr_in *destination, int ttl) {
struct icmp header = create_icmp_header(ttl);
setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int));
- // printf("%u %d\n", destination->sin_addr.s_addr, sockfd);
ssize_t bytes_sent = sendto(
sockfd,
&header,
@@ -84,13 +105,11 @@ void send_icmp_packet(int sockfd, struct sockaddr_in *destination, int ttl) {
fprintf(stderr, "Error while sending ICMP packet: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
- // fprintf(stdout, "Bytes sent: %ld\n", bytes_sent);
}
/* Return ip address of the sender of recceived package */
ssize_t recv_packet(int sockfd, struct sockaddr_in *sender, uint8_t *buffer) {
- socklen_t sender_len = sizeof(*sender);
-
+ socklen_t sender_len = sizeof(*sender);
ssize_t packet_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0,
(struct sockaddr*)sender, &sender_len);
@@ -114,36 +133,14 @@ int try_select(int sockfd, struct timeval *tv) {
return select(sockfd+1, &descriptors, NULL, NULL, tv);
}
-void in_addr_to_string(struct in_addr *sender, char *ip_str) {
- inet_ntop(AF_INET, sender, ip_str, sizeof(ip_str));
-}
-
-void debug_recieved(uint8_t *buffer, struct sockaddr_in *sender, int packet_len) {
- char ip_str[20];
- inet_ntop(AF_INET, &(sender->sin_addr), ip_str, sizeof(ip_str));
-
- // in_addr_to_string(&(sender->sin_addr), ip_str);
- printf("IP packet with ICMP content from: %s\n", ip_str);
- struct ip* ip_header = (struct ip*) buffer;
- ssize_t ip_header_len = 4 * ip_header->ip_hl;
-
- printf ("IP header: ");
- print_as_bytes (buffer, ip_header_len);
- printf("\n");
-
- printf ("IP data: ");
- print_as_bytes (buffer + ip_header_len, packet_len - ip_header_len);
- printf("\n\n");
-}
-
-void pretty_print_router(int ttl, struct in_addr *senders, float mean_wait_time, int messages_recieved) {
+void pretty_print_router(int ttl, struct in_addr *senders, float mean_wait_time, int messages_received) {
char ip_str[20];
printf("%d.\t", ttl);
- if (messages_recieved == 0) {
+ if (messages_received == 0) {
printf("*\n");
}
else {
- for (int i = 0; i < messages_recieved; i++) {
+ for (int i = 0; i < messages_received; i++) {
bool already_printed = false;
for (int j = 0; j < i; j++) {
if (senders[i].s_addr == senders[j].s_addr) {
@@ -153,27 +150,25 @@ void pretty_print_router(int ttl, struct in_addr *senders, float mean_wait_time,
}
if (already_printed) continue;
inet_ntop(AF_INET, senders + i, ip_str, sizeof(ip_str));
- // in_addr_to_string(senders + i, ip_str);
printf("%-15s ", ip_str);
}
- if (messages_recieved < MESSAGES_PER_TTL) printf("\t???\n");
+ if (messages_received < MESSAGES_PER_TTL) printf("\t???\n");
else printf("\t%.2fms\n", mean_wait_time);
}
}
+// This function decapsulates important data from the IMCP replies
void get_important_data(uint8_t *buffer, uint8_t *code, uint16_t *id, uint16_t *seq) {
struct ip* ip_header = (struct ip*) buffer;
ssize_t offset = 4 * ip_header->ip_hl;
*code = ((struct icmp *)(buffer + offset))->icmp_type;
- if (*code == ICMP_TIMXCEED) {
+ if (*code != ICMP_ECHOREPLY && *code != ICMP_TIMXCEED) {
+ return;
+ } else if (*code == ICMP_TIMXCEED) {
offset += ICMP_MINLEN;
offset += 4 * ((struct ip *)(buffer + offset))->ip_hl;
*seq = ((struct icmp *)(buffer + offset))->icmp_seq;
*id = ((struct icmp *)(buffer + offset))->icmp_id;
- }
- else if (*code != ICMP_ECHOREPLY) {
- fprintf(stderr, "Something went wrong, recieved ICMP packet with code %d\n.", *code);
- exit(EXIT_FAILURE);
} else {
*seq = ((struct icmp *)(buffer + offset))->icmp_seq;
*id = ((struct icmp *)(buffer + offset))->icmp_id;
@@ -181,13 +176,13 @@ void get_important_data(uint8_t *buffer, uint8_t *code, uint16_t *id, uint16_t *
}
// timeout in milliseconds
-float get_replies(int sockfd, long timeout, int ttl, int *messages_recieved, struct in_addr *senders) {
+float get_replies(int sockfd, long timeout, int ttl, int *messages_received, struct in_addr *senders) {
struct sockaddr_in sender;
uint8_t buffer[IP_MAXPACKET];
int ready;
long mean_wait_time = 0;
struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = 0;
- *messages_recieved = 0;
+ *messages_received = 0;
while ((ready = try_select(sockfd, &tv))) {
if (ready < 0) {
@@ -201,25 +196,29 @@ float get_replies(int sockfd, long timeout, int ttl, int *messages_recieved, str
get_important_data(buffer, &icmp_code, &id, &seq);
if (seq == ttl) {
- senders[(*messages_recieved)++] = sender.sin_addr;
+ senders[(*messages_received)++] = sender.sin_addr;
mean_wait_time += timeout * 1000 - tv.tv_usec;
- if (*messages_recieved == MESSAGES_PER_TTL) break;
+ if (*messages_received == MESSAGES_PER_TTL) break;
}
}
// changing from microseconds to miliseconds
return (float)mean_wait_time / 3.0 / 1000.0;
}
+// Core of the program.
void traceroute(struct sockaddr_in *destination) {
- int sockfd = create_raw_icmp_socket(), messages_recieved = 0;
+ int sockfd = create_raw_icmp_socket(), messages_received = 0;
struct in_addr senders[MESSAGES_PER_TTL];
for (int ttl = 1; ttl <= MAX_TTL; ++ttl) {
send_icmp_requests(sockfd, destination, ttl, MESSAGES_PER_TTL);
- float mean_wait_time = get_replies(sockfd, 1000, ttl, &messages_recieved, senders);
- pretty_print_router(ttl, senders, mean_wait_time, messages_recieved);
- for (int i = 0; i < messages_recieved; i++) {
+ float mean_wait_time = get_replies(sockfd, 1000, ttl, &messages_received, senders);
+ pretty_print_router(ttl, senders, mean_wait_time, messages_received);
+
+ // what if our packet branched and we got to the destination faster by some path?
+ // we gotta make a loop, not an if
+ for (int i = 0; i < messages_received; i++) {
if (senders[i].s_addr == destination->sin_addr.s_addr) {
return;
}
@@ -234,6 +233,7 @@ int main(int argc, char * argv[]) {
}
struct sockaddr_in destination = get_sockaddr_from_ip(argv[1]);
+ fprintf(stdout, "traceroute to %s, %d hops max\n", argv[1], MAX_TTL);
traceroute(&destination);
return 0;