Added separate file for helper functions.
This commit is contained in:
83
easysock.c
Normal file
83
easysock.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "easysock.h"
|
||||||
|
|
||||||
|
int create_socket(int network, char transport) {
|
||||||
|
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) {
|
||||||
|
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_local (int network, char transport, char* address, int port,struct sockaddr* addr_struct) {
|
||||||
|
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) {
|
||||||
|
printf("Something went wrong: %s\n",strerror(errno));
|
||||||
|
exit(-3);
|
||||||
|
}
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_remote (int network,char transport,char* address,int port) {
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
44
easysock.h
Normal file
44
easysock.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* This function takes:
|
||||||
|
a layer 3 - network layer - integer, which must be '4' for IPv4
|
||||||
|
and 6 for IPv6; and
|
||||||
|
a layer 4 - transport layer - character, which must be 'T' for
|
||||||
|
TCP or 'U' for UDP.
|
||||||
|
|
||||||
|
It returns the created socket, or -1 if the socket creation failed.*/
|
||||||
|
|
||||||
|
int create_socket(int network, char transport);
|
||||||
|
|
||||||
|
|
||||||
|
/* This function fills in the sockaddr struct 'dest' based on the given information.
|
||||||
|
'network' is an integer that contains '4' for IPv4 or '6' for IPv6;
|
||||||
|
'address' is the address that is filled into the struct;
|
||||||
|
port is self-explanatory;
|
||||||
|
and dest is a pointer to the sockaddr struct that will be filled in.
|
||||||
|
|
||||||
|
The function exits with error code -2 if the network parameter contained neither '4'
|
||||||
|
nor '6'. */
|
||||||
|
|
||||||
|
void create_addr(int network, char* address, int port,struct sockaddr* dest);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* This function utilizes the above two functions; it creates the socket and
|
||||||
|
_binds_ the addresses. It is used for local sockets (server sockets). Parameters are
|
||||||
|
same as above.
|
||||||
|
|
||||||
|
It prints the error returned by 'bind' if something went wrong, and exits with error code '-3'.*/
|
||||||
|
|
||||||
|
int create_local (int network, char transport, char* address, int port,struct sockaddr* addr_struct);
|
||||||
|
|
||||||
|
|
||||||
|
/* This function utilizes the same functions as 'create_local' but _connects_ to the
|
||||||
|
requested address. It is used for remoet sockets (client sockets). The paramters are same
|
||||||
|
as above.
|
||||||
|
|
||||||
|
It prints the error returned by 'connect' if something went wrong, and exits with error code '-3'.*/
|
||||||
|
int create_remote (int network,char transport,char* address,int port);
|
102
main.c
102
main.c
@@ -1,108 +1,8 @@
|
|||||||
#include <sys/socket.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.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) {
|
void forward_data(int from_fd, int to_fd) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@@ -117,7 +17,7 @@ int main() {
|
|||||||
int preferred_network = 4;
|
int preferred_network = 4;
|
||||||
char preferred_transport = 'T';
|
char preferred_transport = 'T';
|
||||||
struct sockaddr addr_struct;
|
struct sockaddr addr_struct;
|
||||||
int server_sock = create_and_bind(preferred_network,preferred_transport,"127.0.0.1",3000,&addr_struct);
|
int server_sock = create_local(preferred_network,preferred_transport,"127.0.0.1",3000,&addr_struct);
|
||||||
int addrlen = sizeof(addr_struct);
|
int addrlen = sizeof(addr_struct);
|
||||||
|
|
||||||
listen(server_sock,50); /* Arbitrary number, change later */
|
listen(server_sock,50); /* Arbitrary number, change later */
|
||||||
|
Reference in New Issue
Block a user