Skip to content

Instantly share code, notes, and snippets.

@v2px
Created November 15, 2024 23:16
Show Gist options
  • Save v2px/4489f27781f96a642e8a05da9129af31 to your computer and use it in GitHub Desktop.
Save v2px/4489f27781f96a642e8a05da9129af31 to your computer and use it in GitHub Desktop.
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "log.h"
static const int enable = 1;
static const int disable = 0;
const char *lookup_af(int af) {
switch(af) {
case AF_INET:
return "AF_INET";
case AF_INET6:
return "AF_INET6";
}
return "UNDEF";
}
int detect_af(const char *address) {
int colon = 0;
for(int i = 0; address[i]; i++) {
if(':' == address[i])
colon++;
}
switch(colon) {
case 0:
return AF_INET;
case 1:
return -1;
case 2:
default:
return AF_INET6;
}
}
int psircd_server_create(int *fd, const char *address, int port) {
int af, sasize;
struct in_addr ia;
struct in6_addr ia6;
struct sockaddr_storage sas;
DEBUG("%s:%d", address, port);
memset(&sas, 0, sizeof(sas));
af = detect_af(address);
if(-1 == af) {
ERR("Was unable to detect AF for address; %s", address);
return -1;
}
switch(af) {
case AF_INET:
DEBUG("AF_INET", 0);
if(-1 == inet_pton(af, address, &ia)) {
ERR("inet_pton(): %s", errno);
return -1;
}
((struct sockaddr_in*)&sas)->sin_family = AF_INET;
((struct sockaddr_in*)&sas)->sin_port = htons(port);
((struct sockaddr_in*)&sas)->sin_addr = ia;
sasize = sizeof(struct sockaddr_in);
break;
case AF_INET6:
DEBUG("AF_INET6", 0);
if(-1 == inet_pton(af, address, &ia6)) {
ERR("inet_pton(): %s", errno);
return -1;
}
((struct sockaddr_in6*)&sas)->sin6_family = AF_INET6;
((struct sockaddr_in6*)&sas)->sin6_port = htons(port);
((struct sockaddr_in6*)&sas)->sin6_addr = ia6;
sasize = sizeof(struct sockaddr_in6);
break;
}
*fd = socket(af, SOCK_STREAM, 0);
if (-1 == *fd) {
ERR("Socket could not be created: %s", strerror(errno));
return errno;
}
if (0 != setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
ERR("setsockopt(SO_REUSEADDR) failed: %s", strerror(errno));
return errno;
}
if (0 != bind(*fd, (struct sockaddr *)&sas, sasize)) {
ERR("bind() failed: %s", strerror(errno));
return errno;
}
INFO("Created %s server socket %d, bound to %s:%d",
lookup_af(af), *fd, address, port);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment