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

📄 dhcp_proxy.c

📁 dhcp proxy,在电信设备中的运用
💻 C
📖 第 1 页 / 共 4 页
字号:
			pCB->DhcpWait4ReplyMsg = NULL;
			return (FALSE);
		}

		pCB->DhcpWait4ReplyMsg = NULL;
		pCB->State = DHCP_STATE_BOUND_T2;
		/* Call the DHCP state machine */
		DHCP_fsm (pCB, NULL, NULL, (Uint8) 0, dhcp_private);

		break;

	case DHCP_MSG_LEASEUP_TIMEOUT:
		/* Unsuccesfully negotiate for an extension on the current lease */
		DHCP_DEBUG ("DHCP_TimerProc_ReplyMsg(): DHCP_MSG_LEASEUP_TIMEOUT \n");
		if (pCB->State != DHCP_STATE_REBIND) {
			exec_Event (PEVT_DHCP, EVT_ALLSINKS,
						EVL_UNUSUAL, DHCP_STRINGS, STRING_NUM (dhcp_proxy_illegal_state));
			pCB->DhcpWait4ReplyMsg = NULL;
			return (FALSE);
		}

		/* need to tear down the connection. */
		if (ProxyDiscIfLeaseExp) {
			pCB->DhcpWait4ReplyMsg = NULL;
			DHCP_delete_ondemand (pCB);
			DHCP_Release (pCB);
			return (FALSE);
		} else {
			pCB->DhcpWait4ReplyMsg = NULL;
			DHCP_Release (pCB);
			return (FALSE);
		}
		break;

	default:
		DHCP_DEBUG ("DHCP_TimerProc_ReplyMsg(): STATE %d; TimerType %d\n", pCB->State, pCB->TimerType);
		return FALSE;

	}
	return (FALSE);
}

Boolean
DHCP_TimerProc_ProxyIpMsg (void *parm1)
{
	DHCP_CB *pCB;
	Uint8 TimerTypeProxy;
	ExecStatus status = ES_SUCCESS;
	Int32 indexl;
	Uint32 Xid;
	DhcpIPReqMsg *param;

	Xid = (Uint32) parm1;

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

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

	pCB = &dhcp_array_cb[indexl];

	DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg(): pcb->ProxyIPMsg (%x, %x)\n", pCB, pCB->DhcpProxyIPMsg);

	TimerTypeProxy = (Uint8) pCB->TimerTypeProxy;

	DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg(): STATE %d; TimerType %d\n", pCB->State, pCB->TimerType);

	DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg(): No response DHCP_MSG_PROXYIPADDR_TIMEOUT\n");
	/* Cannot acquire an IP addr from a DHCP server, give it up */

	switch (TimerTypeProxy) {
	case DHCP_MSG_PROXYIPADDR_TIMEOUT:
		if (pCB->DhcpProxyIPMsg == NULL) {
			return (FALSE);
		}

		/* TODO
		 ** Have to actually return error message back to IP.
		 ** As of now just returning IP of 0.0.0.0
		 */
		param = (DhcpIPReqMsg *) EXEC_GET_MSG_PARAM (pCB->msg);
		COPY_NETORDu32 (&param->framed_ip_address, &pCB->YourIpAddr);

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

		DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg : 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);

		pCB->msg = NULL;
		/* This timer already fired ... Don't refree it .. */
		pCB->DhcpProxyIPMsg = NULL;
		pCB->ProxyTimerSet = FALSE;
		DHCP_FreeCB ((DHCP_CB *) pCB);
		exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_UNUSUAL,
					DHCP_STRINGS, STRING_NUM (dhcp_fail_set_timer), status);
		return (FALSE);
		break;

	default:
		DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg(): STATE %d; TimerType %d\n",
					pCB->State, pCB->TimerType);
		return FALSE;
	}
	return FALSE;
}

/*
 * dhcp_proxy_init() initializes all pertinent data structures,
 * allocates a mailbox and registers all DHCP handlers to the mailbox.
 */
