⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp_proxy.c

📁 dhcp proxy,在电信设备中的运用
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* Send response back to IP with the IP address */
				param = (DhcpIPReqMsg *) EXEC_GET_MSG_PARAM (pCB->msg);
				COPY_NETORDu32 (&param->framed_ip_address, &pCB->YourIpAddr);

				DHCP_DEBUG ("dhcp_fsm(): Respond to IP with %ai\n", &param->framed_ip_address);

				DHCP_DEBUG ("Responding to sender %s\n",
							exec_get_process_name (EXEC_GET_MSG_SENDER (pCB->msg)));

				exec_respond_to_msg (pCB->msg, IP_FWD_DHCP_IPADDR_RSP, ES_SUCCESS, DEFAULT_FLAGS);
				dhcp_private->proxy_count.addr_acquired++;
				pCB->ip_addr_acq = TRUE;
				pCB->msg = NULL;
			} else {
				DHCP_DEBUG ("Address already acquired..Just Change the state to DHCP_STATE_BOUND.\n");
			}

			if (pCB->DhcpProxyIPMsg != NULL && pCB->ProxyTimerSet == TRUE) {
				exec_stop_timer (pCB->DhcpProxyIPMsg, TMRF_CHECK_MBOX);
				exec_freemsg (pCB->DhcpProxyIPMsg, DEFAULT_FLAGS);
				DHCP_DEBUG ("got an ACK; setting pcb->ProxyIPMsg (%x, %x) to NULL\n", pCB,
							pCB->DhcpProxyIPMsg);
				pCB->DhcpProxyIPMsg = NULL;
				pCB->ProxyTimerSet = FALSE;
			}

			if (pCB->LeaseTime != ~0UL) {
				/* should be technically indefinite */
				/* start lease renewal timer T1 */
				pCB->T1Time = pCB->LeaseTime / 2;	/* default */
				pCB->T2Time = (pCB->LeaseTime / 4) * 3;	/* default */

				pCB->TimerType = DHCP_MSG_LEASET1UP_TIMEOUT;

				DHCP_DEBUG ("DHCP_fsm(): Starting DHCP_MSG_LEASET1UP_TIMEOUT in state %d\n",
							pCB->State);
				pCB->DhcpWait4ReplyMsg =
					exec_set_alarm (DHCP_TimerProc_ReplyMsg, (void *) pCB->Xid,
									MAGIC_NUMBER ('D', 'P', 'T', 'I'), pCB->T1Time, TMRF_SECONDS,
									&status);
				if (status != ES_SUCCESS) {
					DHCP_FreeCB ((DHCP_CB *) pCB);
					exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_CRITICAL,
								DHCP_STRINGS, STRING_NUM (dhcp_fail_set_proxy_iptimer));
					return;
				}

			} else {
				pCB->T1Time = ~0UL;
				pCB->T2Time = ~0UL;
			}
			return;
		} else {

			exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
						STRING_NUM (dhcp_error_alloc_msg), status);

			/*
			 * There might be something wrong with this IP addr.
			 * That's why the server NAKs it when we try to renew it.
			 * Don't use it, disconnect the NCP connection
			 */
			DHCP_DEBUG ("DHCP_fsm(): Got a NAK State = %d FreeCB\n", pCB->State);
			DHCP_delete_ondemand (pCB);
			DHCP_Release (pCB);
			return;
		}

		break;

	case DHCP_STATE_BOUND_T1:
		DHCP_DEBUG ("DHCP_fsm(): DHCP_STATE_BOUND_T1 \n");
		/* Called by DHCP_TimerProc(): Renewal time T1, send out a DHCP_REQUEST */
		pCB->Retry = 1;

		req_msg = exec_alloc_msg (sizeof (UdpSendMsg_t),
								  UDP_SEND_REQ, MSGF_CLEAR_PARAM | DEFAULT_FLAGS, &status);
		if (req_msg == NULL || status != ES_SUCCESS) {
			DHCP_FreeCB (pCB);
			exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
						STRING_NUM (dhcp_error_alloc_msg), status);
			DHCP_DEBUG ("DHCP_SendReq(): dhcp_error_alloc_msg for req_msg, ERROR !\n");
			return;
		}

		if ((RetCode = DHCP_SendReq (DHCP_REQUEST, pCB, NULL, pCB->ServerID,
									 FALSE, TRUE, req_msg, dhcp_private)) == E_NONE) {
			dhcp_private->proxy_count.t1_renewals_sent++;
			pCB->State = DHCP_STATE_RENEW;
		} else {
			/* Cannnot send request, free CB */
			DHCP_DEBUG ("DHCP_fsm():DHCP_STATE_BOUND_T1 cannot send request FreeCB \n");
			exec_freemsg (req_msg, DEFAULT_FLAGS);
			DHCP_FreeCB (pCB);
			return;
		}
		/* Start timer for retry */
		pCB->TimerType = DHCP_MSG_WAIT4REPLY_TIMEOUT;

		DHCP_DEBUG ("DHCP_fsm(): Starting DHCP_WAIT4REPLY_TIMEOUT in state %d\n", pCB->State);
		pCB->DhcpWait4ReplyMsg = exec_set_alarm (DHCP_TimerProc_ReplyMsg, (void *) pCB->Xid,
												 MAGIC_NUMBER ('D', 'P', 'T', 'R'),
												 DHCP_WAIT4REPLY_TIMEOUT, TMRF_SECONDS, &status);
		if (status != ES_SUCCESS) {
			pCB->DhcpWait4ReplyMsg = NULL;
			DHCP_FreeCB ((DHCP_CB *) pCB);
			exec_Event (PEVT_DHCP, EVT_ALLSINKS,
						EVL_CRITICAL, DHCP_STRINGS,
						STRING_NUM (dhcp_fail_set_proxy_retry_timer), status);
			return;
		}
		break;

	case DHCP_STATE_BOUND_T2:
		DHCP_DEBUG ("DHCP_fsm(): DHCP_STATE_BOUND_T2 \n");
		/* Called by DHCP_TimerProc(): Renewal time T2,
		   send out a broadcast DHCP_REQUEST */
		pCB->Retry = 1;
		/* prepare broadcast UDP message for DHCP_REQUEST */
		req_msg = exec_alloc_msg (sizeof (UdpTxMcastPktMsg),
								  UDP_MCAST_SEND_REQ, DEFAULT_FLAGS, &status);
		if (req_msg == NULL || status != ES_SUCCESS) {
			DHCP_FreeCB (pCB);
			exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
						STRING_NUM (dhcp_error_alloc_msg), status);
			return;
		}

		if ((RetCode = DHCP_SendReq (DHCP_REQUEST, pCB, NULL, 0xffffffff,
									 FALSE, TRUE, req_msg, dhcp_private)) == E_NONE) {
			dhcp_private->proxy_count.t2_renewals_sent++;
			pCB->State = DHCP_STATE_REBIND;
		} else {
			/* Cannnot send request, free CB */
			DHCP_DEBUG ("DHCP_fsm():DHCP_STATE_BOUND_T2 cannot send request FreeCB \n");
			exec_freemsg (req_msg, DEFAULT_FLAGS);
			DHCP_FreeCB (pCB);
			return;
		}
		/* Start timer for retry */
		pCB->TimerType = DHCP_MSG_WAIT4REPLY_TIMEOUT;

		DHCP_DEBUG ("DHCP_fsm(): Starting DHCP_WAIT4REPLY_TIMEOUT in state %d\n", pCB->State);
		pCB->DhcpWait4ReplyMsg = exec_set_alarm (DHCP_TimerProc_ReplyMsg, (void *) pCB->Xid,
												 MAGIC_NUMBER ('D', 'P', 'T', 'R'),
												 DHCP_WAIT4REPLY_TIMEOUT, TMRF_SECONDS, &status);
		if (status != ES_SUCCESS) {
			pCB->DhcpWait4ReplyMsg = NULL;
			DHCP_FreeCB ((DHCP_CB *) pCB);
			exec_Event (PEVT_DHCP, EVT_ALLSINKS,
						EVL_CRITICAL, DHCP_STRINGS,
						STRING_NUM (dhcp_fail_set_proxy_retry_timer), status);
			return;
		}
		break;					/* case DHCP_STATE_BOUND_T2 */


	case DHCP_STATE_BOUND:
		DHCP_DEBUG ("DHCP_fsm():state  DHCP_STATE_BOUND; got msg_type: %x Do Nothing\n", DHCP_MsgType);
		break;

	default:
		DHCP_DEBUG ("DHCP_fsm():Invalid state  %d (Default)\n", pCB->State);
		DHCP_FreeCB (pCB);
		exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
					STRING_NUM (dhcp_proxy_fail_set_timer), status);
	}
}

