🎈perf(tcpdump.c):
优化greedy模式,放弃使用MESA_dump_seek_to_inner拷贝并构造虚拟的MAC头,使用pcap_compile_nopcap构造DLT_RAW类型的bpf,并调用MESA_net_jump_to_layer_greedy找到最内层IP地址直接使用cbpf进行匹配
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ version.c
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
tcpdump_mesa
|
||||
|
||||
91
tcpdump.c
91
tcpdump.c
@@ -986,7 +986,7 @@ static int pkt_dump_recv_ack(int connfd)
|
||||
*/
|
||||
static void *detect_sapp_alive_thread(void *arg)
|
||||
{
|
||||
int tcp_cmd_fd = (int)arg;
|
||||
int tcp_cmd_fd = (int)(long)arg;
|
||||
int ret;
|
||||
char nouse_buf[1500];
|
||||
|
||||
@@ -1156,7 +1156,7 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_create(&pid, NULL, detect_sapp_alive_thread, (void *)tcp_cmd_fd);
|
||||
pthread_create(&pid, NULL, detect_sapp_alive_thread, (void *)(long)tcp_cmd_fd);
|
||||
|
||||
return tcp_cmd_fd;
|
||||
}
|
||||
@@ -1272,6 +1272,7 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter
|
||||
/* 如果有-g参数, 且写了-w, 即需要保存原始包到文件, 则不进行seek操作,
|
||||
只是在没有-w 参数时, 让tcpdump能打印出包的信息, 才进行seek操作.
|
||||
*/
|
||||
#if 0
|
||||
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){
|
||||
@@ -1283,6 +1284,10 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter
|
||||
phony_pcap_hdr.caplen = pkt_len;
|
||||
phony_pcap_hdr.len = pkt_len;
|
||||
}
|
||||
#else
|
||||
phony_pcap_hdr.caplen = pkt_len;
|
||||
phony_pcap_hdr.len = pkt_len;
|
||||
#endif
|
||||
gettimeofday(&phony_pcap_hdr.ts, NULL);
|
||||
|
||||
callback(pcap_userdata, &phony_pcap_hdr, pkt_buf); /* NOTE: 刷屏模式调用print_packet(); 捕包模式调用: dump_packet() */
|
||||
@@ -1305,7 +1310,6 @@ done:
|
||||
#endif
|
||||
|
||||
static struct bpf_program fcode; /* lijia modify, 做为全局变量, 其他函数中调用 */
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -2274,6 +2278,15 @@ main(int argc, char **argv)
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
}
|
||||
else
|
||||
{
|
||||
pcap_freecode(&fcode);
|
||||
if(pcap_compile_nopcap(Oflag, DLT_RAW, &fcode, cmdbuf, 0, netmask) < 0){
|
||||
printf("Compile pcap filter %s error\n", cmdbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
@@ -2948,20 +2961,45 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
static void
|
||||
MESA_dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *raw_pkt)
|
||||
{
|
||||
char modify_pkt_buf[2048];
|
||||
//char modify_pkt_buf[2048];
|
||||
int inner_pkt_len;
|
||||
|
||||
++packets_captured;
|
||||
++infodelay;
|
||||
|
||||
memcpy(modify_pkt_buf, raw_pkt, h->caplen >= 2048? 2048:h->caplen);
|
||||
inner_pkt_len = MESA_dump_seek_to_inner(modify_pkt_buf, h->caplen);
|
||||
if(inner_pkt_len < 0){
|
||||
return;
|
||||
//memcpy(modify_pkt_buf, raw_pkt, h->caplen >= 2048? 2048:h->caplen);
|
||||
//inner_pkt_len = MESA_dump_seek_to_inner(modify_pkt_buf, h->caplen);
|
||||
//if(inner_pkt_len < 0){
|
||||
// return;
|
||||
//}
|
||||
struct mesa_ip4_hdr *ip4hdr_greedy;
|
||||
struct mesa_ip6_hdr *ip6hdr_greedy;
|
||||
const unsigned char *inner_iphdr = NULL;
|
||||
ip4hdr_greedy = (struct mesa_ip4_hdr *)MESA_net_jump_to_layer_greedy(raw_pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4);
|
||||
if(ip4hdr_greedy)
|
||||
{
|
||||
inner_iphdr = (const unsigned char *)ip4hdr_greedy;
|
||||
inner_pkt_len = h->caplen - ((const u_char *)ip4hdr_greedy - raw_pkt) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip6hdr_greedy = (struct mesa_ip6_hdr *)MESA_net_jump_to_layer_greedy(raw_pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6);
|
||||
if(ip6hdr_greedy)
|
||||
{
|
||||
inner_iphdr = (const unsigned char *)ip6hdr_greedy;
|
||||
inner_pkt_len = h->caplen - ((const u_char *)ip6hdr_greedy - raw_pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(has_bpf_filter_flag != 0){
|
||||
if(0 == bpf_filter(fcode.bf_insns,
|
||||
(const unsigned char *)modify_pkt_buf, inner_pkt_len, inner_pkt_len)){
|
||||
(const unsigned char *)inner_iphdr, inner_pkt_len, inner_pkt_len)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2999,6 +3037,7 @@ MESA_dump_print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *
|
||||
{
|
||||
int inner_pkt_len;
|
||||
|
||||
#if 0
|
||||
/* 此函数仅用于tcpdump屏幕打印, 直接修改pkt原始包, 避免再copy一次, 节约点CPU */
|
||||
inner_pkt_len = MESA_dump_seek_to_inner(pkt, h->caplen);
|
||||
if(inner_pkt_len < 0){
|
||||
@@ -3015,7 +3054,41 @@ MESA_dump_print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *
|
||||
/* 改为新的修改后的数据包长度 */
|
||||
((struct pcap_pkthdr *)h)->caplen = (unsigned int)inner_pkt_len;
|
||||
((struct pcap_pkthdr *)h)->len = (unsigned int)inner_pkt_len;
|
||||
#else
|
||||
struct mesa_ip4_hdr *ip4hdr_greedy;
|
||||
struct mesa_ip6_hdr *ip6hdr_greedy;
|
||||
const unsigned char *inner_iphdr = NULL;
|
||||
ip4hdr_greedy = (struct mesa_ip4_hdr *)MESA_net_jump_to_layer_greedy(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4);
|
||||
if(ip4hdr_greedy)
|
||||
{
|
||||
inner_iphdr = (const unsigned char *)ip4hdr_greedy;
|
||||
inner_pkt_len = h->caplen - ((const unsigned char *)ip4hdr_greedy - pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip6hdr_greedy = (struct mesa_ip6_hdr *)MESA_net_jump_to_layer_greedy(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6);
|
||||
if(ip6hdr_greedy)
|
||||
{
|
||||
inner_iphdr = (const unsigned char *)ip6hdr_greedy;
|
||||
inner_pkt_len = h->caplen - ((const unsigned char *)ip6hdr_greedy - pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (has_bpf_filter_flag != 0)
|
||||
{
|
||||
if (0 == bpf_filter(fcode.bf_insns,
|
||||
(const unsigned char *)inner_iphdr, inner_pkt_len, inner_pkt_len))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
print_packet(user, h, pkt);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user