OCT 1.增加cmd命令自动生成过滤器方式

This commit is contained in:
dongwenze 2023-04-14 16:34:42 +08:00
parent 063157c199
commit 24ea2e2525
3 changed files with 150 additions and 7 deletions

View File

@ -96,6 +96,14 @@ responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
messages) originating within their racks to anycast VIPs, one DHCPv4 and one
for DHCPv6.
*/
#define USED_DEFAULT_BPF (1)
#ifndef USED_DEFAULT_BPF
#include "packet_filter.h"
extern struct sock_fprog bpf;
#endif
#ifdef USED_DEFAULT_BPF
static struct sock_filter g_filterCode[] = {
#ifdef UDP_DHCP_FILTER
// create by: tcpdump "udp and port 67 and port 68" -dd
@ -209,14 +217,15 @@ static struct sock_filter g_filterCode[] = {
// endregion
};
static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawScokReq;
static struct sock_fprog bpf = {
.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)),
.filter = g_filterCode,
};
#endif
static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq;
U32 pkg_mmap_tx(U8 *pData, U32 nBytes) {
int i;
@ -680,7 +689,7 @@ static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
ssize_t ret = sendto(g_pkgRing.sock, NULL, 0, MSG_DONTWAIT, NULL, sizeof(struct sockaddr_ll));
if (ret == -1) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send pakcet error\n");
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send packet error\n");
}
break;
}
@ -699,6 +708,14 @@ int dhcpd_init() {
get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr);
#ifndef USED_DEFAULT_BPF
ret = init_filter();
if(ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create packet filter Error\n");
return ret;
}
#endif
ret = create_udp_socket();
if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error\n");
@ -709,8 +726,8 @@ int dhcpd_init() {
dhcp_option_cfg_init();
dhcp_lease_init();
uv_udp_init(get_task_manager(), &g_uvRawScokReq);
uv_udp_open(&g_uvRawScokReq, g_pkgRing.sock);
uv_udp_init(get_task_manager(), &g_uvRawSockReq);
uv_udp_open(&g_uvRawSockReq, g_pkgRing.sock);
uv_poll_init_socket(get_task_manager(), &uvSocket, g_pkgRing.sock);
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);

View File

@ -0,0 +1,15 @@
//
// Created by dongwenzhe on 2023/4/14.
//
#ifndef VCPE_PACKET_FILTER_H
#define VCPE_PACKET_FILTER_H
typedef enum {
CODE_VAL = 0,
JT_VAL,
JF_VAL,
} FILTER_PARAM;
int init_filter();
#endif //VCPE_PACKET_FILTER_H

View File

@ -0,0 +1,111 @@
//
// Created by dongwenzhe on 2023/4/14.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/filter.h>
#include "common.h"
#include "packet_filter.h"
#include "user_errno.h"
const char *cmd_get_filter = "tcpdump \"vlan and udp and port 67 and port 68\" -dd";
int filter_num = 0;
struct sock_fprog bpf;
struct sock_filter g_filterCode[256];
int tolower(int c) {
if (c >= 'A' && c <= 'Z') {
return (c + 'a' - 'A');
} else {
return c;
}
}
int hex_to_int(char s[]) {
int i = 0;
int n = 0;
while(s[i] == ' ') {
i++;
}
if (s[i] == '0' && (s[i+1]=='x'||s[i+1]=='X')){
i = i + 2;
}
for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z');++i)
{
if (tolower(s[i]) > '9') {
n = 16*n + (10 + tolower(s[i]) - 'a');
} else {
n = 16*n + (tolower(s[i]) - '0');
}
}
return n;
}
int init_filter() {
FILE *pFile = NULL;
unsigned int rdSize = 0;
char *pOut;
pFile = popen(cmd_get_filter, "r");
if (pFile == NULL) {
return ERR_OPEN_FILE;
}
pOut = (char *)malloc(4096);
rdSize = fread(pOut, sizeof(char), 4096, pFile);
if(rdSize <= 0) {
return ERR_READ_FILE;
}
for(int i = 0; i < strlen(pOut); i++) {
// read a new array
if (pOut[i] == '{') {
__u16 code;
__u8 jt, jf;
__u32 k;
int val_flag = 0;
i++;
// end of the array
while (pOut[i] != '}') {
char t_val[256];
int j = 0;
// read the value in array
while (pOut[i] != ',' && pOut[i] != '}') {
t_val[j] = pOut[i];
i++;
j++;
}
// whether the read is a valid string
if(j != 0){
t_val[j] = '\0';
//printf("%s\n", t_val);
// write in socket_filter
if (val_flag == CODE_VAL) {
g_filterCode[filter_num].code = (__u16)hex_to_int(t_val);
} else if (val_flag == JT_VAL) {
g_filterCode[filter_num].jt = (__u8)atoi(t_val);
} else if (val_flag == JF_VAL) {
g_filterCode[filter_num].jf = (__u8)atoi(t_val);
} else {
g_filterCode[filter_num].k = (__u32)hex_to_int(t_val);
}
val_flag = (val_flag + 1)%4;
} else {
i++;
}
}
filter_num++;
}
}
bpf.len = filter_num;
bpf.filter = g_filterCode;
free(pOut);
pclose(pFile);
return ERR_SUCCESS;
}