/*
 * DHCP_SendReq() sends out a DHCP request whose type is specified in
 * DHCP_CODE. It saves the pBD for retry later.
 */
DHCP_ERROR_CODE
DHCP_SendReq (Uint8 DHCP_MsgType, DHCP_CB * pCB, ExecBuff pBD, Uint32 DestIpAddr,
			  Boolean StoreSrvrID, Boolean ReTx, ExecMsg req_msg, DHCPPrivateData_t * dhcp_private)
{
	DHCP_PKT *pHdr;
	Uint8 *pChar;
	ExecBuff req_buffer;
	UdpSendMsg_t *req_param;
	UdpTxMcastPktMsg *brcast_param;
	struct udp_conn *udpc;
	ExecStatus status;
	int offset;

	/* check all flags ie. DhcpProxyEnabled, etc. */
	if (!DHCPProxyEnabled) {
		DHCP_DEBUG ("DHCP_proxy_req_proc(): DHCPProxy is not Enabled !\n");
		return E_DHCP_SW_FAULT;
	}


	DHCP_DEBUG ("DHCP_SendReq(): DHCP_MsgType %d. Send MCAST | UCAST UDP packet\n", DHCP_MsgType);

	/*
	 * Broadcast DHCP_REQUEST only if State != DHCP_STATE_BOUND_T1
	 */

	if ((DHCP_MsgType == DHCP_DISCOVER) ||
		((DHCP_MsgType == DHCP_REQUEST) && (pCB->State != DHCP_STATE_BOUND_T1))) {
		/* Broadcast UDP */
		/* Point at the UDP connection block */
		brcast_param = (UdpTxMcastPktMsg *) EXEC_GET_MSG_PARAM (req_msg);
		udpc = &brcast_param->udpc;
	} else {
		req_param = (UdpSendMsg_t *) EXEC_GET_MSG_PARAM (req_msg);
		req_param->bcst_flags = PF_NOT_BROADCAST;
		udpc = &req_param->usc_udpc;
	}

	pCB->InitTime = exec_get_clock ();
	pCB->Retry = 1;

	DHCP_DEBUG ("The Xid for this transaction is = %u\n", pCB->Xid);

	/* Grab a UDP packet buffer */

	req_buffer = UDP_ALLOC (DHCP_MAX_PKT_SIZE, 0, status, MAGIC_NUMBER ('D', 'H', 'U', '0'));
	if (status != ES_SUCCESS) {
		return (E_DHCP_CANT_ALLOC_BUFFER);
	}
	/* UDP_ALLOC above doesn't clean it up ! */
	memset (BUFFER_PTR (req_buffer), 0, DHCP_MAX_PKT_SIZE);

	pHdr = (DHCP_PKT *) (BUFFER_PTR (req_buffer));

	pHdr->OpCode = BOOTP_OP_CODE_REQUEST;

	pHdr->HwType = HW_TYPE_ETHERNET;
	pHdr->HwLen = HW_LEN_ETHERNET;
	pHdr->Hops = 0;
	COPY_NETORDu32 (&pHdr->Xid, &pCB->Xid);

	pHdr->ElapsedSec = exec_get_clock () - (pCB->InitTime);
	pHdr->ElapsedSec = VALUE_NETORDu16 (pHdr->ElapsedSec);
	pHdr->Unused = 0x8000;
	pHdr->ServerName[0] = '\0';
	pHdr->FileName[0] = '\0';
	SETu32 (&pHdr->GatewayIpAddr, 0);

	if (DHCP_MsgType == DHCP_DISCOVER) {
		/*
		 * Rightfully, in the DHCP Request, Ciaddr should also be set to 0 if
		 * there's no previous known IP addr, which is our case. If we set
		 * it to 0, the Incognito DHCP server will not use it to send out
		 * as the dest. IP addr in its DHCP AK, but the NT DHCP server will
		 * discard our DHCP Request. Since Incognito decides to fix its code,
		 * we'll just assign it to contain the newly offerred IP addr. to be
		 * interoperable with NT server even though this is not correct (refer
		 * to RFCs 951(Bootp server) and 1541 (DHCP server)).
		 */
		SETu32 (&pHdr->ClientIpAddr, 0);
	} else {
		/* ClientIpAddr set to offered Ip addr in REQUEST, DECLINE or RELEASE */
		COPY_NETORDu32 (&pHdr->ClientIpAddr, &pCB->YourIpAddr);
	}
	SETu32 (&pHdr->YourIpAddr, 0);
	SETu32 (&pHdr->ServerIpAddr, 0);	/*For PRoxy clients set it to 0(temp) */

	/*The 1st 4 bytes of the Option field (Vendor Info) is the magic cookie */
	pChar = &pHdr->Options[0];

	offset = 0;
	SETu32 (pChar, MAGIC_COOKIE);
	offset = 4;

	ProxyAddSimpleOption (pHdr->Options, &offset, DHCP_OP_MSGTYPE, DHCP_MsgType);

	ProxyAddULONGOption (pHdr->Options, &offset, DHCP_OP_LEASETIME, pCB->LeaseTime);

	ProxyAddStringOption (pHdr->Options, &offset, DHCP_OP_CLIENT_HOSTNAME, pCB->ClientHostName);
	ProxyAddMemOption (pHdr->Options, &offset, DHCP_OP_CLIENT_ID, pCB->ClientID, DHCP_MAX_CID_LEN);

	/* Store the ServerID option */

	if (StoreSrvrID) {
		ProxyAddULONGOption (pHdr->Options, &offset, DHCP_OP_SERVERID, pCB->ServerID);
		DHCP_DEBUG ("Storing ServerID %ai\n", &pCB->ServerID);
	}


	/* If this is a DHCP_REQ, put all options offered in DHCP_OFFER */
	if (DHCP_MsgType == DHCP_REQUEST) {
		COPY_NETORDu32 (&pHdr->ClientIpAddr, &pCB->YourIpAddr);
	}
	/*
	 * End Option
	 */
	pHdr->Options[offset] = DHCP_OP_ENDMARK;

	/* Save Dest IP addr and BD for retransmission */
	if (ReTx) {
		COPY_NETORDu32 (&pCB->DestIpAddr, &DestIpAddr);

		DHCP_DEBUG ("DHCP_SendReq(): ReTx, Duplicating pBD (pCB->SavedpBD).\n");
		if (pBD == NULL) {
			pCB->SavedpBD = exec_duplicate_bchain (req_buffer, DEFAULT_FLAGS, &status);
			if ((pCB->SavedpBD == NULL) || (status != ES_SUCCESS)) {
				exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
							STRING_NUM (dhcp_error_dup_bchain), __FILE__, __LINE__, status);
				return (E_DHCP_SW_FAULT);
			}
		} else {
			pCB->SavedpBD = exec_duplicate_bchain (pBD, DEFAULT_FLAGS, &status);
			if ((pCB->SavedpBD == NULL) || (status != ES_SUCCESS)) {
				exec_free_bchain (pBD, DEFAULT_FLAGS);
				exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
							STRING_NUM (dhcp_error_dup_bchain), __FILE__, __LINE__, status);

				return (E_DHCP_SW_FAULT);
			}
		}						/* (pBD != NULL) */

	}

	memset (&pHdr->ClientHwAddr, 0, CLIENT_HW_ADDR_LEN);
	COPY_MAC_ADDR (&pHdr->ClientHwAddr, &my_mac_addr);

	/* Initialise the connection block */
	udp_conn_init (udpc);

	DHCP_DEBUG ("DHCP: Sending discover/request to %ai\n", &DestIpAddr);
	/* Set source and destination UDP ports */
	udp_conn_set_dst (udpc, VALUE_NETORDu16 (BOOTP_SERVER_PORT));
	udp_conn_set_src (udpc, VALUE_NETORDu16 (BOOTP_CLIENT_PORT));

	ip_conn_set_dst (udp_conn_get_ip_conn (udpc), DestIpAddr);
	ip_conn_set_src (udp_conn_get_ip_conn (udpc), SrcIpAddr);

	/* Remember this function is never called with non NULL pBD... so its
	 ** okey ...
	 */
	EXEC_SET_MSG_BUFFER (req_msg, req_buffer);

	DHCP_DEBUG ("DHCP_SendReq(): calling udp_send_conn\n");
	status = exec_sendmsg (req_msg, dhcp_private->udp_mbox, DEFAULT_FLAGS);
	if (status != ES_SUCCESS) {
		exec_Event (PEVT_DHCP, EVT_ALLSINKS,
					EVL_UNUSUAL, DHCP_STRINGS, STRING_NUM (dhcp_error_udp_sendmsg), status);
		DHCP_DEBUG ("DHCP_SendReq(): Cannot send msg to UDP\n");
		return (E_DHCP_CANT_ALLOC_MEM);
	}

	/* Increment the counter */

	if (DHCP_MsgType == DHCP_DISCOVER)
		dhcp_private->proxy_count.discover_sent++;

	return (E_NONE);
}


