From 24ea2e2525d90f2e775a79d0d07cd2fcec9d39f9 Mon Sep 17 00:00:00 2001 From: dongwenze Date: Fri, 14 Apr 2023 16:34:42 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=E5=A2=9E=E5=8A=A0cmd=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- srcs/service/dhcpd/dhcpd_network.c | 31 ++++-- srcs/service/dhcpd/include/packet_filter.h | 15 +++ srcs/service/dhcpd/packet_filter.c | 111 +++++++++++++++++++++ 3 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 srcs/service/dhcpd/include/packet_filter.h create mode 100644 srcs/service/dhcpd/packet_filter.c diff --git a/srcs/service/dhcpd/dhcpd_network.c b/srcs/service/dhcpd/dhcpd_network.c index c9dc1ef..e6f7c61 100644 --- a/srcs/service/dhcpd/dhcpd_network.c +++ b/srcs/service/dhcpd/dhcpd_network.c @@ -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); diff --git a/srcs/service/dhcpd/include/packet_filter.h b/srcs/service/dhcpd/include/packet_filter.h new file mode 100644 index 0000000..f4cfb83 --- /dev/null +++ b/srcs/service/dhcpd/include/packet_filter.h @@ -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 diff --git a/srcs/service/dhcpd/packet_filter.c b/srcs/service/dhcpd/packet_filter.c new file mode 100644 index 0000000..3060be9 --- /dev/null +++ b/srcs/service/dhcpd/packet_filter.c @@ -0,0 +1,111 @@ +// +// 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; +} +