void
dhcp_proxy_init (DHCPPrivateData_t * dhcp_private, ExecStatus * status)
{
	Uint32 i;

	/*
	 * Zero the counters
	 */

	memset (&dhcp_private->proxy_count, 0, sizeof (DHCPPClient_t));

	/* Alloc initial DHCP pCB table size */
	dhcp_array_cb = (DHCP_CB *) exec_allocate (DHCP_PROXY_ALLOC
											   * sizeof (DHCP_CB),
											   MEMF_STD_ERROR | MEMF_ZERO_MEMORY,
											   mem_default, MAGIC_NUMBER ('D', 'H', '1', '0'), status);
	if (dhcp_array_cb == NULL) {
		DHCP_DEBUG ("Couldn't allocate mem. for dhcp_array_cb\n");
		exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_CRITICAL, DHCP_STRINGS,
					STRING_NUM (dhcp_error_alloc_msg), status);
		return;
	}

	for (i = 0; i < DHCP_PROXY_ALLOC; i++) {
		memset (&dhcp_array_cb[i], 0, sizeof (DHCP_CB));
		dhcp_array_cb[i].msg = NULL;	/* Storage for IPCP msg */
		dhcp_array_cb[i].ip_addr_acq = FALSE;
		dhcp_array_cb[i].ProxyTimerSet = FALSE;
	}

	dhcp_private->client_max_retry = DHCP_MAX_RETRY;
}


/*
**      dhcp_proxy_rcv_msg()
**
**      DHCP Server receive routine. Handles all incoming DHCP packets
**      from UDP port (68).
**
**	msg		Pointer to received message
**	status
**	dhcp_private	Pointer to DHCP Process private data
**	rx_params	Pointer to received message context
**
*/
void
dhcp_proxy_rcv_msg (ExecMsg msg, ExecStatus status,
					DHCPPrivateData_t * dhcp_private, UdpRxMsg_t * rx_params)
{
	ExecBuff bd_buf;
	DHCP_PKT *p_DHCPPacket;
	DHCP_CB *pCB;
	Uint8 DHCP_MsgType;

	DHCP_DEBUG ("dhcp_proxy_rcv_msg(): Packet received\n");

	/*
	 ** Point at DHCP/BOOTP PDU
	 */

	bd_buf = EXEC_GET_MSG_BUFFER (msg);

	if (BUFFER_SIZE (bd_buf) < MIN_DHCP_PACKET_SIZE) {
		DHCP_DEBUG ("dhcp_proxy_rcv_msg(): Packet Size less than minimum DHCP message size.\n");
		return;

	}

	p_DHCPPacket = (DHCP_PKT *) BUFFER_PTR (bd_buf);
	pCB = DHCP_GetCB (p_DHCPPacket->Xid);

	/* if Xid is 0 then this DHCP packet does not have a matching pCB!. */
	if (pCB == NULL) {
		DHCP_DEBUG ("dhcp_proxy_rcv_msg(): No Corresponding pCB found.\n");
		return;
	}

	/* Jump to DHCP process if this is a DHCP reply packet */
	/* First 4 bytes of VendorInfo contains the Magic Cookie, skip it */
	if (DHCP_GetOp (&p_DHCPPacket->Options[4], &DHCP_MsgType, DHCP_OP_MSGTYPE, VENDOR_INFO_LEN, FALSE)) {
		if ((DHCP_MsgType == DHCP_OFFER) || (DHCP_MsgType == DHCP_ACK) || (DHCP_MsgType == DHCP_NAK)) {
			/* Call DHCP process, Packet BD will be freed there */

			DHCP_DEBUG ("dhcp_proxy_rcv_msg():DHCP_MsgType= %d, IP %ai\n", DHCP_MsgType,
						&p_DHCPPacket->YourIpAddr);

			DHCP_fsm (pCB, bd_buf, p_DHCPPacket, DHCP_MsgType, dhcp_private);
		}
	}
}

/* DHCP_GetCB() returns a CB whose Xid matches with the Xid in question */
DHCP_CB *
DHCP_GetCB (Xid)
	 Uint32 Xid;
{
	Int8 i;
	DHCP_CB *pCB = &dhcp_array_cb[0];


	for (i = 0; i < num_of_dhcp_pcb; i++) {
		if (pCB->Xid == Xid) {
			DHCP_DEBUG (" DHCP_GetCB(): Found matching Xid \n");
			return (pCB);
		}
		pCB++;
	}
	return (NULL);
}

/*
 * DHCP_GetFreeCB() tries to get a free CB from the CB array. If none
 * is found, NULL is returned.
 */
