#include #include #include #include #include #include #include #include #include #include uint16_t current_port; void handle_alarm(int signum){ printf(RED("Terminated connect due to alarm on port %d\n"), current_port); } char general_buffer[1024*64 + 1]; int check_for_server(char* hostname, uint16_t cport, char quiet){ current_port = cport; struct sockaddr_in sad; sad.sin_port = htons(cport); sad.sin_family = AF_INET; int skt = socket(AF_INET, SOCK_STREAM, 0); struct hostent* entry = gethostbyname(hostname); struct in_addr **addr_list = (struct in_addr**)entry->h_addr_list; struct in_addr* c_addr = addr_list[0]; char* ip_string = inet_ntoa(*c_addr); sad.sin_addr = *c_addr; alarm(1); if(connect(skt, (struct sockaddr*)&sad, sizeof(struct sockaddr_in))) return 1; alarm(0); char type; char major = 2; char minor = 0; printf(PURPLE("Starting interaction with server on %u\n"), cport); ssize_t readlen = recv(skt, &type, 1, MSG_DONTWAIT); // Might hang right here with HTTP server if(readlen != 1){ // Maybe the server needs a moment sleep(1); if(1 != recv(skt, &type, 1, MSG_DONTWAIT)) goto not_lurk_server; } if(type == 14){ // we might have a version if(read(skt, &major, 1) != 1) goto not_lurk_server; if(read(skt, &minor, 1) != 1) goto not_lurk_server; uint16_t extlen; if(read(skt, &extlen, 2) != 2) goto not_lurk_server; recv(skt, general_buffer, extlen, MSG_WAITALL); read(skt, &type, 1); } uint16_t game_numbers[3]; if(11 == type){ if(6 != recv(skt, game_numbers, 6, MSG_WAITALL)) goto not_lurk_server; ssize_t readlen = recv(skt, general_buffer, game_numbers[2], MSG_WAITALL); general_buffer[readlen] = 0; } else goto not_lurk_server; if(!quiet){ printf(GREEN("Found lurk server on port %u:\n"), cport); printf("Version %u.%u with %u bytes of extensions\n", major, minor); printf("Game has %u initial points, %u stat limit, description: %s\n", game_numbers[0], game_numbers[1], general_buffer); } close(skt); return 0; not_lurk_server: if(!quiet) printf(YELLOW("Port %u is open, but does not seem to be a lurk server\n"), cport); close(skt); return 1; } // Parameters will be port range int main(){ struct sigaction sa; sa.sa_handler = handle_alarm; // sigaction(SIGALRM, &sa, 0); // TODO: Let user specify port range and hostname uint16_t low_port = 5000; uint16_t high_port = 5200; char* hostname = "isoptera.lcsc.edu"; for(uint16_t cport = low_port; cport <= high_port; cport++){ check_for_server(hostname, cport, 0); } return 0; }