diff --git a/src/first-free-port.c b/src/first-free-port.c deleted file mode 100644 index 320b14e..0000000 --- a/src/first-free-port.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define MIN_TCP_PORT 1 -#define TCP_TABLE_PATH "/proc/net/tcp" -#define TCP_TABLE_LINE_LENGTH 151 -#define LOCALHOSTIP_HEX "0100007F" -#define WILDCARDIP_HEX "00000000" -#define LISTENING_HEX "0A" -#define BLOCKS_TO_ALLOC 4 - -/** - * Print a nice error message - */ -static void print_error(char *name, const char *message) { - fprintf(stderr, "%s: %s\n", name, message); -} - -/** - * Get all the listening TCP ports - */ -static unsigned short *get_listening_ports(FILE *tcp_table_fptr) { - unsigned short *listening_ports = malloc(BLOCKS_TO_ALLOC * sizeof(short)); - char line[TCP_TABLE_LINE_LENGTH]; - char delimiter[] = " "; - unsigned short len = 0; - char *address; - char *state; - char *field; - size_t blocks_allocated = BLOCKS_TO_ALLOC; - - // Skip first line (header) - fgets(line, sizeof(line), tcp_table_fptr); - - // Tokenize lines one by one - while (fgets(line, sizeof(line), tcp_table_fptr) != NULL) { - strtok(line, delimiter); - - address = strtok(NULL, delimiter); - strtok(NULL, delimiter); - state = strtok(NULL, delimiter); - field = strtok(NULL, delimiter); - - while (field != NULL) { - field = strtok(NULL, delimiter); - } - - if ((!strncmp(address, LOCALHOSTIP_HEX, 8) || !strncmp(address, WILDCARDIP_HEX, 8)) && !strncmp(state, LISTENING_HEX, 2)) { - if (len == blocks_allocated) { - blocks_allocated = blocks_allocated + BLOCKS_TO_ALLOC; - listening_ports = realloc(listening_ports, blocks_allocated * sizeof(short)); - } - listening_ports[len] = strtol(address + strlen(address) - 4, NULL, 16); - len++; - } - } - - if (len == blocks_allocated) { - listening_ports = realloc(listening_ports, blocks_allocated + 1); - } - listening_ports[len] = 0; - - return listening_ports; -} - -static unsigned char is_port_available(const unsigned short port, const unsigned short *listening_ports) { - unsigned short i = 0; - while (listening_ports[i] != 0 && listening_ports[i] != port) { - i++; - } - return listening_ports[i] == 0; -} - -static inline unsigned char is_valid_tcp_port(const unsigned short tcp_port) { - return tcp_port >= MIN_TCP_PORT; -} - -int main(int argc, char *argv[]) { - unsigned short current_port; - - if (argc >= 2) { - current_port = atoi(argv[1]); - } else { - current_port = 0; - } - - if (!is_valid_tcp_port(current_port)) { - print_error(argv[0], "provide a valid TCP port number as first argument."); - return EX_USAGE; - } - - // Open TCP table - FILE *tcp_table_fptr = fopen(TCP_TABLE_PATH, "r"); - if (tcp_table_fptr == NULL) { - print_error(argv[0], "error opening the TCP table."); - return errno; - } - - unsigned short *listening_ports = get_listening_ports(tcp_table_fptr); - - if (fclose(tcp_table_fptr) != 0) { - print_error(argv[0], "can't close the TCP table."); - return errno; - } - - // Check if the current port is available, add - while (!is_port_available(current_port, listening_ports)) { - current_port++; - } - - free(listening_ports); - - if (is_valid_tcp_port(current_port)) { - printf("%d\n", current_port); - return EXIT_SUCCESS; - } else { - print_error(argv[0], "no more ports available; how did you fuck up that bad ???"); - return EX_TEMPFAIL; - } -}