From b7855c8c34260943c1ace67b19243288cbab8732 Mon Sep 17 00:00:00 2001 From: dongwenze Date: Tue, 18 Apr 2023 11:11:30 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=E6=9B=B4=E6=8D=A2=E9=80=9A=E8=BF=87pca?= =?UTF-8?q?p=E7=94=9F=E6=88=90=E8=BF=87=E6=BB=A4=E5=99=A8=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- depend/third_libs.cmake | 2 + srcs/service/dhcpd/dhcpd_network.c | 54 ++++++---- srcs/service/dhcpd/include/packet_filter.h | 15 --- srcs/service/dhcpd/packet_filter.c | 111 --------------------- 4 files changed, 35 insertions(+), 147 deletions(-) delete mode 100644 srcs/service/dhcpd/include/packet_filter.h delete mode 100644 srcs/service/dhcpd/packet_filter.c diff --git a/depend/third_libs.cmake b/depend/third_libs.cmake index 2ad7b2a..d856f87 100644 --- a/depend/third_libs.cmake +++ b/depend/third_libs.cmake @@ -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") diff --git a/srcs/service/dhcpd/dhcpd_network.c b/srcs/service/dhcpd/dhcpd_network.c index e6f7c61..1e5c21e 100644 --- a/srcs/service/dhcpd/dhcpd_network.c +++ b/srcs/service/dhcpd/dhcpd_network.c @@ -10,6 +10,7 @@ #include #include #include +#include #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,16 +212,12 @@ 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 PACKET_MMAP_RING g_pkgRing; -static NIC_INFO g_nicInfo; -static uv_udp_t g_uvRawSockReq; +static struct sock_fprog bpf; +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; @@ -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) { diff --git a/srcs/service/dhcpd/include/packet_filter.h b/srcs/service/dhcpd/include/packet_filter.h deleted file mode 100644 index f4cfb83..0000000 --- a/srcs/service/dhcpd/include/packet_filter.h +++ /dev/null @@ -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 diff --git a/srcs/service/dhcpd/packet_filter.c b/srcs/service/dhcpd/packet_filter.c deleted file mode 100644 index 3060be9..0000000 --- a/srcs/service/dhcpd/packet_filter.c +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by dongwenzhe on 2023/4/14. -// -#include -#include -#include -#include -#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; -} -