2021-09-14 15:50:53 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <getopt.h>
|
|
|
|
|
#include <pcap/pcap.h>
|
|
|
|
|
#include "MESA_jump_layer.h"
|
|
|
|
|
|
|
|
|
|
static pcap_t *g_pcap_handle;
|
|
|
|
|
static char *g_input_pcap_name;
|
|
|
|
|
static char *g_input_bpf_string;
|
|
|
|
|
static struct bpf_program g_bpf_filter;
|
|
|
|
|
|
2021-10-26 18:41:54 +08:00
|
|
|
static int g_raw_input_layer_type = (int )ADDR_TYPE_MAC;
|
|
|
|
|
static int g_expect_layer_type = (int )ADDR_TYPE_IPV4;
|
|
|
|
|
|
2021-09-14 15:50:53 +08:00
|
|
|
static void usage(const char *prog)
|
|
|
|
|
{
|
|
|
|
|
printf("Usage:\n");
|
|
|
|
|
printf("\t-r set input pcap file.\n");
|
|
|
|
|
printf("\t-f set pcap BPF fileter.\n");
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int pcap_set_bpf(pcap_t *handle, const char *filter_str)
|
|
|
|
|
{
|
|
|
|
|
struct bpf_program bpf_filter;
|
|
|
|
|
|
|
|
|
|
if((NULL == handle) || (NULL == filter_str) || ('\0' == *filter_str)){
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pcap_compile(handle, &bpf_filter, (char *)filter_str, 1, 0) < 0)
|
|
|
|
|
{
|
|
|
|
|
printf("Compile pcap filter '%s' error:%s\n", filter_str, pcap_geterr(handle));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pcap_setfilter(handle, &bpf_filter) < 0){
|
|
|
|
|
printf("Set pcap filter '%s' error:%s\n", filter_str, pcap_geterr(handle));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int pcap_init(void)
|
|
|
|
|
{
|
|
|
|
|
char err_string[PCAP_ERRBUF_SIZE];
|
|
|
|
|
|
|
|
|
|
g_pcap_handle = pcap_open_offline(g_input_pcap_name, err_string);
|
|
|
|
|
if(NULL == g_pcap_handle){
|
|
|
|
|
printf("open file:%s error, %s\n", g_input_pcap_name, err_string);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pcap_compile_nopcap(65535, DLT_RAW, &g_bpf_filter, g_input_bpf_string, 1, 0) < 0){
|
|
|
|
|
printf("Compile pcap filter '%s' error\n", g_input_bpf_string);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-26 18:41:54 +08:00
|
|
|
static void _jump_from_udp(const void *uhdr)
|
|
|
|
|
{
|
|
|
|
|
const void *next_hdr;
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(uhdr, ADDR_TYPE_UDP, ADDR_TYPE_GPRS_TUNNEL);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to gtp from udp succ!\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(uhdr, ADDR_TYPE_UDP, ADDR_TYPE_L2TP);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to l2tp from udp succ!\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void _jump_from_ipv4(const void *ip4_hdr)
|
|
|
|
|
{
|
|
|
|
|
const void *next_hdr;
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(ip4_hdr, ADDR_TYPE_IPV4, ADDR_TYPE_TCP);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to tcp from ipv4 succ!\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(ip4_hdr, ADDR_TYPE_IPV4, ADDR_TYPE_UDP);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to udp from ipv4 succ!\n");
|
|
|
|
|
_jump_from_udp(next_hdr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void _jump_from_ipv6(const void *ip4_hdr)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void _jump_from_ethernet(const void *ehdr)
|
|
|
|
|
{
|
|
|
|
|
const void *next_hdr;
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(ehdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV4);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to ipv4 from ethernet succ!\n");
|
|
|
|
|
_jump_from_ipv4(next_hdr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next_hdr = MESA_jump_layer(ehdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV6);
|
|
|
|
|
if(next_hdr){
|
|
|
|
|
printf("bingo! jump to ipv6 from ethernet succ!\n");
|
|
|
|
|
_jump_from_ipv6(next_hdr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void _jump_greedy(const struct pcap_pkthdr *hdr, const u_char *data)
|
2021-09-14 15:50:53 +08:00
|
|
|
{
|
|
|
|
|
const void *ip4_hdr, *ip6_h;
|
2021-10-26 18:41:54 +08:00
|
|
|
|
2021-09-14 15:50:53 +08:00
|
|
|
char print_buf[128];
|
|
|
|
|
int offset_to_eth;
|
|
|
|
|
static int pkt_index = 0;
|
|
|
|
|
|
2021-09-14 17:33:59 +08:00
|
|
|
ip4_hdr = MESA_jump_layer_greedy(data, ADDR_TYPE_MAC, ADDR_TYPE_IPV4);
|
|
|
|
|
ip6_h = MESA_jump_layer_greedy(data, ADDR_TYPE_MAC, ADDR_TYPE_IPV6);
|
2021-10-26 18:41:54 +08:00
|
|
|
|
2021-09-14 15:50:53 +08:00
|
|
|
|
2021-10-26 18:41:54 +08:00
|
|
|
printf("-----------------------------packet index:%d------------------------------------------\n", pkt_index++);
|
|
|
|
|
if(ip4_hdr){
|
|
|
|
|
offset_to_eth = (u_char *)ip4_hdr-data;
|
|
|
|
|
if(g_input_bpf_string
|
|
|
|
|
&& (0 == bpf_filter(g_bpf_filter.bf_insns, (const unsigned char *)ip4_hdr, hdr->caplen-offset_to_eth, hdr->caplen-offset_to_eth))){
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
printf("Innermost layer ipv4 offset:%d, addr: %s\n", offset_to_eth, MESA_jump_layer_ipv4_ntop((struct ip *)ip4_hdr, print_buf, sizeof(print_buf)));
|
2021-09-14 15:50:53 +08:00
|
|
|
}
|
2021-10-26 18:41:54 +08:00
|
|
|
|
|
|
|
|
if(ip6_h){
|
|
|
|
|
offset_to_eth = (u_char *)ip6_h-data;
|
|
|
|
|
if(g_input_bpf_string
|
|
|
|
|
&& (0 == bpf_filter(g_bpf_filter.bf_insns, (const unsigned char *)ip6_h, hdr->caplen-offset_to_eth, hdr->caplen-offset_to_eth))){
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("Innermost layer ipv6 offset:%d, addr: %s\n", offset_to_eth, MESA_jump_layer_ipv6_ntop((struct ip6_hdr *)ip6_h, print_buf, sizeof(print_buf)));
|
2021-09-14 15:50:53 +08:00
|
|
|
}
|
2021-10-26 18:41:54 +08:00
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
|
|
|
|
|
printf("--------------------------------------------------------------------------------------\n\n");
|
2021-09-14 15:50:53 +08:00
|
|
|
|
2021-10-26 18:41:54 +08:00
|
|
|
}
|
2021-09-14 15:50:53 +08:00
|
|
|
|
2021-10-26 18:41:54 +08:00
|
|
|
static void _pcap_pkt_handle(u_char *user, const struct pcap_pkthdr *hdr, const u_char *data)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
_jump_from_ethernet(data);
|
|
|
|
|
|
|
|
|
|
_jump_greedy(hdr, data);
|
2021-09-14 15:50:53 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void pcap_run(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
pcap_loop(g_pcap_handle, -1, _pcap_pkt_handle, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
int ret, c, opt_index;
|
|
|
|
|
|
|
|
|
|
while(1){
|
|
|
|
|
c = getopt_long(argc, argv, "hr:f:", NULL, &opt_index);
|
|
|
|
|
if(c == -1){
|
|
|
|
|
ret = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(c){
|
|
|
|
|
case 'h':
|
|
|
|
|
usage(argv[0]);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'r':
|
|
|
|
|
g_input_pcap_name = strdup(optarg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'f':
|
|
|
|
|
g_input_bpf_string = strdup(optarg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(NULL == g_input_pcap_name){
|
|
|
|
|
printf("error! must set pcap file name use -r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(NULL == g_input_bpf_string){
|
|
|
|
|
printf("you can set BPF filter use -f\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(pcap_init() < 0){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pcap_run();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|