OCT 1. DHCP 服务支持 ACK, RELEASE, INFO 消息处理
2. DHCP 测试工具支持接收 ACK数据
This commit is contained in:
parent
6ef6baaba3
commit
85b6b108df
|
@ -78,6 +78,7 @@ int dhcp_tools_init_network(const char *pNicName);
|
||||||
U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize);
|
U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize);
|
||||||
U8 *dhcp_create_request_req(PDHCP_INFO pInfo, int *pOutSize);
|
U8 *dhcp_create_request_req(PDHCP_INFO pInfo, int *pOutSize);
|
||||||
int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size);
|
int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size);
|
||||||
|
int cacheDhcpAckBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size);
|
||||||
void details_wnd_create(GtkBuilder *builder);
|
void details_wnd_create(GtkBuilder *builder);
|
||||||
void details_wnd_show(PDHCP_INFO pInfo);
|
void details_wnd_show(PDHCP_INFO pInfo);
|
||||||
#endif //VCPE_MAIN_H
|
#endif //VCPE_MAIN_H
|
||||||
|
|
|
@ -316,6 +316,17 @@ int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) {
|
||||||
return -ERR_MALLOC_MEMORY;
|
return -ERR_MALLOC_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cacheDhcpAckBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) {
|
||||||
|
pInfo->pAckBuf.p = (U8 *)malloc(size);
|
||||||
|
if (pInfo->pAckBuf.p) {
|
||||||
|
memcpy(pInfo->pAckBuf.p, pBuf, size);
|
||||||
|
pInfo->pAckBuf.buf_size = size;
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ERR_MALLOC_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
_Noreturn static void *dhcpThreadCb(void *pData) {
|
_Noreturn static void *dhcpThreadCb(void *pData) {
|
||||||
U8 *pkg;
|
U8 *pkg;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Created by xajhuang on 2023/4/20.
|
// Created by xajhuang on 2023/4/20.
|
||||||
//
|
//
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <linux/filter.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "user_errno.h"
|
#include "user_errno.h"
|
||||||
#include "dhcp_network.h"
|
#include "dhcp_network.h"
|
||||||
|
@ -233,6 +232,11 @@ static void on_dhcp_recv(uv_work_t *req) {
|
||||||
memcpy(&pInfo->offerRsp, &rspDhcp, sizeof(DHCP_RSP));
|
memcpy(&pInfo->offerRsp, &rspDhcp, sizeof(DHCP_RSP));
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_ACK:
|
case DHCP_MSG_ACK:
|
||||||
|
pInfo->step = STEP_ACK;
|
||||||
|
pInfo->status = STA_RECV_RSP;
|
||||||
|
|
||||||
|
cacheDhcpAckBuffer(pInfo, pWork->pPkgBase, pWork->nSize);
|
||||||
|
memcpy(&pInfo->ackRsp, &rspDhcp, sizeof(DHCP_RSP));
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_NAK:
|
case DHCP_MSG_NAK:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,14 +25,13 @@
|
||||||
" mac CHAR(20) NOT NULL," \
|
" mac CHAR(20) NOT NULL," \
|
||||||
" ip INTEGER NOT NULL," \
|
" ip INTEGER NOT NULL," \
|
||||||
" lease INTEGER NOT NULL," \
|
" lease INTEGER NOT NULL," \
|
||||||
" createTm INTEGER NOT NULL," \
|
|
||||||
" netmask INTEGER," \
|
" netmask INTEGER," \
|
||||||
" gateway INTEGER," \
|
" gateway INTEGER," \
|
||||||
" dns1 INTEGER," \
|
" dns1 INTEGER," \
|
||||||
" dns2 INTEGER," \
|
" dns2 INTEGER," \
|
||||||
" server INTEGER NOT NULL," \
|
" server INTEGER NOT NULL," \
|
||||||
" hostname CHAR(64) DEFAULT '' NOT NULL," \
|
" hostname CHAR(64) DEFAULT '' NOT NULL," \
|
||||||
" keyType INTEGER NOT NULL" \
|
" createTm TIMESTAMP DEFAULT (datetime('now', 'localtime')) NOT NULL" \
|
||||||
");" \
|
");" \
|
||||||
"CREATE INDEX IF NOT EXISTS " \
|
"CREATE INDEX IF NOT EXISTS " \
|
||||||
"lease_index ON lease (uid, mac);"
|
"lease_index ON lease (uid, mac);"
|
||||||
|
@ -80,10 +79,121 @@
|
||||||
"SELECT ip, uid FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) < %d;"
|
"SELECT ip, uid FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) < %d;"
|
||||||
|
|
||||||
#define CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT \
|
#define CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT \
|
||||||
"DELETE FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - - strftime('%%s', createTm)) > %d"
|
"DELETE FROM pre_assign WHERE (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) > %d;"
|
||||||
|
|
||||||
#define UPDATE_CREATE_TIME_BY_ID_FMT "UPDATE pre_assign SET createTm = datetime('now', 'localtime') WHERE id = %s"
|
#define UPDATE_CREATE_TIME_BY_ID_FMT "UPDATE pre_assign SET createTm = datetime('now', 'localtime') WHERE id = %s"
|
||||||
|
|
||||||
|
#define INSERT_LEASE_FMT \
|
||||||
|
"INSERT INTO lease(uid, hostname, mac, ip, lease, netmask, gateway, dns1, dns2, server) " \
|
||||||
|
"VALUES (%d, '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s');"
|
||||||
|
|
||||||
|
#define LEASE_FIND_ITEM_FMT \
|
||||||
|
"SELECT id FROM lease WHERE mac = '%s' AND hostname = '%s' AND uid = %d AND ip = '%s' ORDER BY createTm DESC " \
|
||||||
|
"LIMIT 1;"
|
||||||
|
|
||||||
|
#define LEASE_ITEM_UPDATE_FMT \
|
||||||
|
"UPDATE lease SET lease = %d, netmask = '%s', gateway = '%s', dns1 = '%s', dns2 = '%s', server = '%s', " \
|
||||||
|
"createTm = datetime('now', 'localtime') WHERE id = %s;"
|
||||||
|
|
||||||
|
#define CLS_TIMEOUT_LEASE_ROW_FMT \
|
||||||
|
"DELETE FROM lease WHERE (strftime('%%s', 'now', 'localtime') - - strftime('%%s', createTm)) > lease.lease"
|
||||||
|
|
||||||
|
#define GET_LEASE_ROW_FMT \
|
||||||
|
"SELECT ip, uid FROM lease WHERE (strftime('%%s', 'now', 'localtime') - strftime('%%s', createTm)) < lease.lease;"
|
||||||
|
|
||||||
|
#define GET_LEASE_EXISTS_ROW_FMT \
|
||||||
|
"SELECT ip, id FROM lease WHERE mac = '%s' AND hostname = '%s' AND uid = %d AND (strftime('%%s', 'now', " \
|
||||||
|
"'localtime') - strftime('%%s', createTm)) < lease.lease ORDER BY createTm DESC LIMIT 1;"
|
||||||
|
|
||||||
|
#define GET_LEASE_INFO_FMT \
|
||||||
|
"SELECT id, ip, lease, netmask, gateway, dns1, dns2 FROM lease WHERE mac = '%s' AND hostname = '%s' AND " \
|
||||||
|
"uid = %d AND server = '%s' AND (strftime('%%s', 'now','localtime') - strftime('%%s', createTm)) < lease.lease " \
|
||||||
|
"ORDER BY createTm DESC LIMIT 1;"
|
||||||
|
|
||||||
|
#define UPDATE_LEASE_TIME_BY_ID_FMT "UPDATE lease SET createTm = datetime('now', 'localtime') WHERE id = %llu"
|
||||||
|
|
||||||
|
#define LEASE_RELEASE_FMT "DELETE FROM lease WHERE uid = %d AND mac = '%s' AND ip = '%s'"
|
||||||
|
|
||||||
|
|
||||||
|
static int lease_add(PDHCP_REQ pReq,
|
||||||
|
const char *ip,
|
||||||
|
const char *netmask,
|
||||||
|
const char *gw,
|
||||||
|
const char *dns1,
|
||||||
|
const char *dns2,
|
||||||
|
U32 leaseTime) {
|
||||||
|
int rc;
|
||||||
|
char buf[2048] = {0};
|
||||||
|
char macStr[20] = {0};
|
||||||
|
char **dbResult;
|
||||||
|
int nRow = 0, nColumn = 0;
|
||||||
|
|
||||||
|
MAC_TO_STR(pReq->cliMac, macStr);
|
||||||
|
snprintf(buf, 2048, LEASE_FIND_ITEM_FMT, macStr, pReq->hostName, pReq->uid, ip);
|
||||||
|
|
||||||
|
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
||||||
|
if (rc == ERR_SUCCESS) {
|
||||||
|
// 已经存在,则更新
|
||||||
|
if (nRow > 0 && nColumn > 0) {
|
||||||
|
memset(buf, 0, 2048);
|
||||||
|
snprintf(buf, 2048, LEASE_ITEM_UPDATE_FMT, leaseTime, netmask, gw, dns1, dns2,
|
||||||
|
u32_to_str_ip(pReq->serverAddr), dbResult[nColumn]);
|
||||||
|
rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
if (rc != ERR_SUCCESS) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_DB, "Add upgrade to lease db error: id = %s\n", dbResult[nColumn]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//添加一个新的
|
||||||
|
// 记录设备分配的DHCP信息到数据库
|
||||||
|
memset(buf, 0, 2048);
|
||||||
|
snprintf(buf, 2048, INSERT_LEASE_FMT, pReq->uid, pReq->hostName, macStr, ip, leaseTime, netmask, gw, dns1,
|
||||||
|
dns2, u32_to_str_ip(pReq->serverAddr));
|
||||||
|
|
||||||
|
rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (rc != ERR_SUCCESS) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_DB, "Add date to lease db error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_add_lease(PDHCP_REQ pReq, PPOOL_CTX pCtx) {
|
||||||
|
const char *pNetmask = u32_to_str_ip_safe(htonl(pCtx->netMask));
|
||||||
|
const char *pGateway = u32_to_str_ip_safe(htonl(pCtx->gwAddr));
|
||||||
|
const char *pDns1 = u32_to_str_ip_safe(htonl(pCtx->primeDNS));
|
||||||
|
const char *pDns2 = u32_to_str_ip_safe(htonl(pCtx->salveDNS));
|
||||||
|
const char *pIp = u32_to_str_ip_safe(htonl(pReq->cliAddr));
|
||||||
|
|
||||||
|
// 添加租约信息到lease数据库
|
||||||
|
lease_add(pReq, pIp, pNetmask, pGateway, pDns1, pDns2, pCtx->leaseTime);
|
||||||
|
|
||||||
|
free((void *)pNetmask);
|
||||||
|
free((void *)pGateway);
|
||||||
|
free((void *)pDns1);
|
||||||
|
free((void *)pDns2);
|
||||||
|
free((void *)pIp);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_release_lease(PDHCP_REQ pReq) {
|
||||||
|
int rc;
|
||||||
|
char buf[1024] = {0};
|
||||||
|
char macStr[20] = {0};
|
||||||
|
MAC_TO_STR(pReq->cliMac, macStr);
|
||||||
|
snprintf(buf, 1024, LEASE_RELEASE_FMT, pReq->uid, macStr, u32_to_str_ip(htonl(pReq->reqIpAddr)));
|
||||||
|
|
||||||
|
rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (rc != ERR_SUCCESS) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_DB, "DB remove lease item error: %s\n", buf);
|
||||||
|
}
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int lease_lock_pre_assign_ip() {
|
int lease_lock_pre_assign_ip() {
|
||||||
int rc;
|
int rc;
|
||||||
char buf[1024] = {0};
|
char buf[1024] = {0};
|
||||||
|
@ -109,19 +219,45 @@ int lease_lock_pre_assign_ip() {
|
||||||
}
|
}
|
||||||
sqlite3_free_table(dbResult);
|
sqlite3_free_table(dbResult);
|
||||||
|
|
||||||
|
memset(buf, 0, 1024);
|
||||||
|
snprintf(buf, 1024, GET_LEASE_ROW_FMT);
|
||||||
|
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
||||||
|
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
|
||||||
|
int i;
|
||||||
|
for (i = 1; i <= nRow; i++) {
|
||||||
|
U32 uid = strtoul(dbResult[i * nColumn + 1], NULL, 10);
|
||||||
|
U32 ip = ntohl(inet_addr(dbResult[i * nColumn]));
|
||||||
|
PDHCP_USER pUser = dhcp_user_create(uid);
|
||||||
|
if (pUser) {
|
||||||
|
usr_lease_lock_ip(pUser, ip);
|
||||||
|
LOG_MOD(debug, ZM_DHCP_DB, "Lock prepare assign ip %s for user %u\n", dbResult[i * nColumn], uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lease_clearup_timeout_pre_assign() {
|
int lease_clearup_timeout_items() {
|
||||||
int rc;
|
int rc;
|
||||||
char buf[1024] = {0};
|
char buf[1024] = {0};
|
||||||
|
|
||||||
snprintf(buf, 1024, CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT, DCHP_STEP_CLEANUP_TIMEOUT);
|
snprintf(buf, 1024, CLS_TIMEOUT_PRE_ASSIGN_ROW_FMT, DCHP_STEP_CLEANUP_TIMEOUT);
|
||||||
|
|
||||||
rc = db_sqlite3_sql_exec(CREATE_LEASE_TABLE(), NULL, NULL, NULL);
|
rc = db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
LOG_MOD(trace, ZM_DHCP_DB, "Cleanup pre_assign database timeout(%u seconds) data\n", DCHP_STEP_CLEANUP_TIMEOUT);
|
||||||
|
|
||||||
if (rc != ERR_SUCCESS) {
|
if (rc != ERR_SUCCESS) {
|
||||||
return rc;
|
LOG_MOD(error, ZM_DHCP_DB, "Cleanup pre_assign database error: %s\n", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = db_sqlite3_sql_exec(CLS_TIMEOUT_LEASE_ROW_FMT, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
LOG_MOD(trace, ZM_DHCP_DB, "Cleanup assign database lease expire data\n");
|
||||||
|
if (rc != ERR_SUCCESS) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_DB, "Cleanup lease database error: %s\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
@ -176,18 +312,110 @@ int lease_ip_is_pre_assign(U32 uid, U32 ip) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lease_get_assign_info(PDHCP_REQ pReq, PPOOL_CTX pAssign, U64 *pCtx) {
|
static int lease_get_info(PPOOL_CTX pAssign, const char *pRunSql, U64 *pDbId) {
|
||||||
int rc;
|
int rc;
|
||||||
char buf[2048] = {0};
|
|
||||||
char macStr[20] = {0};
|
|
||||||
U32 ipAddr;
|
|
||||||
char **dbResult;
|
char **dbResult;
|
||||||
int nRow = 0, nColumn = 0;
|
int nRow = 0, nColumn = 0;
|
||||||
|
|
||||||
|
rc = db_sqlite3_get_rows(pRunSql, &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));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDbId) {
|
||||||
|
*pDbId = strtoull(dbResult[nColumn], NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
} else {
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
return -ERR_ITEM_UNEXISTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int lease_get_from_lease(PDHCP_REQ pReq, PPOOL_CTX pAssign) {
|
||||||
|
int rc;
|
||||||
|
U64 id;
|
||||||
|
char buf[2048] = {0};
|
||||||
|
char macStr[20] = {0};
|
||||||
|
|
||||||
MAC_TO_STR(pReq->cliMac, macStr);
|
MAC_TO_STR(pReq->cliMac, macStr);
|
||||||
snprintf(buf, 1024, GET_ASSIGN_IP_INFO_FMT, macStr, pReq->hostName, pReq->uid, u32_to_str_ip(pReq->serverAddr),
|
snprintf(buf, 2048, GET_LEASE_INFO_FMT, macStr, pReq->hostName, pReq->uid, u32_to_str_ip(pReq->serverAddr));
|
||||||
|
|
||||||
|
rc = lease_get_info(pAssign, buf, &id);
|
||||||
|
if (rc == ERR_SUCCESS) {
|
||||||
|
// 更新租约时间信息
|
||||||
|
memset(buf, 0, 1024);
|
||||||
|
snprintf(buf, 1024, UPDATE_LEASE_TIME_BY_ID_FMT, id);
|
||||||
|
|
||||||
|
if (db_sqlite3_sql_exec(buf, NULL, NULL, NULL) != ERR_SUCCESS) {
|
||||||
|
LOG_MOD(warn, ZM_DHCP_DB, "Update %llu lease time error: %s\n", id, buf);
|
||||||
|
}
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ERR_ITEM_UNEXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lease_get_from_pre_assign(PDHCP_REQ pReq, PPOOL_CTX pAssign) {
|
||||||
|
int rc;
|
||||||
|
char buf[2048] = {0};
|
||||||
|
char macStr[20] = {0};
|
||||||
|
U64 id;
|
||||||
|
|
||||||
|
MAC_TO_STR(pReq->cliMac, macStr);
|
||||||
|
snprintf(buf, 2048, GET_ASSIGN_IP_INFO_FMT, macStr, pReq->hostName, pReq->uid, u32_to_str_ip(pReq->serverAddr),
|
||||||
DCHP_STEP_REQUEST_TIMEOUT);
|
DCHP_STEP_REQUEST_TIMEOUT);
|
||||||
|
|
||||||
|
rc = lease_get_info(pAssign, buf, &id);
|
||||||
|
|
||||||
|
if (rc == ERR_SUCCESS) {
|
||||||
|
const char *pNetmask = u32_to_str_ip_safe(htonl(pAssign->netMask));
|
||||||
|
const char *pGateway = u32_to_str_ip_safe(htonl(pAssign->gwAddr));
|
||||||
|
const char *pDns1 = u32_to_str_ip_safe(htonl(pAssign->primeDNS));
|
||||||
|
const char *pDns2 = u32_to_str_ip_safe(htonl(pAssign->salveDNS));
|
||||||
|
const char *pIp = u32_to_str_ip_safe(htonl(pAssign->minAddr));
|
||||||
|
|
||||||
|
// 删除预分配IP信息
|
||||||
|
memset(buf, 0, 2048);
|
||||||
|
sprintf(buf, "DELETE FROM pre_assign WHERE id = %llu;", id);
|
||||||
|
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// 添加租约信息到lease数据库
|
||||||
|
lease_add(pReq, pIp, pNetmask, pGateway, pDns1, pDns2, pAssign->leaseTime);
|
||||||
|
|
||||||
|
free((void *)pNetmask);
|
||||||
|
free((void *)pGateway);
|
||||||
|
free((void *)pDns1);
|
||||||
|
free((void *)pDns2);
|
||||||
|
free((void *)pIp);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
return -ERR_ITEM_UNEXISTS;
|
||||||
|
#if 0
|
||||||
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
||||||
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
|
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
|
||||||
char *pNetmask = dbResult[nColumn + 3];
|
char *pNetmask = dbResult[nColumn + 3];
|
||||||
|
@ -215,11 +443,22 @@ int lease_get_assign_info(PDHCP_REQ pReq, PPOOL_CTX pAssign, U64 *pCtx) {
|
||||||
pAssign->salveDNS = ntohl(inet_addr(pDns2));
|
pAssign->salveDNS = ntohl(inet_addr(pDns2));
|
||||||
}
|
}
|
||||||
|
|
||||||
*pCtx = strtoull(dbResult[nColumn], NULL, 10);
|
// 删除预分配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;
|
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;
|
return -ERR_ITEM_UNEXISTS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign) {
|
int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign) {
|
||||||
|
@ -239,13 +478,30 @@ int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *pr
|
||||||
snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);
|
snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);
|
||||||
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
rc = ERR_ITEM_EXISTS;
|
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
return ERR_ITEM_EXISTS;
|
||||||
} else {
|
} else {
|
||||||
rc = ERR_ITEM_UNEXISTS;
|
memset(buf, 0, 1024);
|
||||||
|
snprintf(buf, 1024, GET_LEASE_EXISTS_ROW_FMT, mac, hostname, uid);
|
||||||
|
|
||||||
|
rc = db_sqlite3_get_rows(buf, &dbResult, &nRow, &nColumn, NULL);
|
||||||
|
if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) {
|
||||||
|
if (preAssign) {
|
||||||
|
*preAssign = ntohl(inet_addr(dbResult[2]));
|
||||||
|
// 更新时间戳
|
||||||
|
memset(buf, 0, 1024);
|
||||||
|
snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);
|
||||||
|
db_sqlite3_sql_exec(buf, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_free_table(dbResult);
|
sqlite3_free_table(dbResult);
|
||||||
return rc;
|
return ERR_ITEM_EXISTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_free_table(dbResult);
|
||||||
|
return ERR_ITEM_UNEXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool) {
|
int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool) {
|
||||||
|
|
|
@ -187,7 +187,12 @@ static void fill_package(PDHCP_PACKAGE pRsp, PDHCP_PACKAGE pReq) {
|
||||||
|
|
||||||
// 二层头
|
// 二层头
|
||||||
// 目的IP地址
|
// 目的IP地址
|
||||||
|
if (pReq->vlan_hdr.ip.saddr != 0) {
|
||||||
|
memcpy(pRsp->vlan_hdr.eth.h_dest, pRsp->vlan_hdr.eth.h_source, ETH_ALEN);
|
||||||
|
} else {
|
||||||
memset(pRsp->vlan_hdr.eth.h_dest, 0xFF, ETH_ALEN);
|
memset(pRsp->vlan_hdr.eth.h_dest, 0xFF, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
// 源 IP 地址
|
// 源 IP 地址
|
||||||
memcpy(pRsp->vlan_hdr.eth.h_source, g_nicInfo.macAddr, ETH_ALEN);
|
memcpy(pRsp->vlan_hdr.eth.h_source, g_nicInfo.macAddr, ETH_ALEN);
|
||||||
// protol
|
// protol
|
||||||
|
@ -205,7 +210,11 @@ static void fill_package(PDHCP_PACKAGE pRsp, PDHCP_PACKAGE pReq) {
|
||||||
// 更新源IP
|
// 更新源IP
|
||||||
pRsp->vlan_hdr.ip.saddr = g_nicInfo.ipAddr;
|
pRsp->vlan_hdr.ip.saddr = g_nicInfo.ipAddr;
|
||||||
// 更新目的IP地址,广播255.255.255.255
|
// 更新目的IP地址,广播255.255.255.255
|
||||||
|
if (pReq->vlan_hdr.ip.saddr == 0) {
|
||||||
pRsp->vlan_hdr.ip.daddr = 0xFFFFFFFF;
|
pRsp->vlan_hdr.ip.daddr = 0xFFFFFFFF;
|
||||||
|
} else {
|
||||||
|
pRsp->vlan_hdr.ip.daddr = pReq->vlan_hdr.ip.saddr;
|
||||||
|
}
|
||||||
|
|
||||||
// UDP 头
|
// UDP 头
|
||||||
// 目的端口
|
// 目的端口
|
||||||
|
@ -239,10 +248,60 @@ static void fill_package(PDHCP_PACKAGE pRsp, PDHCP_PACKAGE pReq) {
|
||||||
pRsp->dhcp.giaddr = 0;
|
pRsp->dhcp.giaddr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_resp_ack(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo) {
|
static int dhcp_prepare_tx(U8 *pOpt, PDHCP_PACKAGE pRsp) {
|
||||||
U8 *pOpt;
|
|
||||||
U16 csum;
|
U16 csum;
|
||||||
int tolSize;
|
int tolSize;
|
||||||
|
// 计算包总长度
|
||||||
|
tolSize = (int)((pOpt - pRsp->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
||||||
|
|
||||||
|
// 计算 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, 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);
|
||||||
|
|
||||||
|
// 发送数据
|
||||||
|
if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_NET, "Send package(%u bytes) error\n", tolSize);
|
||||||
|
return -ERR_SOCK_SEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcp_resp_nack(PDHCP_PACKAGE pReq) {
|
||||||
|
U8 *pOpt;
|
||||||
|
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
|
if (pRsp == NULL) {
|
||||||
|
LOG_MOD(error, ZM_DHCP_NET, "Malloc memory error: %u\n", MAX_DHCP_PKG_SIZE);
|
||||||
|
return -ERR_MALLOC_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_package(pRsp, pReq);
|
||||||
|
|
||||||
|
// DHCP Options
|
||||||
|
pOpt = pRsp->dhcp.options;
|
||||||
|
|
||||||
|
// DHCP 消息类型
|
||||||
|
pOpt += dhcp_add_u8_option(pOpt, OPT_MESSAGETYPE, DHCP_MSG_NAK);
|
||||||
|
*pOpt = OPT_END;
|
||||||
|
|
||||||
|
return dhcp_prepare_tx(pOpt, pRsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcp_resp_ack(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo) {
|
||||||
|
U8 *pOpt;
|
||||||
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
if (pRsp == NULL) {
|
if (pRsp == NULL) {
|
||||||
|
@ -286,38 +345,11 @@ 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);
|
||||||
tolSize = (int)((pOpt - pRsp->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
|
||||||
|
|
||||||
// 计算 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, 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);
|
|
||||||
|
|
||||||
// 发送数据
|
|
||||||
if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) {
|
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Send package(%u bytes) error\n", tolSize);
|
|
||||||
return -ERR_SOCK_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo, U32 ip) {
|
static int dhcp_resp_offer(PDHCP_PACKAGE pReq, PPOOL_CTX pIpInfo, U32 ip) {
|
||||||
U8 *pOpt;
|
U8 *pOpt;
|
||||||
U16 csum;
|
|
||||||
int tolSize;
|
|
||||||
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
PDHCP_PACKAGE pRsp = get_pkg_free_buf();
|
||||||
|
|
||||||
if (pRsp == NULL) {
|
if (pRsp == NULL) {
|
||||||
|
@ -360,32 +392,7 @@ 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);
|
||||||
tolSize = (int)((pOpt - pRsp->dhcp.options) + 1 + sizeof(DHCP_PACKAGE));
|
|
||||||
|
|
||||||
// 计算 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, 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);
|
|
||||||
|
|
||||||
// 发送数据
|
|
||||||
if (pkg_mmap_tx((U8 *)pRsp, tolSize) != tolSize) {
|
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Send package(%u bytes) error\n", tolSize);
|
|
||||||
return -ERR_SOCK_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_sock_recv(uv_work_t *req) {
|
static void on_sock_recv(uv_work_t *req) {
|
||||||
|
@ -419,7 +426,9 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
reqDhcp.xid = DHCP_XID(pkg->dhcp.xid);
|
reqDhcp.xid = DHCP_XID(pkg->dhcp.xid);
|
||||||
reqDhcp.uid = VLAN_VNI_ID(pkg->vlan_hdr.vlan.id);
|
reqDhcp.uid = VLAN_VNI_ID(pkg->vlan_hdr.vlan.id);
|
||||||
reqDhcp.serverAddr = g_nicInfo.ipAddr;
|
reqDhcp.serverAddr = g_nicInfo.ipAddr;
|
||||||
|
reqDhcp.cliAddr = ntohl(pkg->dhcp.ciaddr);
|
||||||
memcpy(reqDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN);
|
memcpy(reqDhcp.cliMac, pkg->dhcp.chaddr, ETH_ALEN);
|
||||||
|
MAC_TO_STR(reqDhcp.cliMac, macStr);
|
||||||
|
|
||||||
switch (*optMsg.pValue) {
|
switch (*optMsg.pValue) {
|
||||||
case DHCP_MSG_DISCOVER:
|
case DHCP_MSG_DISCOVER:
|
||||||
|
@ -449,7 +458,6 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
}
|
}
|
||||||
|
|
||||||
MAC_TO_STR(reqDhcp.cliMac, macStr);
|
|
||||||
ret = pre_alloc_dhcp_res(&reqDhcp, pWork->pUser, &ip, &pIpInfo);
|
ret = pre_alloc_dhcp_res(&reqDhcp, pWork->pUser, &ip, &pIpInfo);
|
||||||
|
|
||||||
if (ret == ERR_SUCCESS) {
|
if (ret == ERR_SUCCESS) {
|
||||||
|
@ -457,7 +465,6 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
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(pkg, 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);
|
||||||
}
|
}
|
||||||
|
@ -468,15 +475,24 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
// endregion
|
// endregion
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_REQUEST:
|
case DHCP_MSG_REQUEST:
|
||||||
|
// region DHCP Request 处理
|
||||||
// 客户端请求的服务器
|
// 客户端请求的服务器
|
||||||
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.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 {
|
||||||
|
// Request 服务器IP可以取目的 IP 地址
|
||||||
|
if (pkg->vlan_hdr.ip.saddr != 0) {
|
||||||
|
reqDhcp.reqServer = ntohl(pkg->vlan_hdr.ip.daddr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 客户端请求的IP
|
// 客户端请求的IP
|
||||||
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.options, optSize, &opt);
|
ret = dhcp_get_option(OPT_REQUESTEDIPADDR, pkg->dhcp.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 {
|
||||||
|
reqDhcp.reqIpAddr = reqDhcp.cliAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 客户端主机名
|
// 客户端主机名
|
||||||
|
@ -495,29 +511,64 @@ static void on_sock_recv(uv_work_t *req) {
|
||||||
free((void *)pLocal);
|
free((void *)pLocal);
|
||||||
} else {
|
} else {
|
||||||
POOL_CTX ctx = {0};
|
POOL_CTX ctx = {0};
|
||||||
U64 id = 0;
|
if ((ret = is_pre_assigned(&reqDhcp, &ctx)) == ERR_SUCCESS) {
|
||||||
|
|
||||||
if ((ret = is_pre_assigned(&reqDhcp, &ctx, &id)) == ERR_SUCCESS) {
|
|
||||||
MAC_TO_STR(reqDhcp.cliMac, macStr);
|
|
||||||
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(pkg, &ctx);
|
||||||
|
} else {
|
||||||
|
LOG_MOD(error, ZM_DHCP_NET, "DHCP assign ipaddress error: User %u [%s(%s)] resion %s\n",
|
||||||
|
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
||||||
|
// Send NACK
|
||||||
|
ret = dhcp_resp_nack(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "DHCP assign ipaddress error: User %u [%s(%s)] resion %s\n",
|
|
||||||
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_RELEASE:
|
case DHCP_MSG_RELEASE:
|
||||||
|
// region DHCP Release 处理
|
||||||
|
// 客户端请求的服务器
|
||||||
|
ret = dhcp_get_option(OPT_SERVERID, pkg->dhcp.options, optSize, &opt);
|
||||||
|
if (ret == ERR_SUCCESS && opt.len == sizeof(U32)) {
|
||||||
|
reqDhcp.reqServer = ntohl(*((U32 *)opt.pValue));
|
||||||
|
} else {
|
||||||
|
// Request 服务器IP可以取目的 IP 地址
|
||||||
|
if (pkg->vlan_hdr.ip.saddr != 0) {
|
||||||
|
reqDhcp.reqServer = ntohl(pkg->vlan_hdr.ip.saddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reqDhcp.reqIpAddr = ntohl(pkg->dhcp.ciaddr);
|
||||||
|
lease_release(&reqDhcp);
|
||||||
|
|
||||||
|
LOG_MOD(debug, ZM_DHCP_NET, "User %u DHCP release lease: [%s(%s)] --> %s\n", reqDhcp.uid, macStr,
|
||||||
|
reqDhcp.hostName, u32_to_str_ip(ntohl(reqDhcp.reqIpAddr)));
|
||||||
|
// endregion
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_INFORM:
|
case DHCP_MSG_INFORM:
|
||||||
|
// 客户端主机名
|
||||||
|
ret = dhcp_get_option(OPT_HOSTNAME, pkg->dhcp.options, optSize, &opt);
|
||||||
|
if (ret == ERR_SUCCESS) {
|
||||||
|
strncpy(reqDhcp.hostName, (char *)opt.pValue, MIN((int)opt.len, 256));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前分配的租约添加到本地数据库中, 后续分配能够发现对应的主机信息
|
||||||
|
ret = lease_add_host(&reqDhcp);
|
||||||
|
|
||||||
|
if (ret == ERR_SUCCESS) {
|
||||||
|
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(reqDhcp.cliAddr)));
|
||||||
|
} else {
|
||||||
|
LOG_MOD(error, ZM_DHCP_NET, "DHCP prepare assign ipaddress error: User %u [%s(%s)] resion %s\n",
|
||||||
|
reqDhcp.uid, macStr, reqDhcp.hostName, getErrorEnumNameString(ret));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DHCP_MSG_DECLINE:
|
case DHCP_MSG_DECLINE:
|
||||||
|
// 清理掉上次分配的租约
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_MOD(error, ZM_DHCP_NET, "Unkonwn DHCP message type: %d\n", *optMsg.pValue);
|
LOG_MOD(error, ZM_DHCP_NET, "Unkonwn DHCP message type: %d\n", *optMsg.pValue);
|
||||||
|
|
|
@ -11,9 +11,12 @@ int lease_db_add_pre_assign(PDHCP_REQ pReq, U32 ip, PPOOL_CTX pPool);
|
||||||
int lease_init_database();
|
int lease_init_database();
|
||||||
int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign);
|
int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *preAssign);
|
||||||
int lease_ip_is_pre_assign(U32 uid, U32 ip);
|
int lease_ip_is_pre_assign(U32 uid, U32 ip);
|
||||||
int lease_get_assign_info(PDHCP_REQ pReq, PPOOL_CTX pAssign, U64 *pCtx);
|
int lease_get_from_pre_assign(PDHCP_REQ pReq, PPOOL_CTX pAssign);
|
||||||
int lease_clearup_timeout_pre_assign();
|
int lease_get_from_lease(PDHCP_REQ pReq, PPOOL_CTX pAssign);
|
||||||
|
int lease_clearup_timeout_items();
|
||||||
int lease_lock_pre_assign_ip();
|
int lease_lock_pre_assign_ip();
|
||||||
|
int db_release_lease(PDHCP_REQ pReq);
|
||||||
|
int db_add_lease(PDHCP_REQ pReq, PPOOL_CTX pCtx);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,7 +31,9 @@ typedef struct {
|
||||||
int dhcp_lease_init();
|
int dhcp_lease_init();
|
||||||
int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX *pOutPool);
|
int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX *pOutPool);
|
||||||
int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip);
|
int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip);
|
||||||
int is_pre_assigned(PDHCP_REQ pReq, PPOOL_CTX pCtx, U64 *dbId);
|
int is_pre_assigned(PDHCP_REQ pReq, PPOOL_CTX pCtx);
|
||||||
|
int lease_release(PDHCP_REQ pReq);
|
||||||
|
int lease_add_host(PDHCP_REQ pReq);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct {
|
||||||
char vendorClassId[256];
|
char vendorClassId[256];
|
||||||
U32 reqServer;
|
U32 reqServer;
|
||||||
U32 serverAddr;
|
U32 serverAddr;
|
||||||
|
U32 cliAddr;
|
||||||
char hostName[256];
|
char hostName[256];
|
||||||
} DHCP_REQ, *PDHCP_REQ;
|
} DHCP_REQ, *PDHCP_REQ;
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,36 @@ int usr_lease_lock_ip(PDHCP_USER pUser, U32 ip) {
|
||||||
return -ERR_MALLOC_MEMORY;
|
return -ERR_MALLOC_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_pre_assigned(PDHCP_REQ pReq, PPOOL_CTX pCtx, U64 *dbId) {
|
int lease_add_host(PDHCP_REQ pReq) {
|
||||||
return lease_get_assign_info(pReq, pCtx, dbId);
|
PDHCP_USER pUser = dhcp_user_create(pReq->uid);
|
||||||
|
|
||||||
|
if (pUser) {
|
||||||
|
PPOOL_CTX pPool, pTemp;
|
||||||
|
// 查找对应的地址池
|
||||||
|
LL_FOREACH_SAFE(pUser->pUserPool, pPool, pTemp) {
|
||||||
|
// 比较 IP 范围
|
||||||
|
if (pPool->minAddr <= pReq->cliAddr && pPool->maxAddr >= pReq->cliAddr) {
|
||||||
|
// 添加记录到数据库
|
||||||
|
db_add_lease(pReq, pPool);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_pre_assigned(PDHCP_REQ pReq, PPOOL_CTX pCtx) {
|
||||||
|
// 首先从租约信息中获取数据
|
||||||
|
if (lease_get_from_lease(pReq, pCtx) == ERR_SUCCESS) {
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
// 从预分配IP中获取信息
|
||||||
|
return lease_get_from_pre_assign(pReq, pCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lease_release(PDHCP_REQ pReq) {
|
||||||
|
return db_release_lease(pReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
//int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
|
//int pre_alloc_dhcp_res(U32 uid, const char *pMac, U32 *pOutIp, PIPPOOL_INFO *pOutPool) {
|
||||||
|
@ -70,7 +98,6 @@ int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX
|
||||||
|
|
||||||
// 该 IP 可用
|
// 该 IP 可用
|
||||||
if (pLock == NULL) {
|
if (pLock == NULL) {
|
||||||
#if 1
|
|
||||||
if (lease_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
|
if (lease_ip_is_pre_assign(pReq->uid, addr) == FALSE) {
|
||||||
usr_lease_lock_ip(pUser, addr);
|
usr_lease_lock_ip(pUser, addr);
|
||||||
*pOutIp = addr;
|
*pOutIp = addr;
|
||||||
|
@ -80,16 +107,6 @@ int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
usr_lease_lock_ip(pUser, addr);
|
|
||||||
*pOutIp = addr;
|
|
||||||
*pOutPool = pPool;
|
|
||||||
|
|
||||||
lease_db_add_pre_assign(pReq, addr, pPool);
|
|
||||||
// LOG_MOD(debug, ZM_DHCP_LEASE, "User %u(%u) prepar assign ipaddr %08X of %p\n", pReq->uid, pUser->uid,
|
|
||||||
// addr, pPool);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr++;
|
addr++;
|
||||||
|
@ -97,7 +114,7 @@ int pre_alloc_dhcp_res(PDHCP_REQ pReq, PDHCP_USER pUser, U32 *pOutIp, PPOOL_CTX
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理所有超时的预分配IP
|
// 清理所有超时的预分配IP
|
||||||
lease_clearup_timeout_pre_assign();
|
lease_clearup_timeout_items();
|
||||||
// 没有可预分配的IP,报错
|
// 没有可预分配的IP,报错
|
||||||
//LOG_MOD(error, ZM_DHCP_LEASE, "No free ipaddress in poll: uid = %u, pool = %p\n", pReq->uid, pUser->pUserPool);
|
//LOG_MOD(error, ZM_DHCP_LEASE, "No free ipaddress in poll: uid = %u, pool = %p\n", pReq->uid, pUser->pUserPool);
|
||||||
return -ERR_DHCP_NO_ADDR;
|
return -ERR_DHCP_NO_ADDR;
|
||||||
|
@ -113,7 +130,7 @@ int dhcp_lease_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理所有超时的预分配IP
|
// 清理所有超时的预分配IP
|
||||||
lease_clearup_timeout_pre_assign();
|
lease_clearup_timeout_items();
|
||||||
|
|
||||||
// lock 预分配 IP
|
// lock 预分配 IP
|
||||||
lease_lock_pre_assign_ip();
|
lease_lock_pre_assign_ip();
|
||||||
|
|
Loading…
Reference in New Issue