2019-02-14 12:50:43 +00:00
|
|
|
#include "packet.h"
|
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
union abstract_packet* ap_next(union abstract_packet* ap) {
|
|
|
|
if (ap->fmt.headers.flags & FLAG_READ_NEXT)
|
|
|
|
return (union abstract_packet*)(&ap->raw + ap->fmt.headers.size);
|
|
|
|
|
|
|
|
return NULL;
|
2019-05-09 17:53:47 +00:00
|
|
|
}
|
|
|
|
|
2019-08-12 14:24:20 +00:00
|
|
|
union abstract_packet* buffer_last_ap(struct buffer_packet* bp) {
|
2019-08-12 13:28:22 +00:00
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip, *apn = NULL;
|
|
|
|
while ((apn = ap_next(ap)) != NULL) ap = apn;
|
2019-08-09 15:01:28 +00:00
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
return ap;
|
|
|
|
}
|
|
|
|
|
2019-08-12 14:24:20 +00:00
|
|
|
union abstract_packet* buffer_free_ap(struct buffer_packet* bp) {
|
|
|
|
union abstract_packet* ap = buffer_last_ap (bp);
|
2019-08-12 13:28:22 +00:00
|
|
|
ap = (union abstract_packet*)(&ap->raw + ap->fmt.headers.size);
|
|
|
|
|
|
|
|
return ap;
|
|
|
|
}
|
|
|
|
|
2019-08-12 14:24:20 +00:00
|
|
|
size_t buffer_count_ap(struct buffer_packet* bp) {
|
|
|
|
size_t s = 1;
|
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip;
|
|
|
|
while ((ap = ap_next(ap)) != NULL) s++;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
size_t get_full_size(struct buffer_packet* bp) {
|
2019-08-12 14:24:20 +00:00
|
|
|
return &(buffer_free_ap (bp))->raw - &bp->ip[0];
|
2019-08-12 13:28:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void buffer_append_ap(struct buffer_packet* bp, union abstract_packet* ap) {
|
2019-08-12 14:24:20 +00:00
|
|
|
buffer_last_ap(bp)->fmt.headers.flags |= FLAG_READ_NEXT;
|
|
|
|
memcpy(buffer_last_ap(bp), ap, ap->fmt.headers.size);
|
2019-08-09 15:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
enum FD_STATE read_packet_from_tcp(struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp) {
|
2019-02-14 14:40:05 +00:00
|
|
|
ssize_t nread;
|
2019-08-09 15:01:28 +00:00
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip;
|
|
|
|
size_t pkt_size_size = sizeof(ap->fmt.headers.size);
|
2019-02-18 16:51:13 +00:00
|
|
|
if (bp->mode != BP_READING) return FDS_ERR;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
|
|
|
while (bp->aread < pkt_size_size) {
|
2019-08-09 15:01:28 +00:00
|
|
|
nread = read(fdinfo->fd, &(ap->raw) + bp->aread, pkt_size_size - bp->aread);
|
2019-02-14 12:50:43 +00:00
|
|
|
if (nread == 0) return FDS_AGAIN;
|
|
|
|
if (nread == -1 && errno == EAGAIN) return FDS_AGAIN;
|
|
|
|
if (nread == -1) return FDS_ERR;
|
|
|
|
bp->aread += nread;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
while (bp->aread < ap->fmt.headers.size) {
|
|
|
|
nread = read(fdinfo->fd, &(ap->raw) + bp->aread, ap->fmt.headers.size - bp->aread);
|
2019-02-14 12:50:43 +00:00
|
|
|
if (nread == 0) return FDS_AGAIN;
|
|
|
|
if (nread == -1 && errno == EAGAIN) return FDS_AGAIN;
|
|
|
|
if (nread == -1) return FDS_ERR;
|
|
|
|
bp->aread += nread;
|
|
|
|
}
|
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
bp->ap_count++;
|
2019-08-12 14:24:20 +00:00
|
|
|
if (bp->ap_count != buffer_count_ap (bp)) {
|
|
|
|
printf(" Expected %ld packets in buffer, received %d\n", get_full_size(bp), bp->ap_count);
|
|
|
|
return FDS_AGAIN;
|
|
|
|
}
|
2019-08-12 13:28:22 +00:00
|
|
|
|
2019-02-18 20:55:53 +00:00
|
|
|
bp->mode = BP_WRITING;
|
2019-02-14 12:50:43 +00:00
|
|
|
bp->awrite = 0;
|
|
|
|
|
|
|
|
return FDS_READY;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
enum FD_STATE write_packet_to_tcp(struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp) {
|
2019-02-14 14:40:05 +00:00
|
|
|
ssize_t nwrite;
|
2019-08-09 15:01:28 +00:00
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-06-03 13:14:12 +00:00
|
|
|
//dump_buffer_packet (bp);
|
2019-02-18 16:51:13 +00:00
|
|
|
if (bp->mode != BP_WRITING) return FDS_ERR;
|
2019-05-09 17:53:47 +00:00
|
|
|
while (bp->awrite < get_full_size(bp)) {
|
2019-08-09 15:01:28 +00:00
|
|
|
nwrite = send(fdinfo->fd, &(ap->raw) + bp->awrite, get_full_size(bp) - bp->awrite, 0);
|
2019-02-14 12:50:43 +00:00
|
|
|
if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN;
|
|
|
|
if (nwrite == -1) return FDS_ERR;
|
|
|
|
bp->awrite += nwrite;
|
|
|
|
}
|
2019-02-18 20:55:53 +00:00
|
|
|
bp->mode = BP_READING;
|
2019-02-14 12:50:43 +00:00
|
|
|
bp->aread = 0;
|
2019-05-09 17:53:47 +00:00
|
|
|
bp->ap_count = 0;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
|
|
|
return FDS_READY;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
enum FD_STATE write_packet_to_udp(struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp, struct udp_target* udp_t) {
|
2019-02-14 16:15:13 +00:00
|
|
|
ssize_t nwrite;
|
2019-08-12 13:28:22 +00:00
|
|
|
union abstract_packet* ap = (union abstract_packet*) (&bp->ip + bp->awrite);
|
2019-08-12 14:24:20 +00:00
|
|
|
union abstract_packet* end = buffer_free_ap(bp);
|
2019-08-12 13:28:22 +00:00
|
|
|
if (bp->mode != BP_WRITING) return FDS_ERR;
|
2019-08-09 15:01:28 +00:00
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
while (ap != end) {
|
|
|
|
if (ap->fmt.headers.cmd != CMD_UDP_ENCAPSULATED) continue;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
size_t bytes_to_send;
|
|
|
|
size_t pkt_header_size = sizeof(ap->fmt.headers);
|
|
|
|
struct sockaddr* addr = NULL;
|
|
|
|
socklen_t addrlen = 0;
|
|
|
|
if (udp_t->set) {
|
|
|
|
addr = (struct sockaddr*) &udp_t->addr;
|
|
|
|
addrlen = sizeof(struct sockaddr_in);
|
|
|
|
}
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
bytes_to_send = ap->fmt.headers.size - pkt_header_size;
|
|
|
|
nwrite = sendto(fdinfo->fd,
|
2019-08-09 15:01:28 +00:00
|
|
|
&(ap->fmt.content.udp_encapsulated),
|
2019-02-14 12:50:43 +00:00
|
|
|
bytes_to_send,
|
2019-02-19 09:32:33 +00:00
|
|
|
0,
|
2019-02-19 13:54:42 +00:00
|
|
|
addr,
|
|
|
|
addrlen);
|
2019-02-14 16:15:13 +00:00
|
|
|
|
2019-08-12 13:28:22 +00:00
|
|
|
if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN;
|
|
|
|
if (nwrite != bytes_to_send) return FDS_ERR;
|
|
|
|
bp->awrite += nwrite;
|
|
|
|
}
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-02-18 20:55:53 +00:00
|
|
|
bp->mode = BP_READING;
|
2019-02-14 12:50:43 +00:00
|
|
|
bp->aread = 0;
|
2019-05-09 17:53:47 +00:00
|
|
|
bp->ap_count = 0;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
|
|
|
return FDS_READY;
|
|
|
|
}
|
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
enum FD_STATE read_packet_from_udp (struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp, struct udp_target* udp_t) {
|
2019-02-14 14:40:05 +00:00
|
|
|
ssize_t nread;
|
2019-08-09 15:01:28 +00:00
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip;
|
|
|
|
|
2019-05-23 20:53:00 +00:00
|
|
|
if (bp->mode != BP_READING) {
|
2019-05-24 08:52:49 +00:00
|
|
|
fprintf(stderr, "Buffer packet is not in reading mode (mode: %d)\n", bp->mode);
|
2019-05-23 20:53:00 +00:00
|
|
|
return FDS_ERR;
|
|
|
|
}
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
size_t pkt_header_size = sizeof(ap->fmt.headers);
|
|
|
|
size_t udp_packet_size = sizeof(bp->ip) - pkt_header_size;
|
2019-02-19 13:49:44 +00:00
|
|
|
socklen_t addrlen = sizeof(struct sockaddr_in);
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-08-09 15:01:28 +00:00
|
|
|
nread = recvfrom(fdinfo->fd,
|
|
|
|
&(ap->fmt.content.udp_encapsulated.payload),
|
2019-02-19 09:32:33 +00:00
|
|
|
udp_packet_size,
|
|
|
|
MSG_TRUNC,
|
2019-02-19 13:49:44 +00:00
|
|
|
(struct sockaddr*)&udp_t->addr,
|
|
|
|
&addrlen);
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-05-24 08:52:49 +00:00
|
|
|
if ((int)nread > (int)udp_packet_size) {
|
|
|
|
fprintf(stderr, "Packet has been truncated (%ld instead of %d)\n", nread, (int)udp_packet_size);
|
|
|
|
return FDS_ERR;
|
|
|
|
}
|
2019-02-14 12:50:43 +00:00
|
|
|
if (nread == -1 && errno == EAGAIN) return FDS_AGAIN;
|
2019-06-11 16:14:38 +00:00
|
|
|
if (nread == 0) return FDS_AGAIN;
|
2019-05-24 08:52:49 +00:00
|
|
|
if (nread == -1) {
|
2019-07-31 08:40:58 +00:00
|
|
|
fprintf(stderr, "A system error occurred\n");
|
2019-05-24 08:52:49 +00:00
|
|
|
return FDS_ERR;
|
|
|
|
}
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-02-19 13:49:44 +00:00
|
|
|
udp_t->set = 1;
|
|
|
|
udp_t->addrlen = addrlen;
|
2019-08-09 15:01:28 +00:00
|
|
|
ap->fmt.headers.size = nread + pkt_header_size;
|
|
|
|
ap->fmt.headers.cmd = CMD_UDP_ENCAPSULATED;
|
|
|
|
ap->fmt.content.udp_encapsulated.port = url_get_port_int (fdinfo->url);
|
2019-02-14 12:50:43 +00:00
|
|
|
|
2019-02-18 20:55:53 +00:00
|
|
|
bp->mode = BP_WRITING;
|
2019-02-14 12:50:43 +00:00
|
|
|
bp->awrite = 0;
|
2019-05-09 17:53:47 +00:00
|
|
|
bp->ap_count = 1;
|
2019-02-14 12:50:43 +00:00
|
|
|
|
|
|
|
return FDS_READY;
|
|
|
|
}
|
|
|
|
|
2019-05-24 09:46:23 +00:00
|
|
|
void dump_buffer_packet(struct buffer_packet* bp) {
|
|
|
|
printf("<Buffer Packet>\n");
|
2019-08-09 15:01:28 +00:00
|
|
|
printf(" mode=%d, aread=%d, awrite=%d, ap_count=%d, usage=%ld/%ld\n", bp->mode, bp->aread, bp->awrite, bp->ap_count, get_full_size (bp), sizeof(bp->ip));
|
|
|
|
union abstract_packet* ap = (union abstract_packet*) &bp->ip;
|
2019-05-24 09:46:23 +00:00
|
|
|
for (int i = 0; i < bp->ap_count; i++) {
|
|
|
|
dump_abstract_packet(ap);
|
|
|
|
ap = (union abstract_packet*)(&ap->raw + ap->fmt.headers.size);
|
|
|
|
}
|
|
|
|
printf("</Buffer Packet>\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump_abstract_packet(union abstract_packet* ap) {
|
2019-05-24 09:49:00 +00:00
|
|
|
printf(" <Abstract Packet>\n");
|
|
|
|
printf(" size=%d, cmd=%d\n", ap->fmt.headers.size, ap->fmt.headers.cmd);
|
2019-05-24 09:46:23 +00:00
|
|
|
switch (ap->fmt.headers.cmd) {
|
2019-08-09 15:01:28 +00:00
|
|
|
case CMD_LINK_MONITORING_THUNDER:
|
2019-05-24 11:51:56 +00:00
|
|
|
printf(" <Health>id=%d, deltat=%d, prevlink=%d, min_blocked_pkt=%d, bitfield=%02x</Health>\n",
|
2019-08-09 15:01:28 +00:00
|
|
|
ap->fmt.content.link_monitoring_thunder.id,
|
|
|
|
ap->fmt.content.link_monitoring_thunder.deltat,
|
|
|
|
ap->fmt.content.link_monitoring_thunder.prevlink,
|
|
|
|
ap->fmt.content.link_monitoring_thunder.min_blocked_pkt,
|
|
|
|
ap->fmt.content.link_monitoring_thunder.bitfield);
|
2019-05-24 09:46:23 +00:00
|
|
|
break;
|
2019-08-09 15:01:28 +00:00
|
|
|
case CMD_UDP_METADATA_THUNDER:
|
|
|
|
printf(" <Clear>id=%d</Clear>\n",
|
|
|
|
ap->fmt.content.udp_metadata_thunder.id);
|
2019-05-24 09:46:23 +00:00
|
|
|
break;
|
2019-08-09 15:01:28 +00:00
|
|
|
case CMD_UDP_ENCAPSULATED:
|
|
|
|
printf(" <Payload>port=%d</Payload>\n", ap->fmt.content.udp_encapsulated.port);
|
2019-05-24 09:46:23 +00:00
|
|
|
break;
|
|
|
|
default:
|
2019-05-24 09:49:00 +00:00
|
|
|
printf(" <Unknown/>\n");
|
2019-05-24 09:46:23 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2019-05-24 09:49:00 +00:00
|
|
|
printf(" </Abstract Packet>\n");
|
2019-05-24 09:46:23 +00:00
|
|
|
}
|