modular-worm/plugins/3_network_recv.c

101 lines
3.0 KiB
C

#define P4_NETWORK_FROM ((plugin_t){3, 0, 0, 1})
/*
Handle an incoming message, and transmit it to the right module
@param buf the message to handle
@param numbytes the amount of bytes of the message (buf's size)
@return SUCCESS if everything is ok
*/
static int p_recv_message_handle_msg(char *buf, int numbytes) {
if ((size_t)numbytes < sizeof(p3_msg_t)) {
printf("invalid msg (received %lu bytes instead of %lu)", (size_t)numbytes, sizeof(p3_msg_t));
return ERR_INVALID_MSG;
}
p3_msg_t *packet = (p3_msg_t*)buf;
char *body = (buf + sizeof(p3_msg_t));
p_printf_packet(packet);
// TODO: reallocate the buf to the heap ... ?
// TODO: if destination_host == current_host {} else { forward_to_host }
api_send_message(packet->destination_plugin, body, (size_t)packet->body_length, 1);
// TODO: send the aknowledgement and then use the packet
return SUCCESS;
}
/*
TODO
Handle an incoming ACK
@param buf the ack to handle
@param numbutes the amount of bytes to process
@return SUCCESS if everything is ok
*/
static int p_recv_message_handle_ack(char *buf, int numbytes) {
if ((size_t)numbytes != sizeof(p3_ack_t)) {
printf("invalid ack (received %lu bytes instead of %lu)", (size_t)numbytes, sizeof(p3_ack_t));
return ERR_INVALID_ACK;
}
p3_ack_t *packet = (p3_ack_t*)buf;
(void)packet;
// TODO: validate that the packet.packet_id has been sent
// TODO: then send it to the right plugin
return SUCCESS;
}
/*
Handles an incoming message (read the socket, and handle)
*/
static int p_recv_message() {
if (server_p == -1)
return -1;
int numbytes;
struct sockaddr_storage their_addr;
char buf[sizeof(p3_msg_t) + BODY_LEN + 1];
socklen_t addr_len;
char s[INET6_ADDRSTRLEN];
struct timeval tv;
fd_set readfds;
tv.tv_sec = 0;
tv.tv_usec = 10;
FD_ZERO(&readfds);
FD_SET(server_p, &readfds);
select(server_p + 1, &readfds, NULL, NULL, &tv);
printf("waiting to recvfrom...\n");
if (!FD_ISSET(server_p, &readfds)) {
printf("no datagram ready!\n");
return ERR_NO_MESSAGE; // no packet
}
printf("datagram ready!\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(server_p, buf, sizeof(p3_msg_t) + BODY_LEN , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
return ERR_READ;
}
printf("got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("packet is %d bytes long\n", numbytes);
buf[numbytes] = 0;
/* printf("packet contains \"%s\"\n\n", buf); // debug test */
if ((size_t)numbytes >= sizeof(magic_number_t)) {
magic_number_t *mn = (void *)buf;
if (mn->value == MN_MSG) {
return p_recv_message_handle_msg(buf, numbytes);
}
else if (mn->value == MN_ACK) {
return p_recv_message_handle_ack(buf, numbytes);
}
else {
printf("unknown magic number (%x)\n", mn->value);
return ERR_INVALID_HEADER;
}
}
else {
printf("garbage received\n");
return ERR_INVALID_HEADER;
}
}