支持-g参数, 可以按最内层IP,PORT过滤, 支持BPF过滤规则.
This commit is contained in:
181
tcpdump.c
181
tcpdump.c
@@ -44,13 +44,15 @@
|
||||
#define MESA_DUMP (1)
|
||||
#if MESA_DUMP
|
||||
#include "mesa_pkt_dump.h"
|
||||
const int tcpdump_mesa_version_VERSION_20180119 = 20180119;
|
||||
const int tcpdump_mesa_version_VERSION_20181114 = 20181114;
|
||||
int tcpdump_data_offset = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ijЩ<C4B3>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD><EFBFBD>, <20><>vxlan, <20><><EFBFBD><EFBFBD>ֱ<EFBFBD>ӻ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vxlan<61><6E><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD> */
|
||||
unsigned char tcpdump_thread_index_array[64]; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>id<69><64><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><C8BE><EFBFBD>id<69><64><EFBFBD><EFBFBD>, ÿ<><C3BF>ռ1<D5BC>ֽ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֶ<EFBFBD><D6B6>ŷָ<C5B7> */
|
||||
int tcpdump_thread_index_array_num = 0;
|
||||
const char *tcpdump_thread_index_str;
|
||||
int tcpdump_perceptive_flag = 0;
|
||||
unsigned int perceptive_pkt_seq[256]; /* <20><><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>256<35><36><EFBFBD>߳<EFBFBD> */
|
||||
static int greedy_seek_flag = 0; /* ƫ<>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ڲ<EFBFBD>IP, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3>²<EFBFBD><C2B2><EFBFBD>BUG */
|
||||
static int dump_to_file_flag = 0; /* <20>Ƿ<EFBFBD><C7B7><EFBFBD>-w <20><><EFBFBD><EFBFBD> */
|
||||
#endif
|
||||
|
||||
#ifndef lint
|
||||
@@ -485,8 +487,8 @@ show_devices_and_exit (void)
|
||||
#define Q_FLAG
|
||||
#endif
|
||||
|
||||
#if MESA_DUMP /* lijia add, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>k, o, P */
|
||||
#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "k:KlLm:M:nNo:OP:pq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#"
|
||||
#if MESA_DUMP /* lijia add, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g, k, o, P */
|
||||
#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:gG:hHi:" I_FLAG j_FLAG J_FLAG "k:KlLm:M:nNo:OP:pq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#"
|
||||
#else
|
||||
#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#"
|
||||
#endif
|
||||
@@ -786,7 +788,85 @@ set_dumper_capsicum_rights(pcap_dumper_t *p)
|
||||
#endif
|
||||
|
||||
#if MESA_DUMP
|
||||
#include "mesa_net.h"
|
||||
#include "stream_base.h"
|
||||
static int MESA_dump_seek_to_inner(char *pkt_buf, int pktlen)
|
||||
{
|
||||
struct mesa_ethernet_hdr *ehdr = (struct mesa_ethernet_hdr *)pkt_buf;
|
||||
char *first_ip_layer = NULL;
|
||||
struct mesa_ip4_hdr *ip4hdr_greedy;
|
||||
struct mesa_ip6_hdr *ip6hdr_greedy;
|
||||
int bpf_match_pkt_len = -1;
|
||||
int bpf_match_ipv4 = 0, bpf_match_ipv6 = 0;
|
||||
|
||||
if(ETHERTYPE_IP == ntohs(ehdr->ether_type)){
|
||||
first_ip_layer = pkt_buf + sizeof(struct mesa_ethernet_hdr);
|
||||
}else if(ETHERTYPE_IPv6 == ntohs(ehdr->ether_type)){
|
||||
first_ip_layer = pkt_buf + sizeof(struct mesa_ethernet_hdr);
|
||||
}else{
|
||||
first_ip_layer = NULL;
|
||||
}
|
||||
|
||||
ip4hdr_greedy = (struct mesa_ip4_hdr *)MESA_net_jump_to_layer_greedy(pkt_buf, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4);
|
||||
if(ip4hdr_greedy){
|
||||
if((char *)ip4hdr_greedy == first_ip_layer){
|
||||
bpf_match_pkt_len = pktlen; /* <20><><EFBFBD>ڲ<EFBFBD><DAB2>͵<EFBFBD>һ<EFBFBD><D2BB>IPһ<50><D2BB>, ˵<><CBB5><EFBFBD>DZ<EFBFBD>ethernet->IPv4<76><34>, <20><><EFBFBD><EFBFBD>memmove<76><65><EFBFBD><EFBFBD> */
|
||||
}else{
|
||||
memmove(pkt_buf + sizeof(struct mesa_ethernet_hdr),
|
||||
ip4hdr_greedy,
|
||||
pktlen - ((char *)ip4hdr_greedy - pkt_buf));
|
||||
bpf_match_pkt_len = pktlen - ((char *)ip4hdr_greedy - pkt_buf) + sizeof(struct mesa_ethernet_hdr);
|
||||
ehdr->ether_type = htons(ETHERTYPE_IP); /* <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2><EFBFBD>IPV4, <20><><EFBFBD><EFBFBD>MPLS, VLAN<41><4E>, <20><>Ҫ<EFBFBD>ij<EFBFBD>IP, <20>Ա<EFBFBD>bpf<70><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷִ<C8B7><D6B4> */
|
||||
}
|
||||
|
||||
if(bpf_match_pkt_len <= 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ, <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ;
|
||||
<20><><EFBFBD><EFBFBD>û<EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>ģʽ, Ϊ<>˾<EFBFBD><CBBE><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>, <20><><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD>ְ<EFBFBD>.
|
||||
*/
|
||||
|
||||
bpf_match_ipv4 = 1;
|
||||
}else{
|
||||
bpf_match_ipv4 = 0;
|
||||
}
|
||||
|
||||
ip6hdr_greedy = (struct mesa_ip6_hdr *)MESA_net_jump_to_layer_greedy(pkt_buf, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6);
|
||||
if(ip6hdr_greedy){
|
||||
if((char *)ip6hdr_greedy == first_ip_layer){
|
||||
bpf_match_pkt_len = pktlen; /* <20><><EFBFBD>ڲ<EFBFBD><DAB2>͵<EFBFBD>һ<EFBFBD><D2BB>IPһ<50><D2BB>, ˵<><CBB5><EFBFBD>DZ<EFBFBD>ethernet->IPv6<76><36>, <20><><EFBFBD><EFBFBD>memmove<76><65><EFBFBD><EFBFBD> */
|
||||
}else{
|
||||
memmove(pkt_buf + sizeof(struct mesa_ethernet_hdr),
|
||||
ip6hdr_greedy,
|
||||
pktlen - ((char *)ip6hdr_greedy - pkt_buf));
|
||||
bpf_match_pkt_len = pktlen - ((char *)ip4hdr_greedy - pkt_buf) + sizeof(struct mesa_ethernet_hdr);
|
||||
ehdr->ether_type = htons(ETHERTYPE_IPv6); /* <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2><EFBFBD>IPV6, <20><><EFBFBD><EFBFBD>MPLS, VLAN<41><4E>,<2C><>Ҫ<EFBFBD>ij<EFBFBD>IP,<2C>Ա<EFBFBD>bpf<70><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷִ<C8B7><D6B4> */
|
||||
}
|
||||
|
||||
if(bpf_match_pkt_len <= 0){
|
||||
///sapp_runtime_log(20, "cycle_pkt_dump_seek_to_inner_ip() length error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ, <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ;
|
||||
<20><><EFBFBD><EFBFBD>û<EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>ģʽ, Ϊ<>˾<EFBFBD><CBBE><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>, <20><><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD>ְ<EFBFBD>.
|
||||
*/
|
||||
bpf_match_ipv6 = 1;
|
||||
}else{
|
||||
bpf_match_ipv6 = 0;
|
||||
}
|
||||
|
||||
if(bpf_match_ipv4 || bpf_match_ipv6){
|
||||
return bpf_match_pkt_len; /* <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* <20><>֧<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD>߳<EFBFBD>, <20>ö<EFBFBD><C3B6>ŷָ<C5B7>"1,3,5,7" */
|
||||
static int MESA_dump_thread_index_convert(const char *raw_index_str)
|
||||
{
|
||||
char *index_str = strdup(raw_index_str);
|
||||
@@ -878,6 +958,24 @@ static int pkt_dump_recv_ack(int connfd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <pthread.h>
|
||||
static void *detect_sapp_thread(void *arg)
|
||||
{
|
||||
int tcp_cmd_fd = (int)arg;
|
||||
int ret;
|
||||
char nouse_buf[1500];
|
||||
|
||||
while(1){
|
||||
ret = read(tcp_cmd_fd, nouse_buf, 1500);
|
||||
if(0 == ret){
|
||||
printf("\033[33m[INFO]sapp is not running, tcpdump_mesa exit!\033[0m\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_port, char *filter)
|
||||
{
|
||||
int tcp_cmd_fd = -1;
|
||||
@@ -887,6 +985,7 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
|
||||
struct pkt_dump_handshake pkt_hdr;
|
||||
unsigned int opt_num = 1; /* <20><><EFBFBD>˽<EFBFBD><CBBD>ն˿<D5B6>Ϊ<EFBFBD><CEAA>ѡ<EFBFBD><D1A1> */
|
||||
struct pkt_dump_opt opt;
|
||||
pthread_t pid;
|
||||
|
||||
tcp_cmd_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
@@ -923,7 +1022,7 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
|
||||
|
||||
/************** pkt handshake *************/
|
||||
pkt_hdr.magic = htonl(PKT_DUMP_HDR_MAGIC);
|
||||
pkt_hdr.version = htonl(tcpdump_mesa_version_VERSION_20180119);
|
||||
pkt_hdr.version = htonl(tcpdump_mesa_version_VERSION_20181114);
|
||||
pkt_hdr.opt_num = htonl(opt_num);
|
||||
ret = write(tcp_cmd_fd, &pkt_hdr, sizeof(pkt_hdr));
|
||||
if(ret < 0){
|
||||
@@ -1012,6 +1111,8 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_create(&pid, NULL, detect_sapp_thread, (void *)tcp_cmd_fd);
|
||||
|
||||
return tcp_cmd_fd;
|
||||
}
|
||||
|
||||
@@ -1066,7 +1167,7 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter
|
||||
int tot_pkt, unsigned short sapp_cmd_port )
|
||||
{
|
||||
unsigned short udp_default_port = 12345;
|
||||
int opt, pkt_len;
|
||||
int opt, pkt_len, inner_pkt_len;
|
||||
unsigned char pkt_buf[65536];
|
||||
struct pcap_pkthdr phony_pcap_hdr;
|
||||
int udp_rcv_fd = -1;
|
||||
@@ -1119,10 +1220,24 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter
|
||||
}
|
||||
perceptive_pkt_seq[pperceptive->thread_id] = cur_pkt_seq;
|
||||
}
|
||||
phony_pcap_hdr.caplen = pkt_len;
|
||||
phony_pcap_hdr.len = pkt_len;
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-g<><67><EFBFBD><EFBFBD>, <20><>д<EFBFBD><D0B4>-w, <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>, <20><EFBFBD><F2B2BBBD><EFBFBD>seek<65><6B><EFBFBD><EFBFBD>,
|
||||
ֻ<><D6BB><EFBFBD><EFBFBD>û<EFBFBD><C3BB>-w <20><><EFBFBD><EFBFBD>ʱ, <20><>tcpdump<6D>ܴ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ, <20>Ž<EFBFBD><C5BD><EFBFBD>seek<65><6B><EFBFBD><EFBFBD>.
|
||||
*/
|
||||
if((greedy_seek_flag != 0) && (dump_to_file_flag == 0)){
|
||||
inner_pkt_len = MESA_dump_seek_to_inner(pkt_buf, pkt_len);
|
||||
if(inner_pkt_len < 0){
|
||||
continue;
|
||||
}
|
||||
phony_pcap_hdr.caplen = inner_pkt_len;
|
||||
phony_pcap_hdr.len = inner_pkt_len;
|
||||
}else{
|
||||
phony_pcap_hdr.caplen = pkt_len;
|
||||
phony_pcap_hdr.len = pkt_len;
|
||||
}
|
||||
gettimeofday(&phony_pcap_hdr.ts, NULL);
|
||||
callback(pcap_userdata, &phony_pcap_hdr, pkt_buf); /* ˢ<><CBA2>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>print_packet(); <20><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>: dump_packet() */
|
||||
|
||||
callback(pcap_userdata, &phony_pcap_hdr, pkt_buf); /* NOTE: ˢ<><CBA2>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>print_packet(); <20><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>: dump_packet() */
|
||||
actual_rcv_pkt_num++;
|
||||
}
|
||||
}
|
||||
@@ -1302,6 +1417,13 @@ main(int argc, char **argv)
|
||||
case 'F':
|
||||
infile = optarg;
|
||||
break;
|
||||
|
||||
#if MESA_DUMP
|
||||
case 'g':
|
||||
greedy_seek_flag = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case 'G':
|
||||
Gflag = atoi(optarg);
|
||||
@@ -1385,6 +1507,21 @@ main(int argc, char **argv)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if MESA_DUMP
|
||||
case 'k':
|
||||
tcpdump_thread_index_str = optarg;
|
||||
if(MESA_dump_thread_index_convert(tcpdump_thread_index_str) < 0){
|
||||
printf("thread index invalid: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'K':
|
||||
++ndo->ndo_Kflag;
|
||||
break;
|
||||
|
||||
|
||||
case 'l':
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
@@ -1409,20 +1546,6 @@ main(int argc, char **argv)
|
||||
case 'L':
|
||||
Lflag++;
|
||||
break;
|
||||
|
||||
#if MESA_DUMP
|
||||
case 'k':
|
||||
tcpdump_thread_index_str = optarg;
|
||||
if(MESA_dump_thread_index_convert(tcpdump_thread_index_str) < 0){
|
||||
printf("thread index invalid: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'K':
|
||||
++ndo->ndo_Kflag;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
#ifdef USE_LIBSMI
|
||||
@@ -1503,7 +1626,12 @@ main(int argc, char **argv)
|
||||
#endif /* HAVE_PCAP_SETDIRECTION */
|
||||
|
||||
case 'r':
|
||||
#if MESA_DUMP
|
||||
printf("tcpdump_mesa not support -r arg, only support capture from sapp so far, TODO!\n");
|
||||
exit(1);
|
||||
#else
|
||||
RFileName = optarg;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 's':
|
||||
@@ -1582,6 +1710,9 @@ main(int argc, char **argv)
|
||||
|
||||
case 'w':
|
||||
WFileName = optarg;
|
||||
#if MESA_DUMP
|
||||
dump_to_file_flag = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
@@ -2863,9 +2994,11 @@ print_usage(void)
|
||||
(void)fprintf(stderr,
|
||||
"----------------------------------------------------------------------------------------------.\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t\tThe follow args is customized for tcpdump_mesa:\n");
|
||||
"\t\tThe follow args is customized for tcpdump_mesa(%d):\n", tcpdump_mesa_version_VERSION_20181114);
|
||||
(void)fprintf(stderr,
|
||||
"\t\t[ -a ] to enable perceptive mode, can detect loss packet number.\n");
|
||||
"\t\t[ -a ] enable perceptive mode, can detect loss packet number.\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t\t[ -g greedy-seek ] enable greedy seek to most inner IP layer, for tunnel, embed protocol.\n");
|
||||
(void)fprintf(stderr,
|
||||
"\t\t[ -k thread-id ] to assign sapp recv thread id, support multi-range, for example: 1,3,5,7.\n");
|
||||
(void)fprintf(stderr,
|
||||
|
||||
Reference in New Issue
Block a user