DHCP_CB *
DHCP_GetFreeCB ()
{
	DHCP_CB *pCB = &dhcp_array_cb[0];
	DHCP_CB *temp_array;
	ExecStatus status = ES_SUCCESS;
	Int32 i = 0;

	/*
	 * Check to see if the space allocated to hold the DHCP Proxy
	 * entries needs to be expanded.
	 */

	if (num_of_dhcp_pcb == num_of_dhcp_pcb_allocated) {
		temp_array = exec_realloc (dhcp_array_cb, (num_of_dhcp_pcb_allocated + DHCP_PROXY_ALLOC)
								   * sizeof (DHCP_CB), &status);

		if (temp_array == NULL) {
			exec_Event (PEVT_DHCP, EVT_ALLSINKS, EVL_CRITICAL,
						DHCP_STRINGS, STRING_NUM (dhcp_proxy_error_realloc));
			return (FALSE);
		}

		memset (&temp_array[num_of_dhcp_pcb_allocated], 0, DHCP_PROXY_ALLOC * sizeof (DHCP_CB));

		dhcp_array_cb = temp_array;
		num_of_dhcp_pcb_allocated = num_of_dhcp_pcb_allocated + DHCP_PROXY_ALLOC;

		for (i = num_of_dhcp_pcb; i < num_of_dhcp_pcb_allocated; i++) {
			dhcp_array_cb[i].ProxyTimerSet = FALSE;
			dhcp_array_cb[i].msg = NULL;	/* Storage for IPCP msg */
			dhcp_array_cb[i].ip_addr_acq = FALSE;
		}

	}

	pCB = &dhcp_array_cb[num_of_dhcp_pcb];
	pCB->Xid = exec_random ();
	pCB->State = DHCP_STATE_INIT;
	pCB->ProxyTimerSet = FALSE;
	pCB->msg = NULL;			/* Storage for IPCP msg */
	pCB->LeaseTime = 0;
	pCB->T1Time = 0;
	pCB->T2Time = 0;
	pCB->ElapsedSec = 0;
	pCB->YourIpAddr = 0;
	pCB->ClientIpAddr = 0;
	pCB->ServerID = 0;
	pCB->DestIpAddr = 0;
	pCB->ip_addr_acq = FALSE;
	memset (pCB->ClientHostName, 0, CLIENT_HOSTNAME_LEN);
	memset (pCB->ClientID, 0, DHCP_MAX_CID_LEN);
	pCB->Retry = 0;
	pCB->SavedpBD = NULL;
	pCB->TimerType = 0;
	pCB->msg = NULL;
	pCB->dhcp_connection_id = 0;
	pCB->DhcpWait4ReplyMsg = NULL;
	pCB->DhcpProxyIPMsg = NULL;

	DHCP_DEBUG ("GetFreeCB(): Allocating pCB with indexl %d TimerState %d\n", num_of_dhcp_pcb,
				pCB->ProxyTimerSet);

	num_of_dhcp_pcb++;			/* increment usage count */

	return (pCB);
}

/*
 *   Ths function is for the hidden command _show dhcp_proxy active_pcb
 */
void
dhcp_proxy_get_active_pcb (void)
{

	int i;
	char tmp_string[2048];
	extern void cli_send_data (const char *);
	DHCP_CB *pCB = &dhcp_array_cb[0];


	for (i = 0; i < num_of_dhcp_pcb; i++) {
		if (pCB->State != DHCP_STATE_INIT) {
			exec_sprintf (tmp_string,
						  "pCB: %d  State: %d TimerType: %d \t Xid:  %d \t IP Addr: %ai\n", i,
						  pCB->State, pCB->TimerType, pCB->Xid, &pCB->YourIpAddr);
			cli_send_data (tmp_string);
		}
		pCB++;					/* move to next */
	}
}

/*
 *   This function is for deleting pCB connections and releasing IP addresses
 *   in case of error conditions. Warning : Highly risky !.
 */
void
dhcp_del_active_pcb (int indexl)
{
	DHCP_CB *pCB;
	char tmp_string[2048];
	extern void cli_send_data (const char *);


	if (indexl >= num_of_dhcp_pcb) {
		exec_sprintf (tmp_string, "pCB with indexl %d doesn't exist", indexl);
		cli_send_data (tmp_string);
		return;
	}

	exec_sprintf (tmp_string, "Request to delete pCB %d", indexl);
	cli_send_data (tmp_string);

	pCB = &dhcp_array_cb[indexl];
	DHCP_Release (pCB);

	return;
}

