Add tools packet_parser
This commit is contained in:
@@ -2,11 +2,106 @@
|
||||
#include <pcap/pcap.h>
|
||||
#include "packet_priv.h"
|
||||
|
||||
struct options
|
||||
{
|
||||
char *file;
|
||||
int print_proto;
|
||||
int print_summary;
|
||||
};
|
||||
|
||||
static uint64_t number = 0;
|
||||
|
||||
static int packet_proto_to_str(const struct packet *pkt, char *buff, int size)
|
||||
{
|
||||
int used = 0;
|
||||
int8_t num = packet_get_layers_number(pkt);
|
||||
for (int8_t i = 0; i < num; i++)
|
||||
{
|
||||
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");
|
||||
break;
|
||||
case LAYER_TYPE_PPP:
|
||||
used += snprintf(buff + used, size - used, "ppp");
|
||||
break;
|
||||
case LAYER_TYPE_HDLC:
|
||||
used += snprintf(buff + used, size - used, "hdlc");
|
||||
break;
|
||||
case LAYER_TYPE_L2TP:
|
||||
used += snprintf(buff + used, size - used, "l2tp");
|
||||
break;
|
||||
case LAYER_TYPE_VLAN:
|
||||
used += snprintf(buff + used, size - used, "vlan:ethertype");
|
||||
break;
|
||||
case LAYER_TYPE_PPPOE:
|
||||
used += snprintf(buff + used, size - used, "pppoe");
|
||||
break;
|
||||
case LAYER_TYPE_MPLS:
|
||||
used += snprintf(buff + used, size - used, "mpls");
|
||||
break;
|
||||
case LAYER_TYPE_IPV4:
|
||||
used += snprintf(buff + used, size - used, "ip");
|
||||
break;
|
||||
case LAYER_TYPE_IPV6:
|
||||
used += snprintf(buff + used, size - used, "ipv6");
|
||||
break;
|
||||
case LAYER_TYPE_GRE:
|
||||
used += snprintf(buff + used, size - used, "gre");
|
||||
break;
|
||||
case LAYER_TYPE_UDP:
|
||||
used += snprintf(buff + used, size - used, "udp");
|
||||
break;
|
||||
case LAYER_TYPE_TCP:
|
||||
used += snprintf(buff + used, size - used, "tcp");
|
||||
break;
|
||||
case LAYER_TYPE_ICMP:
|
||||
used += snprintf(buff + used, size - used, "icmp");
|
||||
break;
|
||||
case LAYER_TYPE_ICMP6:
|
||||
used += snprintf(buff + used, size - used, "icmpv6");
|
||||
break;
|
||||
case LAYER_TYPE_VXLAN:
|
||||
used += snprintf(buff + used, size - used, "vxlan");
|
||||
break;
|
||||
case LAYER_TYPE_GTPV1_U:
|
||||
used += snprintf(buff + used, size - used, "gtp");
|
||||
break;
|
||||
default:
|
||||
used += snprintf(buff + used, size - used, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != num - 1)
|
||||
{
|
||||
used += snprintf(buff + used, size - used, ":");
|
||||
}
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
static void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
|
||||
{
|
||||
struct options *opts = (struct options *)user;
|
||||
|
||||
struct packet pkt;
|
||||
packet_parse(&pkt, (const char *)bytes, h->caplen);
|
||||
packet_print_table(&pkt);
|
||||
number++;
|
||||
|
||||
if (opts->print_summary)
|
||||
{
|
||||
printf("\033[0;32m frame=%lu len=%u \033[0m", number, h->caplen);
|
||||
packet_print_str(&pkt);
|
||||
}
|
||||
|
||||
if (opts->print_proto)
|
||||
{
|
||||
char buff[1024] = {0};
|
||||
packet_proto_to_str(&pkt, buff, sizeof(buff));
|
||||
printf("%lu %s\n", number, buff);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(char *cmd)
|
||||
@@ -14,6 +109,8 @@ static void usage(char *cmd)
|
||||
printf("Usage: %s\n", cmd);
|
||||
printf("Options:\n");
|
||||
printf(" -f <pcap file> pcap file\n");
|
||||
printf(" -p print protocol\n");
|
||||
printf(" -s print summary\n");
|
||||
printf(" -h print help\n");
|
||||
printf("\n");
|
||||
}
|
||||
@@ -21,36 +118,40 @@ static void usage(char *cmd)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt = 0;
|
||||
char *file = NULL;
|
||||
while ((opt = getopt(argc, argv, "f:h")) != -1)
|
||||
struct options opts = {0};
|
||||
while ((opt = getopt(argc, argv, "f:psh")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'f':
|
||||
file = optarg;
|
||||
opts.file = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
opts.print_proto = 1;
|
||||
break;
|
||||
case 's':
|
||||
opts.print_summary = 1;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
if (opts.file == NULL)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcap_t *pcap = pcap_open_offline(file, NULL);
|
||||
pcap_t *pcap = pcap_open_offline(opts.file, NULL);
|
||||
if (pcap == NULL)
|
||||
{
|
||||
printf("pcap_open_offline() failed\n");
|
||||
return -1;
|
||||
}
|
||||
pcap_loop(pcap, -1, packet_handler, NULL);
|
||||
pcap_loop(pcap, -1, packet_handler, (u_char *)&opts);
|
||||
pcap_close(pcap);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user