Merge branch 'libuv_dhcpd_dev' of http://git.komect.net/ZNJK/vcpe into v1.2.0_dev

This commit is contained in:
dongwenze 2023-04-11 17:37:56 +08:00
commit 063157c199
7 changed files with 285 additions and 91 deletions

View File

@ -72,7 +72,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 140
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true

View File

@ -42,6 +42,8 @@ int process_lock_pidfile(char *pFilePath);
void process_unlock_pidfile();
int get_all_network_info(PSYS_NIC_INFO pInfo);
const char *u32_to_str_ip(unsigned int ip);
unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp);
unsigned short ip_checksum(unsigned char *pIp);
#ifdef __cplusplus
}
#endif

View File

@ -70,6 +70,7 @@ extern "C" {
ERR_CODE(ERR_DHCP_NO_POOL, "找不到可用地址池") \
ERR_CODE(ERR_DHCP_NO_ADDR, "找不到可用IP地址") \
ERR_CODE(ERR_SOCK_CREATE, "创建套接字失败") \
ERR_CODE(ERR_SOCK_SEND, "套接字发送数据失败") \
ERR_CODE(ERR_SOCK_SETOPT, "设置套接字参数失败")
#define GENERATE_ENUM(ENUM, x) ENUM,

View File

@ -11,12 +11,13 @@
#include <sys/ioctl.h>
#include <linux/if_ether.h>
#include <sys/time.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
#include "user_errno.h"
#include "misc.h"
#include "zlog_module.h"
#include "common.h"
#include "uthash/uthash.h"
PSYS_NIC_INFO g_sysNicInfo = NULL;
@ -365,3 +366,53 @@ const char *get_cur_process_name() {
return basename_v2(g_exeName);
}
unsigned short calc_checksum(unsigned short *buffer, int size, U32 sum) {
unsigned long cksum = ((sum & 0xFFFF0000) >> 16) + (sum & 0xFFFF);
while (size > 1) {
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size) {
cksum += *(unsigned short *)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return cksum;
//return (unsigned short)(~cksum);
}
unsigned short ip_checksum(unsigned char *pIp) {
unsigned int csum;
struct iphdr *pIph = (struct iphdr *)pIp;
pIph->check = 0;
csum = calc_checksum((unsigned short *)pIp, 20, 0);
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
return (unsigned short)(~csum);
}
unsigned short udp_checksum(unsigned int saddr, unsigned int daddr, unsigned char *pUdp) {
unsigned char padBuf[12];
unsigned int csum;
struct udphdr *pUhd = (struct udphdr *)pUdp;
memcpy(&padBuf[0], &saddr, 4);
memcpy(&padBuf[4], &daddr, 4);
padBuf[8] = 0;
padBuf[9] = 17;
padBuf[10] = pUdp[4];
padBuf[11] = pUdp[5];
pUhd->check = 0;
csum = calc_checksum((unsigned short *)pUdp, ntohs(pUhd->len), 0);
csum = calc_checksum((unsigned short *)padBuf, 12, csum);
csum = ((csum & 0xFFFF0000) >> 16) + (csum & 0xFFFF);
return (unsigned short)(~csum);
}

View File

@ -141,22 +141,39 @@ void dhcp_option_cfg_init() {
}
}
void dhcp_add_number_option(U8 *pBegin, int opt, U8 value, U8 nSize) {
int dhcp_add_u8_option(U8 *pBegin, int opt, U8 value) {
*pBegin = opt;
pBegin++;
*pBegin = nSize;
*pBegin = 1;
pBegin++;
memcpy(pBegin, &value, nSize);
pBegin += nSize;
*pBegin = value;
return 3;
}
void dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize) {
int dhcp_add_u32_option(U8 *pBegin, int opt, U32 value) {
*pBegin = opt;
pBegin++;
*pBegin = 4;
pBegin++;
memcpy(pBegin, &value, 4);
return 4 + 2;
}
int dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize) {
*pBegin = opt;
pBegin++;
*pBegin = nSize;
pBegin++;
memcpy(pBegin, buf, nSize);
pBegin += nSize;
return nSize + 2;
}
int dhcp_add_string_option(U8 *pBegin, int opt, const char *buf) {
dhcp_add_buf_option(pBegin, opt, (U8 *)buf, strlen(buf) + 1);
return (int)(strlen(buf) + 1 + 2);
}
int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal) {
@ -177,8 +194,6 @@ int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal) {
if (g_optRuntime[id].enable && id == opt) {
pVal->len = len;
pVal->pValue = p + 2;
printf("++++ %d size %d\n", id, len);
return ERR_SUCCESS;
}

View File

@ -21,12 +21,16 @@
#include "misc.h"
#include "user_mgr.h"
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
#define MAX_DHCP_PKG_SIZE (512)
#define DHCP_COOKIE_VAL (0x63825363)
#define PKG_MMAP_BLOCKSIZ (1 << 22)
#define PKG_MMAP_FRAMESIZ (1 << 11)
#define PKG_MMAP_BLOCKNUM (64)
#define MAX_DHCP_PKG_SIZE (512)
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
#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])
#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])
typedef struct {
U8 unicast;
@ -40,9 +44,15 @@ typedef struct {
} DHCP_REQ, *PDHCP_REQ;
typedef struct {
struct iovec *rd;
uint8_t *map;
struct tpacket_req3 req;
int sock;
struct sockaddr_ll addr;
struct iovec *rx;
struct iovec *tx;
uint8_t *map_recv;
uint8_t *map_send;
struct tpacket_req3 recv;
struct tpacket_req3 send;
unsigned int index;
} PACKET_MMAP_RING, *PPACKET_MMAP_RING;
typedef struct {
@ -201,16 +211,39 @@ static struct sock_filter g_filterCode[] = {
static PACKET_MMAP_RING g_pkgRing;
static NIC_INFO g_nicInfo;
#define VLAN_VNI_ID(x) ntohs((x))
#define DHCP_XID(x) ntohl((x))
static uv_udp_t g_uvRawScokReq;
static struct sock_fprog bpf = {
.len = sizeof(g_filterCode) / (sizeof(struct sock_filter)),
.filter = g_filterCode,
};
U32 pkg_mmap_tx(U8 *pData, U32 nBytes) {
int i;
ssize_t ret;
struct tpacket3_hdr *hdr;
for (i = 0; i < g_pkgRing.send.tp_frame_nr; i++) {
hdr = (struct tpacket3_hdr *)(g_pkgRing.tx[0].iov_base + (g_pkgRing.send.tp_frame_size * g_pkgRing.index));
g_pkgRing.index = (g_pkgRing.index + 1) % g_pkgRing.send.tp_frame_nr;
if (!(hdr->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING))) {
U8 *p = (U8 *)hdr + TPACKET3_HDRLEN - sizeof(struct sockaddr_ll);
memcpy(p, pData, nBytes);
hdr->tp_next_offset = 0;
hdr->tp_len = nBytes;
hdr->tp_snaplen = nBytes;
hdr->tp_status = TP_STATUS_SEND_REQUEST;
return hdr->tp_len;
}
}
return 0;
}
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
U16 csum;
int tolSize;
PDHCP_PACKAGE pRsp = (PDHCP_PACKAGE)malloc(MAX_DHCP_PKG_SIZE);
U8 *pOpt = pRsp->dhcp.options;
@ -236,8 +269,10 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
// IP 头
memcpy(&pRsp->vlan_hdr.ip, &pReq->vlan_hdr.ip, sizeof(struct iphdr));
// TOS
pRsp->vlan_hdr.ip.tos = 0;
// 更新源IP
pRsp->vlan_hdr.ip.saddr = htonl(g_nicInfo.ipAddr);
pRsp->vlan_hdr.ip.saddr = g_nicInfo.ipAddr;
// 更新目的IP地址广播255.255.255.255
pRsp->vlan_hdr.ip.daddr = 0xFFFFFFFF;
@ -263,7 +298,10 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
// DHCP服务端主机名
memcpy(pRsp->dhcp.sname, g_nicInfo.hostname, MIN(64, strlen(g_nicInfo.hostname)));
// Magic Cookie: DHCP
memcpy(&pRsp->dhcp.cookie, "DHCP", 4);
//
// memcpy(&pRsp->dhcp.cookie, DHCP_COOKIE_VAL, 4);
pRsp->dhcp.cookie = htonl(DHCP_COOKIE_VAL);
pRsp->dhcp.hops = 0;
pRsp->dhcp.secs = 0;
pRsp->dhcp.flags = 0;
@ -273,39 +311,57 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PIPPOOL_INFO pIpInfo, U32 ip) {
// DHCP Options
// DHCP 消息类型
dhcp_add_number_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_OFFER, 1);
pOpt += 3;
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_OFFER);
// 子网掩码
dhcp_add_number_option(pOpt, OPT_NETMASK, pIpInfo->netMask, 4);
pOpt += 6;
pOpt += dhcp_add_u32_option(pOpt, OPT_NETMASK, htonl(pIpInfo->netMask));
// 租约
dhcp_add_number_option(pOpt, OPT_IPADDRLEASE, htonl(pIpInfo->leaseTime), 4);
pOpt += 6;
pOpt += dhcp_add_u32_option(pOpt, OPT_IPADDRLEASE, htonl(pIpInfo->leaseTime));
// DHCP Server
dhcp_add_number_option(pOpt, OPT_SERVERID, g_nicInfo.ipAddr, 4);
pOpt += 6;
pOpt += dhcp_add_u32_option(pOpt, OPT_SERVERID, g_nicInfo.ipAddr);
// DNS
if (pIpInfo->primeDNS != 0) {
if (pIpInfo->salveDNS == 0) {
dhcp_add_number_option(pOpt, OPT_DNS, pIpInfo->primeDNS, 4);
pOpt += 6;
pOpt += dhcp_add_u32_option(pOpt, OPT_DNS, htonl(pIpInfo->primeDNS));
} else {
dhcp_add_buf_option(pOpt, OPT_DNS, (U8 *)&pIpInfo->primeDNS, 8);
pOpt += 10;
U8 buf[8] = {0};
U32 *pVal = (U32 *)buf;
*pVal++ = htonl(pIpInfo->primeDNS);
*pVal = htonl(pIpInfo->salveDNS);
pOpt += dhcp_add_buf_option(pOpt, OPT_DNS, buf, 8);
}
}
// 网关
if (pIpInfo->gwAddr != 0) {
dhcp_add_number_option(pOpt, OPT_ROUTER, pIpInfo->gwAddr, 4);
pOpt += 6;
pOpt += dhcp_add_u32_option(pOpt, OPT_ROUTER, htonl(pIpInfo->gwAddr));
}
// DHCP 主机名
dhcp_add_buf_option(pOpt, OPT_DOMAINNAME, (U8 *)g_nicInfo.hostname, strlen(g_nicInfo.hostname));
pOpt += strlen(g_nicInfo.hostname) + 2;
pOpt += dhcp_add_string_option(pOpt, OPT_DOMAINNAME, "workgroup");
*pOpt = OPT_END;
*pOpt = OPT_END;
// 计算包总长度
tolSize = (int)((pOpt - pRsp->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
LOG_MSG_HEX(debug, pRsp, 256);
// 计算 IP 数据长度
pRsp->vlan_hdr.ip.tot_len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr));
// 计算 UDP 数据长度
pRsp->vlan_hdr.udp.len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr));
// 计算 IP 校验和
csum = htons(ip_checksum((unsigned char *)&pRsp->vlan_hdr.ip));
pRsp->vlan_hdr.ip.check = htons(csum);
// 计算 UDP 校验和
csum = htons(udp_checksum(pRsp->vlan_hdr.ip.saddr, pRsp->vlan_hdr.ip.daddr, (unsigned char *)&pRsp->vlan_hdr.udp));
pRsp->vlan_hdr.udp.check = htons(csum);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "OPTIONS size: %ld\n", (intptr_t)(pOpt - pRsp->dhcp.options) + 1);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "Total size: %d\n", tolSize);
// 发送数据
if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send package(%u bytes) error\n", tolSize);
return -ERR_SOCK_SEND;
}
return ERR_SUCCESS;
}
@ -380,8 +436,16 @@ static void on_sock_recv(uv_work_t *req) {
u32_to_str_ip(ntohl(ip)));
ret = dhcp_resp_offer(pkg, pIpInfo, ip);
if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Send Offer error: %d\n", ret);
}
} else {
//LOG_MOD(error, ZLOG_MOD_DHCPD, );
LOG_MOD(error,
ZLOG_MOD_DHCPD,
"DHCP prepare assign ipaddress error: [%s(%s)]\n",
macStr,
reqDhcp.hostName);
}
break;
case DHCP_MSG_REQUEST:
@ -440,8 +504,8 @@ static void after_msg_recv(uv_work_t *req, int status) {
void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
static unsigned int block_num = 0;
if (status >= 0) {
struct block_desc *pbd = (struct block_desc *)g_pkgRing.rd[block_num].iov_base;
if (status >= 0 && (events & UV_READABLE)) {
struct block_desc *pbd = (struct block_desc *)g_pkgRing.rx[block_num].iov_base;
if ((pbd->h1.block_status & TP_STATUS_USER) && (pbd->h1.num_pkts > 0)) {
int i;
@ -486,14 +550,14 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
}
static int create_udp_socket() {
int i;
int err;
int v = TPACKET_V3;
struct sockaddr_ll addr;
unsigned int size;
int i;
int err;
int v = TPACKET_V3;
// 1. create socket
int sock_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
int sock_fd = socket(PF_PACKET, SOCK_RAW, 0);
if (sock_fd < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Socket created failure\n");
return -ERR_SOCK_CREATE;
@ -504,74 +568,130 @@ static int create_udp_socket() {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Attaching filter failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
#if 1
// 3. set PACKET_MMAP version
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_VERSION option failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
// 4. setup PAKCET_MMAP ring
memset(&g_pkgRing.req, 0, sizeof(g_pkgRing.req));
g_pkgRing.req.tp_block_size = PKG_MMAP_BLOCKSIZ;
g_pkgRing.req.tp_frame_size = PKG_MMAP_FRAMESIZ;
g_pkgRing.req.tp_block_nr = PKG_MMAP_BLOCKNUM;
g_pkgRing.req.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ;
g_pkgRing.req.tp_retire_blk_tov = 60;
g_pkgRing.req.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
// 4. setup PAKCET_MMAP rx ring
memset(&g_pkgRing.recv, 0, sizeof(g_pkgRing.recv));
g_pkgRing.recv.tp_block_size = PKG_MMAP_BLOCKSIZ;
g_pkgRing.recv.tp_frame_size = PKG_MMAP_FRAMESIZ;
g_pkgRing.recv.tp_block_nr = PKG_MMAP_BLOCKNUM;
g_pkgRing.recv.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ;
g_pkgRing.recv.tp_retire_blk_tov = 60;
g_pkgRing.recv.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &g_pkgRing.req, sizeof(g_pkgRing.req))) < 0) {
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_RX_RING, &g_pkgRing.recv, sizeof(g_pkgRing.recv))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_RX_RING option failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
g_pkgRing.map = mmap(NULL,
g_pkgRing.req.tp_block_size * g_pkgRing.req.tp_block_nr,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_LOCKED,
sock_fd,
0);
// 5. setup PACKET_MMAP tx ring
memset(&g_pkgRing.send, 0, sizeof(g_pkgRing.send));
g_pkgRing.send.tp_block_size = PKG_MMAP_BLOCKSIZ;
g_pkgRing.send.tp_frame_size = PKG_MMAP_FRAMESIZ;
g_pkgRing.send.tp_block_nr = PKG_MMAP_BLOCKNUM;
g_pkgRing.send.tp_frame_nr = (PKG_MMAP_BLOCKSIZ * PKG_MMAP_BLOCKNUM) / PKG_MMAP_FRAMESIZ;
if (g_pkgRing.map == MAP_FAILED) {
if ((err = setsockopt(sock_fd, SOL_PACKET, PACKET_TX_RING, &g_pkgRing.send, sizeof(g_pkgRing.recv))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Set PACKET_TX_RING option failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
// 6. mmap RX/TX ring
size = g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr +
g_pkgRing.send.tp_block_size * g_pkgRing.send.tp_block_nr;
g_pkgRing.map_recv = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED | MAP_POPULATE, sock_fd, 0);
g_pkgRing.map_send = g_pkgRing.map_recv + g_pkgRing.recv.tp_block_size * g_pkgRing.recv.tp_block_nr;
if (g_pkgRing.map_recv == MAP_FAILED) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "MMAP socket ring failed\n");
perror("title");
return -ERR_MMAP_MEMORY;
}
// 5. malloc read buffer
g_pkgRing.rd = malloc(g_pkgRing.req.tp_block_nr * sizeof(struct iovec));
LOG_MOD(trace, ZLOG_MOD_DHCPD, "size = %u\n", size);
LOG_MOD(trace, ZLOG_MOD_DHCPD, "MMAP address recv = %p, send = %p\n", g_pkgRing.map_recv, g_pkgRing.map_send);
if (g_pkgRing.rd == NULL) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Malloc memory failed: %lu\n", g_pkgRing.req.tp_block_nr * sizeof(struct iovec));
// 7. malloc read buffer
g_pkgRing.rx = malloc(g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
if (g_pkgRing.rx == NULL) {
LOG_MOD(error,
ZLOG_MOD_DHCPD,
"Malloc memory failed: %lu\n",
g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
return -ERR_MMAP_MEMORY;
}
for (i = 0; i < g_pkgRing.req.tp_block_nr; ++i) {
g_pkgRing.rd[i].iov_base = g_pkgRing.map + (i * g_pkgRing.req.tp_block_size);
g_pkgRing.rd[i].iov_len = g_pkgRing.req.tp_block_size;
memset(g_pkgRing.rx, 0, g_pkgRing.recv.tp_block_nr * sizeof(struct iovec));
for (i = 0; i < g_pkgRing.recv.tp_block_nr; ++i) {
g_pkgRing.rx[i].iov_base = g_pkgRing.map_recv + (i * g_pkgRing.recv.tp_block_size);
g_pkgRing.rx[i].iov_len = g_pkgRing.recv.tp_block_size;
}
#endif
// 6. bind socket
memset(&addr, 0, sizeof(addr));
// 8. malloc send buffer
g_pkgRing.tx = malloc(g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
if (g_pkgRing.tx == NULL) {
LOG_MOD(error,
ZLOG_MOD_DHCPD,
"Malloc memory failed: %lu\n",
g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
munmap(g_pkgRing.map_recv, size * 2);
return -ERR_MMAP_MEMORY;
}
memset(g_pkgRing.tx, 0, g_pkgRing.send.tp_block_nr * sizeof(struct iovec));
for (i = 0; i < g_pkgRing.send.tp_block_nr; ++i) {
g_pkgRing.tx[i].iov_base = g_pkgRing.map_send + (i * g_pkgRing.send.tp_block_size);
g_pkgRing.tx[i].iov_len = g_pkgRing.send.tp_block_size;
}
// 9. bind socket
memset(&addr, 0, sizeof(struct sockaddr_ll));
addr.sll_ifindex = (int)if_nametoindex(g_nicInfo.pIfName);
addr.sll_family = AF_PACKET;
addr.sll_family = PF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_hatype = 0;
addr.sll_pkttype = 0;
addr.sll_halen = 0;
if ((err = bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
if ((err = bind(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll))) < 0) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Bind raw socket failed: %d\n", err);
return -ERR_SOCK_SETOPT;
}
return sock_fd;
g_pkgRing.sock = sock_fd;
return ERR_SUCCESS;
}
static void socket_send_task(uv_timer_t *UNUSED(pArg)) {
int i;
struct tpacket3_hdr *hdr;
for (i = 0; i < g_pkgRing.send.tp_frame_nr && g_pkgRing.sock != 0; i++) {
hdr = (struct tpacket3_hdr *)(g_pkgRing.tx[0].iov_base + (g_pkgRing.send.tp_frame_size * i));
if ((hdr->tp_status & TP_STATUS_SEND_REQUEST) || (hdr->tp_status & TP_STATUS_SENDING)) {
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");
}
break;
}
}
}
int dhcpd_init() {
static uv_udp_t uvRaw;
static uv_poll_t uvSocket;
int sock;
size_t size = MAX_PATH;
static uv_poll_t uvSocket;
static uv_timer_t uvTm;
int ret;
size_t size = MAX_PATH;
memset(&g_nicInfo, 0, sizeof(NIC_INFO));
g_nicInfo.pIfName = (char *)config_get_dhcp_nic_name();
@ -579,21 +699,24 @@ int dhcpd_init() {
get_nic_info(g_nicInfo.pIfName, &g_nicInfo.ipAddr, &g_nicInfo.netmask, NULL, g_nicInfo.macAddr);
sock = create_udp_socket();
if (sock <= 0) {
return sock;
ret = create_udp_socket();
if (ret != ERR_SUCCESS) {
LOG_MOD(error, ZLOG_MOD_DHCPD, "Create receive RAW Socket Error\n");
return ret;
}
dhcp_user_mgr_init();
dhcp_option_cfg_init();
dhcp_lease_init();
uv_udp_init(get_task_manager(), &uvRaw);
uv_udp_open(&uvRaw, sock);
uv_udp_init(get_task_manager(), &g_uvRawScokReq);
uv_udp_open(&g_uvRawScokReq, g_pkgRing.sock);
uv_poll_init_socket(get_task_manager(), &uvSocket, sock);
uv_poll_init_socket(get_task_manager(), &uvSocket, g_pkgRing.sock);
uv_poll_start(&uvSocket, UV_READABLE, raw_sock_recv_cb);
uv_timer_init(get_task_manager(), &uvTm);
uv_timer_start(&uvTm, socket_send_task, 3000, 100);
return ERR_SUCCESS;
}

View File

@ -141,8 +141,10 @@ typedef struct {
U8 len;
} DHCP_OPT, *PDHCP_OPT;
void dhcp_add_number_option(U8 *pBegin, int opt, U8 value, U8 nSize);
void dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize);
int dhcp_add_u8_option(U8 *pBegin, int opt, U8 value);
int dhcp_add_u32_option(U8 *pBegin, int opt, U32 value);
int dhcp_add_buf_option(U8 *pBegin, int opt, U8 *buf, U8 nSize);
int dhcp_add_string_option(U8 *pBegin, int opt, const char *buf);
int dhcp_get_option(int opt, U8 *pOptData, U32 nSize, PDHCP_OPT pVal);
void dhcp_option_cfg_init();
#ifdef __cplusplus