STATUS rtdDhcpServerAddManualBind(int htype, char *haddr, int haddr_len,
struct in_addr ipAddr, struct client_id *cid, char *poolName)
{
struct dhcp_binding *binding = NULL;
struct dhcp_binding *res = NULL;
struct dhcp_binding tempBind;
struct hash_member *head = NULL;
struct hash_member *bindptr = NULL;
int result;
if (haddr == NULL || NULL == poolName || NULL == cid)
{
return ERROR;
}
/*
* Read binding information from entries with the following format:
* idtype:id:subnet:htype:haddr:"expire_date":resource_name
*/
DBG_DHCP_VRF("type %d", htype);
DBG_DHCP_VRF("ADD MANUAL BIND=%x%x%x%x%x%x", haddr[0], haddr[1], haddr[2],
haddr[3], haddr[4], haddr[5]);
/* Create linked list element. */
DHCP_SERVER_RTD_LOCK();
head = availreslist;
if (availreslist != NULL)
{
availreslist = availreslist->next;
head->next = bindlist;
bindlist = head;
binding = (struct dhcp_binding *)(head->data);
binding->bindtype = MANUAL_BIND_TYPE;
DHCP_SERVER_IP sIp={};
sIp.ip.s_addr=ipAddr.s_addr;
strncpy(sIp.vrfName,cid->vrfName,DHCP_VRF_NAME_LEN);
memcpy(&binding->ip_addr,&sIp,sizeof(sIp));
/* 静态绑定,但是还未被discover请求 */
binding->flag = FREE_ENTRY;
/* read client identifier type */
binding->cid.idtype = cid->idtype;
/* read client identifier value */
binding->cid.idlen = cid->idlen;
memcpy(binding->cid.id, cid->id, cid->idlen);
/* read subnet number of client */
binding->cid.subnet.s_addr = cid->subnet.s_addr;
/* read hardware address type (e.g. "1" for 10 MB ethernet). */
binding->haddr.htype = htype;
/* read client hardware address */
binding->haddr.hlen = haddr_len;
memcpy(binding->haddr.haddr, haddr, haddr_len);
/* read expiration time for lease */
binding->temp_epoch = binding->expire_epoch = DHCP_SERVER_FORERVER;
/* read index of lease descriptor */
snprintf(binding->poolName, DHCPS_POOLNAME_LEN + 1, "%s", poolName);
strncpy(binding->cid.vrfName,cid->vrfName,DHCP_VRF_NAME_LEN);
/* 判断IP是否已被分配 */
res = (struct dhcp_binding *)hash_find(&iphashtable, (char *)&binding->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &binding->ip_addr);
/* 如果该manual绑定已经存在,直接返回添加成功 */
if (NULL != res && DHCP_SERVER_FORERVER == res->expire_epoch)
{
head = bindlist;
if (bindlist)
{
bindlist = bindlist->next;
}
if (head)
{
head->next = availreslist;
}
availreslist = head;
DHCP_SERVER_RTD_UNLOCK();
return OK;
}
if ((binding->haddr.htype == ETHERNET_BIND) || (binding->haddr.htype == IEEE802_BIND))
{
DBG_DHCP_VRF("no haddr type");
bindptr = bindlist;
while (bindptr != NULL)
{
res = (struct dhcp_binding *)((bindptr)->data);
/* 客户端原先已有绑定记录,先删除 */
if (memcmp(res->haddr.haddr, binding->haddr.haddr, binding->haddr.hlen) == 0 &&
res->cid.idtype == binding->haddr.htype &&
hash_find(&iphashtable, (char *)&res->ip_addr.ip.s_addr, sizeof(UINT32), resipcmp, &res->ip_addr) != NULL
&& (0 == strcmp(res->poolName, binding->poolName)))
{
memcpy(&tempBind, res, sizeof(struct dhcp_binding));
DBG_DHCP_VRF("res ip %x", (UINT32)res->ip_addr.ip.s_addr);
DBG_DHCP_VRF("res %p", res);
DBG_DHCP_VRF("res->cid.idlen %d", res->cid.idlen);
DBG_DHCP_VRF("res->cid=%x%x%x%x%x%x%x%x", res->cid.id[0], res->cid.id[1], res->cid.id[2],
res->cid.id[3], res->cid.id[4], res->cid.id[5], res->cid.id[6], res->cid.id[7]);
result = hash_del(&cidhashtable, res->cid.id, res->cid.idlen,
bindcidcmp, &res->cid, free_bind);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err cid");
goto ERR_RET;
}
result = hash_del(&iphashtable, (char *)&res->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &res->ip_addr, free_element);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err ip");
goto ERR_RET;
}
/* 若客户端原先为绑定状态,则对应地址池已分配地址-1 */
if (tempBind.flag == BIND_ENTRY)
{
del_bind(tempBind.poolName);
}
}
bindptr = bindptr->next;
}
}
else
{
/* 判断客户端cid是否已有绑定 */
res = (struct dhcp_binding *)hash_find(&cidhashtable, binding->cid.id, binding->cid.idlen,
bindcidcmp, &binding->cid);
if (res != NULL)/* 客户端已有绑定 需要先删除 */
{
memcpy(&tempBind, res, sizeof(struct dhcp_binding));
result = hash_del(&cidhashtable, res->cid.id, res->cid.idlen,
bindcidcmp, &res->cid, free_bind);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err cid");
goto ERR_RET;
}
result = hash_del(&iphashtable, (char *)&res->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &res->ip_addr, free_element);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err ip");
goto ERR_RET;
}
res->flag = FREE_ENTRY;
res->expire_epoch = 0;
DBG_DHCP_VRF("remove manual bind success");
/* 若客户端原先为绑定状态,则对应地址池已分配地址-1 */
if (tempBind.flag == BIND_ENTRY)
{
del_bind(tempBind.poolName);
}
}
}
/* 判断IP是否已被分配 */
res = (struct dhcp_binding *)hash_find(&iphashtable, (char *)&binding->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &binding->ip_addr);
if (res != NULL)
{
memcpy(&tempBind, res, sizeof(struct dhcp_binding));
result = hash_del(&cidhashtable, res->cid.id, res->cid.idlen,
bindcidcmp, &res->cid, free_bind);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err cid");
goto ERR_RET;
}
result = hash_del(&iphashtable, (char *)&res->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &res->ip_addr, free_element);
if (OK != result)
{
DBG_DHCP_VRF("remove manual bind err:hash del err ip");
goto ERR_RET;
}
res->flag = FREE_ENTRY;
res->expire_epoch = 0;
DBG_DHCP_VRF("remove manual bind success");
/* 若客户端原先为绑定状态,则对应地址池已分配地址-1 */
if (tempBind.flag == BIND_ENTRY)
{
del_bind(tempBind.poolName);
}
}
DBG_DHCP_VRF("cid hash ins len %d-- %x:%x:%x:%x:%x:%x", binding->cid.idlen, binding->cid.id[0], binding->cid.id[1], binding->cid.id[2], binding->cid.id[3], binding->cid.id[4], binding->cid.id[5]);
if ((hash_ins(&cidhashtable, binding->cid.id, binding->cid.idlen,
bindcidcmp, &binding->cid, binding) < 0))
{
DBG("cid hash ins error");
goto ERR_RET;
}
DBG_DHCP_VRF("cid hash ins");
DBG_DHCP_VRF("cid hash ins %x", (UINT32)binding->ip_addr.ip.s_addr);
if (hash_ins(&iphashtable, (char *)&binding->ip_addr.ip.s_addr, sizeof(UINT32),
resipcmp, &binding->ip_addr, binding) < 0)
{
hash_del(&cidhashtable, binding->cid.id, binding->cid.idlen,
bindcidcmp, &binding->cid, free_bind);
DBG_DHCP_VRF("ip hash ins error");
goto ERR_RET;
}
DBG_DHCP_VRF("ip hash ins %x", (UINT32)binding->ip_addr.ip.s_addr);
DBG("add client identifier to hash table ok.");
/*memcpy(&bindingCopy, binding, sizeof(struct dhcp_binding));
add_reslist_node(&bindingCopy);*/
DHCP_SERVER_RTD_UNLOCK();
add_bind(poolName);/* 手动绑定成功,地址池中已分配地址+1 */
rtdDhcpServerChangePoolStatis(poolName, DHCP_SERVER_POOL_STATIS_PARAM_MANUAL_CNT, 1);
return OK;
}
else
{
DBG("no available resource, fail.");
DHCP_SERVER_RTD_UNLOCK();
return ERROR;
}
DHCP_SERVER_RTD_UNLOCK();
return OK;
ERR_RET:
head = bindlist;
if (bindlist)
{
bindlist = bindlist->next;
}
if (head)
{
head->next = availreslist;
}
availreslist = head;
DHCP_SERVER_RTD_UNLOCK();
return ERROR;
}
这是添加静态绑定的函数 type 为free_entry啊