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

View File

@ -10,6 +10,7 @@
#include <net/if.h> #include <net/if.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <pcap/pcap.h>
#include "service/dhcpd.h" #include "service/dhcpd.h"
#include "user_errno.h" #include "user_errno.h"
@ -28,6 +29,7 @@
#define MAX_DHCP_PKG_SIZE (512) #define MAX_DHCP_PKG_SIZE (512)
#define VLAN_VNI_ID(x) ntohs((x)) #define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x)) #define DHCP_XID(x) ntohl((x))
#define MAXIMUM_SNAPLEN (262144)
#define MAC_TO_STR(mac, str) \ #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]) 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 messages) originating within their racks to anycast VIPs, one DHCPv4 and one
for DHCPv6. 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 #ifdef USED_DEFAULT_BPF
static struct sock_filter g_filterCode[] = { static struct sock_filter g_filterCode[] = {
@ -216,13 +212,9 @@ static struct sock_filter g_filterCode[] = {
{0x6, 0, 0, 0x00000000}, {0x6, 0, 0, 0x00000000},
// endregion // endregion
}; };
static struct sock_fprog bpf = {
.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)),
.filter = g_filterCode,
};
#endif #endif
static struct sock_fprog bpf;
static PACKET_MMAP_RING g_pkgRing; static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo; static NIC_INFO g_nicInfo;
static uv_udp_t g_uvRawSockReq; 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() { int dhcpd_init() {
static uv_poll_t uvSocket; static uv_poll_t uvSocket;
static uv_timer_t uvTm; 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); get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr);
#ifndef USED_DEFAULT_BPF init_filter();
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(); ret = create_udp_socket();
if (ret != ERR_SUCCESS) { 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;
}