// // Created by xajhuang on 2023/3/23. // #include #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