#ifdef __cplusplus extern "C" { #endif #include #include #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; static int g_raw_input_layer_type = (int )ADDR_TYPE_MAC; static int g_expect_layer_type = (int )ADDR_TYPE_IPV4; 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; } 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) { const void *ip4_hdr, *ip6_h; char print_buf[128]; int offset_to_eth; static int pkt_index = 0; 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); 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))); } 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))); } done: printf("--------------------------------------------------------------------------------------\n\n"); } 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); } 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