123 lines
2.9 KiB
C
123 lines
2.9 KiB
C
#include <netdb.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
|
|
#define USAGE "usage: %s IP PORT OPCODE [ARGS...]\n"
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc < 4) {
|
|
fprintf(stderr, USAGE, argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
const char *ip = argv[1];
|
|
const char *port = argv[2];
|
|
const char *opcode = argv[3];
|
|
|
|
if (strlen(opcode) != 1) {
|
|
fprintf(stderr, "invalid opcode\n");
|
|
return 1;
|
|
}
|
|
|
|
char *payload = NULL;
|
|
|
|
switch (opcode[0]) {
|
|
case 'A':
|
|
case 'D':
|
|
case 'C': {
|
|
if (argc < 6) {
|
|
fprintf(stderr, USAGE, argv[0]);
|
|
fprintf(stderr, "not enough arguments for opcode %s\n", opcode);
|
|
return 1;
|
|
}
|
|
|
|
int payload_len = strlen(ip) + strlen(port) + 1;
|
|
payload = (char *)malloc(sizeof(char) * (payload_len + 1));
|
|
memset(payload, 0, payload_len + 1);
|
|
|
|
strcat(payload, argv[4]);
|
|
|
|
if (opcode[0] == 'C') {
|
|
strcat(payload, ",");
|
|
} else {
|
|
strcat(payload, " ");
|
|
}
|
|
|
|
strcat(payload, argv[5]);
|
|
}
|
|
case 'L': {
|
|
break;
|
|
}
|
|
default: {
|
|
fprintf(stderr, "invalid opcode\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
unsigned char payload_size = 0;
|
|
if (payload != NULL) {
|
|
payload_size = strlen(payload);
|
|
}
|
|
|
|
char *message = (char *)malloc(sizeof(char) * (payload_size + 3));
|
|
message[0] = opcode[0];
|
|
message[1] = payload_size;
|
|
if (payload != NULL) {
|
|
strcat(message + 2, payload);
|
|
free(payload);
|
|
}
|
|
|
|
// fwrite(message, 1, 2 + payload_size, stdout);
|
|
|
|
struct addrinfo addr_spec;
|
|
struct addrinfo *addrinfo_res;
|
|
|
|
memset(&addr_spec, 0, sizeof(addr_spec));
|
|
addr_spec.ai_family = AF_UNSPEC;
|
|
addr_spec.ai_socktype = SOCK_STREAM;
|
|
|
|
int addrinfo_status = getaddrinfo(ip, port, &addr_spec, &addrinfo_res);
|
|
if (addrinfo_status != 0) {
|
|
fprintf(stderr, "get address info: %s\n",
|
|
gai_strerror(addrinfo_status));
|
|
return 1;
|
|
}
|
|
|
|
int sd = socket(addrinfo_res->ai_family, addrinfo_res->ai_socktype,
|
|
addrinfo_res->ai_protocol);
|
|
|
|
if (sd == -1) {
|
|
perror("failed to open socket");
|
|
return 1;
|
|
}
|
|
|
|
if (connect(sd, addrinfo_res->ai_addr, addrinfo_res->ai_addrlen) == -1) {
|
|
perror("failed to connect");
|
|
return 1;
|
|
}
|
|
|
|
if (send(sd, message, 2 + payload_size, 0) == -1) {
|
|
perror("failed to write to remote");
|
|
return 1;
|
|
}
|
|
|
|
char *buf = (char *)malloc(sizeof(char) * 128);
|
|
int num_bytes;
|
|
while ((num_bytes = recv(sd, buf, 128, 0)) != 0) {
|
|
if (num_bytes == -1) {
|
|
perror("failed to read from remote");
|
|
return 1;
|
|
}
|
|
fwrite(buf, 1, num_bytes, stdout);
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
free(buf);
|
|
free(message);
|
|
freeaddrinfo(addrinfo_res);
|
|
|
|
return 0;
|
|
}
|