2023-03-29 09:02:21 +00:00
|
|
|
|
//
|
|
|
|
|
// Created by xajhuang on 2023/3/23.
|
|
|
|
|
//
|
|
|
|
|
#include <arpa/inet.h>
|
2023-04-25 09:06:34 +00:00
|
|
|
|
#include "misc.h"
|
2023-03-29 09:02:21 +00:00
|
|
|
|
#include "ip_pool.h"
|
|
|
|
|
#include "zvector/zvector.h"
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "user_errno.h"
|
|
|
|
|
#include "zlog_module.h"
|
|
|
|
|
#include "user_mgr.h"
|
2023-04-07 07:56:38 +00:00
|
|
|
|
#include "ipaddr.h"
|
2023-04-25 01:17:08 +00:00
|
|
|
|
#include "uthash/utlist.h"
|
2023-04-25 09:06:34 +00:00
|
|
|
|
#include "dhcp_network.h"
|
2023-03-29 09:02:21 +00:00
|
|
|
|
|
2023-04-25 01:17:08 +00:00
|
|
|
|
static PPOOL_CONFIG g_pUsrCommonCfg = NULL;
|
|
|
|
|
static PPOOL_CONFIG g_pUsrGrpCfg = NULL;
|
|
|
|
|
static PPOOL_CONFIG g_pUsrCfg = NULL;
|
2023-03-29 09:02:21 +00:00
|
|
|
|
|
2023-04-25 09:06:34 +00:00
|
|
|
|
PPOOL_CTX get_pool_cfg(U32 uid, U32 gid) {
|
|
|
|
|
PPOOL_CONFIG pCfg;
|
|
|
|
|
|
|
|
|
|
if (gid != 0) {
|
|
|
|
|
HASH_FIND_INT(g_pUsrGrpCfg, &gid, pCfg);
|
|
|
|
|
|
|
|
|
|
if (pCfg) {
|
|
|
|
|
return pCfg->pCtx;
|
|
|
|
|
}
|
|
|
|
|
} else if (uid != 0) {
|
|
|
|
|
HASH_FIND_INT(g_pUsrCfg, &uid, pCfg);
|
|
|
|
|
if (pCfg) {
|
|
|
|
|
return pCfg->pCtx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (g_pUsrCommonCfg) {
|
|
|
|
|
return g_pUsrCommonCfg->pCtx;
|
|
|
|
|
} else {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-25 09:06:34 +00:00
|
|
|
|
static void add_usr_pool_cfg(U32 id, PPOOL_CONFIG *pPoolList, PPOOL_CTX pCtx) {
|
2023-04-25 01:17:08 +00:00
|
|
|
|
PPOOL_CTX p, pTmp;
|
|
|
|
|
PPOOL_CONFIG pCfg;
|
|
|
|
|
|
|
|
|
|
// 判断当前用户组是否存在
|
2023-04-25 09:06:34 +00:00
|
|
|
|
HASH_FIND_INT(*pPoolList, &id, pCfg);
|
2023-04-25 01:17:08 +00:00
|
|
|
|
|
|
|
|
|
// 不存在则新建一个配置并保存
|
|
|
|
|
if (pCfg == NULL) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
pCfg = (PPOOL_CONFIG)malloc(sizeof(POOL_CONFIG));
|
|
|
|
|
|
|
|
|
|
if (pCfg == NULL) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Malloc memory %lu error\n", sizeof(POOL_CONFIG));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(pCfg, 0, sizeof(POOL_CONFIG));
|
|
|
|
|
pCfg->id = id;
|
|
|
|
|
LL_APPEND(pCfg->pCtx, pCtx);
|
|
|
|
|
|
|
|
|
|
HASH_ADD_INT(*pPoolList, id, pCfg);
|
2023-04-25 01:17:08 +00:00
|
|
|
|
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(trace, ZM_DHCP_POOL, "%p Add user %u\n", *pPoolList, id);
|
|
|
|
|
return;
|
2023-04-25 01:17:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果存在,则遍历当前所有IP地址池配置,检查配置是否合法
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LL_FOREACH_SAFE((*pPoolList)->pCtx, p, pTmp) {
|
|
|
|
|
if (p->minAddr >= pCtx->minAddr && p->maxAddr <= pCtx->maxAddr) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Pool [%08X, %08X] conflict with [%08X, %08X]", pCtx->minAddr, pCtx->maxAddr,
|
|
|
|
|
p->minAddr, p->maxAddr);
|
2023-04-25 01:17:08 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-25 09:06:34 +00:00
|
|
|
|
|
|
|
|
|
// 如果没有冲突,则将新的配置添加到链表中
|
|
|
|
|
LL_APPEND(pCfg->pCtx, pCtx);
|
2023-04-25 01:17:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-25 09:06:34 +00:00
|
|
|
|
void ip_pool_init_from_config() {
|
|
|
|
|
c_vector pool = (c_vector)config_get_dhcp_server_range_set();
|
|
|
|
|
for (int i = 0; (pool && i < vect_size(pool)); i++) {
|
|
|
|
|
POBJ_DHCP_RNG pRange = (POBJ_DHCP_RNG)vect_get_at(pool, i);
|
|
|
|
|
if (pRange && strlen(pRange->rangAddr) > 0) {
|
|
|
|
|
struct in_addr addr;
|
|
|
|
|
char *pConnChar;
|
|
|
|
|
char tmpStr[64];
|
|
|
|
|
PPOOL_CTX p = (PPOOL_CTX)malloc(sizeof(POOL_CTX));
|
|
|
|
|
|
|
|
|
|
if (!p) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Error: size %lu of config %s\n", sizeof(POOL_CTX), pRange->rangAddr);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(p, 0, sizeof(POOL_CTX));
|
|
|
|
|
|
|
|
|
|
// 如果未配置租约,取默认值,否则使用地址池配置值
|
|
|
|
|
p->leaseTime = (pRange->lease == 0) ? config_get_dhcp_server_lease_time() : pRange->lease;
|
|
|
|
|
|
|
|
|
|
// 处理地址池字符串
|
|
|
|
|
memset(tmpStr, 0, 64);
|
|
|
|
|
strcpy(tmpStr, pRange->rangAddr);
|
|
|
|
|
pConnChar = strchr(tmpStr, '-');
|
|
|
|
|
|
|
|
|
|
// '-' 连接IP地址类型
|
|
|
|
|
if (pConnChar) {
|
|
|
|
|
char *pSecIp = pConnChar + 1;
|
|
|
|
|
pConnChar[0] = 0;
|
|
|
|
|
// 地址范围
|
|
|
|
|
if (inet_aton(tmpStr, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->rangAddr);
|
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
p->minAddr = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inet_aton(pSecIp, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->rangAddr);
|
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
p->maxAddr = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Bad DHCP range format: %s\n", tmpStr);
|
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 子网掩码
|
|
|
|
|
if (strlen(pRange->subnet) > 0) {
|
|
|
|
|
if (inet_aton(pRange->subnet, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip %s ERROR, used default value %s\n", pRange->subnet,
|
|
|
|
|
u32_to_str_ip(dhcp_get_default_netmask()));
|
|
|
|
|
p->netMask = ntohl(dhcp_get_default_netmask());
|
|
|
|
|
} else {
|
|
|
|
|
p->netMask = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 当前网络默认IP地址池
|
|
|
|
|
p->netMask = ntohl(dhcp_get_default_netmask());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 网关
|
|
|
|
|
if (strlen(pRange->gateway) > 0) {
|
|
|
|
|
if (inet_aton(pRange->gateway, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->gateway);
|
|
|
|
|
} else {
|
|
|
|
|
p->gwAddr = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DNS 配置
|
|
|
|
|
if (strlen(pRange->dnsSvr) > 0) {
|
|
|
|
|
memset(tmpStr, 0, 64);
|
|
|
|
|
strcpy(tmpStr, pRange->dnsSvr);
|
|
|
|
|
|
|
|
|
|
pConnChar = strchr(tmpStr, ',');
|
|
|
|
|
|
|
|
|
|
if (pConnChar) {
|
|
|
|
|
char *pSecIp = pConnChar + 1;
|
|
|
|
|
pConnChar[0] = 0;
|
|
|
|
|
|
|
|
|
|
if (inet_aton(tmpStr, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
|
|
|
|
|
} else {
|
|
|
|
|
p->primeDNS = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inet_aton(pSecIp, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr);
|
|
|
|
|
} else {
|
|
|
|
|
p->salveDNS = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (inet_aton(pRange->dnsSvr, &addr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
|
|
|
|
|
} else {
|
|
|
|
|
p->primeDNS = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当前配置为用户组配置
|
|
|
|
|
if (pRange->gid != 0) {
|
|
|
|
|
// 添加到Group配置表
|
|
|
|
|
add_usr_pool_cfg(pRange->gid, &g_pUsrGrpCfg, p);
|
|
|
|
|
LOG_MOD(debug, ZM_DHCP_POOL, "Load user group %d configure: %s\n", pRange->gid, pRange->rangAddr);
|
|
|
|
|
} else if (pRange->vni == 0) {
|
|
|
|
|
// VNI 为 0 时表示用户公共配置
|
|
|
|
|
add_usr_pool_cfg(pRange->vni, &g_pUsrCommonCfg, p);
|
|
|
|
|
LOG_MOD(debug, ZM_DHCP_POOL, "Load common user configure: %s\n", pRange->rangAddr);
|
|
|
|
|
} else {
|
|
|
|
|
// 添加到用户独立配置
|
|
|
|
|
add_usr_pool_cfg(pRange->vni, &g_pUsrCfg, p);
|
|
|
|
|
LOG_MOD(debug, ZM_DHCP_POOL, "Load user %d configure: %s\n", pRange->vni, pRange->rangAddr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Error configure %p value \"%s\"\n", pRange, pRange ? pRange->rangAddr : "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
2023-03-29 09:02:21 +00:00
|
|
|
|
void init_default_pool() {
|
|
|
|
|
c_vector pool = (c_vector)config_get_dhcp_server_range_set();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; (pool && i < vect_size(pool)); i++) {
|
|
|
|
|
char *pConnChar;
|
|
|
|
|
char tmpStr[64];
|
|
|
|
|
POBJ_DHCP_RNG pRange = (POBJ_DHCP_RNG)vect_get_at(pool, i);
|
|
|
|
|
|
|
|
|
|
if (pRange) {
|
|
|
|
|
struct in_addr addr;
|
|
|
|
|
PIPPOOL_INFO p = (PIPPOOL_INFO)malloc(sizeof(IPPOOL_INFO));
|
|
|
|
|
|
|
|
|
|
if (!p) {
|
|
|
|
|
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Malloc memory error: %lu\n", sizeof(IPPOOL_INFO));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 07:56:38 +00:00
|
|
|
|
memset(p, 0, sizeof(IPPOOL_INFO));
|
|
|
|
|
|
2023-03-29 09:02:21 +00:00
|
|
|
|
if (strlen(pRange->rangAddr) == 0) {
|
|
|
|
|
LOG_MOD(error, ZLOG_MOD_OPENDHCPD, "Error ip pool configure of address\n");
|
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pRange->lease > config_get_dhcp_server_lease_time()) {
|
|
|
|
|
p->leaseTime = 0;
|
|
|
|
|
} else {
|
|
|
|
|
p->leaseTime = pRange->lease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(tmpStr, 0, 64);
|
|
|
|
|
strcpy(tmpStr, pRange->rangAddr);
|
|
|
|
|
|
|
|
|
|
pConnChar = strchr(tmpStr, '-');
|
|
|
|
|
|
|
|
|
|
// '-' 连接IP地址类型
|
|
|
|
|
if (pConnChar) {
|
|
|
|
|
char *pSecIp = pConnChar + 1;
|
|
|
|
|
pConnChar[0] = 0;
|
|
|
|
|
|
|
|
|
|
if (inet_aton(tmpStr, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->rangAddr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->minAddr = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inet_aton(pSecIp, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->rangAddr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->maxAddr = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Bad DHCP range format: %s\n", tmpStr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 07:56:38 +00:00
|
|
|
|
if (strlen(pRange->subnet) > 0) {
|
|
|
|
|
if (inet_aton(pRange->subnet, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->subnet);
|
2023-04-07 07:56:38 +00:00
|
|
|
|
} else {
|
|
|
|
|
p->netMask = ntohl(addr.s_addr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 当前网络默认IP地址池
|
|
|
|
|
if (inet_aton("255.255.255.0", &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->subnet);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->netMask = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 07:56:38 +00:00
|
|
|
|
// 填充POOL Hash Key
|
|
|
|
|
p->poolKey = ipv4_get_network_addr(p->minAddr, p->netMask);
|
|
|
|
|
p->assignPool = bitset_create_with_capacity(ipv4_network_total_addr(p->netMask));
|
|
|
|
|
|
|
|
|
|
if (!p->assignPool) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Create address pool bitset ERROR: 0x%08X total address %u\n",
|
|
|
|
|
htonl(p->netMask), ipv4_network_total_addr(p->netMask));
|
2023-04-07 07:56:38 +00:00
|
|
|
|
free(p);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strlen(pRange->gateway) > 0) {
|
|
|
|
|
if (inet_aton(pRange->gateway, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->gateway);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->gwAddr = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strlen(pRange->dnsSvr) > 0) {
|
|
|
|
|
memset(tmpStr, 0, 64);
|
|
|
|
|
strcpy(tmpStr, pRange->dnsSvr);
|
|
|
|
|
|
|
|
|
|
pConnChar = strchr(tmpStr, ',');
|
|
|
|
|
|
|
|
|
|
if (pConnChar) {
|
|
|
|
|
char *pSecIp = pConnChar + 1;
|
|
|
|
|
pConnChar[0] = 0;
|
|
|
|
|
|
|
|
|
|
if (inet_aton(tmpStr, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->primeDNS = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (inet_aton(pSecIp, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", pSecIp, pRange->dnsSvr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->salveDNS = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (inet_aton(pRange->dnsSvr, &addr) == 0) {
|
2023-04-25 09:06:34 +00:00
|
|
|
|
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s of %s\n", tmpStr, pRange->dnsSvr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
} else {
|
2023-04-07 07:56:38 +00:00
|
|
|
|
p->primeDNS = ntohl(addr.s_addr);
|
2023-03-29 09:02:21 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user_add_ip_pool(pRange->vni, p);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-25 09:06:34 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|