aboutsummaryrefslogtreecommitdiff
path: root/mcnetwork.c
diff options
context:
space:
mode:
Diffstat (limited to 'mcnetwork.c')
-rw-r--r--mcnetwork.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/mcnetwork.c b/mcnetwork.c
new file mode 100644
index 0000000..00cdf6c
--- /dev/null
+++ b/mcnetwork.c
@@ -0,0 +1,84 @@
+#include "mcnetwork.h"
+
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "mctypes.h"
+
+void send_handshake(int socket, int protocol, char* address,
+ unsigned short port, int next_state)
+{
+ void* raw_handshake;
+ size_t handshake_size;
+ handshake hs = { to_varint(protocol),
+ { to_varint(strlen(address)), address }, port, to_varint(next_state) };
+ handshake_size = serialize_handshake(hs, &raw_handshake);
+ send_packet(socket, 0x0, handshake_size, raw_handshake);
+ free_handshake(hs);
+}
+
+void send_packet(int socket, int packet_id, size_t raw_size, void* raw_data)
+{
+ void* raw_packet;
+ size_t p_size;
+ packet p = { to_varint(raw_size + size_varint(to_varint(packet_id))),
+ to_varint(packet_id), raw_data };
+ p_size = serialize_packet(p, &raw_packet);
+ free_packet(p);
+
+ if (send(socket, raw_packet, p_size, 0) < 0)
+ perror("packet failed");
+}
+
+void connect_mc_server_ping(int socket, char* address, unsigned short port)
+{
+ struct addrinfo* mc_info = malloc(sizeof(struct addrinfo));
+ memset(mc_info, 0, sizeof(struct addrinfo));
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if (getaddrinfo(address, "80", &hints, &mc_info) != 0)
+ exit(1);
+
+ struct sockaddr_in mc_sock;
+ mc_sock.sin_family = AF_INET;
+ mc_sock.sin_port = htons(port);
+ memcpy(&mc_sock.sin_addr, mc_info->ai_addr->sa_data + 2,
+ mc_info->ai_addrlen); // stupidity
+
+ freeaddrinfo(mc_info);
+
+ if (connect(socket, (struct sockaddr*)&mc_sock, sizeof(mc_sock)) < 0)
+ exit(1);
+}
+
+varint recv_varint(int s)
+{
+ unsigned long i = 0;
+ varint v = NULL;
+ do {
+ v = reallocarray(v, i, sizeof(u_int8_t));
+ recv(s, v + i, 1, 0);
+ i++;
+ } while ((v[i - 1] & 0x80) != 0);
+ return v;
+}
+
+packet recv_packet(int socket)
+{
+ packet p;
+ size_t data_size;
+ p.length = recv_varint(socket);
+ p.id = recv_varint(socket);
+ data_size = from_varint(p.length) - size_varint(p.id);
+ p.data = malloc(data_size);
+ recv(socket, p.data, data_size, MSG_WAITALL);
+ return p;
+}