First commit

master
Aadhavan Srinivasan 2 years ago
commit d204627b73

155
main.c

@ -0,0 +1,155 @@
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
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);
}
}
Loading…
Cancel
Save