vcpe/srcs/service/dhcpd/ip_pool.c

338 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by xajhuang on 2023/3/23.
//
#include <arpa/inet.h>
#include "misc.h"
#include "ip_pool.h"
#include "zvector/zvector.h"
#include "config.h"
#include "user_errno.h"
#include "zlog_module.h"
#include "user_mgr.h"
#include "ipaddr.h"
#include "uthash/utlist.h"
#include "dhcp_network.h"
static PPOOL_CONFIG g_pUsrCommonCfg = NULL;
static PPOOL_CONFIG g_pUsrGrpCfg = NULL;
static PPOOL_CONFIG g_pUsrCfg = NULL;
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;
}
}
static void add_usr_pool_cfg(U32 id, PPOOL_CONFIG *pPoolList, PPOOL_CTX pCtx) {
PPOOL_CTX p, pTmp;
PPOOL_CONFIG pCfg;
// 判断当前用户组是否存在
HASH_FIND_INT(*pPoolList, &id, pCfg);
// 不存在则新建一个配置并保存
if (pCfg == NULL) {
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);
LOG_MOD(trace, ZM_DHCP_POOL, "%p Add user %u\n", *pPoolList, id);
return;
}
// 如果存在则遍历当前所有IP地址池配置检查配置是否合法
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);
return;
}
}
// 如果没有冲突,则将新的配置添加到链表中
LL_APPEND(pCfg->pCtx, pCtx);
}
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
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;
}
memset(p, 0, sizeof(IPPOOL_INFO));
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) {
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 ERROR: %s\n", pRange->subnet);
} else {
p->netMask = ntohl(addr.s_addr);
}
} else {
// 当前网络默认IP地址池
if (inet_aton("255.255.255.0", &addr) == 0) {
LOG_MOD(error, ZM_DHCP_POOL, "Convert ip ERROR: %s\n", pRange->subnet);
} else {
p->netMask = ntohl(addr.s_addr);
}
}
// 填充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) {
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));
free(p);
continue;
}
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);
}
}
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);
}
}
}
user_add_ip_pool(pRange->vni, p);
}
}
}
#endif