This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/test/packet_parser/packet_parser.cpp

187 lines
5.0 KiB
C++

#include <unistd.h>
#include <pcap/pcap.h>
#include "ipv6_utils.h"
#include "packet_priv.h"
struct options
{
char *file;
int print_proto;
int print_summary;
};
static uint64_t number = 0;
static int ipv6_proto_to_str(const struct packet_layer *ipv6_layer, char *buff, int size)
{
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.hopopt");
break;
case IPPROTO_ROUTING:
used += snprintf(buff + used, size - used, ":ipv6.routing");
break;
case IPPROTO_AH:
used += snprintf(buff + used, size - used, ":ipv6.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;
}
return used;
}
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, "pppoes");
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 += ipv6_proto_to_str(layer, buff + used, size - used);
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);
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)
{
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");
}
int main(int argc, char **argv)
{
int opt = 0;
struct options opts = {0};
while ((opt = getopt(argc, argv, "f:psh")) != -1)
{
switch (opt)
{
case 'f':
opts.file = optarg;
break;
case 'p':
opts.print_proto = 1;
break;
case 's':
opts.print_summary = 1;
break;
case 'h':
default:
usage(argv[0]);
return 0;
}
}
if (opts.file == NULL)
{
usage(argv[0]);
return -1;
}
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, (u_char *)&opts);
pcap_close(pcap);
return 0;
}