Uint32
DHCP_get_src_ip_address (void)
{
	ExecStatus status;
	IpFwdFindInternalNetMsg *findIntNetReqP;
	ExecMsg findIntNetMsgP;
	Uint32 src_ipAddr;
	DHCPPrivateData_t *dhcp_private = exec_get_my_data ();


	findIntNetMsgP = exec_alloc_msg (sizeof (IpFwdFindInternalNetMsg),
									 IP_FWD_FIND_INTERNAL_NET_REQ,
									 MSGF_CLEAR_PARAM | MSGF_STD_ERROR, &status);
	if (status != ES_SUCCESS) {
		return (0);
	}
	findIntNetReqP = (IpFwdFindInternalNetMsg *) EXEC_GET_MSG_PARAM (findIntNetMsgP);

	status = exec_passmsg (findIntNetMsgP, dhcp_private->ip_fwd_mbox, MSGF_PASSONLY | MSGF_STD_ERROR);

	/* Since this is passmsg, we have to free it. */
	src_ipAddr = findIntNetReqP->ip_addr;
	exec_freemsg (findIntNetMsgP, DEFAULT_FLAGS);

	if (status != ES_SUCCESS) {
		return (0);
	}

	return (src_ipAddr);
}

void
DHCP_get_my_mac_addr (ExecMsg msg)
{
	ArpResolveAddrMsg *arp_rsp;
	ExecStatus status = ES_SUCCESS;


	arp_rsp = EXEC_GET_MSG_PARAM (msg);
	status = EXEC_GET_MSG_STATUS (msg);

	if (status != ARP_NO_ERROR) {
		exec_Event (PEVT_DHCP, EVT_ALLSINKS,
					EVL_UNUSUAL, DHCP_STRINGS, STRING_NUM (dhcp_proxy_arp_rsp_null), status);
		DHCP_DEBUG ("ARP RESPONSE is NULL for MAC ADDR \n");
		return;
	}

	COPY_MAC_ADDR (&my_mac_addr, &arp_rsp->mac_address);

	my_mac_resolved = TRUE;

	DHCP_DEBUG ("get_my_mac_addr: %ai -> %ae\n", &arp_rsp->addr_to_be_resolved, &arp_rsp->mac_address);

	return;
}

static void
ProxyAddSimpleOption (Uint8 * Options, int *p_Offset, Uint8 Code, Uint8 Value)
{
	Options[(*p_Offset)++] = Code;
	Options[(*p_Offset)++] = 1;	/* Simple length */
	Options[(*p_Offset)++] = Value;
}

static void
ProxyAddMemOption (Uint8 * Options, int *p_Offset, Uint8 Code, char *Str, int Length)
{

	Options[(*p_Offset)++] = Code;
	Options[(*p_Offset)++] = (Uint8) Length;
	memmove (Options + *p_Offset, Str, Length);
	*p_Offset += Length;
	return;
}

static void
ProxyAddULONGOption (Uint8 * Options, int *p_Offset, Uint8 Code, Uint32 Value)
{

	Options[(*p_Offset)++] = Code;
	Options[(*p_Offset)++] = 4;
	/*
	 ** Transform to network order
	 */
	COPY_NETORDu32 (&Options[*p_Offset], &Value);
	(*p_Offset) += 4;
	return;
}

void
DHCP_delete_ondemand (DHCP_CB * pCB)
{

	ExecMsg delete_msg;
	ExecStatus status;
	DhcpDeleteConnection *param;
	DHCPPrivateData_t *dhcp_private = exec_get_my_data ();

	delete_msg = exec_alloc_msg (sizeof (DhcpDeleteConnection),
								 DHCP_DELETE_CONN_REQ, MSGF_CLEAR_PARAM | MSGF_STD_ERROR, &status);

	if ((delete_msg == NULL) || (status != ES_SUCCESS))
		return;

	param = (DhcpDeleteConnection *) EXEC_GET_MSG_PARAM (delete_msg);

	param->address = pCB->YourIpAddr;

	status = exec_sendmsg (delete_msg, dhcp_private->ip_fwd_mbox, DEFAULT_FLAGS);
	if (status != ES_SUCCESS) {
		exec_freemsg (delete_msg, DEFAULT_FLAGS);
		return;
	}
}

⌨️ 快捷键说明

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