feat(tcpdump.c): 新增classify过滤参数

--classify in|forward|inject|drop|error
--enable_classify_watermark  record classify type in src mac address
This commit is contained in:
yangwei
2020-11-03 10:13:32 +08:00
parent 0c5a950d71
commit 8fdcb9ac35
2 changed files with 150 additions and 46 deletions

View File

@@ -55,6 +55,8 @@ static int dump_to_file_flag = 0; /* 是否有-w 参数, 原有标准的WFileNam
static int has_device_flag = 0; /* 是否有-i, -r参数, 原有标准的device变量是main()的局部变量, 不方便使用, 使用此变量表示是否从某个网卡捕包 */
static int has_bpf_filter_flag = 0; /* 是否有正确的BPF过滤条件 */
extern int treat_vlan_as_mac_in_mac_sw;
static short pkt_classify_flag = 0;
static char pkt_classify_watermark_sw = 0;
#endif
@@ -532,6 +534,8 @@ show_devices_and_exit (void)
#if MESA_DUMP
#define OPTION_VLAN_AS_MAC_IN_MAC 131 /* 短参数不够用了, 增加长参数 */
#define OPTION_PKT_CLASSIFY 132 /* 增加长参数包类型定义见PKT_DUMP_OPT_CLASSIFY */
#define OPTION_PKT_CLASSIFY_WATERMARK 133 /* PKT_DUMP_OPT_CLASSIFY_WATERMARK */
#endif
static const struct option longopts[] = {
@@ -575,6 +579,8 @@ static const struct option longopts[] = {
{ "version", no_argument, NULL, OPTION_VERSION },
#if MESA_DUMP
{ "vlan-as-mac-in-mac", no_argument, NULL, OPTION_VLAN_AS_MAC_IN_MAC },
{ "classify", required_argument, NULL, OPTION_PKT_CLASSIFY },
{ "enable_classify_watermark", no_argument, NULL, OPTION_PKT_CLASSIFY_WATERMARK },
#endif
{ NULL, 0, NULL, 0 }
};
@@ -1058,6 +1064,16 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
opt_num++;
}
if(pkt_classify_flag != 0)
{
opt_num++;
}
if(pkt_classify_watermark_sw != 0)
{
opt_num++;
}
/************** pkt handshake *************/
pkt_hdr.magic = htonl(PKT_DUMP_HDR_MAGIC);
pkt_hdr.version = htonl(20180119); /* 之前sapp对20180119版本做了严格校验, 此处向后兼容, 先固定用此值, 以后更新sapp后, 不再校验版本 */
@@ -1155,6 +1171,36 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_
}
}
/************** pkt classify *************/
if(pkt_classify_flag != 0){
short t = pkt_classify_flag;
opt.opt_type = htons(PKT_DUMP_OPT_CLASSIFY);
opt.opt_len = htons(sizeof(short));
ret = write(tcp_cmd_fd, &opt, sizeof(opt));
if (ret < 0)
{
printf("connection down!\n");
exit(1);
}
t = htons(t);
ret = write(tcp_cmd_fd, &t, sizeof(short));
if (ret < 0)
{
printf("connection down!\n");
exit(1);
}
}
/************** pkt classify watermark*************/
if(pkt_classify_watermark_sw != 0){
opt.opt_type = htons(PKT_DUMP_OPT_CLASSIFY_WATERMARK);
opt.opt_len = 0;
ret = write(tcp_cmd_fd, &opt, sizeof(opt));
if(ret < 0){
printf("connection down!\n");
exit(1);
}
}
/********** after send opt, start recv sapp ACK *******/
if(pkt_dump_recv_ack(tcp_cmd_fd) < 0){
printf("connection down!\n");
@@ -1312,6 +1358,42 @@ done:
return;
}
static short get_pkt_classify_optarg(const char *optarg)
{
char *p_arg = strdup(optarg);
short pkt_classify_flag = 0;
char *section, *save_ptr;
section = strtok_r(p_arg, "|", &save_ptr);
if(section == NULL)
{
section = p_arg;
}
do {
if (strcasecmp(section, "in") == 0)
pkt_classify_flag |= PKT_CLASSIFY_IN;
else if (strcasecmp(section, "forward") == 0)
pkt_classify_flag |= PKT_CLASSIFY_FORWARD;
else if (strcasecmp(section, "inject") == 0)
pkt_classify_flag |= PKT_CLASSIFY_INJECT;
else if (strcasecmp(section, "drop") == 0)
pkt_classify_flag |= PKT_CLASSIFY_DROP;
else if (strcasecmp(section, "error") == 0)
pkt_classify_flag |= PKT_CLASSIFY_ERROR;
else
{
return 0;
}
}
while((section=strtok_r(NULL, "|", &save_ptr)));
free(p_arg);
return pkt_classify_flag;
}
#endif
static struct bpf_program fcode; /* lijia modify, 做为全局变量, 其他函数中调用 */
@@ -1845,6 +1927,16 @@ main(int argc, char **argv)
case OPTION_VLAN_AS_MAC_IN_MAC:
treat_vlan_as_mac_in_mac_sw = 1;
break;
case OPTION_PKT_CLASSIFY:
pkt_classify_flag = get_pkt_classify_optarg(optarg);
if(pkt_classify_flag == 0)
{
error("unknown classify `%s', must be in|forward|inject|drop|error", optarg);
}
break;
case OPTION_PKT_CLASSIFY_WATERMARK:
pkt_classify_watermark_sw = 1;
break;
#endif
default:
@@ -3243,6 +3335,10 @@ print_usage(void)
"\t\t[ -P port ] to assign sapp recv command port.\n");
(void)fprintf(stderr,
"\t\t[ --vlan-as-mac-in-mac ] force VLAN to be analysed as MAC-IN-MAC format.\n");
(void)fprintf(stderr,
"\t\t[ --classify in|forward|inject|drop|error ]. specify packet capture classifier by direction and operation\n");
(void)fprintf(stderr,
"\t\t[ --enable_classify_watermark ]. enable record classify type in src mac address\n");
#endif
}
/*