diff --git a/monitor/main.c b/monitor/main.c index 66faabad..f88fd347 100644 --- a/monitor/main.c +++ b/monitor/main.c @@ -139,13 +139,20 @@ static struct l_netlink *genl_lookup(const char *ifname) return genl; } +#define MAX_SNAPLEN (1024 * 16) + static int process_pcap(struct pcap *pcap) { struct nlmon *nlmon = NULL; + struct timeval tv; uint8_t *buf; - uint32_t len; + uint32_t snaplen, len, real_len; - buf = malloc(1024 * 16); + snaplen = pcap_get_snaplen(pcap); + if (snaplen > MAX_SNAPLEN) + snaplen = MAX_SNAPLEN; + + buf = malloc(snaplen); if (!buf) { fprintf(stderr, "Failed to allocate packet buffer\n"); return EXIT_FAILURE; @@ -153,7 +160,7 @@ static int process_pcap(struct pcap *pcap) nlmon = nlmon_create(); - while (pcap_read(pcap, NULL, buf, 1024 * 16, &len)) { + while (pcap_read(pcap, &tv, buf, snaplen, &len, &real_len)) { uint16_t arphrd_type; uint16_t proto_type; @@ -162,6 +169,9 @@ static int process_pcap(struct pcap *pcap) continue; } + if (len < real_len) + printf("Packet truncated from %u\n", real_len); + arphrd_type = L_GET_UNALIGNED((const uint16_t *) (buf + 2)); if (L_BE16_TO_CPU(arphrd_type) != ARPHRD_NETLINK) { @@ -174,10 +184,10 @@ static int process_pcap(struct pcap *pcap) switch (L_BE16_TO_CPU(proto_type)) { case NETLINK_ROUTE: - nlmon_print_rtnl(nlmon, buf, len); + nlmon_print_rtnl(nlmon, &tv, buf, len); break; case NETLINK_GENERIC: - nlmon_print_genl(nlmon, buf + 16, len - 16); + nlmon_print_genl(nlmon, &tv, buf + 16, len - 16); break; } } diff --git a/monitor/nlmon.c b/monitor/nlmon.c index d99d1c01..c3e04643 100644 --- a/monitor/nlmon.c +++ b/monitor/nlmon.c @@ -1429,16 +1429,18 @@ static void genl_ctrl(struct nlmon *nlmon, const void *data, uint32_t len) nlmon->id = id; } -void nlmon_print_rtnl(struct nlmon *nlmon, const void *data, uint32_t size) +void nlmon_print_rtnl(struct nlmon *nlmon, const struct timeval *tv, + const void *data, uint32_t size) { char str[16]; sprintf(str, "len %u", size); - print_packet(NULL, '*', COLOR_WHITE, "Route Netlink", str, ""); + print_packet(tv, '*', COLOR_WHITE, "Route Netlink", str, ""); } -void nlmon_print_genl(struct nlmon *nlmon, const void *data, uint32_t size) +void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv, + const void *data, uint32_t size) { const struct nlmsghdr *nlmsg; @@ -1448,7 +1450,7 @@ void nlmon_print_genl(struct nlmon *nlmon, const void *data, uint32_t size) genl_ctrl(nlmon, NLMSG_DATA(nlmsg), NLMSG_PAYLOAD(nlmsg, 0)); else - nlmon_message(nlmon, NULL, NULL, nlmsg); + nlmon_message(nlmon, tv, NULL, nlmsg); } } diff --git a/monitor/nlmon.h b/monitor/nlmon.h index d8777c68..dc107d0b 100644 --- a/monitor/nlmon.h +++ b/monitor/nlmon.h @@ -21,6 +21,7 @@ */ #include +#include struct nlmon; @@ -29,5 +30,7 @@ void nlmon_close(struct nlmon *nlmon); struct nlmon *nlmon_create(void); void nlmon_destroy(struct nlmon *nlmon); -void nlmon_print_rtnl(struct nlmon *nlmon, const void *data, uint32_t size); -void nlmon_print_genl(struct nlmon *nlmon, const void *data, uint32_t size); +void nlmon_print_rtnl(struct nlmon *nlmon, const struct timeval *tv, + const void *data, uint32_t size); +void nlmon_print_genl(struct nlmon *nlmon, const struct timeval *tv, + const void *data, uint32_t size); diff --git a/monitor/pcap.c b/monitor/pcap.c index 377b0fa9..73df376e 100644 --- a/monitor/pcap.c +++ b/monitor/pcap.c @@ -133,7 +133,7 @@ uint32_t pcap_get_snaplen(struct pcap *pcap) } bool pcap_read(struct pcap *pcap, struct timeval *tv, - void *data, uint32_t size, uint32_t *len) + void *data, uint32_t size, uint32_t *len, uint32_t *real_len) { struct pcap_pkt pkt; uint32_t toread; @@ -166,5 +166,8 @@ bool pcap_read(struct pcap *pcap, struct timeval *tv, if (len) *len = toread; + if (real_len) + *real_len = pkt.incl_len; + return true; } diff --git a/monitor/pcap.h b/monitor/pcap.h index 6a912c76..429d77a5 100644 --- a/monitor/pcap.h +++ b/monitor/pcap.h @@ -37,4 +37,4 @@ uint32_t pcap_get_type(struct pcap *pcap); uint32_t pcap_get_snaplen(struct pcap *pcap); bool pcap_read(struct pcap *pcap, struct timeval *tv, - void *data, uint32_t size, uint32_t *len); + void *data, uint32_t size, uint32_t *len, uint32_t *real_len);