#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
#include <winsock.h>
int main()
{
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
return EXIT_FAILURE;
#endif
uint16_t portStart = 0, portEnd = 0;
printf("Enter port range: Start:");
scanf("%hu", &portStart);
printf("End:");
scanf("%hu", &portEnd);
SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
if (!s)
return EXIT_FAILURE;
BOOL broadcast = TRUE;
setsockopt(s, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
struct sockaddr_in bindaddr = { AF_INET };
if (bind(s, &bindaddr, 16) != NO_ERROR)
{
closesocket(s);
return EXIT_FAILURE;
}
struct sockaddr_in sendaddr = { AF_INET };
sendaddr.sin_addr.s_addr = INADDR_BROADCAST;
for (uint16_t i = portStart; i <= portEnd; ++i)
{
sendaddr.sin_port = htons(i);
char buffer[] = { 0x56, 0x43, 0x4D, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, i & 0xFF, i >> 8 & 0xFF, 'i' };
sendto(s, buffer, sizeof(buffer), 0, &sendaddr, sizeof(sendaddr));
}
while (1)
{
struct sockaddr_in recvaddr = { 0 };
int size = sizeof(recvaddr);
char *recvBuff = calloc(532, sizeof(char));
int recvlen = recvfrom(s, recvBuff, 532, 0, &recvaddr, &size);
if (recvlen != -1)
{
char *buf = recvBuff;
if (*(int *)buf == 0x3430504D) // MP04
{
char *ip = inet_ntoa(recvaddr.sin_addr);
uint16_t port = ntohs(recvaddr.sin_port);
buf += 11;
char version[12];
memmove(version, buf, sizeof(version));
buf += 17;
int strlen = *(int *)buf;
char *servername = alloca(strlen + 1);
buf += 4;
strncpy(servername, buf, strlen);
servername[strlen] = 0;
buf += strlen;
strlen = *(int *)buf;
char *gamemode = alloca(strlen + 1);
buf += 4;
strncpy(gamemode, buf, strlen);
gamemode[strlen] = 0;
buf += strlen;
strlen = *(int *)buf;
char *mapname = alloca(strlen + 1);
buf += 4;
strncpy(mapname, buf, strlen);
mapname[strlen] = 0;
printf("%s:%hu|%s|%s|%s|%s\n", ip, port, version, servername, gamemode, mapname);
}
}
free(recvBuff);
}
return 0;
}