aboutsummaryrefslogtreecommitdiff
path: root/Semestr 4/sieci/pracownia2
diff options
context:
space:
mode:
Diffstat (limited to 'Semestr 4/sieci/pracownia2')
-rw-r--r--Semestr 4/sieci/pracownia2/router.c212
-rw-r--r--Semestr 4/sieci/pracownia2/router/router.c91
-rw-r--r--Semestr 4/sieci/pracownia2/router/router_addr.c32
-rw-r--r--Semestr 4/sieci/pracownia2/router/router_addr.h19
-rw-r--r--Semestr 4/sieci/pracownia2/router/utils.c90
-rw-r--r--Semestr 4/sieci/pracownia2/router/utils.h23
-rwxr-xr-xSemestr 4/sieci/pracownia2/udp_client.c12
7 files changed, 265 insertions, 214 deletions
diff --git a/Semestr 4/sieci/pracownia2/router.c b/Semestr 4/sieci/pracownia2/router.c
deleted file mode 100644
index 79754b3..0000000
--- a/Semestr 4/sieci/pracownia2/router.c
+++ /dev/null
@@ -1,212 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <strings.h>
-#include <string.h>
-#include <netinet/ip.h>
-#include <arpa/inet.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <poll.h>
-#include <time.h>
-#include <unistd.h>
-
-#define SERVER_PORT 54321
-#define TURN_LEN_S 5
-#define TURN_LEN_MS (1000 * TURN_LEN_S)
-#define TURN_LEN_US (1000000 * TURN_LEN_S)
-#define NS_TO_MS(X) ((long)(X) / (long)1000000)
-#define S_TO_MS(X) ((long)(X) * (long)1000)
-
-struct router_addr {
- struct in_addr addr;
- uint16_t distance;
- uint8_t netmask;
-};
-
-struct in_addr get_broadcast_address(struct router_addr ra) {
- struct in_addr result = ra.addr;
- /* bitshift by more than 31 is UB */
- if (ra.netmask < 32) {
- result.s_addr |= ~((1<<ra.netmask) - 1);
- }
- return result;
-}
-
-void pretty_print(struct router_addr ra) {
- char ip_addr[20];
- inet_ntop(AF_INET, &ra.addr, ip_addr, sizeof(ip_addr));
- printf("%s/%d distance %d\n", ip_addr, ra.netmask, ra.distance);
-}
-
-/* converts string of IP with netmask in CIDR notation to router_addr */
-struct router_addr stora(char *str) {
- struct router_addr result;
- char addr[20];
- size_t ip_preffix = strcspn(str, "/");
-
- strncpy(addr, str, strlen(str));
- addr[ip_preffix] = 0;
- inet_pton(AF_INET, addr, &(result.addr));
- result.netmask = atoi(str + ip_preffix + 1);
- return result;
-}
-
-int get_socket() {
- int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sockfd < 0) {
- fprintf(stderr, "Socket error: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- return sockfd;
-}
-
-void bind_to_port(int sockfd, uint16_t port) {
- struct sockaddr_in server_address;
- bzero(&server_address, sizeof(server_address));
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(port);
- server_address.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
- fprintf(stderr, "Bind error: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- int broadcastPermission = 1;
- setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, (void *)&broadcastPermission, sizeof(broadcastPermission));
-}
-
-uint16_t read_configuration(struct router_addr** networks) {
- uint16_t n;
- scanf("%hd", &n);
- *networks = malloc(n * sizeof(struct router_addr));
- for (int i = 0; i < n; i++) {
- char addr[20];
- char _dist[10];
- uint16_t dist;
- scanf(" %s %s %hd", addr, _dist, &dist);
- (*networks)[i] = stora(addr);
- (*networks)[i].distance = dist;
- }
- return n;
-}
-
-long get_time_interval(struct timespec start, struct timespec finish) {
- return S_TO_MS(finish.tv_sec - start.tv_sec) + NS_TO_MS(finish.tv_nsec - start.tv_nsec);
-}
-
-int poll_modify_timeout(struct pollfd *fds, nfds_t nfd, int *timeout) {
- if (*timeout < 0) {
- fprintf(stderr, "poll_modify_timeout: timeout is negative.\n");
- exit(EXIT_FAILURE);
- }
-
- struct timespec start;
- clock_gettime(CLOCK_REALTIME, &start);
- int result = poll(fds, nfd, *timeout);
-
- if (result == -1) {
- fprintf(stderr, "poll error: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- if (result == 0) {
- *timeout = 0;
- return 0;
- }
- struct timespec finish;
- clock_gettime(CLOCK_REALTIME, &finish);
- *timeout -= get_time_interval(start, finish);
- printf("Timeout: %dms, time waiting: %ldms.\n", *timeout, get_time_interval(start, finish));
- return result;
-}
-
-/* For debug purposes only */
-void recv_and_print(int sockfd, int networks_number, struct router_addr *networks) {
- struct sockaddr_in sender;
- socklen_t sender_len = sizeof(sender);
- uint8_t buffer[IP_MAXPACKET + 1];
- ssize_t datagram_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0,
- (struct sockaddr*)&sender, &sender_len);
- if (datagram_len < 0) {
- fprintf(stderr, "recvfrom error: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- for (int i = 0; i < networks_number; i++) {
- if (networks[i].addr.s_addr == sender.sin_addr.s_addr) {
- return;
- }
- }
-
- char sender_ip_str[20];
- inet_ntop(AF_INET, &(sender.sin_addr), sender_ip_str, sizeof(sender_ip_str));
- printf("Received UDP packet from IP address: %s, port %d\n",
- sender_ip_str, ntohs(sender.sin_port));
-
- buffer[datagram_len] = 0;
- printf("%ld-byte message: +%s+\n", datagram_len, buffer);
-
-}
-
-void listen_for_routers(int sockfd, int timeout, int networks_number, struct router_addr *netowrks) {
- printf("Listening for %dms.\n", timeout);
- struct pollfd fds;
- fds.fd = sockfd;
- fds.events = POLLIN;
- fds.revents = 0;
- while (poll_modify_timeout(&fds, 1, &timeout)) {
- printf("Poll returned, remaining timeout: %dms.\n", timeout);
- recv_and_print(sockfd, networks_number, netowrks);
- }
- printf("Finished listening\n");
-}
-
-int send_distance_vector(int sockfd, struct in_addr network) {
- struct sockaddr_in network_address;
- bzero (&network_address, sizeof(network_address));
- network_address.sin_family = AF_INET;
- network_address.sin_port = htons(SERVER_PORT);
- network_address.sin_addr = network;
-
- char* message = "Hello server! My name is S1\n";
- ssize_t message_len = strlen(message);
- int result;
-
- char addr[20];
- inet_ntop(AF_INET, &network, addr, sizeof(addr));
- printf("Sending datagram to %s\n", addr);
- if ((result = sendto(sockfd, message, message_len, 0, (struct sockaddr*) &network_address, sizeof(network_address))) != message_len) {
- fprintf(stderr, "sendto error: %s\n", strerror(errno));
- // return EXIT_FAILURE;
- }
-}
-
-void propagate_distance_vector(int sockfd, int networks_number, struct router_addr *networks) {
- printf("Propagating distance vector\n");
- for (int i = 0; i < networks_number; i++) {
- struct in_addr broadcast_address = get_broadcast_address(networks[i]);
- send_distance_vector(sockfd, broadcast_address);
- }
- printf("Distance vector propagated.\n");
-}
-
-void router_loop(int sockfd, int networks_number, struct router_addr *networks) {
- printf("Starting the router loop...\n");
- for (;;) {
- listen_for_routers(sockfd, TURN_LEN_MS, networks_number, networks);
- propagate_distance_vector(sockfd, networks_number, networks);
- }
-}
-
-int main() {
- struct router_addr* networks;
- int n = read_configuration(&networks);
- for (int i = 0; i < n; i++) {
- pretty_print(networks[i]);
- }
-
- int sockfd = get_socket();
- bind_to_port(sockfd, SERVER_PORT);
- router_loop(sockfd, n, networks);
-
- close(sockfd);
- free(networks);
-} \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/router/router.c b/Semestr 4/sieci/pracownia2/router/router.c
new file mode 100644
index 0000000..f68a6a3
--- /dev/null
+++ b/Semestr 4/sieci/pracownia2/router/router.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <errno.h>
+#include <strings.h>
+#include <string.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "router_addr.h"
+#include "utils.h"
+
+#define SERVER_PORT 54321
+#define TURN_LEN_S 5
+#define TURN_LEN_MS (1000 * TURN_LEN_S)
+#define TURN_LEN_US (1000000 * TURN_LEN_S)
+
+uint16_t read_configuration(struct router_addr** networks) {
+ uint16_t n;
+ scanf("%hd", &n);
+ *networks = malloc(n * sizeof(struct router_addr));
+ for (int i = 0; i < n; i++) {
+ char addr[20];
+ char _dist[10];
+ uint16_t dist;
+ scanf(" %s %s %hd", addr, _dist, &dist);
+ (*networks)[i] = stora(addr);
+ (*networks)[i].distance = dist;
+ }
+ return n;
+}
+
+void listen_for_routers(int sockfd, int timeout, int networks_number, struct router_addr *netowrks) {
+ printf("Listening for %dms.\n", timeout);
+ while (poll_socket_modify_timeout(sockfd, &timeout)) {
+ printf("Poll returned, remaining timeout: %dms.\n", timeout);
+ recv_and_print(sockfd, networks_number, netowrks);
+ }
+ printf("Finished listening\n\n");
+}
+
+int send_distance_vector(int sockfd, struct in_addr network) {
+ struct sockaddr_in network_address;
+ bzero (&network_address, sizeof(network_address));
+ network_address.sin_family = AF_INET;
+ network_address.sin_port = htons(SERVER_PORT);
+ network_address.sin_addr = network;
+
+ char* message = "Hello server! My name is S1\n";
+ ssize_t message_len = strlen(message);
+ int result;
+
+ char addr[20];
+ inet_ntop(AF_INET, &network, addr, sizeof(addr));
+ printf("Sending datagram to %s\n", addr);
+ if ((result = sendto(sockfd, message, message_len, 0, (struct sockaddr*) &network_address, sizeof(network_address))) != message_len) {
+ fprintf(stderr, "sendto error: %s\n", strerror(errno));
+ }
+}
+
+void propagate_distance_vector(int sockfd, int networks_number, struct router_addr *networks) {
+ printf("Propagating distance vector\n");
+ for (int i = 0; i < networks_number; i++) {
+ struct in_addr broadcast_address = get_broadcast_address(networks[i]);
+ send_distance_vector(sockfd, broadcast_address);
+ }
+ printf("Distance vector propagated.\n\n");
+}
+
+void router_loop(int sockfd, int networks_number, struct router_addr *networks) {
+ printf("Starting the router loop...\n");
+ for (;;) {
+ listen_for_routers(sockfd, TURN_LEN_MS, networks_number, networks);
+ propagate_distance_vector(sockfd, networks_number, networks);
+ }
+}
+
+int main() {
+ struct router_addr* networks;
+ int n = read_configuration(&networks);
+ for (int i = 0; i < n; i++) {
+ pretty_print(networks[i]);
+ }
+
+ int sockfd = get_socket();
+ bind_to_port(sockfd, SERVER_PORT);
+ router_loop(sockfd, n, networks);
+
+ close(sockfd);
+ free(networks);
+} \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/router/router_addr.c b/Semestr 4/sieci/pracownia2/router/router_addr.c
new file mode 100644
index 0000000..1e4c086
--- /dev/null
+++ b/Semestr 4/sieci/pracownia2/router/router_addr.c
@@ -0,0 +1,32 @@
+#include "router_addr.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct in_addr get_broadcast_address(struct router_addr ra) {
+ struct in_addr result = ra.addr;
+ /* bitshift by more than 31 is UB */
+ if (ra.netmask < 32) {
+ result.s_addr |= ~((1<<ra.netmask) - 1);
+ }
+ return result;
+}
+
+void pretty_print(struct router_addr ra) {
+ char ip_addr[20];
+ inet_ntop(AF_INET, &ra.addr, ip_addr, sizeof(ip_addr));
+ printf("%s/%d distance %d\n", ip_addr, ra.netmask, ra.distance);
+}
+
+/* converts string of IP with netmask in CIDR notation to router_addr */
+struct router_addr stora(char *str) {
+ struct router_addr result;
+ char addr[20];
+ size_t ip_preffix = strcspn(str, "/");
+
+ strncpy(addr, str, strlen(str));
+ addr[ip_preffix] = 0;
+ inet_pton(AF_INET, addr, &(result.addr));
+ result.netmask = atoi(str + ip_preffix + 1);
+ return result;
+} \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/router/router_addr.h b/Semestr 4/sieci/pracownia2/router/router_addr.h
new file mode 100644
index 0000000..bebb0f5
--- /dev/null
+++ b/Semestr 4/sieci/pracownia2/router/router_addr.h
@@ -0,0 +1,19 @@
+#ifndef ROUTER_ADDR_H
+#define ROUTER_ADDR_H
+
+#include <arpa/inet.h>
+#include <stdint.h>
+
+struct router_addr {
+ struct in_addr addr;
+ uint16_t distance;
+ uint8_t netmask;
+};
+
+struct in_addr get_broadcast_address(struct router_addr ra);
+
+void pretty_print(struct router_addr ra);
+
+struct router_addr stora(char *str);
+
+#endif \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/router/utils.c b/Semestr 4/sieci/pracownia2/router/utils.c
new file mode 100644
index 0000000..9f008eb
--- /dev/null
+++ b/Semestr 4/sieci/pracownia2/router/utils.c
@@ -0,0 +1,90 @@
+#include "utils.h"
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+int get_socket() {
+ int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0) {
+ fprintf(stderr, "Socket error: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ return sockfd;
+}
+
+void bind_to_port(int sockfd, uint16_t port) {
+ struct sockaddr_in server_address;
+ bzero(&server_address, sizeof(server_address));
+ server_address.sin_family = AF_INET;
+ server_address.sin_port = htons(port);
+ server_address.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
+ fprintf(stderr, "Bind error: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ int broadcastPermission = 1;
+ setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, (void *)&broadcastPermission, sizeof(broadcastPermission));
+}
+
+long get_time_interval(struct timespec start, struct timespec finish) {
+ return S_TO_MS(finish.tv_sec - start.tv_sec) + NS_TO_MS(finish.tv_nsec - start.tv_nsec);
+}
+
+int poll_socket_modify_timeout(int sockfd, int *timeout) {
+ if (*timeout < 0) {
+ fprintf(stderr, "poll_modify_timeout: timeout is negative.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ struct pollfd fds;
+ fds.fd = sockfd;
+ fds.events = POLLIN;
+ fds.revents = 0;
+
+ struct timespec start;
+ clock_gettime(CLOCK_REALTIME, &start);
+ int result = poll(&fds, 1, *timeout);
+
+ if (result == -1) {
+ fprintf(stderr, "poll error: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (result == 0) {
+ *timeout = 0;
+ return 0;
+ }
+ struct timespec finish;
+ clock_gettime(CLOCK_REALTIME, &finish);
+ *timeout -= get_time_interval(start, finish);
+ printf("Timeout: %dms, time waiting: %ldms.\n", *timeout, get_time_interval(start, finish));
+ return result;
+}
+
+/* For debug purposes only */
+void recv_and_print(int sockfd, int networks_number, struct router_addr *networks) {
+ struct sockaddr_in sender;
+ socklen_t sender_len = sizeof(sender);
+ uint8_t buffer[IP_MAXPACKET + 1];
+ ssize_t datagram_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0,
+ (struct sockaddr*)&sender, &sender_len);
+ if (datagram_len < 0) {
+ fprintf(stderr, "recvfrom error: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ for (int i = 0; i < networks_number; i++) {
+ if (networks[i].addr.s_addr == sender.sin_addr.s_addr) {
+ return;
+ }
+ }
+
+ char sender_ip_str[20];
+ inet_ntop(AF_INET, &(sender.sin_addr), sender_ip_str, sizeof(sender_ip_str));
+ printf("Received UDP packet from IP address: %s, port %d\n",
+ sender_ip_str, ntohs(sender.sin_port));
+
+ buffer[datagram_len] = 0;
+ printf("%ld-byte message: +%s+\n", datagram_len, buffer);
+} \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/router/utils.h b/Semestr 4/sieci/pracownia2/router/utils.h
new file mode 100644
index 0000000..3d36aed
--- /dev/null
+++ b/Semestr 4/sieci/pracownia2/router/utils.h
@@ -0,0 +1,23 @@
+#ifndef UTILS_H
+#define UTILS_H
+#define UTILS_H
+
+#include <stdint.h>
+#include <time.h>
+#include <poll.h>
+#include "router_addr.h"
+
+#define NS_TO_MS(X) ((long)(X) / (long)1000000)
+#define S_TO_MS(X) ((long)(X) * (long)1000)
+
+int get_socket();
+
+void bind_to_port(int sockfd, uint16_t port);
+
+long get_time_interval(struct timespec start, struct timespec finish);
+
+int poll_socket_modify_timeout(int sockfd, int *timeout);
+
+void recv_and_print(int sockfd, int networks_number, struct router_addr *networks);
+
+#endif \ No newline at end of file
diff --git a/Semestr 4/sieci/pracownia2/udp_client.c b/Semestr 4/sieci/pracownia2/udp_client.c
index 5624484..4e7dce4 100755
--- a/Semestr 4/sieci/pracownia2/udp_client.c
+++ b/Semestr 4/sieci/pracownia2/udp_client.c
@@ -6,8 +6,13 @@
#include <unistd.h>
#include <errno.h>
-int main()
+int main(int argc, char * argv[])
{
+ if (argc < 2) {
+ printf("Usage:\n\t%s [server ip]\n", argv[0]);
+ return -1;
+ }
+
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
fprintf(stderr, "socket error: %s\n", strerror(errno));
@@ -18,7 +23,10 @@ int main()
bzero (&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(54321);
- inet_pton(AF_INET, "192.168.1.2", &server_address.sin_addr);
+ if (!inet_pton(AF_INET, argv[1], &server_address.sin_addr)) {
+ printf("Inavlid ip address\n");
+ return -1;
+ }
char* message = "Hello server!";
ssize_t message_len = strlen(message);