From e6c94b64a05cd749e569d52f08f44ff307f2097c Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Fri, 22 Mar 2024 03:50:58 +0400 Subject: [PATCH] First try to implement a network module. --- src/net.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net.h | 24 +++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/net.c create mode 100644 src/net.h diff --git a/src/net.c b/src/net.c new file mode 100644 index 0000000..70caa0b --- /dev/null +++ b/src/net.c @@ -0,0 +1,81 @@ +#include "net.h" + +#include +#include +#include + +#include + +int net_client_init(net_t *const n, const int af_family, const char *const raddr, const int rport) { + if ((n->fd = socket(af_family, SOCK_DGRAM, 0)) == -1 ) + return -1; + + memset(&n->inaddr, 0, sizeof(n->inaddr)); + n->inaddr_len = sizeof(n->inaddr); + + memset(&n->raddr, 0, sizeof(n->raddr)); + n->raddr.sin_family = af_family; + n->raddr.sin_addr.s_addr = inet_addr(raddr); + n->raddr.sin_port = htons(rport); + + return 0; +} + +int net_server_init(net_t *const n, const int af_family, const char *const laddr, const int lport) { + if ((n->fd = socket(af_family, SOCK_DGRAM, 0)) == -1 ) + return -1; + + memset(&n->inaddr, 0, sizeof(n->inaddr)); + n->inaddr_len = sizeof(n->inaddr); + + memset(&n->laddr, 0, sizeof(n->laddr)); + n->laddr.sin_family = af_family; + n->laddr.sin_addr.s_addr = inet_addr(laddr); + n->laddr.sin_port = htons(lport); + + memset(&n->raddr, 0, sizeof(n->raddr)); + n->raddr_len = sizeof(n->raddr); + + if (bind(n->fd, (struct sockaddr *)&n->laddr, sizeof(n->laddr)) == -1) + return -1; + + return 0; +} + +void net_destroy(net_t *n) { + if (n->fd > 0) { + close(n->fd); + n->fd = -1; + } + + memset(&n->raddr, 0, sizeof(n->raddr)); + n->raddr_len = sizeof(n->raddr); + memset(&n->laddr, 0, sizeof(n->laddr)); + + memset(&n->buffer, 0, NET_BUFLEN); +} + +int net_sendto(net_t *const n, const char *const buf, const int buf_len) { + if (n->fd == -1) + return -1; + + if (sendto(n->fd, buf, buf_len, 0, (struct sockaddr *)&n->raddr, sizeof(n->raddr)) == -1) + return -1; + + return 0; +} + +int net_recvfrom(net_t *const n) { + if (n->fd == -1 || n->raddr.sin_addr.s_addr == 0) + return -1; + + if ((recvfrom(n->fd, n->buffer, NET_BUFLEN, 0, (struct sockaddr *)&n->inaddr, &n->inaddr_len)) == -1) + return -1; + + if (n->raddr.sin_addr.s_addr != n->inaddr.sin_addr.s_addr) { + /* Incoming packet doesn't originate from the one we are talking to. Drop it. */ + return 0; + } + + return 0; +} diff --git a/src/net.h b/src/net.h new file mode 100644 index 0000000..c15b8c1 --- /dev/null +++ b/src/net.h @@ -0,0 +1,24 @@ +#ifndef _NET_H_ +#define _NET_H_ + +#include +#include + +#define NET_BUFLEN 256 + +typedef struct net_t { + int fd; + struct sockaddr_in laddr, raddr, inaddr; + socklen_t raddr_len, inaddr_len; + + char buffer[NET_BUFLEN]; +} net_t; + +int net_client_init(net_t *const n, const int af_family, const char *const raddr, const int rport); +int net_server_init(net_t *const n, const int af_family, const char *const laddr, const int lport); +void net_destroy(net_t *n); + +int net_sendto(net_t *const n, const char *const buf, const int buf_len); +int net_recvfrom(net_t *const n); + +#endif /* _NET_H_ */ \ No newline at end of file