📄 dhcp_proxy.c
字号:
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 (¶m->framed_ip_address, &pCB->YourIpAddr);
DHCP_DEBUG ("DHCP_TimerProc_ProxyIpMsg(): Respond to IP with %ai\n",
¶m->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 + -