/*
 * Release the IP and send call DHCP_Release when IP connection
 * gets torn down
 *
 */
void
DHCP_proxy_del_ip (ExecMsg msg)
{
	DHCP_CB *pCB = &dhcp_array_cb[0];
	Int32 i = 0;
	Dhcp_DelIp *param;

	param = EXEC_GET_MSG_PARAM (msg);

	for (i = 0; i < num_of_dhcp_pcb; i++) {
		if (pCB->YourIpAddr == param->intf_addr) {
			DHCP_DEBUG ("DHCP_proxy_del_ip(): Found matching IP %ai\n", &pCB->YourIpAddr);
			break;
		}
		pCB++;
	}

	if (i == num_of_dhcp_pcb) {
		DHCP_DEBUG ("DHCP_proxy_del_ip() : DID NOT FIND A MATCH\n");
		return;
	}

	DHCP_Release (pCB);

	DHCP_DEBUG (" Free DHCP_DEL_IP msg \n");
	exec_freemsg (msg, DEFAULT_FLAGS);
	return;
}

/*
 * DHCP_Release() sends a DHCP RELEASE request and frees the DHCP
 * Control Block. Called by BCP and IPCP when they're taking
 * down the NCP connection.
 */
void
DHCP_Release (DHCP_CB * pCB)
{
	ExecStatus status = ES_SUCCESS;
	DHCPPrivateData_t *dhcp_private = exec_get_my_data ();
	DHCP_ERROR_CODE RetCode = E_NONE;
	ExecMsg req_msg;
	UdpSendMsg_t *req_param;

	DHCP_DEBUG ("DHCP_Release(): Release IP and kill Timers \n");

	req_msg = exec_alloc_msg (sizeof (UdpSendMsg_t),
							  UDP_SEND_REQ, MSGF_CLEAR_PARAM | DEFAULT_FLAGS, &status);
	if (req_msg == NULL || status != ES_SUCCESS) {
		exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
					STRING_NUM (dhcp_error_alloc_msg), status);
		DHCP_DEBUG ("DHCP_SendReq(): dhcp_error_alloc_msg for req_msg, ERROR !\n");
		return;
	}

	req_param = (UdpSendMsg_t *) EXEC_GET_MSG_PARAM (req_msg);
	req_param->bcst_flags = PF_NOT_BROADCAST;
	req_param->policy.type = IP_POLICY_NONE;

	DHCP_DEBUG ("DHCP_Release: pCB->ServerID = %ai\n", &pCB->ServerID);
	if (pCB->ServerID != 0) {
		/* We must have leased an IP addr. from a DHCP server, release it */
		DHCP_DEBUG ("DHCP_Release: Send DHCP_RELEASE via udp \n");
		if ((RetCode = DHCP_SendReq (DHCP_RELEASE, pCB, NULL, pCB->ServerID, TRUE, FALSE,
									 req_msg, dhcp_private)) != E_NONE)
			exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL, DHCP_STRINGS,
						STRING_NUM (dhcp_error_udp_sendmsg), status);
		else
			dhcp_private->proxy_count.released++;
	} else {
		/* No point in sending RELEASE, just free the message */
		exec_freemsg (req_msg, DEFAULT_FLAGS);
	}

	/* Free the DHCP CB */
	DHCP_FreeCB (pCB);
	return;
}

