💾 Archived View for gmi.noulin.net › spartclientudp.c captured on 2024-05-10 at 10:51:32.

View Raw

More Information

⬅️ Previous capture (2023-07-22)

-=-=-=-=-=-=-

// Usage: spartclient hostname port path
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>

int64_t parseInt(const char *string) {
    while (!isdigit(*string) && *string != '-' && *string != 0) {
        string++;
    }
    int64_t r = strtoll(string, NULL, 10);
    return(r);
}

int main(int ac, char **av){
    int sock;
    struct sockaddr_in server;
    struct hostent *hp;
    int mysock;
    char buf[65536] = {0};
    int rval;
    int i;

    if (ac < 4) {
        puts("Usage: spartclient hostname port path");
        return 0;
    }

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0){
        perror("Failed to create socket");
    }

    server.sin_family = AF_INET;

    hp = gethostbyname(av[1]);
    if (hp==0) {
        perror("gethostbyname failed");
        close(sock);
        exit(1);
    }

    memcpy(&server.sin_addr, hp->h_addr, hp->h_length);

    int64_t port = parseInt(av[2]);

    if (port < 1 || port > 65000) {
        printf("Invalid port %d.\n", port);
        return 1;
    }

    server.sin_port = htons(port);

    // open socket for response
    struct sockaddr_in respaddr;
    int rsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (rsock < 0){
        perror("Failed to create socket");
    }

    respaddr.sin_family = AF_INET;
    respaddr.sin_addr.s_addr = INADDR_ANY;
    respaddr.sin_port = htons(port);

    if (bind(rsock, (struct sockaddr *) &respaddr, sizeof(respaddr))){
        perror("bind failed");
        exit(1);
    }

    // build request
    size_t len = strlen(av[1]);
    memcpy(buf, av[1], len);
    buf[len] = ' ';
    char *cursor = buf + len + 1;
    len = strlen(av[3]);
    memcpy(cursor, av[3], len);
    memcpy(cursor + len, " 0\r\n", strlen(" 0\r\n"));
    cursor += len + strlen(" 0\r\n");

    // send request
    if (sendto(sock, buf, cursor - buf, 0, (const struct sockaddr *)&server, sizeof(server)) < 0) {
        perror("send failed");
        close(sock);
        exit(1);
    }
    close(sock);

    // reveice server response
    struct sockaddr_in addr;
    socklen_t ln = sizeof(addr);
    rval = recvfrom(rsock, buf, sizeof(buf)-1/* -1 to add end of string before printing */, 0, (struct sockaddr *) &addr, &ln);
    close(rsock);
    if (addr.sin_addr.s_addr == server.sin_addr.s_addr && rval != -1 && rval != 0) {
        buf[rval] = 0;
        puts(buf);
    }
}