// // Created by xajhuang on 2023/3/21. // #include #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 g_dhcpUserList = NULL; #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 0 if (pRequest == NULL || strlen(pRequest) == 0) { LOG_MOD(error, ZM_DHCP, "Misson POST json params\n"); return ERR_INPUT_PARAMS; } pStrContent = proto_decode_context(pRequest, NULL, NULL, &errCode); if (pStrContent == NULL) { LOG_MOD(error, ZM_DHCP, "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_CFG 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-", u32_to_str_ip_safe(htonl(pPool->minAddr))); // Because: u32_to_str_ip call inet_ntoa not thread safe strcat(buf, u32_to_str_ip_safe(htonl(pPool->maxAddr))); cJSON_AddStringToObject(pItem, "dhcp_range", buf); cJSON_AddStringToObject(pItem, "netMask", u32_to_str_ip(htonl(pPool->netMask))); cJSON_AddStringToObject(pItem, "gateway", u32_to_str_ip(htonl(pPool->gwAddr))); memset(buf, 0, 256); sprintf(buf, "%s,", u32_to_str_ip(htonl(pPool->primeDNS))); // Because: u32_to_str_ip call inet_ntoa not thread safe strcat(buf, u32_to_str_ip(htonl(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_CFG 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-", u32_to_str_ip_safe(htonl(pPool->minAddr))); strcat(buf, u32_to_str_ip_safe(htonl(pPool->maxAddr))); cJSON_AddStringToObject(pItem, "dhcp_range", buf); cJSON_AddStringToObject(pItem, "netMask", u32_to_str_ip(htonl(pPool->netMask))); cJSON_AddStringToObject(pItem, "gateway", u32_to_str_ip(htonl(pPool->gwAddr))); memset(buf, 0, 256); sprintf(buf, "%s,", u32_to_str_ip(htonl(pPool->primeDNS))); strcat(buf, u32_to_str_ip(htonl(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); #endif 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_assign_pool(PDHCP_USER pUser, PPOOL_CTX pPool) { if (pUser == NULL || pPool == NULL) { return -ERR_INPUT_PARAMS; } LL_APPEND(pUser->pUserPool, pPool); return ERR_SUCCESS; } PDHCP_USER dhcp_user_create(U32 uId) { PDHCP_USER pUser; // 判断当前用户是否存在 HASH_FIND_INT(g_dhcpUserList, &uId, pUser); if (pUser) { return pUser; } pUser = (PDHCP_USER)malloc(sizeof(DHCP_USER)); // 创建一个新用户 if (pUser) { memset(pUser, 0, sizeof(DHCP_USER)); pUser->uid = uId; // 管理地址池配置 pUser->pUserPool = get_pool_cfg(uId, 0); if (pUser->pUserPool == NULL) { LOG_MOD(error, ZM_DHCP_USR, "User %u get ipaddress pool error\n", uId); free(pUser); return NULL; } // 添加用户 HASH_ADD_INT(g_dhcpUserList, uid, pUser); LOG_MOD(trace, ZM_DHCP_USR, "Create User %u with Pool %08X - %08X of %p\n", uId, pUser->pUserPool->minAddr, pUser->pUserPool->maxAddr, pUser->pUserPool); return pUser; } return NULL; } int dhcp_user_mgr_init() { #ifdef HTTPSERVER_ON user_init_httpd(); #endif return ERR_SUCCESS; } #if 0 PIPPOOL_INFO user_get_pool(U32 uId) { PDHCP_USER_CFG 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; } #endif