From: Sam Smith Date: Tue, 19 Apr 2022 04:48:56 +0000 (-0700) Subject: First commit X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=8aff8513c94be1db29b8d8ec8ab6eecdcabc6945;p=patchyircd.git First commit --- diff --git a/client.c b/client.c new file mode 100644 index 0000000..f977d32 --- /dev/null +++ b/client.c @@ -0,0 +1,16 @@ +#include +#include + +int main(void) { + puts("NICK e"); + puts("USER "); + puts("JOIN #epic"); + fflush(stdout); + char buffer[1024]; + while (1) { + scanf("%s", buffer); + printf("PRIVMSG #epic :%s\n", buffer); + fflush(stdout); + } + return 0; +} diff --git a/main.c b/main.c new file mode 100755 index 0000000..94e9af5 --- /dev/null +++ b/main.c @@ -0,0 +1,455 @@ +// Some macros to control options +#define LISTENING_PORT 6667 +#define LISTENING_BACKLOG 10 +#define CLIENT_SOCKETS 30 +#define FD_SETSIZE 1024 +#define SUPPORT_IPV4 +#define SUPPORT_IPV6 + +#include +#include +#include +#include +#if defined(_WIN32) +#pragma message("Warning: Windows detected.") +//#include +//#include +//#include +#include +#include +#include +#pragma message("IMPORTANT: COMPILE WITH -lws2_32") +#pragma comment(lib, "ws2_32.lib") +#define PRISocket "llu" +#else +#include +#include +#include +#include +#include +#include +#include +#include +//typedef unsigned long long SOCKET; +typedef int SOCKET; +#define PRISocket "d" +#endif + +struct client_data { + SOCKET FD; + char type; + char nick[32]; + size_t nickLen; +}; + +struct client_data client_socket[CLIENT_SOCKETS]; + +#if defined(_WIN32) +#define net_errno() (WSAGetLastError()) +const char *net_strerror(int e) { + static char msg[256]; + if (!FormatMessageA(\ + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, e, 0, msg, 256, NULL)) + sprintf(msg, "WSA Error %d", e); + return msg; +} +int net_nonblock(SOCKET fd) { + u_long v = 1; + return ioctlsocket(fd, FIONBIO, &v); +} +#else +#define net_errno() ((int)errno) +#define net_strerror(e) strerror((e)) +#define closesocket close +#define INVALID_SOCKET -1 +int net_nonblock(SOCKET fd) { + int f = fcntl(fd, F_GETFL); + if (f == -1) + return -1; + return fcntl(fd, F_SETFL, f | O_NONBLOCK); +} +#endif +void net_perror(const char *p) +{ + if (p && *p) + fprintf(stderr, "%s: %s\n", p, net_strerror(net_errno())); + else + fprintf(stderr, "%s\n", net_strerror(net_errno())); +} + +size_t send_log(int socket, const void *buffer, size_t length, int flags) { + printf("SERVER: %s", (char*)buffer); + fflush(stdout); + return send(socket, buffer, length, flags); +} + +void sendall_log(int socket, const void *buffer, size_t length, int flags) { + int i; + for(i=0;iFD, packet, packetLen, 0); + } else if(strncmp(packet, "NICK ", 5) == 0) { + // User now registered + setNick(client, packet+5, 32); + printf("USER SET NICKNAME %lu %s\n", client->nickLen, client->nick); + fflush(stdout); + } else if(strncmp(packet, "USER ", 5) == 0) { + // Send welcome + newUser(client); + } else if(strncmp(packet, "MOTD", 4) == 0) { + // Send welcome + sendMOTD(client); + // Horrible join but it works and its funny + } else if(strncmp(packet, "JOIN ", 5) == 0) { + char data[256]; + data[0] = ':'; + strcpy(data+1, client->nick); + strcpy(data+1+client->nickLen, " JOIN :"); + strcpy(data+8+client->nickLen, packet+5); + send_log(client->FD, data, strlen(data), 0); + sendall_log(client->FD, data, strlen(data), 0); + } else if(strncmp(packet, "PRIVMSG ", 8) == 0) { + char data[256]; + data[0] = ':'; + strcpy(data+1, client->nick); + data[1+client->nickLen] = ' '; + strcpy(data+2+client->nickLen, packet); + sendall_log(client->FD, data, strlen(data), 0); + } + +} + +void newUser(struct client_data *client) { + char data[1024]; + // Copy in basics + strcpy(data, ":irc.patchysicp.xyz 001 "); + strcpy(data+24, client->nick); + strcpy(data+24+client->nickLen, " :Welcome to PatchyIRCD!!!\n"); + //send_log(client->FD, data, (26+client->nickLen+27), 0); + send_log(client->FD, data, strlen(data), 0); + data[22] = '2'; + strcpy(data+26+client->nickLen, "Your host is PatchyIRCD V0.0.0\n"); + send_log(client->FD, data, strlen(data), 0); + data[22] = '3'; + strcpy(data+26+client->nickLen, "This server was created when I had cybersex with your mother.\n"); + send_log(client->FD, data, strlen(data), 0); + data[20] = '2'; + data[21] = '5'; + data[22] = '1'; + strcpy(data+26+client->nickLen, "This server exists\n"); + send_log(client->FD, data, strlen(data), 0); + data[22] = '2'; + strcpy(data+26+client->nickLen, "Jannies don't exist\n"); + send_log(client->FD, data, strlen(data), 0); + sendMOTD(client); +} + +void sendMOTD(struct client_data *client) { + char data[1024]; + // Copy in basics + strcpy(data, ":irc.patchysicp.xyz 375 "); + strcpy(data+24, client->nick); + strcpy(data+24+client->nickLen, " :PatchySICP /MOTD\n"); + send_log(client->FD, data, strlen(data), 0); + data[22] = '2'; + strcpy(data+26+client->nickLen, "Welcome to Montreal!\n"); + send_log(client->FD, data, strlen(data), 0); + strcpy(data+26+client->nickLen, "You are retarded and I will have cybersex with your mom.\n"); + send_log(client->FD, data, strlen(data), 0); + data[22] = '6'; + strcpy(data+26+client->nickLen, "/MOTD over\n"); + send_log(client->FD, data, strlen(data), 0); +} + +void setNick(struct client_data *client, char* nickname, size_t size) { + // TODO: perform basic sanitization + strncpy(client->nick, nickname, size); + // Null term + client->nick[size-1] = 0; + // Remove newline + int i; + for(i=0;inick[i] == 13) { + client->nick[i] = 0; + break; + } + // Newline + if(client->nick[i] == 10) { + client->nick[i] = 0; + break; + } + } + // Set length + client->nickLen = strlen(client->nick); + return; +} + +int main(){ + fd_set readfds; + SOCKET highestFD; + int i; + SOCKET SD; + SOCKET serverSocketV4 = 0; + SOCKET serverSocketV6 = 0; + char client_addr[100]; + char *welcomeMessage = ":irc.patchysicp.xyz NOTICE * :Hello welcome to PatchyIRCD!\n"; + char buffer[1024]; + size_t bytesRead; + +#if defined(_WIN32) + struct WSAData wd; + if (WSAStartup(MAKEWORD(2, 0), &wd)) printf("Winsock API startup failed.\n"); +#endif + + puts("Starting"); + fflush(stdout); + +#ifdef SUPPORT_IPV4 + struct sockaddr_in serverAddrV4; + memset(&serverAddrV4, 0, sizeof(struct sockaddr_in)); + serverAddrV4.sin_addr.s_addr = INADDR_ANY; + serverAddrV4.sin_port = htons(LISTENING_PORT); + serverAddrV4.sin_family = AF_INET; + size_t serverAddrV4len = sizeof(serverAddrV4); +#endif +#ifdef SUPPORT_IPV6 + struct sockaddr_in6 serverAddrV6; + memset(&serverAddrV6, 0, sizeof(struct sockaddr_in6)); + serverAddrV6.sin6_addr = in6addr_any; + serverAddrV6.sin6_flowinfo = 0; + serverAddrV6.sin6_port = htons(LISTENING_PORT); + serverAddrV6.sin6_family = AF_INET6; + size_t serverAddrV6len = sizeof(serverAddrV6); +#endif + + int opt = 1; +#ifdef SUPPORT_IPV4 + // Create socket + serverSocketV4 = socket(AF_INET, SOCK_STREAM, 0); + if(serverSocketV4 == (SOCKET)INVALID_SOCKET) { + net_perror("ERROR SOCKET IPV4"); + exit(EXIT_FAILURE); + } + // Set socket options + if(setsockopt(serverSocketV4, SOL_SOCKET,\ + SO_REUSEADDR,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV4"); + exit(EXIT_FAILURE); + } + // Set nonblock + net_nonblock(serverSocketV4); + // Bind to socket + if(bind(serverSocketV4, (struct sockaddr*)&serverAddrV4,\ + sizeof(struct sockaddr_in)) == -1) { + net_perror("ERROR BIND IPV4"); + exit(EXIT_FAILURE); + } + // Listen to socket + if(listen(serverSocketV4, LISTENING_BACKLOG) == -1) { + net_perror("ERROR LISTEN IPV4"); + exit(EXIT_FAILURE); + } +#endif +#ifdef SUPPORT_IPV6 + // Create socket + serverSocketV6 = socket(AF_INET6, SOCK_STREAM, 0); + if(serverSocketV6 == (SOCKET)INVALID_SOCKET) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // Set socket options + if(setsockopt(serverSocketV6, SOL_SOCKET,\ + SO_REUSEADDR,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // IPV6 Only + if(setsockopt(serverSocketV6, IPPROTO_IPV6,\ + IPV6_V6ONLY,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // Set nonblock + net_nonblock(serverSocketV6); + // Bind to socket + if(bind(serverSocketV6, (struct sockaddr*)&serverAddrV6,\ + sizeof(struct sockaddr_in6)) == -1) { + net_perror("ERROR BIND IPV6"); + exit(EXIT_FAILURE); + } + // Listen to socket + if(listen(serverSocketV6, LISTENING_BACKLOG) == -1) { + net_perror("ERROR LISTEN IPV6"); + exit(EXIT_FAILURE); + } +#endif + + memset(client_socket, 0, sizeof(client_socket)); + + puts("Ready"); + fflush(stdout); + while(1){ + // Clear all sockets + FD_ZERO(&readfds); + // Add main sockets +#ifdef SUPPORT_IPV4 + FD_SET(serverSocketV4, &readfds); +#endif +#ifdef SUPPORT_IPV6 + FD_SET(serverSocketV6, &readfds); +#endif + if(serverSocketV4 < serverSocketV6) highestFD = serverSocketV6; + else highestFD = serverSocketV4; + + // Check for new sockets + for(i=0;i0){ + FD_SET(SD, &readfds); + // Update highest FD + if(SD>highestFD){ + highestFD = SD; + } + } + } + + // Wait until activity on sockets + if(select(highestFD+1,&readfds,NULL,NULL,NULL) == -1) { + net_perror("ERROR SELECT"); + } + +#ifdef SUPPORT_IPV4 + if (FD_ISSET(serverSocketV4, &readfds)) { + SOCKET newSocket = accept(serverSocketV4, NULL, NULL); + if(newSocket == (SOCKET)INVALID_SOCKET){ + net_perror("ERROR newSocket IPV4"); + } + getpeername(newSocket,(struct sockaddr*)&serverAddrV4,(socklen_t*)&serverAddrV4len); + inet_ntop(AF_INET, &(serverAddrV4.sin_addr), client_addr, sizeof(client_addr)); + printf("Connection accepted from Socket: %"PRISocket", IP: %s PORT: %d\n", newSocket, client_addr, ntohs(serverAddrV4.sin_port)); + fflush(stdout); + send_log(newSocket, welcomeMessage, strlen(welcomeMessage), 0); + // Add to list of sockets + for(i=0;i0) { + closesocket(client_socket[i].FD); + } + } + return 0; +} + diff --git a/networking-tests/windows.c b/networking-tests/windows.c new file mode 100755 index 0000000..4109d70 --- /dev/null +++ b/networking-tests/windows.c @@ -0,0 +1,303 @@ +// Some macros to control options +#define LISTENING_PORT 4444 +#define LISTENING_BACKLOG 10 +#define CLIENT_SOCKETS 100 +#define FD_SETSIZE 1024 +#define SUPPORT_IPV4 +#define SUPPORT_IPV6 + +#include +#include +#include +#include +#if defined(_WIN32) +#pragma message("Warning: Windows detected.") +//#include +//#include +//#include +#include +#include +#include +#pragma message("IMPORTANT: COMPILE WITH -lws2_32") +#pragma comment(lib, "ws2_32.lib") +#define PRISocket "llu" +#else +#include +#include +#include +#include +#include +#include +#include +#include +//typedef unsigned long long SOCKET; +typedef int SOCKET; +#define PRISocket "d" +#endif + +struct client_data { + SOCKET FD; + char type; +}; + +struct client_data client_socket[CLIENT_SOCKETS]; + +#if defined(_WIN32) +#define net_errno() (WSAGetLastError()) +const char *net_strerror(int e) { + static char msg[256]; + if (!FormatMessageA(\ + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, e, 0, msg, 256, NULL)) + sprintf(msg, "WSA Error %d", e); + return msg; +} +int net_nonblock(SOCKET fd) { + u_long v = 1; + return ioctlsocket(fd, FIONBIO, &v); +} +#else +#define net_errno() ((int)errno) +#define net_strerror(e) strerror((e)) +#define closesocket close +#define INVALID_SOCKET -1 +int net_nonblock(SOCKET fd) { + int f = fcntl(fd, F_GETFL); + if (f == -1) + return -1; + return fcntl(fd, F_SETFL, f | O_NONBLOCK); +} +#endif +void net_perror(const char *p) +{ + if (p && *p) + fprintf(stderr, "%s: %s\n", p, net_strerror(net_errno())); + else + fprintf(stderr, "%s\n", net_strerror(net_errno())); +} + +int main(){ + fd_set readfds; + SOCKET highestFD; + int i; + SOCKET SD; + SOCKET serverSocketV4 = 0; + SOCKET serverSocketV6 = 0; + char client_addr[100]; + char *welcomeMessage = "Hello welcome to PatchyIRCD\n"; + char buffer[1024]; + size_t bytesRead; + +#if defined(_WIN32) + struct WSAData wd; + if (WSAStartup(MAKEWORD(2, 0), &wd)) printf("Winsock API startup failed.\n"); +#endif + + puts("Starting"); + +#ifdef SUPPORT_IPV4 + struct sockaddr_in serverAddrV4; + memset(&serverAddrV4, 0, sizeof(struct sockaddr_in)); + serverAddrV4.sin_addr.s_addr = INADDR_ANY; + serverAddrV4.sin_port = htons(LISTENING_PORT); + serverAddrV4.sin_family = AF_INET; + size_t serverAddrV4len = sizeof(serverAddrV4); +#endif +#ifdef SUPPORT_IPV6 + struct sockaddr_in6 serverAddrV6; + memset(&serverAddrV6, 0, sizeof(struct sockaddr_in6)); + serverAddrV6.sin6_addr = in6addr_any; + serverAddrV6.sin6_flowinfo = 0; + serverAddrV6.sin6_port = htons(LISTENING_PORT); + serverAddrV6.sin6_family = AF_INET6; + size_t serverAddrV6len = sizeof(serverAddrV6); +#endif + + int opt = 1; +#ifdef SUPPORT_IPV4 + // Create socket + serverSocketV4 = socket(AF_INET, SOCK_STREAM, 0); + if(serverSocketV4 == (SOCKET)INVALID_SOCKET) { + net_perror("ERROR SOCKET IPV4"); + exit(EXIT_FAILURE); + } + // Set socket options + if(setsockopt(serverSocketV4, SOL_SOCKET,\ + SO_REUSEADDR,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV4"); + exit(EXIT_FAILURE); + } + // Set nonblock + net_nonblock(serverSocketV4); + // Bind to socket + if(bind(serverSocketV4, (struct sockaddr*)&serverAddrV4,\ + sizeof(struct sockaddr_in)) == -1) { + net_perror("ERROR BIND IPV4"); + exit(EXIT_FAILURE); + } + // Listen to socket + if(listen(serverSocketV4, LISTENING_BACKLOG) == -1) { + net_perror("ERROR LISTEN IPV4"); + exit(EXIT_FAILURE); + } +#endif +#ifdef SUPPORT_IPV6 + // Create socket + serverSocketV6 = socket(AF_INET6, SOCK_STREAM, 0); + if(serverSocketV6 == (SOCKET)INVALID_SOCKET) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // Set socket options + if(setsockopt(serverSocketV6, SOL_SOCKET,\ + SO_REUSEADDR,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // IPV6 Only + if(setsockopt(serverSocketV6, IPPROTO_IPV6,\ + IPV6_V6ONLY,\ + (void*)&opt, sizeof(opt)) == -1) { + net_perror("ERROR SOCKET IPV6"); + exit(EXIT_FAILURE); + } + // Set nonblock + net_nonblock(serverSocketV6); + // Bind to socket + if(bind(serverSocketV6, (struct sockaddr*)&serverAddrV6,\ + sizeof(struct sockaddr_in6)) == -1) { + net_perror("ERROR BIND IPV6"); + exit(EXIT_FAILURE); + } + // Listen to socket + if(listen(serverSocketV6, LISTENING_BACKLOG) == -1) { + net_perror("ERROR LISTEN IPV6"); + exit(EXIT_FAILURE); + } +#endif + + memset(client_socket, 0, sizeof(client_socket)); + + puts("Ready"); + while(1){ + // Clear all sockets + FD_ZERO(&readfds); + // Add main sockets +#ifdef SUPPORT_IPV4 + FD_SET(serverSocketV4, &readfds); +#endif +#ifdef SUPPORT_IPV6 + FD_SET(serverSocketV6, &readfds); +#endif + if(serverSocketV4 < serverSocketV6) highestFD = serverSocketV6; + else highestFD = serverSocketV4; + + // Check for new sockets + for(i=0;i0){ + FD_SET(SD, &readfds); + // Update highest FD + if(SD>highestFD){ + highestFD = SD; + } + } + } + + // Wait until activity on sockets + if(select(highestFD+1,&readfds,NULL,NULL,NULL) == -1) { + net_perror("ERROR SELECT"); + } + +#ifdef SUPPORT_IPV4 + if (FD_ISSET(serverSocketV4, &readfds)) { + SOCKET newSocket = accept(serverSocketV4, NULL, NULL); + if(newSocket == (SOCKET)INVALID_SOCKET){ + net_perror("ERROR newSocket IPV4"); + } + getpeername(newSocket,(struct sockaddr*)&serverAddrV4,(socklen_t*)&serverAddrV4len); + inet_ntop(AF_INET, &(serverAddrV4.sin_addr), client_addr, sizeof(client_addr)); + printf("Connection accepted from Socket: %"PRISocket", IP: %s PORT: %d\n", newSocket, client_addr, ntohs(serverAddrV4.sin_port)); + send(newSocket, welcomeMessage, strlen(welcomeMessage), 0); + // Add to list of sockets + for(i=0;i0) { + closesocket(client_socket[i].FD); + } + } + return 0; +} + diff --git a/networking-tests/windows.c.bak b/networking-tests/windows.c.bak new file mode 100755 index 0000000..ba935f1 --- /dev/null +++ b/networking-tests/windows.c.bak @@ -0,0 +1,80 @@ +#include +#include +#include +#if defined(_WIN32) +#pragma message("Warning: Windows detected.") +//#include +//#include +#include +#include +#pragma comment(lib, "ws2_32.lib") +#else +#include +#include +#include +#include +#include +#endif +//#include +//#include +//#include +//#include +//#include + +#include +//int socket(int family, int type, int protocol); +//int bind(int socket_fd, const struct sockaddr *myaddress, socklen_t address_length); +//int listen(int socket_fd, int backlog); + +#define PORT 4444 + +int main(){ + #if defined(_WIN32) + #pragma message("Warning: Windows detected.") + struct WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData)); + if (WSAStartup(MAKEWORD(2, 0), wd)) printf("Winsock API startup failed.\n"); + free(wd); + #endif + //struct WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData)); + //if (WSAStartup(MAKEWORD(2, 0), wd)) printf("Winsock API startup failed.\n"); + //free(wd); + + puts("Starting"); + + struct sockaddr_in6 serverAddr; + char client_addr_ipv6[100]; + memset(&serverAddr, '\0', sizeof(serverAddr)); + serverAddr.sin6_flowinfo = 0; + serverAddr.sin6_family = AF_INET6; + serverAddr.sin6_port = htons(PORT); + serverAddr.sin6_addr = in6addr_any; + + char buffer[1024]; + + struct sockaddr_in6 newAddr; + socklen_t addr_size; + + + int socket2 = socket(AF_INET6, SOCK_STREAM, 0); + int bind2 = bind(socket2, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); + int listen2 = listen(socket2, 10); + + while(1){ + puts("Ready"); + int newSocket = accept(socket2, NULL, NULL); + if(newSocket < 0){ + //printf("%s", strerror(errno)); + printf("%d\n", newSocket); + exit(1); + } + inet_ntop(AF_INET6, &(newAddr.sin6_addr), client_addr_ipv6, 100); + printf("Connection accepted from IP: %s PORT: %d\n", client_addr_ipv6, ntohs(newAddr.sin6_port)); + while(1){ + memset(buffer, 0, sizeof(buffer)); + send(newSocket, buffer, recv(newSocket, buffer, sizeof(buffer), 0), 0); + } + } + //WSACleanup(); + +} +