// // Created by xajhuang on 2023/3/21. // #include "user_mgr.h" #include "user_errno.h" #include "zlog_module.h" #ifdef HTTPSERVER_ON #include "http_svr.h" #include "s2j/cJSON.h" #include "proto.h" #include "misc.h" #endif static PDHCP_USER_INFO g_dhcpUsrCfg = NULL; #define INIT_DHCP_USER(id) \ /* region INIT_DHCP_USER Macro define */ \ do { \ HASH_FIND_INT(g_dhcpUsrCfg, &(id), pUserCfg); \ if (pUserCfg == NULL) { \ pUserCfg = (PDHCP_USER_INFO)malloc(sizeof(DHCP_USER_INFO)); \ \ if (pUserCfg == NULL) { \ LOG_MOD(error, ZLOG_MOD_USER, "Malloc memory error: %lu\n", sizeof(DHCP_USER_INFO)); \ return -ERR_MALLOC_MEMORY; \ } \ memset(pUserCfg, 0, sizeof(DHCP_USER_INFO)); \ pUserCfg->uid = (id); \ HASH_ADD_INT(g_dhcpUsrCfg, uid, pUserCfg); \ } \ } while (0) // endregion #ifdef HTTPSERVER_ON // region 用户管理接口 static int get_user_pool_cfg(const char **pRsp, const char *pRequest) { char logBuff[512]; const char *pStrContent; cJSON *pRspRoot, *pRoot, *pUidSet, *pPoolCfgs; int i, errCode = 0; if (pRequest == NULL || strlen(pRequest) == 0) { LOG_MOD(error, ZLOG_MOD_DHCPD, "Misson POST json params\n"); return ERR_INPUT_PARAMS; } pStrContent = proto_decode_context(pRequest, NULL, NULL, &errCode); if (pStrContent == NULL) { LOG_MOD(error, ZLOG_MOD_DHCPD, "Request Json error %s\n", pRequest); return ERR_PROTO_DECODE; } pRoot = cJSON_Parse(pStrContent); free((void *)pStrContent); if (!pRoot) { return ERR_JSON_PARSE_OBJ; } pUidSet = cJSON_GetObjectItem(pRoot, "uid"); pRspRoot = cJSON_CreateObject(); pRspRoot = cJSON_CreateObject(); pPoolCfgs = cJSON_CreateArray(); cJSON_AddItemToObject(pRspRoot, "poolSet", pPoolCfgs); if (cJSON_GetArraySize(pUidSet) == 0) { PDHCP_USER_INFO pInfo, pTemp; HASH_ITER(hh, g_dhcpUsrCfg, pInfo, pTemp) { cJSON *pUid = cJSON_CreateObject(); cJSON *pPoolSet = cJSON_CreateArray(); cJSON_AddItemToArray(pPoolCfgs, pUid); cJSON_AddNumberToObject(pUid, "uid", pInfo->uid); cJSON_AddItemToObject(pUid, "poolSet", pPoolSet); if (pInfo->pPoolMgr) { PIPPOOL_INFO pPool, pTmp; HASH_ITER(hh, pInfo->pPoolMgr, pPool, pTmp) { char buf[256]; cJSON *pItem = cJSON_CreateObject(); memset(buf, 0, 256); sprintf(buf, "%s-%s", u32_to_str_ip(pPool->minAddr), u32_to_str_ip(pPool->maxAddr)); cJSON_AddStringToObject(pItem, "dhcp_range", buf); cJSON_AddStringToObject(pItem, "netMask", u32_to_str_ip(pPool->netMask)); cJSON_AddStringToObject(pItem, "gateway", u32_to_str_ip(pPool->gwAddr)); memset(buf, 0, 256); sprintf(buf, "%s,", u32_to_str_ip(pPool->primeDNS)); strcat(buf, u32_to_str_ip(pPool->salveDNS)); cJSON_AddStringToObject(pItem, "domain_server", buf); cJSON_AddNumberToObject(pItem, "lease", pPool->leaseTime); cJSON_AddItemToArray(pPoolSet, pItem); } } } } else { for (i = 0; i < cJSON_GetArraySize(pUidSet); i++) { PDHCP_USER_INFO pInfo; cJSON *pId = cJSON_GetArrayItem(pUidSet, i); cJSON *pUid = cJSON_CreateObject(); cJSON_AddItemToArray(pPoolCfgs, pUid); cJSON_AddNumberToObject(pUid, "uid", pId->valueint); HASH_FIND_INT(g_dhcpUsrCfg, &pId->valueint, pInfo); if (pInfo) { cJSON *pPoolSet = cJSON_CreateArray(); cJSON_AddItemToObject(pUid, "poolSet", pPoolSet); if (pInfo->pPoolMgr) { PIPPOOL_INFO pPool, pTmp; HASH_ITER(hh, pInfo->pPoolMgr, pPool, pTmp) { char buf[256]; cJSON *pItem = cJSON_CreateObject(); memset(buf, 0, 256); sprintf(buf, "%s-%s", u32_to_str_ip(pPool->minAddr), u32_to_str_ip(pPool->maxAddr)); cJSON_AddStringToObject(pItem, "dhcp_range", buf); cJSON_AddStringToObject(pItem, "netMask", u32_to_str_ip(pPool->netMask)); cJSON_AddStringToObject(pItem, "gateway", u32_to_str_ip(pPool->gwAddr)); memset(buf, 0, 256); sprintf(buf, "%s,", u32_to_str_ip(pPool->primeDNS)); strcat(buf, u32_to_str_ip(pPool->salveDNS)); cJSON_AddStringToObject(pItem, "domain_server", buf); cJSON_AddNumberToObject(pItem, "lease", pPool->leaseTime); cJSON_AddItemToArray(pPoolSet, pItem); } } } else { cJSON_AddNumberToObject(pUid, "status", ERR_ITEM_UNEXISTS); cJSON_AddStringToObject(pUid, "message", getErrorEnumDesc(ERR_ITEM_UNEXISTS)); } } } *pRsp = proto_create_new(pRspRoot, 200); cJSON_Delete(pRoot); return ERR_SUCCESS; } static void on_get_user_pool(struct mg_http_message *h, void *user_data, PHTTP_RSP_CTX pCtx) { pCtx->pRspHeads = HTTP_HEAD_CONTENT_TYPE_JSON; pCtx->errCode = get_user_pool_cfg((const char **)&pCtx->pRspData, h->body.ptr); if (pCtx->errCode != ERR_SUCCESS) { pCtx->httpCode = 500; free(pCtx->pRspData); return; } pCtx->httpCode = 200; } static HTTP_ROUTE_INFO g_usrRouteTable[] = { {"/user/dhcp/ippool", POST, PRI_NORMAL, on_get_user_pool, NULL}, }; int user_init_httpd() { int i; for (i = 0; i < ARRAY_SIZE(g_usrRouteTable); i++) { PHTTP_ROUTE_INFO p = &g_usrRouteTable[i]; http_add_route(p->routeName, p->method, p->priority, p->cb, p->pUserData); } return ERR_SUCCESS; } // endregion #endif int dhcp_user_mgr_init() { #ifdef HTTPSERVER_ON user_init_httpd(); #endif init_default_pool(); return ERR_SUCCESS; } int user_alloc_addr(U32 uId, U8 mac[ETH_ALEN], U32 *pAddr) { PDHCP_USER_INFO pUserCfg, pTemp; INIT_DHCP_USER(uId); return ERR_SUCCESS; } PIPPOOL_INFO user_get_pool(U32 uId) { PDHCP_USER_INFO pUser; HASH_FIND_INT(g_dhcpUsrCfg, &uId, pUser); if (pUser == NULL) { U32 id = 0; HASH_FIND_INT(g_dhcpUsrCfg, &id, pUser); if (pUser == NULL) { return NULL; } return pUser->pPoolMgr; } return NULL; } int user_add_ip_pool(U32 uId, PIPPOOL_INFO pPool) { U32 k; U32 begin; U32 end; PIPPOOL_INFO pPoolCfg; PDHCP_USER_INFO pUserCfg, pTemp; INIT_DHCP_USER(uId); // 该设备没有地址配置时,直接返回 if (pPool == NULL) { return ERR_SUCCESS; } HASH_FIND_INT(pUserCfg->pPoolMgr, &pPool->poolKey, pPoolCfg); // 改地址池已经存在,提示错误 if (pPoolCfg != NULL) { free(pPool); } else { // 添加新地址池当前用户配置项中 HASH_ADD_INT(pUserCfg->pPoolMgr, poolKey, pPool); pPoolCfg = pPool; } // 计算可用的IP begin = pPoolCfg->minAddr & (~pPoolCfg->netMask); end = pPoolCfg->maxAddr & (~pPoolCfg->netMask); for (k = MAX(begin, 1U); k <= MIN(end, ntohl(~pPoolCfg->netMask) - 1); k++) { bitset_set(pPoolCfg->assignPool, k); } return ERR_SUCCESS; }