消息 4104,级别 16,状态 1,第 1 行 无法绑定由多个部分组成的标识符 "client.Cid"。

本文解决了在数据库操作中,由于未正确绑定client表而导致的问题。通过添加client表,可以确保数据的正确关联。

在这里插入图片描述出现这样的原因是因为from后面没有添加client表,因此无法绑定,只要添加client表就行。
在这里插入图片描述

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啊
09-26
static int dhcprequest(TP_PACKET_T *packet) { BOOL reqforme = FALSE; struct dhcp_binding *res = NULL; //struct dhcp_binding resCopy = {}; struct dhcp_binding *binding = NULL; struct client_id cid; DHCP_SERVER_IP reqip; struct in_addr netmask; unsigned long offer_lease = 0; /* offering lease */ unsigned long reqlease = 0; /* requested lease duration */ char *option = NULL; int response; /* Accept request? */ BOOL hasReqip = FALSE; /* packet has REQUEST IP option */ DHCP_SERVER_IP networkIp; /* add by supeng 2011.3.8 */ char datestr[sizeof(EPOCH)]; char addrstr[sizeof(BRDCSTSTR)]; time_t curr_epoch = 0; /* current epoch */ struct chaddr tmpmac = {}; int ret = ERR_NO_ERROR; struct in_addr poolNetworkIp; struct in_addr poolNetmask; int index = 0; DHCP_SERVER_POOL pool_para={}; tmpmac.htype = dhcpsMsgIn.dhcp->htype; tmpmac.hlen = dhcpsMsgIn.dhcp->hlen; memcpy(tmpmac.haddr, dhcpsMsgIn.dhcp->chaddr, tmpmac.hlen); memset((char *)&cid, 0, sizeof(cid)); memcpy(datestr, EPOCH, sizeof(EPOCH)); memcpy(addrstr, BRDCSTSTR, sizeof(BRDCSTSTR)); DEBUG_DHCPS("dhcprequst"); if (swDhcpsTime(&curr_epoch) != ERR_NO_ERROR) { DEBUG_DHCPS("Warning: Couldn't get timestamp when processing request."); return (-1); } dhcpServerMutexTake(); response = 2;/* Response not determined. */ sendNak = 0; reqlease = get_reqlease(dhcpsMsgIn.dhcp, priv_rdhcplen); priv_maxoptlen = get_maxoptlen(dhcpsMsgIn.dhcp, priv_rdhcplen); get_cid(dhcpsMsgIn.dhcp, priv_rdhcplen, &cid); DBG_DHCP_VRF("cid is %s",bindCidtos(&cid,0,0)); if (get_subnet(dhcpsMsgIn.dhcp, priv_rdhcplen, cid.vrfName,&cid.subnet, packet) != 0) { DEBUG_DHCPS("requst:get subnet error.%x", cid.subnet.s_addr); dhcpServerMutexGive(); return (-1); } DHCP_SERVER_POOL poolParam = {0}; DHCP_SERVER_IP cid_subnet_svr={}; COPY_SERVER_IP(cid_subnet_svr,cid.subnet,cid.vrfName); /* 更新报文统计数 */ rtdDhcpsGetPoolByIp(cid_subnet_svr, &poolParam); rtdDhcpServerChangePoolStatis(poolParam.name, DHCPREQUEST, 1); DEBUG_DHCPS("requst:cid.subnet=%x",cid.subnet.s_addr); /* Check if this DHCP server is the request destination. (Option not present unless client is in SELECTING state). */ option = (char*)pickup_opt(dhcpsMsgIn.dhcp, priv_rdhcplen, _DHCP_SERVER_ID_TAG); if (option != NULL) { if (swDhcpsIsServerIp(GETHL(OPTBODY(option))) == ERR_NO_ERROR) { reqforme = TRUE; } if (!reqforme) { DEBUG_DHCPS("requst: not request for this SERVER!"); dhcpServerMutexGive(); return (-1); } } /* 获取入口vlan的网段信息 */ swDhcpsGetNetworkMaskByVid(packet->vid, &networkIp.ip, &netmask); COPY_VRF(networkIp.vrfName,cid.vrfName); /* Requesting client has no IP address (i.e. - initial request * from SELECTING state or verification of cached lease from * INIT-REBOOT state).*/ /* 获取请求ip */ reqip.ip.s_addr = 0; option = (char*)pickup_opt(dhcpsMsgIn.dhcp, priv_rdhcplen, _DHCP_REQUEST_IPADDR_TAG); if (option != NULL) { reqip.ip.s_addr = (GETHL(OPTBODY(option))); COPY_VRF(reqip.vrfName,cid.vrfName); hasReqip = TRUE; } DBG_DHCP_VRF("reqip=%s", inet_ntoa(reqip.ip)); /* first deal with manual binding */ struct dhcp_binding tmpBp; memset(&tmpBp, 0, sizeof(tmpBp)); /* 静态绑定地址,cid优先 */ ret = rtdDhcpServerGetBindEntryByCid(&cid, bindcidcmp_manual,&tmpBp); if (ret == ERR_NO_ERROR && tmpBp.cid.idtype != ETHERNET_BIND && tmpBp.cid.idtype != IEEE802_BIND) { binding = &tmpBp; } /* 静态绑定条目,无需判断时间戳---chenwenjing 2015.5.21 */ if (binding != NULL && binding->flag >= TEMP_ENTRY ) { DEBUG_DHCPS("dhcp munual binding for cid found"); res = binding; if (hasReqip) { DEBUG_DHCPS("manual-binding: with Request Ip option"); DBG_DHCP_MLAG("res->ip_addr.s_addr: %x dhcpsMsgIn.dhcp->ciaddr.s_addr: %x", res->ip_addr.ip.s_addr, dhcpsMsgIn.dhcp->ciaddr.s_addr); DBG_DHCP_MLAG("res->ip_addr: %s, reqip: %s", inet_ntoa(res->ip_addr.ip), inet_ntoa(reqip.ip)); //if (res->ip_addr.ip.s_addr == reqip.s_addr&&DHCP_VRF_NAME_SAME(cid.vrfName,res->cid.vrfName)) if(DHCP_SERVER_IP_SAME(res->ip_addr,reqip))///???报错 { ret = dhcpServerChkReqIpAvailable(reqip, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } else { response = 0; sendNak = 1; } } else { DEBUG_DHCPS("res->ip_addr.s_addr: %s dhcpsMsgIn.dhcp->ciaddr.s_addr: %x", inet_ntoa(res->ip_addr.ip), inet_ntoa(dhcpsMsgIn.dhcp->ciaddr)); if (res->ip_addr.ip.s_addr == dhcpsMsgIn.dhcp->ciaddr.s_addr && (DHCP_VRF_NAME_SAME(res->ip_addr.vrfName,dhcpsMsgIn.vrfName))) { ret = dhcpServerChkReqIpAvailable(res->ip_addr, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } } } /* 静态绑定,haddr */ if (response == 2) { struct client_id tmpCid; memset(&tmpCid, 0, sizeof(tmpCid)); tmpCid.idtype = cid.idtype; tmpCid.idlen = tmpmac.hlen; tmpCid.subnet=cid.subnet; memcpy(tmpCid.id, tmpmac.haddr, tmpmac.hlen); COPY_VRF(tmpCid.vrfName,cid.vrfName); ret = rtdDhcpServerGetBindEntryByCid(&tmpCid, bindcidcmp_manual, &tmpBp); if (ret == ERR_NO_ERROR) { binding = &tmpBp; } else { binding = NULL; } /* 静态绑定条目,无需判断时间戳---chenwenjing 2015.5.21 */ if (binding != NULL && binding->flag >= TEMP_ENTRY) { DEBUG_DHCPS("temp_epoch:%d, curr_epoch:%d", (int)binding->temp_epoch, (int)curr_epoch); DEBUG_DHCPS("dhcp binding for haddr found"); res = binding; if (hasReqip) { DEBUG_DHCPS("manual-binding: with Request Ip option"); if(DHCP_SERVER_IP_SAME(res->ip_addr,reqip)) { ret = dhcpServerChkReqIpAvailable(reqip, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } else { response = 0; sendNak = 1; } } else { if (res->ip_addr.ip.s_addr == dhcpsMsgIn.dhcp->ciaddr.s_addr && (DHCP_VRF_NAME_SAME(res->ip_addr.vrfName,dhcpsMsgIn.vrfName))) { ret = dhcpServerChkReqIpAvailable(res->ip_addr, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } } } } /* 曾经分配给客户端的IP地址信息 */ if (response == 2) { ret = rtdDhcpServerGetBindEntryByCid(&cid, bindcidcmp_not_manual, &tmpBp);//为啥没在这里找到? if (ret == ERR_NO_ERROR) { binding = &tmpBp; } else { binding = NULL; } if (binding != NULL && binding->flag >= TEMP_ENTRY && binding->temp_epoch > curr_epoch) { DEBUG_DHCPS("dhcp binding for cid found"); res = binding; if (hasReqip) { DEBUG_DHCPS("auto-binding: with Request Ip option"); DBG_DHCP_MLAG("res->ip_addr: %u, reqip: %u",res->ip_addr.ip.s_addr,reqip.ip.s_addr); DBG_DHCP_MLAG("res->ip_addr: %s, reqip: %s", inet_ntoa(res->ip_addr.ip), inet_ntoa(reqip.ip)); DBG_DHCP_MLAG("res->ip_addr: %u, reqip: %u",res->ip_addr.ip.s_addr,reqip.ip.s_addr); //if (res->ip_addr.s_addr == reqip.s_addr) if(DHCP_SERVER_IP_SAME(res->ip_addr,reqip)) { ret = dhcpServerChkReqIpAvailable(reqip, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } else { DBG_DHCP_MLAG(""); response = 0; sendNak = 1; } } else { DEBUG_DHCPS("res->ip_addr.s_addr: %x dhcpsMsgIn.dhcp->ciaddr.s_addr: %x", res->ip_addr.ip.s_addr, dhcpsMsgIn.dhcp->ciaddr.s_addr); if (res->ip_addr.ip.s_addr == dhcpsMsgIn.dhcp->ciaddr.s_addr && (DHCP_VRF_NAME_SAME(res->ip_addr.vrfName,dhcpsMsgIn.vrfName))) { ret = dhcpServerChkReqIpAvailable(res->ip_addr, networkIp, packet, NULL); if (ret == TRUE) { response = 1; } } } } } int needNak = 0; /* 通过request ip */ if (response == 2 && hasReqip) /* Response still undetermined. */ { if (reqip.ip.s_addr != 0) { binding = NULL; ret = rtdDhcpServerGetBindEntryByIp(reqip, &tmpBp); if (ret == ERR_NO_ERROR) { res = &tmpBp; DEBUG_DHCPS("select_wreqip:res!=null"); rtdDhcpsPoolGetNetworkAndMask(res->poolName, &poolNetworkIp, &poolNetmask); rtdDhcpsGetPoolByPoolName(res->poolName,&pool_para); if (poolNetworkIp.s_addr == (res->ip_addr.ip.s_addr & poolNetmask.s_addr) && DHCP_VRF_NAME_SAME(pool_para.vrfName,cid.vrfName) && res->flag >= TEMP_ENTRY && res->temp_epoch >= curr_epoch && (cid.subnet.s_addr == (res->ip_addr.ip.s_addr & poolNetmask.s_addr)) && ((memcmp(res->haddr.haddr, tmpmac.haddr, tmpmac.hlen) == 0 && res->haddr.htype == tmpmac.htype) || (memcmp(res->cid.id, cid.id, cid.idlen) == 0))) { binding = &tmpBp; } } if (binding != NULL) { needNak =0; ret = dhcpServerChkReqIpAvailable(reqip, networkIp, packet, &needNak); if (ret == TRUE) { DBG("reponse=1"); response = 1; } else if (needNak == 1) { response = 0; sendNak = 1; } } } } /* 通过ciaddr, 原来已获取的ip---特指续约状态下 */ if (response == 2 && !hasReqip) /* Response still undetermined. */ { //reqip.s_addr = dhcpsMsgIn.dhcp->ciaddr.s_addr; COPY_SERVER_IP(reqip,dhcpsMsgIn.dhcp->ciaddr,dhcpsMsgIn.vrfName); if (reqip.ip.s_addr != 0) { binding = NULL; ret = rtdDhcpServerGetBindEntryByIp(reqip, &tmpBp); if (ret == ERR_NO_ERROR) { res = &tmpBp; DEBUG_DHCPS("select_wreqip:res!=null"); rtdDhcpsPoolGetNetworkAndMask(res->poolName, &poolNetworkIp, &poolNetmask); if (poolNetworkIp.s_addr == (res->ip_addr.ip.s_addr & poolNetmask.s_addr) && res->flag >= TEMP_ENTRY && res->temp_epoch >= curr_epoch && (cid.subnet.s_addr == (res->ip_addr.ip.s_addr & poolNetmask.s_addr)) && ((memcmp(res->haddr.haddr, tmpmac.haddr, tmpmac.hlen) == 0 && res->haddr.htype == tmpmac.htype) || (memcmp(res->cid.id, cid.id, cid.idlen) == 0))) { binding = &tmpBp; } } if (binding != NULL) { needNak =0; ret = dhcpServerChkReqIpAvailable(reqip, networkIp, packet, &needNak); if (ret == TRUE) { response = 1; } else if (needNak == 1) { response = 0; sendNak = 1; } } } } /* Ignore message if needed IP address not present. */ /* * Client's notion of IP address is incorrect - * deny the request. (Follows suggested behavior * of RFC 1541 for client in SELECTING state). */ if (response == 2) /* Don't exit if response undetermined. */ { if (dhcpsMsgIn.dhcp->giaddr.s_addr != 0) { DEBUG_DHCPS("send nak:giaddr=%s,reqip=%s,netmask=%s", inet_ntoa(dhcpsMsgIn.dhcp->giaddr),inet_ntoa(reqip.ip),inet_netof(netmask)); } else { DEBUG_DHCPS("send nak:addrpool=%s,req_ip=%s,netmask=%s", inet_ntoa(networkIp.ip),inet_ntoa(reqip.ip),inet_ntoa(netmask)); } response = 0; /* Send NAK to client. */ } if (response == 1 && swDhcpsIpIsEnable(binding->ip_addr) != OK && res->expire_epoch != DHCP_SERVER_FORERVER)//ip是动态绑定的,却存在手动绑定条目,则认为出错 { DEBUG_DHCPS("ip is not enable"); response = 0; sendNak = 1; } if (response == 1) /* A DHCP server will send ACK to client. */ { DEBUG_DHCPS("ack"); #ifdef PFM_TO_DO #ifdef INC_DHCPSNOOP if (swDhcpSnoopChkEntryIsReachLimit(packet, res->ip_addr.s_addr)) { if (dhcpsMsgIn.dhcp->ciaddr.s_addr != 0) { if (res) { if (res->flag > TEMP_ENTRY) { dhcpsSendRuntimeData(DHCPS_BIND_DEL, res); } res->flag = FREE_ENTRY; } construct_msg(DHCPNAK, NULL, offer_lease, packet); if (0 == send_dhcp(packet, DHCPNAK)) { if (reqip.s_addr != 0) { dhcpServerSendReplyMsgToMainQueue(DHCPNAK, htonl(reqip.s_addr), (UINT8 *)dhcpsMsgIn.dhcp->chaddr, 0, htonl(dhcpsMsgIn.dhcp->xid)); } } } dhcpServerMutexGive(); return -1; } #endif #endif offer_lease = choose_lease(reqlease, curr_epoch, res);//更新租约时长 DBG("lease is %d",offer_lease); if (rtdDhcpServerUpdateEntryByIp(DHCPREQUEST, res->ip_addr, offer_lease, curr_epoch, BIND_ENTRY) != 0) { if (reqforme == TRUE) /* Error in selected server's database. */ { response = 0; } else { DEBUG_DHCPS("update_db error"); dhcpServerMutexGive(); return (-1); } } if (response == 1) /* Lease selected and stored in database. */ { DHCP_SERVER_RUNTIME_MSG runTimeMsg; int oldFlg = 0; oldFlg = res->flag; res->flag = BIND_ENTRY; DEBUG_DHCPS("ack construct_msg"); if (offer_lease == DHCP_SERVER_FORERVER) { res->expire_epoch = DHCP_SERVER_FORERVER; } else { res->expire_epoch = curr_epoch + offer_lease; } res->temp_epoch=res->expire_epoch; construct_msg(DHCPACK, res, offer_lease, packet); /* send DHCPACK from the interface * xxx must be able to handle the fragments, but currently not * implemented. */ if (0 == send_dhcp(packet, DHCPACK, res->poolName)) { dhcpServerSendReplyMsgToMainQueue(DHCPACK, htonl(res->ip_addr.ip.s_addr), (UINT8 *)dhcpsMsgIn.dhcp->chaddr, offer_lease, htonl(dhcpsMsgIn.dhcp->xid)); } res->lease=offer_lease; DBG_DHCP_MLAG("a binded entry formed: "); _printBinding(*res); memset(&runTimeMsg, 0, sizeof(DHCP_SERVER_RUNTIME_MSG)); memcpy(&runTimeMsg.binding, res, sizeof(struct dhcp_binding)); /* 如果是手动绑定条目或者是已经绑定的普通条目,都只需要更新?? */ if (MANUAL_BIND_TYPE == res->bindtype || oldFlg == BIND_ENTRY) { //#ifdef PFM_TODO DBG("update rtd"); runTimeMsg.option = DHCPS_BIND_SET; rtdDhcpsSendRuntimeData(&runTimeMsg); //#endif } else { //#ifdef PFM_TODO DBG("update rtd"); runTimeMsg.option = DHCPS_BIND_ADD; rtdDhcpsSendRuntimeData(&runTimeMsg); //#endif } dhcpServerMutexGive(); } } //只要没有处理成功,无论是否显式置nak,只要没有relay,都回复nak;有relay的情况下,只有当前面的处理后nak==1时才回复nak if (response == 0) /* Deny request with NAK if client or server error occurred. */ { DEBUG_DHCPS("sendnak: %d, dhcprGetGlobalStatus: %d", sendNak, dhcpRelayModuleGetGlobalStatus()); /* 如果Relay开启,尝试交给Relay处理,不发送NAK */ if (0 == sendNak && dhcpRelayModuleGetGlobalStatus()) { DEBUG_DHCPS("dhcprToServer"); user_port up = {}; user_port rxUp = {}; UP_ITER_LIST(packet->uportList, index, up) { rxUp = up; break; } ret = swDhcpsRelayToServer(packet->vid, rxUp, DHCPREQUEST,&dhcpsMsgIn); if (ERR_NO_ERROR != ret) { DEBUG_DHCPS("DHCP relay error!!"); dhcpServerMutexGive(); return (-1); } dhcpServerMutexGive(); return (0); } DEBUG_DHCPS("send nak"); /* if request is for this server, reply with NAK. Otherwise * throw the packet silently By huzhiyuan 2013,7,17 */ //#ifdef PFM_TODO if (res) { DHCP_SERVER_RUNTIME_MSG runTimeMsg; memset(&runTimeMsg, 0, sizeof(DHCP_SERVER_RUNTIME_MSG)); memcpy(&runTimeMsg.binding, res, sizeof(struct dhcp_binding)); if (res->flag > 1) { DBG("update rtd"); runTimeMsg.option = DHCPS_BIND_DEL; rtdDhcpsSendRuntimeData(&runTimeMsg); } res->flag = FREE_ENTRY; } //#endif construct_msg(DHCPNAK, NULL, offer_lease, packet); char poolName[DHCPS_POOLNAME_LEN + 1]; if (res) { memcpy(poolName, res->poolName, sizeof(res->poolName)); } if (0 == send_dhcp(packet, DHCPNAK, poolName)) { //发送nak成功 if (reqip.ip.s_addr != 0) { dhcpServerSendReplyMsgToMainQueue(DHCPNAK, htonl(reqip.ip.s_addr), (UINT8 *)dhcpsMsgIn.dhcp->chaddr, 0, htonl(dhcpsMsgIn.dhcp->xid)); } } } dhcpServerMutexGive(); return (0); }对于这个函数 dhcp client renew发来的报文会怎么运
最新发布
09-26
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值