OCT 1.更换通过pcap生成过滤器方式

This commit is contained in:
dongwenze 2023-04-18 11:11:30 +08:00
parent 24ea2e2525
commit b7855c8c34
4 changed files with 35 additions and 147 deletions

View File

@ -4,6 +4,7 @@ INCLUDE(FetchContent)
PKG_SEARCH_MODULE(LIBCURL REQUIRED libcurl)
PKG_SEARCH_MODULE(LIBSSL REQUIRED libssl)
PKG_SEARCH_MODULE(LIBCRYPTO REQUIRED libcrypto)
PKG_SEARCH_MODULE(LIBPCAP REQUIRED libpcap)
IF (USED_SQLITE AND (NOT USED_SQLITE_CRYPTO))
PKG_SEARCH_MODULE(LIBSQLITE3 REQUIRED sqlite3)
@ -20,6 +21,7 @@ IF ((NOT LIBCRYPTO_FOUND) OR (NOT LIBSSL_FOUND) OR (NOT LIBCURL_FOUND))
ENDIF ()
LIST(APPEND COMMON_LIBS "${LIBCURL_LDFLAGS} ${LIBSSL_LDFLAGS} ${LIBCRYPTO_LDFLAGS} ${LIBSQLITE3_LDFLAGS}")
LIST(APPEND COMMON_LIBS "${LIBPCAP_LDFLAGS}")
LIST(APPEND COMMON_LIBS "${LIBZMQ_LDFLAGS}")
LIST(APPEND COMMON_LIBS "-lm -lpthread")

View File

@ -10,6 +10,7 @@
#include <net/if.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <pcap/pcap.h>
#include "service/dhcpd.h"
#include "user_errno.h"
@ -28,6 +29,7 @@
#define MAX_DHCP_PKG_SIZE (512)
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
#define MAXIMUM_SNAPLEN (262144)
#define MAC_TO_STR(mac, str) \
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])
@ -96,12 +98,6 @@ 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[] = {
@ -216,13 +212,9 @@ static struct sock_filter g_filterCode[] = {
{0x6, 0, 0, 0x00000000},
// endregion
};
static struct sock_fprog bpf = {
.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)),
.filter = g_filterCode,
};
#endif
static struct sock_fprog bpf;
static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq;
@ -696,6 +688,32 @@ static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
}
}
void init_filter() {
#ifdef USED_DEFAULT_BPF
bpf.len = sizeof(g_filterCode) / (sizeof(struct sock_filter));
bpf.filter = g_filterCode;
#else
static pcap_t *pd;
pd = pcap_open_dead(DLT_EN10MB, MAXIMUM_SNAPLEN);
struct bpf_program fcode;
char *cmd_buf = "vlan and udp and port 67 and port 68";
pcap_compile(pd, &fcode, cmd_buf, 1, 0);
struct bpf_insn *insn = fcode.bf_insns;
struct sock_filter *g_filters = (struct sock_filter *)malloc(fcode.bf_len * sizeof (struct sock_filter));
for (int i = 0; i < fcode.bf_len; ++insn, ++i){
g_filters[i].code = insn->code;
g_filters[i].jt = insn->jt;
g_filters[i].jf = insn->jf;
g_filters[i].k = insn->k;
}
bpf.len = fcode.bf_len;
bpf.filter = g_filters;
#endif
}
int dhcpd_init() {
static uv_poll_t uvSocket;
static uv_timer_t uvTm;
@ -708,13 +726,7 @@ 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
init_filter();
ret = create_udp_socket();
if (ret != ERR_SUCCESS) {

View File

@ -1,15 +0,0 @@
//
// 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

@ -1,111 +0,0 @@
//
// 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;
}