From d204627b7318b460b0295063b910af94918c6e29 Mon Sep 17 00:00:00 2001 From: Rockingcool Date: Wed, 22 Feb 2023 07:40:58 -0600 Subject: [PATCH] First commit --- main.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 main.c diff --git a/main.c b/main.c new file mode 100644 index 0000000..4f0e316 --- /dev/null +++ b/main.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include +#include +#include +int create_socket(int network, char transport) { + +/* 'network' contains 4 for ipv4 or 6 for ipv6. + 'transport' contains 'T' for TCP or 'U' for UDP. + The function returns -1 if the paramters do not match the above statement. */ + + int domain; + int type; + + if (network == 4) { + domain = AF_INET; + } else if (network == 6) { + domain = AF_INET6; + } else { + return -1; + } + + if (transport == 'T') { + type = SOCK_STREAM; + } else if (transport == 'U') { + type = SOCK_DGRAM; + } else { + return -1; + } + + int newSock = socket(domain,type,0); + return newSock; +} + + +void create_addr(int network, char* address, int port,struct sockaddr* dest) { +/* Takes the relevant values - network (4 or 6), address, port - and fills them + into dest */ + + if (network == 4) { + struct sockaddr_in listen_address; + + listen_address.sin_family = AF_INET; + listen_address.sin_port = htons(port); + inet_pton(AF_INET,address,&listen_address.sin_addr); + memcpy(dest,&listen_address,sizeof(listen_address)); + return; + + } else if (network == 6) { + struct sockaddr_in6 listen_ipv6; + listen_ipv6.sin6_family = AF_INET6; + listen_ipv6.sin6_port = htons(port); + inet_pton(AF_INET6,address,&listen_ipv6.sin6_addr); + memcpy(dest,&listen_ipv6,sizeof(listen_ipv6)); + return; + + } else { + exit(-2); + } + +} + + + + + +int create_and_bind (int network, char transport, char* address, int port,struct sockaddr* addr_struct) { +/* combines the socket creation and address creation into one + function - simply pass the required values, and a structure, + and this function does the legwork for you */ + + int socket = create_socket(network,transport); + if (socket == -1) { + exit(-1); + } + create_addr(network,address,port,addr_struct); + int addrlen = sizeof(*addr_struct); + int i = bind (socket,addr_struct,(socklen_t)addrlen); + if (i < 0) { + exit(-3); + } + return socket; +} + +int create_remote (int network,char transport,char* address,int port) { +/* same as 'create_and_bind', but for remote sockets - client rather + than server sockets */ + + int socket = create_socket(network,transport); + if (socket == -1) { + exit(-1); + } + struct sockaddr remote_addr_struct; + create_addr(network,address,port,&remote_addr_struct); + int addrlen = sizeof(remote_addr_struct); + int i = connect(socket,&remote_addr_struct,(socklen_t)addrlen); + if (i < 0) { + printf("Something went wrong: %s\n",strerror(errno)); + exit(-3); + } + return socket; +} + +void forward_data(int from_fd, int to_fd) { + int n = 0; + char* buffer = malloc(3000*sizeof(char)); + while ((n = recv(to_fd, buffer, 3000, 0)) > 0) { // read data from input socket + send(to_fd, buffer, n, 0); // send data to output socket + } +} + +int main() { + + int preferred_network = 4; + char preferred_transport = 'T'; + struct sockaddr addr_struct; + int server_sock = create_and_bind(preferred_network,preferred_transport,"127.0.0.1",3000,&addr_struct); + int addrlen = sizeof(addr_struct); + + listen(server_sock,50); /* Arbitrary number, change later */ + + while (1) { + int from_client = accept(server_sock,&addr_struct,(socklen_t *)&addrlen); + int to_server = create_remote(preferred_network,preferred_transport,"127.0.0.1",5000); + + if (fork() == 0) { + + /* fork returns 0 for a child, so we're in the child's execution + right now */ + close(server_sock); + if (fork() == 0) { + forward_data(from_client,to_server); + exit(0); + } + if (fork() == 0) { + forward_data(to_server,from_client); + exit(0); + } + exit(0); + + + } +// recv(from_client,buffer,3000,0); + + +// printf("%s",buffer); + + + } + +} +