#include #include #include #include #include #include #include #include #include #include #include struct _entry { u_int16_t gameid; u_int32_t ip; u_int16_t port1; u_int16_t port2; } __attribute__ ((packed)); static char scanmsg[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH"; char *gameid2name[] = { "Unknown", // 0 "HL", "Q1", "Q2", "Q3Comp", "UT", "Q3", "EF", "RtCW", "GSProt", "CCR", // 10 "MoHAA", "JK2", "SoF2", "UT2K3", "AAO", "BF1942", "AvP2", "Rune", "IGI2", "NWN", // 20 "MoHAAS", "OPF", "OPFR", "DVS", "ET", "EF2", "JK3", "MoHAAB", "Tribes2", "HALO", // 30 "CoD", "Savage", "UT2K4", "HLSteam", "BFV", "GS2Prot", "PK", "D3", "OGPProt", "HL2", // 40 "TribesV", "CoDUO" }; int main(int argc, char *argv[]) { struct sockaddr_in dst; struct timeval tv; struct _entry *srv; fd_set fdsel, fdcpy; int sock, i = 1, recvsize; void *pkt; if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket()"); exit(-1); } if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i))) { perror("setsockopt()"); exit(-1); } dst.sin_family = AF_INET; dst.sin_port = htons(7130); inet_aton("0.0.0.0", &dst.sin_addr); if (bind(sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) { perror("bind()"); exit(-1); } dst.sin_port = htons(7140); inet_aton("255.255.255.255", &dst.sin_addr); if (sendto(sock, scanmsg, sizeof(scanmsg), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0) { perror("sendto()"); exit(-1); } FD_ZERO(&fdsel); FD_SET(sock, &fdsel); tv.tv_sec = 1; tv.tv_usec = 0; while (1) { memcpy(&fdcpy, &fdsel, sizeof(fdsel)); if (select(FD_SETSIZE, &fdcpy, NULL, NULL, &tv) < 0) { perror("select"); exit(-1); } if (tv.tv_sec == 0 && tv.tv_usec == 0) exit(0); ioctl(sock, FIONREAD, &recvsize); if (recvsize <= 0) { continue; } if (!(pkt = malloc(recvsize))) { perror("malloc()"); exit(-1); } i = sizeof(struct sockaddr_in); recvsize = recvfrom(sock, pkt, recvsize, 0, (struct sockaddr *)&dst, &i); printf("received packet from: %s:%d size=%d\n", inet_ntoa(dst.sin_addr), ntohs(dst.sin_port), recvsize); srv = pkt + sizeof(scanmsg); while ((void *)srv < pkt + recvsize) { dst.sin_addr.s_addr = srv->ip; printf(" ip=%s port1=%d port2=%d gameid=%d (%s)\n", inet_ntoa(dst.sin_addr), srv->port1, srv->port2, srv->gameid, gameid2name[srv->gameid]); srv++; } free(pkt); } return 0; }