/* * Half-Life Linux dedicated server Checker * Part of dedtools * Code by Tomas Janousek * * Returns success if the server is not living. * Returns failure if the server is ok or an error occurs. */ #include #include #include #include #include #include #include #include #include static char infostring[] = "\xff\xff\xff\xffinfostring\0"; static int infostring_sz = sizeof(infostring) / sizeof(*infostring); static char infostring2[] = "\xFF\xFF\xFF\xFF\x54Source Engine Query"; static int infostring2_sz = sizeof(infostring2) / sizeof(*infostring2); int main(int argc, char *argv[]) { int sock, salen, i; struct sockaddr_in sa, sa2; char buffer[4096]; if (argc != 2) { puts("Usage: ./hlds_check "); return -1; } sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sa.sin_port = htons(atol(argv[1])); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) return -1; int set_opt = 1; setsockopt(sock, SOL_IP, IP_RECVERR, &set_opt, sizeof(set_opt)); for (i = 0; i < 30; i++) { fd_set fd; struct timeval timeout; FD_ZERO(&fd); FD_SET(sock, &fd); timeout.tv_sec = 0; timeout.tv_usec = 500000; if (sendto(sock, infostring, infostring_sz, 0, &sa, sizeof(sa)) != infostring_sz) { select(0, 0, 0, 0, &timeout); continue; } if (sendto(sock, infostring2, infostring2_sz, 0, &sa, sizeof(sa)) != infostring2_sz) { select(0, 0, 0, 0, &timeout); continue; } if (select(sock + 1, &fd, 0, 0, &timeout) > 0) { salen = sizeof(sa2); recvfrom(sock, buffer, 4096, 0, &sa2, &salen); return -1; } } return 0; }