/*
**  This function will free up the pCB and rearrange the array so that
**  ths deleted CB will be nulled
*/
void
DHCP_FreeCB (DHCP_CB * pCB)
{
	Int32 indexl;
	DhcpIPReqMsg *param;

	for (indexl = 0; indexl < num_of_dhcp_pcb; indexl++) {
		if (dhcp_array_cb[indexl].Xid == pCB->Xid)
			break;
	}

	if (indexl == num_of_dhcp_pcb) {
		DHCP_DEBUG ("DHCP_FreeCB: DID NOT FIND A MATCH\n");
		return;
	}

	/* Kill timers */
	if (pCB->DhcpWait4ReplyMsg != NULL) {
		exec_stop_timer (pCB->DhcpWait4ReplyMsg, TMRF_CHECK_MBOX);
		exec_freemsg (pCB->DhcpWait4ReplyMsg, DEFAULT_FLAGS);
		pCB->DhcpWait4ReplyMsg = NULL;
	}

	if (pCB->DhcpProxyIPMsg != NULL && pCB->ProxyTimerSet == TRUE) {
		exec_stop_timer (pCB->DhcpProxyIPMsg, TMRF_CHECK_MBOX);
		exec_freemsg (pCB->DhcpProxyIPMsg, DEFAULT_FLAGS);
		pCB->DhcpProxyIPMsg = NULL;
	}

	if (pCB->msg != NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -