vcpe/srcs/service/dhcpd/user_mgr.c

245 lines
7.4 KiB
C

//
// Created by xajhuang on 2023/3/21.
//
#include <uthash/utlist.h>
#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