Snippets

Richard Yu VCMP Lan

Created by Richard Yu last modified
#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;
}

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.