hlswmaster/tools/masterquery.c
2006-02-02 16:29:30 +01:00

150 lines
2.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
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;
}