diff --git a/test/packet_parser/cmp_layers.sh b/test/packet_parser/cmp_layers.sh index 496961f..aa6b8f7 100644 --- a/test/packet_parser/cmp_layers.sh +++ b/test/packet_parser/cmp_layers.sh @@ -148,11 +148,24 @@ for pcap in "${pcap_files[@]}"; do curr_count=$((curr_count + 1)) - # tshark output frame.protocols - tshark -r ${pcap} -T fields -e frame.number -e frame.protocols >>${tmp_file_dir}/tshark_output.txt + # tshark output + tshark -r ${pcap} -T fields \ + -e frame.number \ + -e frame.protocols \ + -e eth.src \ + -e eth.dst \ + -e ip.src \ + -e ip.dst \ + -e ipv6.src \ + -e ipv6.dst \ + -e tcp.srcport \ + -e tcp.dstport \ + -e udp.srcport \ + -e udp.dstport \ + >>${tmp_file_dir}/tshark_output.txt - # packet_parser output frame.protocols - ./packet_parser -f ${pcap} -p >>${tmp_file_dir}/parser_output.txt + # packet_parser output + ./packet_parser -f ${pcap} -t >>${tmp_file_dir}/parser_output.txt # compare tshark and packet_parser output preprocess_tshark_ouput ${tmp_file_dir}/tshark_output.txt ${tmp_file_dir}/tshark_format.txt diff --git a/test/packet_parser/packet_parser.cpp b/test/packet_parser/packet_parser.cpp index 22f11bc..0d3d04a 100644 --- a/test/packet_parser/packet_parser.cpp +++ b/test/packet_parser/packet_parser.cpp @@ -2,119 +2,222 @@ #include #include "ipv6_utils.h" #include "packet_priv.h" +#include "eth_utils.h" +#include "ipv4_utils.h" +#include "ipv6_utils.h" +#include "tcp_utils.h" +#include "udp_utils.h" struct options { char *file; - int print_proto; - int print_summary; + int print_tshark_format; + int print_readable_format; }; static uint64_t number = 0; -static int ipv6_proto_to_str(const struct packet_layer *ipv6_layer, char *buff, int size) +#define MAX_BUFF_SIZE 2048 +struct buffer { - int used = snprintf(buff, size, "ipv6"); - uint8_t next_hdr = ipv6_hdr_get_next_header((const struct ip6_hdr *)ipv6_layer->hdr_ptr); - switch (next_hdr) - { - case IPPROTO_HOPOPTS: - used += snprintf(buff + used, size - used, ":ipv6.hopopts"); - break; - case IPPROTO_ROUTING: - used += snprintf(buff + used, size - used, ":ipv6.routing"); - break; - case IPPROTO_AH: - used += snprintf(buff + used, size - used, ":ah"); - break; - case IPPROTO_DSTOPTS: - used += snprintf(buff + used, size - used, ":ipv6.dstopts"); - break; - case IPPROTO_FRAGMENT: - used += snprintf(buff + used, size - used, ":ipv6.fraghdr"); - break; - default: - break; - } + char buff[MAX_BUFF_SIZE]; + int used; + char elimiter; +}; - return used; +static void buffer_push(struct buffer *buff, const char *str) +{ + int len = strlen(str); + if (buff->used + len + 1 >= MAX_BUFF_SIZE) + { + return; + } + if (buff->used) + { + buff->buff[buff->used++] = buff->elimiter; + } + memcpy(buff->buff + buff->used, str, len); + buff->used += len; } -static int packet_proto_to_str(const struct packet *pkt, char *buff, int size) +static void packet_to_tshark_format(const struct packet *pkt, uint64_t idx) { - int used = 0; + /* + tshark -r ${pcap} -T fields \ + -e frame.number \ + -e frame.protocols \ + -e eth.src \ + -e eth.dst \ + -e ip.src \ + -e ip.dst \ + -e ipv6.src \ + -e ipv6.dst \ + -e tcp.srcport \ + -e tcp.dstport \ + -e udp.srcport \ + -e udp.dstport \ + >> tshark_output.txt + */ + + struct buffer buff_proto = {.buff = {0}, .used = 0, .elimiter = ':'}; + struct buffer buff_eth_src = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_eth_dst = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_ipv4_src = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_ipv4_dst = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_ipv6_src = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_ipv6_dst = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_tcp_src = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_tcp_dst = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_udp_src = {.buff = {0}, .used = 0, .elimiter = ','}; + struct buffer buff_udp_dst = {.buff = {0}, .used = 0, .elimiter = ','}; + const struct ethhdr *eth_hdr = NULL; + const struct ip *ipv4_hdr = NULL; + const struct ip6_hdr *ipv6_hdr = NULL; + const struct tcphdr *tcp_hdr = NULL; + const struct udphdr *udp_hdr = NULL; + struct in_addr src_addr_v4 = {0}; + struct in_addr dst_addr_v4 = {0}; + struct in6_addr src_addr_v6 = {0}; + struct in6_addr dst_addr_v6 = {0}; + uint16_t src_port = 0; + uint16_t dst_port = 0; + char tmp_src_buff[256] = {0}; + char tmp_dst_buff[256] = {0}; + int8_t num = packet_get_layers_number(pkt); for (int8_t i = 0; i < num; i++) { + memset(tmp_src_buff, 0, sizeof(tmp_src_buff)); + memset(tmp_dst_buff, 0, sizeof(tmp_dst_buff)); const struct packet_layer *layer = packet_get_layer(pkt, i); switch (layer->type) { case LAYER_TYPE_ETHER: - used += snprintf(buff + used, size - used, "eth:ethertype"); + buffer_push(&buff_proto, "eth:ethertype"); + eth_hdr = (const struct ethhdr *)layer->hdr_ptr; + eth_hdr_get_source(eth_hdr, tmp_src_buff, sizeof(tmp_src_buff)); + eth_hdr_get_dest(eth_hdr, tmp_dst_buff, sizeof(tmp_dst_buff)); + buffer_push(&buff_eth_src, tmp_src_buff); + buffer_push(&buff_eth_dst, tmp_dst_buff); break; case LAYER_TYPE_PWETH: - used += snprintf(buff + used, size - used, "pwethheuristic:pwethcw"); + buffer_push(&buff_proto, "pwethheuristic:pwethcw"); break; case LAYER_TYPE_PPP: - used += snprintf(buff + used, size - used, "ppp"); + buffer_push(&buff_proto, "ppp"); break; case LAYER_TYPE_HDLC: - used += snprintf(buff + used, size - used, "hdlc"); + buffer_push(&buff_proto, "hdlc"); break; case LAYER_TYPE_L2TP: - used += snprintf(buff + used, size - used, "l2tp"); + buffer_push(&buff_proto, "l2tp"); break; case LAYER_TYPE_VLAN: - used += snprintf(buff + used, size - used, "vlan:ethertype"); + buffer_push(&buff_proto, "vlan:ethertype"); break; case LAYER_TYPE_PPPOE: - used += snprintf(buff + used, size - used, "pppoes"); + buffer_push(&buff_proto, "pppoes"); break; case LAYER_TYPE_MPLS: - used += snprintf(buff + used, size - used, "mpls"); + buffer_push(&buff_proto, "mpls"); break; case LAYER_TYPE_IPV4: - used += snprintf(buff + used, size - used, "ip"); + buffer_push(&buff_proto, "ip"); + ipv4_hdr = (const struct ip *)layer->hdr_ptr; + src_addr_v4 = ipv4_hdr_get_src_in_addr(ipv4_hdr); + dst_addr_v4 = ipv4_hdr_get_dst_in_addr(ipv4_hdr); + inet_ntop(AF_INET, &src_addr_v4, tmp_src_buff, sizeof(tmp_src_buff)); + inet_ntop(AF_INET, &dst_addr_v4, tmp_dst_buff, sizeof(tmp_dst_buff)); + buffer_push(&buff_ipv4_src, tmp_src_buff); + buffer_push(&buff_ipv4_dst, tmp_dst_buff); break; case LAYER_TYPE_IPV6: - used += ipv6_proto_to_str(layer, buff + used, size - used); + buffer_push(&buff_proto, "ipv6"); + ipv6_hdr = (const struct ip6_hdr *)layer->hdr_ptr; + switch (ipv6_hdr_get_next_header(ipv6_hdr)) + { + case IPPROTO_HOPOPTS: + buffer_push(&buff_proto, "ipv6.hopopts"); + break; + case IPPROTO_ROUTING: + buffer_push(&buff_proto, "ipv6.routing"); + break; + case IPPROTO_AH: + buffer_push(&buff_proto, "ah"); + break; + case IPPROTO_DSTOPTS: + buffer_push(&buff_proto, "ipv6.dstopts"); + break; + case IPPROTO_FRAGMENT: + buffer_push(&buff_proto, "ipv6.fraghdr"); + break; + default: + break; + } + src_addr_v6 = ipv6_hdr_get_src_in6_addr(ipv6_hdr); + dst_addr_v6 = ipv6_hdr_get_dst_in6_addr(ipv6_hdr); + inet_ntop(AF_INET6, &src_addr_v6, tmp_src_buff, sizeof(tmp_src_buff)); + inet_ntop(AF_INET6, &dst_addr_v6, tmp_dst_buff, sizeof(tmp_dst_buff)); + buffer_push(&buff_ipv6_src, tmp_src_buff); + buffer_push(&buff_ipv6_dst, tmp_dst_buff); break; case LAYER_TYPE_IPAH: - used += snprintf(buff + used, size - used, "ah"); + buffer_push(&buff_proto, "ah"); break; case LAYER_TYPE_GRE: - used += snprintf(buff + used, size - used, "gre"); + buffer_push(&buff_proto, "gre"); break; case LAYER_TYPE_UDP: - used += snprintf(buff + used, size - used, "udp"); + buffer_push(&buff_proto, "udp"); + udp_hdr = (const struct udphdr *)layer->hdr_ptr; + src_port = udp_hdr_get_src_port(udp_hdr); + dst_port = udp_hdr_get_dst_port(udp_hdr); + snprintf(tmp_src_buff, sizeof(tmp_src_buff), "%u", src_port); + snprintf(tmp_dst_buff, sizeof(tmp_dst_buff), "%u", dst_port); + buffer_push(&buff_udp_src, tmp_src_buff); + buffer_push(&buff_udp_dst, tmp_dst_buff); break; case LAYER_TYPE_TCP: - used += snprintf(buff + used, size - used, "tcp"); + buffer_push(&buff_proto, "tcp"); + tcp_hdr = (const struct tcphdr *)layer->hdr_ptr; + src_port = tcp_hdr_get_src_port(tcp_hdr); + dst_port = tcp_hdr_get_dst_port(tcp_hdr); + snprintf(tmp_src_buff, sizeof(tmp_src_buff), "%u", src_port); + snprintf(tmp_dst_buff, sizeof(tmp_dst_buff), "%u", dst_port); + buffer_push(&buff_tcp_src, tmp_src_buff); + buffer_push(&buff_tcp_dst, tmp_dst_buff); break; case LAYER_TYPE_ICMP: - used += snprintf(buff + used, size - used, "icmp"); + buffer_push(&buff_proto, "icmp"); break; case LAYER_TYPE_ICMP6: - used += snprintf(buff + used, size - used, "icmpv6"); + buffer_push(&buff_proto, "icmpv6"); break; case LAYER_TYPE_VXLAN: - used += snprintf(buff + used, size - used, "vxlan"); + buffer_push(&buff_proto, "vxlan"); break; case LAYER_TYPE_GTPV1_U: - used += snprintf(buff + used, size - used, "gtp"); + buffer_push(&buff_proto, "gtp"); break; default: - used += snprintf(buff + used, size - used, "unknown"); + buffer_push(&buff_proto, "unknown"); break; } - - if (i != num - 1) - { - used += snprintf(buff + used, size - used, ":"); - } } - return used; + printf("%lu\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", + number, + buff_proto.buff, + buff_eth_src.buff, + buff_eth_dst.buff, + buff_ipv4_src.buff, + buff_ipv4_dst.buff, + buff_ipv6_src.buff, + buff_ipv6_dst.buff, + buff_tcp_src.buff, + buff_tcp_dst.buff, + buff_udp_src.buff, + buff_udp_dst.buff); } static void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) @@ -125,17 +228,15 @@ static void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_ch packet_parse(&pkt, (const char *)bytes, h->caplen); number++; - if (opts->print_summary) + if (opts->print_readable_format) { printf("\033[0;32m frame=%lu len=%u \033[0m", number, h->caplen); packet_print_str(&pkt); } - if (opts->print_proto) + if (opts->print_tshark_format) { - char buff[1024] = {0}; - packet_proto_to_str(&pkt, buff, sizeof(buff)); - printf("%lu %s\n", number, buff); + packet_to_tshark_format(&pkt, number); } } @@ -144,8 +245,8 @@ static void usage(char *cmd) printf("Usage: %s\n", cmd); printf("Options:\n"); printf(" -f pcap file\n"); - printf(" -p print protocol\n"); - printf(" -s print summary\n"); + printf(" -t print tshark format\n"); + printf(" -r print readable format\n"); printf(" -h print help\n"); printf("\n"); } @@ -154,18 +255,18 @@ int main(int argc, char **argv) { int opt = 0; struct options opts = {0}; - while ((opt = getopt(argc, argv, "f:psh")) != -1) + while ((opt = getopt(argc, argv, "f:trh")) != -1) { switch (opt) { case 'f': opts.file = optarg; break; - case 'p': - opts.print_proto = 1; + case 't': + opts.print_tshark_format = 1; break; - case 's': - opts.print_summary = 1; + case 'r': + opts.print_readable_format = 1; break; case 'h': default: