1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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;
}
|