#include #include "scolor.h" #include #include #include #include #include #include #include #include uint16_t current_port; char *connect_error = RED("Terminated connect due to alarm on port %d\n"); char error_buffer[1024]; char *current_error; void handle_alarm(int signum){ printf(current_error, current_port); } char general_buffer[1024*64 + 1]; int check_for_server(char* hostname, uint16_t cport, char quiet){ current_error = connect_error; 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; } current_error = error_buffer; if(type == 14){ // we might have a version sprintf(error_buffer, RED("Terminated while waiting after receiving type 14 on port %d\n"), current_port); alarm(1); 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; if(extlen) recv(skt, general_buffer, extlen, MSG_WAITALL); sprintf(error_buffer, RED("Terminated while waiting for game on lurk server version %d.%d on port %d\n"), major, minor, current_port); if(!read(skt, &type, 1)) goto bad_lurk_server; alarm(0); } uint16_t game_numbers[3]; if(11 == type){ current_error = error_buffer; sprintf(error_buffer, RED("Terminated while waiting after receiving type 11 %u on port %d\n"), game_numbers[2], current_port); alarm(1); if(6 != recv(skt, game_numbers, 6, MSG_WAITALL)) goto not_lurk_server; sprintf(error_buffer, RED("Terminated waiting for game description of length %u on port %d\n"), game_numbers[2], current_port); ssize_t readlen = recv(skt, general_buffer, game_numbers[2], MSG_WAITALL); alarm(0); if(readlen != game_numbers[2]) goto bad_lurk_server; 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; bad_lurk_server: if(!quiet) printf(YELLOW("Port %u is open, and might have a lurk server that isn't following the protocol correctly.\n"), cport); close(skt); return 1; 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(int argc, char ** argv){ struct sigaction sa; sa.sa_handler = handle_alarm; sigaction(SIGALRM, &sa, 0); uint16_t low_port = 5000; uint16_t high_port = 5200; char* hostname = "isoptera.lcsc.edu"; if(argc == 2){ low_port = atoi(argv[1]); high_port = low_port; } if(argc == 3){ low_port = atoi(argv[1]); high_port = atoi(argv[2]); } for(uint16_t cport = low_port; cport <= high_port; cport++){ check_for_server(hostname, cport, 0); } return 0; }