OCT 1. DHCP 服务支持自动识别VLAN、单层QinQ, 双层QinQ头部
This commit is contained in:
parent
a5d99d5dba
commit
958fbab193
|
@ -20,6 +20,12 @@ extern "C" {
|
||||||
|
|
||||||
#define VXLAN_VIN_ID_PACK(x) ((ntohs(x)) & 0xFFF)
|
#define VXLAN_VIN_ID_PACK(x) ((ntohs(x)) & 0xFFF)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VLAN_NONE,
|
||||||
|
VLAN_LEVEL1,
|
||||||
|
VLAN_LEVEL2
|
||||||
|
} VLAN_TYPE;
|
||||||
|
|
||||||
typedef struct vlan_hdr {
|
typedef struct vlan_hdr {
|
||||||
#if VLAN_SUPPORT
|
#if VLAN_SUPPORT
|
||||||
U16 id;
|
U16 id;
|
||||||
|
@ -27,6 +33,21 @@ typedef struct vlan_hdr {
|
||||||
#endif
|
#endif
|
||||||
} VLAN_HDR, *PVLAN_HDR;
|
} VLAN_HDR, *PVLAN_HDR;
|
||||||
|
|
||||||
|
typedef struct vlan_hdr2 {
|
||||||
|
#if VLAN_SUPPORT
|
||||||
|
U16 id1;
|
||||||
|
U16 h_type;
|
||||||
|
U16 id2;
|
||||||
|
U16 type;
|
||||||
|
#endif
|
||||||
|
} VLAN_HDR2, *PVLAN_HDR2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct ethhdr eth;
|
||||||
|
struct iphdr ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
} VLAN_PKG_HDR, *PVLAN_PKG_HDR;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct ethhdr eth;
|
struct ethhdr eth;
|
||||||
#if VLAN_SUPPORT
|
#if VLAN_SUPPORT
|
||||||
|
@ -34,7 +55,16 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
struct iphdr ip;
|
struct iphdr ip;
|
||||||
struct udphdr udp;
|
struct udphdr udp;
|
||||||
} VLAN_PKG_HDR, *PVLAN_PKG_HDR;
|
} VLAN_PKG_HDR1, *PVLAN_PKG_HDR1;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct ethhdr eth;
|
||||||
|
#if VLAN_SUPPORT
|
||||||
|
struct vlan_hdr2 vlan;
|
||||||
|
#endif
|
||||||
|
struct iphdr ip;
|
||||||
|
struct udphdr udp;
|
||||||
|
} VLAN_PKG_HDR2, *PVLAN_PKG_HDR2;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
// 10小时以上清理无效的预分配IP
|
// 10小时以上清理无效的预分配IP
|
||||||
#define DCHP_STEP_CLEANUP_TIMEOUT (36000)
|
#define DCHP_STEP_CLEANUP_TIMEOUT (36000)
|
||||||
// Discover 预分配IP 和Request 请求间的超时时间
|
// Discover 预分配IP 和 Request 请求间的超时时间
|
||||||
#define DCHP_STEP_REQUEST_TIMEOUT (600000)
|
#define DCHP_STEP_REQUEST_TIMEOUT (600000)
|
||||||
|
|
||||||
#define CREATE_LEASE_TABLE() \
|
#define CREATE_LEASE_TABLE() \
|
||||||
|
@ -114,7 +114,6 @@
|
||||||
|
|
||||||
#define LEASE_RELEASE_FMT "DELETE FROM lease WHERE uid = %d AND mac = '%s' AND ip = '%s'"
|
#define LEASE_RELEASE_FMT "DELETE FROM lease WHERE uid = %d AND mac = '%s' AND ip = '%s'"
|
||||||
|
|
||||||
|
|
||||||
static int lease_add(PDHCP_REQ pReq,
|
static int lease_add(PDHCP_REQ pReq,
|
||||||
const char *ip,
|
const char *ip,
|
||||||
const char *netmask,
|
const char *netmask,
|
||||||
|
@ -400,10 +399,11 @@ int db_get_pre_lease(PDHCP_REQ pReq, PPOOL_CTX pAssign) {
|
||||||
const char *pIp = u32_to_str_ip_safe(htonl(pAssign->minAddr));
|
const char *pIp = u32_to_str_ip_safe(htonl(pAssign->minAddr));
|
||||||
|
|
||||||
// 删除预分配IP信息
|
// 删除预分配IP信息
|
||||||
|
#if 0
|
||||||
memset(buf, 0, 2048);
|
memset(buf, 0, 2048);
|
||||||
sprintf(buf, "DELETE FROM pre_assign WHERE id = %llu;", id);
|
sprintf(buf, "DELETE FROM pre_assign WHERE id = %llu;", id);
|
||||||
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
#endif
|
||||||
// 添加租约信息到lease数据库
|
// 添加租约信息到lease数据库
|
||||||
lease_add(pReq, pIp, pNetmask, pGateway, pDns1, pDns2, pAssign->leaseTime);
|
lease_add(pReq, pIp, pNetmask, pGateway, pDns1, pDns2, pAssign->leaseTime);
|
||||||
|
|
||||||
|
@ -415,50 +415,6 @@ int db_get_pre_lease(PDHCP_REQ pReq, PPOOL_CTX pAssign) {
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
return -ERR_ITEM_UNEXISTS;
|
return -ERR_ITEM_UNEXISTS;
|
||||||
#if 0
|
|
||||||
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
|
||||||
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
|
|
||||||
char *pNetmask = dbResult[nColumn + 3];
|
|
||||||
char *pGateway = dbResult[nColumn + 4];
|
|
||||||
char *pDns1 = dbResult[nColumn + 5];
|
|
||||||
char *pDns2 = dbResult[nColumn + 6];
|
|
||||||
|
|
||||||
// minAddr 记录可分配的IP
|
|
||||||
pAssign->minAddr = ntohl(inet_addr(dbResult[nColumn + 1]));
|
|
||||||
pAssign->leaseTime = strtoul(dbResult[nColumn + 2], NULL, 10);
|
|
||||||
|
|
||||||
if (strlen(pNetmask) > 0) {
|
|
||||||
pAssign->netMask = ntohl(inet_addr(pNetmask));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(pGateway) > 0) {
|
|
||||||
pAssign->gwAddr = ntohl(inet_addr(pGateway));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(pDns1) > 0) {
|
|
||||||
pAssign->primeDNS = ntohl(inet_addr(pDns1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(pDns2) > 0) {
|
|
||||||
pAssign->salveDNS = ntohl(inet_addr(pDns2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除预分配IP信息
|
|
||||||
memset(buf, 0, 2048);
|
|
||||||
sprintf(buf, "DELETE FROM pre_assign WHERE id = %s;", dbResult[nColumn]);
|
|
||||||
//db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
lease_add(pReq, dbResult[nColumn + 1], pNetmask, pGateway, pDns1, pDns2, pAssign->leaseTime);
|
|
||||||
|
|
||||||
sqlite3_free_table(dbResult);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
} else {
|
|
||||||
LOG_MOD(error, ZM_DHCP_DB, "No previously records: \n%s\n", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_free_table(dbResult);
|
|
||||||
return -ERR_ITEM_UNEXISTS;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int db_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign) {
|
int db_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign) {
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
|
|
||||||
#define MAXIMUM_SNAPLEN (262144)
|
#define MAXIMUM_SNAPLEN (262144)
|
||||||
|
|
||||||
|
#define IP_HDR_OFFSET (sizeof(struct ethhdr))
|
||||||
|
#define UDP_HDR_OFFSET (sizeof(struct ethhdr) + sizeof(struct iphdr))
|
||||||
|
#define DHCP_OFFSET (sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
|
TORs (Top of Rack switch) at Facebook run DHCP relayers, these relayers are
|
||||||
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
|
responsible for relaying broadcast DHCP traffic (DISCOVERY and SOLICIT
|
||||||
|
@ -152,6 +156,18 @@ static NIC_INFO g_nicInfo;
|
||||||
static uv_udp_t g_uvRawSockReq;
|
static uv_udp_t g_uvRawSockReq;
|
||||||
static DHCP_WORK_MODE g_dhcpMode;
|
static DHCP_WORK_MODE g_dhcpMode;
|
||||||
|
|
||||||
|
VLAN_TYPE get_package_vlan_type(void *pBuf) {
|
||||||
|
U8 *p = (U8 *)pBuf;
|
||||||
|
|
||||||
|
if (p[12] == 0x81 && p[13] == 0x00 && p[16] == 0x81 && p[17] == 0x00) {
|
||||||
|
return VLAN_LEVEL2;
|
||||||
|
} else if (p[12] == 0x81 && p[13] == 0x00) {
|
||||||
|
return VLAN_LEVEL1;
|
||||||
|
} else {
|
||||||
|
return VLAN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
U32 dhcp_get_default_netmask() {
|
U32 dhcp_get_default_netmask() {
|
||||||
return g_nicInfo.netmask;
|
return g_nicInfo.netmask;
|
||||||
}
|
}
|
||||||
|
@ -182,93 +198,172 @@ U32 pkg_mmap_tx(U8 *pData, U32 nBytes) {
|
||||||
return hdr->tp_len;
|
return hdr->tp_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_package(PDHCP_PACKAGE pRsp, PDHCP_PACKAGE pReq) {
|
static void add_eth_head(U8 *pRsp, struct ethhdr *pEth, int isBst) {
|
||||||
memset(pRsp, 0, MAX_DHCP_PKG_SIZE);
|
struct ethhdr *p = (struct ethhdr *)pRsp;
|
||||||
|
|
||||||
// 二层头
|
// 二层头
|
||||||
// 目的IP地址
|
// 目的 MAC 地址
|
||||||
if (pReq->hdr.ip.saddr != 0) {
|
if (!isBst) {
|
||||||
memcpy(pRsp->hdr.eth.h_dest, pRsp->hdr.eth.h_source, ETH_ALEN);
|
memcpy(p->h_dest, pEth->h_source, ETH_ALEN);
|
||||||
} else {
|
} else {
|
||||||
memset(pRsp->hdr.eth.h_dest, 0xFF, ETH_ALEN);
|
memset(p->h_dest, 0xFF, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 源 IP 地址
|
// 源 MAC 地址
|
||||||
memcpy(pRsp->hdr.eth.h_source, g_nicInfo.macAddr, ETH_ALEN);
|
memcpy(p->h_source, g_nicInfo.macAddr, ETH_ALEN);
|
||||||
// protol
|
// protol
|
||||||
pRsp->hdr.eth.h_proto = pReq->hdr.eth.h_proto;
|
p->h_proto = pEth->h_proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_vlan_head(U8 *pRsp, PVLAN_PKG_HDR1 pvHdr) {
|
||||||
|
PVLAN_PKG_HDR1 p = (PVLAN_PKG_HDR1)pRsp;
|
||||||
|
|
||||||
#if VLAN_SUPPORT
|
|
||||||
// QinQ 隧道
|
// QinQ 隧道
|
||||||
pRsp->hdr.vlan.id = pReq->hdr.vlan.id;
|
p->vlan.id = pvHdr->vlan.id;
|
||||||
pRsp->hdr.vlan.type = pReq->hdr.vlan.type;
|
p->vlan.type = pvHdr->vlan.type;
|
||||||
// TODO 可能的二层QinQ隧道
|
}
|
||||||
#endif
|
|
||||||
// IP 头
|
|
||||||
memcpy(&pRsp->hdr.ip, &pReq->hdr.ip, sizeof(struct iphdr));
|
|
||||||
// TOS
|
|
||||||
pRsp->hdr.ip.tos = 0;
|
|
||||||
// 更新源IP
|
|
||||||
pRsp->hdr.ip.saddr = g_nicInfo.ipAddr;
|
|
||||||
// 更新目的IP地址,广播255.255.255.255
|
|
||||||
if (pReq->hdr.ip.saddr == 0) {
|
|
||||||
pRsp->hdr.ip.daddr = 0xFFFFFFFF;
|
|
||||||
} else {
|
|
||||||
pRsp->hdr.ip.daddr = pReq->hdr.ip.saddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void add_vlan2_head(U8 *pRsp, PVLAN_PKG_HDR2 pvHdr) {
|
||||||
|
PVLAN_PKG_HDR2 p = (PVLAN_PKG_HDR2)pRsp;
|
||||||
|
|
||||||
|
// QinQ 隧道
|
||||||
|
p->vlan.id1 = pvHdr->vlan.id1;
|
||||||
|
p->vlan.h_type = pvHdr->vlan.h_type;
|
||||||
|
p->vlan.id2 = pvHdr->vlan.id2;
|
||||||
|
p->vlan.type = pvHdr->vlan.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_ip_head(struct iphdr *p, struct iphdr *pIp) {
|
||||||
|
// IP 头
|
||||||
|
memcpy(p, pIp, sizeof(struct iphdr));
|
||||||
|
// TOS
|
||||||
|
p->tos = 0;
|
||||||
|
// 更新源IP
|
||||||
|
p->saddr = g_nicInfo.ipAddr;
|
||||||
|
// 更新目的IP地址,广播255.255.255.255
|
||||||
|
if (pIp->saddr == 0) {
|
||||||
|
p->daddr = 0xFFFFFFFF;
|
||||||
|
} else {
|
||||||
|
p->daddr = pIp->saddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_udp_head(struct udphdr *p, struct udphdr *pUdp) {
|
||||||
// UDP 头
|
// UDP 头
|
||||||
// 目的端口
|
// 目的端口
|
||||||
pRsp->hdr.udp.dest = pReq->hdr.udp.source;
|
p->dest = pUdp->source;
|
||||||
// 源端口
|
// 源端口
|
||||||
pRsp->hdr.udp.source = pReq->hdr.udp.dest;
|
p->source = pUdp->dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_dhcp_common(PDHCP_PROTO p, PDHCP_PROTO pDhcp) {
|
||||||
//DHCP 协议
|
//DHCP 协议
|
||||||
// 返回类型
|
// 返回类型
|
||||||
pRsp->dhcp.op = BOOTP_REPLY;
|
p->op = BOOTP_REPLY;
|
||||||
// 地址类型长度
|
// 地址类型长度
|
||||||
pRsp->dhcp.htype = pReq->dhcp.htype;
|
p->htype = pDhcp->htype;
|
||||||
// 地址长度
|
// 地址长度
|
||||||
pRsp->dhcp.hlen = pReq->dhcp.hlen;
|
p->hlen = pDhcp->hlen;
|
||||||
// xid
|
// xid
|
||||||
pRsp->dhcp.xid = pReq->dhcp.xid;
|
p->xid = pDhcp->xid;
|
||||||
// 客户端 MAC 地址
|
// 客户端 MAC 地址
|
||||||
memcpy(pRsp->dhcp.chaddr, pReq->dhcp.chaddr, ETH_ALEN);
|
memcpy(p->chaddr, pDhcp->chaddr, ETH_ALEN);
|
||||||
// DHCP服务端主机名
|
// DHCP服务端主机名
|
||||||
memcpy(pRsp->dhcp.sname, g_nicInfo.hostname, MIN(64, strlen(g_nicInfo.hostname)));
|
memcpy(p->sname, g_nicInfo.hostname, MIN(64, strlen(g_nicInfo.hostname)));
|
||||||
// Magic Cookie: DHCP
|
// Magic Cookie: DHCP
|
||||||
//
|
//
|
||||||
// memcpy(&pRsp->dhcp.cookie, DHCP_COOKIE_VAL, 4);
|
// memcpy(&pRsp->dhcp.cookie, DHCP_COOKIE_VAL, 4);
|
||||||
pRsp->dhcp.cookie = htonl(DHCP_COOKIE_VAL);
|
p->cookie = htonl(DHCP_COOKIE_VAL);
|
||||||
|
|
||||||
pRsp->dhcp.hops = 0;
|
p->hops = 0;
|
||||||
pRsp->dhcp.secs = 0;
|
p->secs = 0;
|
||||||
pRsp->dhcp.flags = 0;
|
p->flags = 0;
|
||||||
pRsp->dhcp.ciaddr = 0;
|
p->ciaddr = 0;
|
||||||
pRsp->dhcp.siaddr = 0;
|
p->siaddr = 0;
|
||||||
pRsp->dhcp.giaddr = 0;
|
p->giaddr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_prepare_tx(U8 *pOpt, PDHCP_PACKAGE pRsp) {
|
static PDHCP_PROTO fill_pkg(U8 *pRsp, U8 *pReq) {
|
||||||
|
U8 *p;
|
||||||
|
struct ethhdr *pEth = (struct ethhdr *)pReq;
|
||||||
|
struct iphdr *pIp = NULL;
|
||||||
|
struct udphdr *pUdp = NULL;
|
||||||
|
PDHCP_PROTO pDhcp = NULL;
|
||||||
|
|
||||||
|
memset(pRsp, 0, MAX_DHCP_PKG_SIZE);
|
||||||
|
switch (get_package_vlan_type(pReq)) {
|
||||||
|
default:
|
||||||
|
pIp = (struct iphdr *)(pReq + IP_HDR_OFFSET);
|
||||||
|
pUdp = (struct udphdr *)(UDP_HDR_OFFSET);
|
||||||
|
pDhcp = (PDHCP_PROTO)((U8 *)pReq + DHCP_OFFSET);
|
||||||
|
p = pRsp + sizeof(struct ethhdr);
|
||||||
|
break;
|
||||||
|
case VLAN_LEVEL1:
|
||||||
|
pIp = (struct iphdr *)(pReq + IP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||||
|
pUdp = (struct udphdr *)(pReq + UDP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||||
|
pDhcp = (PDHCP_PROTO)((U8 *)pReq + DHCP_OFFSET + sizeof(VLAN_HDR));
|
||||||
|
add_vlan_head(pRsp, (PVLAN_PKG_HDR1)pReq);
|
||||||
|
p = pRsp + sizeof(struct ethhdr) + sizeof(VLAN_HDR);
|
||||||
|
break;
|
||||||
|
case VLAN_LEVEL2:
|
||||||
|
pIp = (struct iphdr *)(pReq + IP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||||
|
pUdp = (struct udphdr *)(pReq + UDP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||||
|
pDhcp = (PDHCP_PROTO)((U8 *)pReq + DHCP_OFFSET + sizeof(VLAN_HDR2));
|
||||||
|
add_vlan2_head(pRsp, (PVLAN_PKG_HDR2)pReq);
|
||||||
|
p = pRsp + sizeof(struct ethhdr) + sizeof(VLAN_HDR2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_eth_head(pRsp, pEth, (pIp->saddr == 0) ? TRUE : FALSE);
|
||||||
|
add_ip_head((struct iphdr *)p, pIp);
|
||||||
|
p += sizeof(struct iphdr);
|
||||||
|
add_udp_head((struct udphdr *)p, pUdp);
|
||||||
|
p += sizeof(struct udphdr);
|
||||||
|
add_dhcp_common((PDHCP_PROTO)p, pDhcp);
|
||||||
|
|
||||||
|
return (PDHCP_PROTO)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcp_prepare_tx(U8 *pRsp, U32 optSize) {
|
||||||
|
struct iphdr *pIp = NULL;
|
||||||
|
struct udphdr *pUdp = NULL;
|
||||||
U16 csum;
|
U16 csum;
|
||||||
int tolSize;
|
U32 tolSize;
|
||||||
|
|
||||||
|
switch (get_package_vlan_type(pRsp)) {
|
||||||
|
default:
|
||||||
|
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET);
|
||||||
|
pUdp = (struct udphdr *)(UDP_HDR_OFFSET);
|
||||||
// 计算包总长度
|
// 计算包总长度
|
||||||
tolSize = (int)((pOpt - pRsp->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET;
|
||||||
|
break;
|
||||||
|
case VLAN_LEVEL1:
|
||||||
|
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||||
|
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR));
|
||||||
|
// 计算包总长度
|
||||||
|
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET + sizeof(VLAN_HDR);
|
||||||
|
break;
|
||||||
|
case VLAN_LEVEL2:
|
||||||
|
pIp = (struct iphdr *)(pRsp + IP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||||
|
pUdp = (struct udphdr *)(pRsp + UDP_HDR_OFFSET + sizeof(VLAN_HDR2));
|
||||||
|
// 计算包总长度
|
||||||
|
tolSize = optSize + sizeof(DHCP_PROTO) + DHCP_OFFSET + sizeof(VLAN_HDR2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// 计算 IP 数据长度
|
// 计算 IP 数据长度
|
||||||
pRsp->hdr.ip.tot_len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr));
|
pIp->tot_len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr));
|
||||||
// 计算 UDP 数据长度
|
// 计算 UDP 数据长度
|
||||||
pRsp->hdr.udp.len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr));
|
pUdp->len = htons(tolSize - sizeof(struct ethhdr) - sizeof(struct vlan_hdr) - sizeof(struct iphdr));
|
||||||
|
|
||||||
// 计算 IP 校验和
|
// 计算 IP 校验和
|
||||||
csum = htons(ip_checksum((unsigned char *)&pRsp->hdr.ip));
|
csum = htons(ip_checksum((unsigned char *)pIp));
|
||||||
pRsp->hdr.ip.check = htons(csum);
|
pIp->check = htons(csum);
|
||||||
|
|
||||||
// 计算 UDP 校验和
|
// 计算 UDP 校验和
|
||||||
csum = htons(udp_checksum(pRsp->hdr.ip.saddr, pRsp->hdr.ip.daddr, (unsigned char *)&pRsp->hdr.udp));
|
csum = htons(udp_checksum(pIp->saddr, pIp->daddr, (unsigned char *)pUdp));
|
||||||
pRsp->hdr.udp.check = htons(csum);
|
pUdp->check = htons(csum);
|
||||||
|
|
||||||
LOG_MOD(trace, ZM_DHCP_NET, "OPTIONS size: %ld\n", (intptr_t)(pOpt - pRsp->dhcp.options) + 1);
|
|
||||||
LOG_MOD(trace, ZM_DHCP_NET, "Total size: %d\n", tolSize);
|
LOG_MOD(trace, ZM_DHCP_NET, "Total size: %d\n", tolSize);
|
||||||
|
|
||||||
// 发送数据
|
// 发送数据
|
||||||
|
@ -280,43 +375,45 @@ static int dhcp_prepare_tx(U8 *pOpt, PDHCP_PACKAGE pRsp) {
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_resp_nack(PDHCP_PACKAGE pReq) {
|
static int dhcp_resp_nack(void *pReq) {
|
||||||
U8 *pOpt;
|
U8 *pOpt;
|
||||||
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
PDHCP_PROTO pDhcp = NULL;
|
||||||
|
U8 *pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
if (pRsp == NULL) {
|
if (pRsp == NULL) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
||||||
return -ERR_MALLOC_MEMORY;
|
return -ERR_MALLOC_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_package(pRsp, pReq);
|
pDhcp = fill_pkg(pRsp, (U8 *)pReq);
|
||||||
|
|
||||||
// DHCP Options
|
// DHCP Options
|
||||||
pOpt = pRsp->dhcp.options;
|
pOpt = pDhcp->options;
|
||||||
|
|
||||||
// DHCP 消息类型
|
// DHCP 消息类型
|
||||||
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_NAK);
|
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_NAK);
|
||||||
*pOpt = OPT_END;
|
*pOpt = OPT_END;
|
||||||
|
|
||||||
return dhcp_prepare_tx(pOpt, pRsp);
|
return dhcp_prepare_tx(pRsp, (int)((pOpt - pDhcp->options) + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_resp_ack(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo) {
|
static int dhcp_resp_ack(void *pReq, PPOOL_CTX pIpInfo) {
|
||||||
U8 *pOpt;
|
U8 *pOpt;
|
||||||
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
PDHCP_PROTO pDhcp = NULL;
|
||||||
|
U8 *pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
if (pRsp == NULL) {
|
if (pRsp == NULL) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
||||||
return -ERR_MALLOC_MEMORY;
|
return -ERR_MALLOC_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_package(pRsp, pReq);
|
pDhcp = fill_pkg((U8 *)pRsp, (U8 *)pReq);
|
||||||
|
|
||||||
// 分配的 IP 地址
|
// 分配的 IP 地址
|
||||||
pRsp->dhcp.yiaddr = htonl(pIpInfo->minAddr);
|
pDhcp->yiaddr = htonl(pIpInfo->minAddr);
|
||||||
|
|
||||||
// DHCP Options
|
// DHCP Options
|
||||||
pOpt = pRsp->dhcp.options;
|
pOpt = pDhcp->options;
|
||||||
|
|
||||||
// DHCP 消息类型
|
// DHCP 消息类型
|
||||||
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_ACK);
|
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_ACK);
|
||||||
|
@ -346,24 +443,26 @@ static int dhcp_resp_ack(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo) {
|
||||||
pOpt += dhcp_add_string_option(pOpt, OPT_DOMAINNAME, "workgroup");
|
pOpt += dhcp_add_string_option(pOpt, OPT_DOMAINNAME, "workgroup");
|
||||||
*pOpt = OPT_END;
|
*pOpt = OPT_END;
|
||||||
|
|
||||||
return dhcp_prepare_tx(pOpt, pRsp);
|
return dhcp_prepare_tx(pRsp, (int)((pOpt - pDhcp->options) + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo, U32 ip) {
|
static int dhcp_resp_offer(void *pReq, PPOOL_CTX pIpInfo, U32 ip) {
|
||||||
U8 *pOpt;
|
U8 *pOpt;
|
||||||
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
PDHCP_PROTO pDhcp = NULL;
|
||||||
|
U8 *pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
if (pRsp == NULL) {
|
if (pRsp == NULL) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
||||||
return -ERR_MALLOC_MEMORY;
|
return -ERR_MALLOC_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_package(pRsp, pReq);
|
pDhcp = fill_pkg(pRsp, (U8 *)pReq);
|
||||||
|
|
||||||
// 分配的 IP 地址
|
// 分配的 IP 地址
|
||||||
pRsp->dhcp.yiaddr = htonl(ip);
|
pDhcp->yiaddr = htonl(ip);
|
||||||
|
|
||||||
// DHCP Options
|
// DHCP Options
|
||||||
pOpt = pRsp->dhcp.options;
|
pOpt = pDhcp->options;
|
||||||
|
|
||||||
// DHCP 消息类型
|
// DHCP 消息类型
|
||||||
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_OFFER);
|
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_OFFER);
|
||||||
|
@ -393,10 +492,41 @@ static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo, U32 ip) {
|
||||||
pOpt += dhcp_add_string_option(pOpt, OPT_DOMAINNAME, "workgroup");
|
pOpt += dhcp_add_string_option(pOpt, OPT_DOMAINNAME, "workgroup");
|
||||||
*pOpt = OPT_END;
|
*pOpt = OPT_END;
|
||||||
|
|
||||||
return dhcp_prepare_tx(pOpt, pRsp);
|
return dhcp_prepare_tx(pRsp, (int)((pOpt - pDhcp->options) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PDHCP_PROTO get_dhcp_date(void *pBuf, U32 *pOptSize, U32 bufSize) {
|
||||||
|
U8 *p = (U8 *)pBuf;
|
||||||
|
U32 hdrCom = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
|
||||||
|
|
||||||
|
if (p[12] == 0x81 && p[13] == 0x00 && p[16] == 0x81 && p[17] == 0x00) {
|
||||||
|
*pOptSize = bufSize - hdrCom - sizeof(DHCP_PROTO) - sizeof(VLAN_HDR2);
|
||||||
|
return (PDHCP_PROTO)(p + hdrCom + 8);
|
||||||
|
} else if (p[12] == 0x81 && p[13] == 0x00) {
|
||||||
|
*pOptSize = bufSize - hdrCom - sizeof(DHCP_PROTO) - sizeof(VLAN_HDR);
|
||||||
|
return (PDHCP_PROTO)(p + hdrCom + 4);
|
||||||
|
} else {
|
||||||
|
*pOptSize = bufSize - hdrCom - sizeof(DHCP_PROTO);
|
||||||
|
return (PDHCP_PROTO)(p + hdrCom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 dhcp_get_uid(void *pBuf) {
|
||||||
|
U8 *p = (U8 *)pBuf;
|
||||||
|
PVLAN_HDR pQinQ = (PVLAN_HDR)(p + sizeof(struct ethhdr));
|
||||||
|
|
||||||
|
if (p[12] == 0x81 && p[13] == 0x00 && p[16] == 0x81 && p[17] == 0x00) {
|
||||||
|
PVLAN_HDR2 pHdr = (PVLAN_HDR2)pQinQ;
|
||||||
|
return (pHdr->id1 & 0x0FFF) >> 12 | (pHdr->id2 & 0x0FFF) << 12;
|
||||||
|
} else if (p[12] == 0x81 && p[13] == 0x00) {
|
||||||
|
return (pQinQ->id & 0x0FFF);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_sock_recv(uv_work_t *req) {
|
static void on_sock_recv(uv_work_t *req) {
|
||||||
|
U32 optSize = 0;
|
||||||
char macStr[20] = {0};
|
char macStr[20] = {0};
|
||||||
U32 ip;
|
U32 ip;
|
||||||
PPOOL_CTX pIpInfo;
|
PPOOL_CTX pIpInfo;
|
||||||
|
@ -404,62 +534,58 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
DHCP_OPT optMsg, opt;
|
DHCP_OPT optMsg, opt;
|
||||||
int ret;
|
int ret;
|
||||||
PPKG_PROCESS_INFO pWork = (PPKG_PROCESS_INFO)req->data;
|
PPKG_PROCESS_INFO pWork = (PPKG_PROCESS_INFO)req->data;
|
||||||
PDHCP_PACKAGE pkg = (PDHCP_PACKAGE)pWork->pPkgBase;
|
PDHCP_PROTO pkg = get_dhcp_date(pWork->pPkgBase, &optSize, pWork->nSize);
|
||||||
U32 optSize = pWork->nSize - sizeof(DHCP_PACKAGE);
|
struct iphdr *pIpHdr = (struct iphdr *)((U8 *)pkg - sizeof(struct iphdr) - sizeof(struct udphdr));
|
||||||
|
|
||||||
//sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macStr[0], macStr[1], macStr[2], macStr[3], macStr[4], macStr[5]);
|
//sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macStr[0], macStr[1], macStr[2], macStr[3], macStr[4], macStr[5]);
|
||||||
|
|
||||||
// Check op flag
|
// Check op flag
|
||||||
if (pkg->dhcp.op != BOOTP_REQUEST) {
|
if (pkg->op != BOOTP_REQUEST) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->dhcp.op);
|
LOG_MOD(error, ZM_DHCP_NET, "Error message op code %d\n", pkg->op);
|
||||||
LOG_MSG_HEX(error, pkg, pWork->nSize);
|
LOG_MSG_HEX(error, pkg, pWork->nSize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取消息类型
|
// 获取消息类型
|
||||||
ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->dhcp.options, optSize, &optMsg);
|
ret = dhcp_get_option(OPT_MESSAGETYPE, pkg->options, optSize, &optMsg);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Get \'message type\' option error %d\n", ret);
|
LOG_MOD(error, ZM_DHCP_NET, "Get \'message type\' option error %d\n", ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&reqDhcp, 0, sizeof(DHCP_REQ));
|
memset(&reqDhcp, 0, sizeof(DHCP_REQ));
|
||||||
reqDhcp.unicast = pkg->dhcp.flags != 0 ? TRUE : FALSE;
|
reqDhcp.unicast = pkg->flags != 0 ? TRUE : FALSE;
|
||||||
reqDhcp.xid = DHCP_XID(pkg->dhcp.xid);
|
reqDhcp.xid = DHCP_XID(pkg->xid);
|
||||||
#if VLAN_SUPPORT
|
reqDhcp.uid = dhcp_get_uid(pWork->pPkgBase);
|
||||||
reqDhcp.uid = VLAN_VNI_ID(pkg->hdr.vlan.id);
|
|
||||||
#else
|
|
||||||
reqDhcp.uid = 0;
|
|
||||||
#endif
|
|
||||||
reqDhcp.serverAddr = g_nicInfo.ipAddr;
|
reqDhcp.serverAddr = g_nicInfo.ipAddr;
|
||||||
reqDhcp.cliAddr = ntohl(pkg->dhcp.ciaddr);
|
reqDhcp.cliAddr = ntohl(pkg->ciaddr);
|
||||||
memcpy(reqDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN);
|
memcpy(reqDhcp.cliMac, pkg->chaddr, ETH_ALEN);
|
||||||
MAC_TO_STR(reqDhcp.cliMac, macStr);
|
MAC_TO_STR(reqDhcp.cliMac, macStr);
|
||||||
|
|
||||||
switch (*optMsg.pValue) {
|
switch (*optMsg.pValue) {
|
||||||
case DHCP_MSG_DISCOVER:
|
case DHCP_MSG_DSCIOVER:
|
||||||
// region DHCP Discover 处理
|
// region DHCP Discover 处理
|
||||||
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
reqDhcp.reqIpAddr = ntohl(*((U32 *)opt.pValue));
|
reqDhcp.reqIpAddr = ntohl(*((U32 *)opt.pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dhcp_get_option(OPT_IPADDRLEASE, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_IPADDRLEASE, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
reqDhcp.leaseTime = ntohl(*((U32 *)opt.pValue));
|
reqDhcp.leaseTime = ntohl(*((U32 *)opt.pValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dhcp_get_option(OPT_CLIENTID, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_CLIENTID, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
strncpy(reqDhcp.clientId, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.clientId, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dhcp_get_option(OPT_VENDORCLASSID, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_VENDORCLASSID, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
strncpy(reqDhcp.vendorClassId, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.vendorClassId, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dhcp_get_option(OPT_HOSTNAME, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_HOSTNAME, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
@ -470,7 +596,7 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP prepare assign ipaddress: [%s(%s)] --> %s\n", reqDhcp.uid,
|
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP prepare assign ipaddress: [%s(%s)] --> %s\n", reqDhcp.uid,
|
||||||
macStr, reqDhcp.hostName, u32_to_str_ip(ntohl(ip)));
|
macStr, reqDhcp.hostName, u32_to_str_ip(ntohl(ip)));
|
||||||
|
|
||||||
ret = dhcp_resp_offer(pkg, pIpInfo, ip);
|
ret = dhcp_resp_offer(pWork->pPkgBase, pIpInfo, ip);
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Send Offer error: %d\n", ret);
|
LOG_MOD(error, ZM_DHCP_NET, "Send Offer error: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
@ -479,7 +605,7 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
||||||
|
|
||||||
// Send NACK
|
// Send NACK
|
||||||
ret = dhcp_resp_nack(pkg);
|
ret = dhcp_resp_nack(pWork->pPkgBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
|
@ -490,18 +616,18 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
case DHCP_MSG_REQUEST:
|
case DHCP_MSG_REQUEST:
|
||||||
// region DHCP Request 处理
|
// region DHCP Request 处理
|
||||||
// 客户端请求的服务器
|
// 客户端请求的服务器
|
||||||
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_SERVERID, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
reqDhcp.reqServer = ntohl(*((U32 *)opt.pValue));
|
reqDhcp.reqServer = ntohl(*((U32 *)opt.pValue));
|
||||||
} else {
|
} else {
|
||||||
// Request 服务器IP可以取目的 IP 地址
|
// Request 服务器IP可以取目的 IP 地址
|
||||||
if (pkg->hdr.ip.saddr != 0) {
|
if (pIpHdr->saddr != 0) {
|
||||||
reqDhcp.reqServer = ntohl(pkg->hdr.ip.daddr);
|
reqDhcp.reqServer = ntohl(pIpHdr->daddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 客户端请求的IP
|
// 客户端请求的IP
|
||||||
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
reqDhcp.reqIpAddr = ntohl(*((U32 *)opt.pValue));
|
reqDhcp.reqIpAddr = ntohl(*((U32 *)opt.pValue));
|
||||||
} else {
|
} else {
|
||||||
|
@ -509,7 +635,7 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 客户端主机名
|
// 客户端主机名
|
||||||
ret = dhcp_get_option(OPT_HOSTNAME, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_HOSTNAME, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
@ -529,12 +655,12 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP assign ipaddress: [%s(%s)] --> %s\n", reqDhcp.uid, macStr,
|
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP assign ipaddress: [%s(%s)] --> %s\n", reqDhcp.uid, macStr,
|
||||||
reqDhcp.hostName, u32_to_str_ip(ntohl(ctx.minAddr)));
|
reqDhcp.hostName, u32_to_str_ip(ntohl(ctx.minAddr)));
|
||||||
|
|
||||||
ret = dhcp_resp_ack(pkg, &ctx);
|
ret = dhcp_resp_ack(pWork->pPkgBase, &ctx);
|
||||||
} else {
|
} else {
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "DHCP assign ipaddress error: User %u [%s(%s)] resion %s\n",
|
LOG_MOD(error, ZM_DHCP_NET, "DHCP assign ipaddress error: User %u [%s(%s)] resion %s\n",
|
||||||
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
||||||
// Send NACK
|
// Send NACK
|
||||||
ret = dhcp_resp_nack(pkg);
|
ret = dhcp_resp_nack(pWork->pPkgBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != ERR_SUCCESS) {
|
if (ret != ERR_SUCCESS) {
|
||||||
|
@ -546,17 +672,17 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
case DHCP_MSG_RELEASE:
|
case DHCP_MSG_RELEASE:
|
||||||
// region DHCP Release 处理
|
// region DHCP Release 处理
|
||||||
// 客户端请求的服务器
|
// 客户端请求的服务器
|
||||||
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_SERVERID, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
reqDhcp.reqServer = ntohl(*((U32 *)opt.pValue));
|
reqDhcp.reqServer = ntohl(*((U32 *)opt.pValue));
|
||||||
} else {
|
} else {
|
||||||
// Request 服务器IP可以取目的 IP 地址
|
// Request 服务器IP可以取目的 IP 地址
|
||||||
if (pkg->hdr.ip.saddr != 0) {
|
if (pIpHdr->saddr != 0) {
|
||||||
reqDhcp.reqServer = ntohl(pkg->hdr.ip.saddr);
|
reqDhcp.reqServer = ntohl(pIpHdr->saddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reqDhcp.reqIpAddr = ntohl(pkg->dhcp.ciaddr);
|
reqDhcp.reqIpAddr = ntohl(pkg->ciaddr);
|
||||||
lease_release(&reqDhcp);
|
lease_release(&reqDhcp);
|
||||||
|
|
||||||
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP release lease: [%s(%s)] --> %s\n", reqDhcp.uid, macStr,
|
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP release lease: [%s(%s)] --> %s\n", reqDhcp.uid, macStr,
|
||||||
|
@ -565,7 +691,7 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_INFORM:
|
case DHCP_MSG_INFORM:
|
||||||
// 客户端主机名
|
// 客户端主机名
|
||||||
ret = dhcp_get_option(OPT_HOSTNAME, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_HOSTNAME, pkg->options, optSize, &opt);
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
@ -591,14 +717,14 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dhcp_option_prase(optMsg, pkg->dhcp.options, pWork->nSize - sizeof(DHCP_PACKAGE));
|
//dhcp_option_prase(optMsg, pkg->options, pWork->nSize - sizeof(DHCP_PACKAGE));
|
||||||
|
|
||||||
LOG_MSG_HEX(trace, pkg, pWork->nSize);
|
LOG_MSG_HEX(trace, pkg, pWork->nSize);
|
||||||
//LOG_MSG(info, "vni: %d, xid: 0x%08X\n", VLAN_VNI_ID(pkg->hdr.vlan.id), DHCP_XID(pkg->dhcp.xid));
|
//LOG_MSG(info, "vni: %d, xid: 0x%08X\n", VLAN_VNI_ID(pkg->hdr.vlan.id), DHCP_XID(pkg->xid));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
LOG_MOD(info, ZM_DHCP_NET, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->hdr.vlan.id));
|
LOG_MOD(info, ZM_DHCP_NET, "vlan = %u\n", VXLAN_VIN_ID_PACK(pkg->hdr.vlan.id));
|
||||||
LOG_MSG(info, "xid: 0x%08X\n", ntohl(pkg->dhcp.xid));
|
LOG_MSG(info, "xid: 0x%08X\n", ntohl(pkg->xid));
|
||||||
LOG_MSG(info,
|
LOG_MSG(info,
|
||||||
"dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
"dest mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||||
pkg->hdr.eth.h_dest[0],
|
pkg->hdr.eth.h_dest[0],
|
||||||
|
@ -609,16 +735,16 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
pkg->hdr.eth.h_dest[5]);
|
pkg->hdr.eth.h_dest[5]);
|
||||||
LOG_MSG(info,
|
LOG_MSG(info,
|
||||||
"client mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
"client mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||||
pkg->dhcp.chaddr[0],
|
pkg->chaddr[0],
|
||||||
pkg->dhcp.chaddr[1],
|
pkg->chaddr[1],
|
||||||
pkg->dhcp.chaddr[2],
|
pkg->chaddr[2],
|
||||||
pkg->dhcp.chaddr[3],
|
pkg->chaddr[3],
|
||||||
pkg->dhcp.chaddr[4],
|
pkg->chaddr[4],
|
||||||
pkg->dhcp.chaddr[5]);
|
pkg->chaddr[5]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void after_msg_recv(uv_work_t *req, int status) {
|
static void after_msg_recv(uv_work_t *req, int UNUSED(status)) {
|
||||||
PPKG_PROCESS_INFO pInfo = (PPKG_PROCESS_INFO)req->data;
|
PPKG_PROCESS_INFO pInfo = (PPKG_PROCESS_INFO)req->data;
|
||||||
PPKG_MSG pMsg = (PPKG_MSG)pInfo->pData;
|
PPKG_MSG pMsg = (PPKG_MSG)pInfo->pData;
|
||||||
|
|
||||||
|
@ -662,19 +788,14 @@ void raw_sock_recv_cb(uv_poll_t *handle, int status, int events) {
|
||||||
pMsg->nf = pbd->h1.num_pkts;
|
pMsg->nf = pbd->h1.num_pkts;
|
||||||
ppd = (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->h1.offset_to_first_pkt);
|
ppd = (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->h1.offset_to_first_pkt);
|
||||||
for (i = 0; i < pbd->h1.num_pkts; i++) {
|
for (i = 0; i < pbd->h1.num_pkts; i++) {
|
||||||
PDHCP_PACKAGE pkg;
|
|
||||||
U32 uid;
|
U32 uid;
|
||||||
pMsg->pPkgInfo[i].pPkgBase = ((uint8_t *)ppd + ppd->tp_mac);
|
pMsg->pPkgInfo[i].pPkgBase = ((uint8_t *)ppd + ppd->tp_mac);
|
||||||
pMsg->pPkgInfo[i].nSize = ppd->tp_snaplen;
|
pMsg->pPkgInfo[i].nSize = ppd->tp_snaplen;
|
||||||
pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i];
|
pMsg->pPkgInfo[i].uvWork.data = &pMsg->pPkgInfo[i];
|
||||||
pMsg->pPkgInfo[i].pData = pMsg;
|
pMsg->pPkgInfo[i].pData = pMsg;
|
||||||
if (g_dhcpMode == MODE_DHCP_SERVER) {
|
if (g_dhcpMode == MODE_DHCP_SERVER) {
|
||||||
#if VLAN_SUPPORT
|
uid = dhcp_get_uid(pMsg->pPkgInfo[i].pPkgBase);
|
||||||
pkg = (PDHCP_PACKAGE)pMsg->pPkgInfo[i].pPkgBase;
|
|
||||||
uid = VLAN_VNI_ID(pkg->hdr.vlan.id);
|
|
||||||
#else
|
|
||||||
uid = 0;
|
|
||||||
#endif
|
|
||||||
pMsg->pPkgInfo[i].pUser = dhcp_user_create(uid);
|
pMsg->pPkgInfo[i].pUser = dhcp_user_create(uid);
|
||||||
|
|
||||||
// LOG_MOD(trace, ZM_DHCP_NET, ">>> User %u xid %08X addr %p\n", uid, DHCP_XID(pkg->dhcp.xid),
|
// LOG_MOD(trace, ZM_DHCP_NET, ">>> User %u xid %08X addr %p\n", uid, DHCP_XID(pkg->dhcp.xid),
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef struct {
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VLAN_PKG_HDR hdr;
|
VLAN_PKG_HDR1 hdr;
|
||||||
DHCP_PROTO dhcp;
|
DHCP_PROTO dhcp;
|
||||||
} DHCP_PACKAGE, *PDHCP_PACKAGE;
|
} DHCP_PACKAGE, *PDHCP_PACKAGE;
|
||||||
|
|
||||||
|
|
|
@ -95,18 +95,14 @@ int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX
|
||||||
addr = pPool->minAddr;
|
addr = pPool->minAddr;
|
||||||
do {
|
do {
|
||||||
PLOCK_IP pLock;
|
PLOCK_IP pLock;
|
||||||
|
|
||||||
HASH_FIND_INT(pUser->plockIp, &addr, pLock);
|
HASH_FIND_INT(pUser->plockIp, &addr, pLock);
|
||||||
|
|
||||||
// 该 IP 可用
|
// 该 IP 可用
|
||||||
if (pLock == NULL) {
|
if (pLock == NULL) {
|
||||||
if (db_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
|
if (db_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
|
||||||
usr_lease_lock_ip(pUser, addr);
|
usr_lease_lock_ip(pUser, addr);
|
||||||
*pOutIp = addr;
|
*pOutIp = addr;
|
||||||
*pOutPool = pPool;
|
*pOutPool = pPool;
|
||||||
|
|
||||||
db_add_pre_assign(pReq, addr, pPool);
|
db_add_pre_assign(pReq, addr, pPool);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue