📄 ncp.c
字号:
#ifdef NU_DEBUG_PPP
_PRINT ("IPCP State: STOPPED ");
#endif
/* Otherwise we have tried to many times, set the event
that will tell initialization we could not configure. */
NU_Set_Events (&link->negotiation_progression, LCP_CONFIG_FAIL, NU_OR);
}
break;
case ACK_SENT :
#ifdef NU_DEBUG_PPP
_PRINT ("ack_sent\r\n");
#endif
/* See if we get another try at configuring. */
if (ipcp->num_transmissions-- > 0)
{
/* We need to send another configure request with the newest
current set of configuration options. */
UTL_Timerset (NCP_SEND_CONFIG, dev_ptr, 0, 0);
}
else
{
/* Stop the restart timer. */
NU_Control_Timer (&ipcp->restart_timer, NU_DISABLE_TIMER);
/* Stop the echo timer since we are leaving the open state */
NU_Control_Timer (&lcp->echo_timer, NU_DISABLE_TIMER);
/* Change states */
ipcp->state = STOPPED;
#ifdef NU_DEBUG_PPP
_PRINT ("IPCP State: STOPPED ");
#endif
/* Otherwise we have tried to many times, set the event
that will tell initialization we could not configure. */
NU_Set_Events (&link->negotiation_progression, LCP_CONFIG_FAIL, NU_OR);
}
break;
}
}
/************************************************************************
* FUNCTION
*
* NCP_SnmpTimer_Expire
*
* DESCRIPTION
*
* This is the SNMP periodic timer that reports the NCP state to SNMP
*
* AUTHOR
*
* Raj Johnson
*
* INPUTS
*
* UNSIGNED dev_ptr The address of the PPP device
* for which the NCP timer expired.
*
* OUTPUTS
*
* none
*
************************************************************************/
#if (INCLUDE_PPP_MIB == NU_TRUE)
void NCP_SnmpTimer_Expire(UNSIGNED dev_ptr)
{
DV_DEVICE_ENTRY *device;
IPCP_LAYER *ipcp;
#ifdef NU_DEBUG_PPP
_PRINT ("\SnmpTimer expire\r\n");
#endif
/* Make a pointer to the device for this timer. */
device = (DV_DEVICE_ENTRY *)dev_ptr;
/* Get a pointer to the IPCP stucture for this device. */
ipcp = &(((LINK_LAYER *)device->link_layer)->ipcp);
if (ipcp->state == OPENED)
SNMP_pppIpOperStatus(device->dev_index, PPP_IP_OPER_STATUS_UP);
else
SNMP_pppIpOperStatus(device->dev_index, PPP_IP_OPER_STATUS_DOWN);
}
#endif
/************************************************************************
* FUNCTION
*
* NCP_IP_Change_Mode
*
* DESCRIPTION
*
* This function sets the mode of operation for NCP and the rest of PPP.
* The main difference between modes is in CLIENT mode PPP requests an
* IP address and in SERVER mode PPP assigns an IP address.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* INT8 new_mode CLIENT or SERVER
* DV_DEVICE_ENTRY *dev_ptr Pointer to PPP device.
*
* OUTPUTS
*
* STATUS NU_SUCCESS if the passed in mode
* was acceptable NU_UNAVAILABLE if
* the passed in mode was
* unacceptable
*
************************************************************************/
STATUS NCP_Change_IP_Mode(INT8 new_mode, DV_DEVICE_ENTRY *dev_ptr)
{
STATUS ret_val;
/* Make sure it is a valid mode */
if ((new_mode == NCP_CLIENT) || (new_mode == NCP_SERVER))
{
/* Change the mode the one that was passed in */
((LINK_LAYER *)dev_ptr->link_layer)->ipcp.mode = new_mode;
ret_val = NU_SUCCESS;
}
else
ret_val = NU_UNAVAILABLE;
return (ret_val);
}
/************************************************************************
* FUNCTION
*
* NCP_Configure_Req_Check
*
* DESCRIPTION
*
* This function checks all configuration options in the incoming
* configure request packet. If everything is ok then it will send
* an ACK to the peer. If any one option is not ok it will NAK those
* options. If an option is unknown it will reject that option.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* NET_BUFFER *in_buf_ptr Pointer to the incoming NCP
* packet
*
* OUTPUTS
*
* STATUS Were all the options ok
*
************************************************************************/
STATUS NCP_Configure_Req_Check (NET_BUFFER *in_buf_ptr)
{
IPCP_LAYER *ipcp;
NET_BUFFER *reject_buf_ptr, *nak_buf_ptr, *ack_buf_ptr;
LCP_HEADER *ncp_reject_pkt, *ncp_nak_pkt, *ncp_ack_pkt;
UINT8 HUGE *ncp_pkt_ptr,
HUGE *ncp_reject_ptr,
HUGE *ncp_nak_ptr;
UINT8 options_ok, dont_need_to_reject, identifier;
UINT16 length, reject_length, nak_length;
UINT8 temp_ip_address[2][4]; /* two IP addresses */
UINT8 HUGE *ncp_pkt = in_buf_ptr->data_ptr;
INT num_dns_servers;
/* Allocate a buffer for each one of the packets that we may need to send. */
reject_buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
nak_buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
ack_buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
/* Make sure a buffer was available */
if ((nak_buf_ptr == NU_NULL) || (ack_buf_ptr == NU_NULL) ||
(reject_buf_ptr == NU_NULL))
{
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
/* If any buffer were allocated then we need to put them back
before we return. */
if (reject_buf_ptr)
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, reject_buf_ptr);
if (nak_buf_ptr)
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, nak_buf_ptr);
if (ack_buf_ptr)
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, ack_buf_ptr);
/* Get out */
return (NU_FALSE);
}
/* Get a pointer to the IPCP structure for this packet. */
ipcp = &(((LINK_LAYER *)in_buf_ptr->mem_buf_device->link_layer)->ipcp);
/* Set the data pointer to give room for the PPP header. */
reject_buf_ptr->data_ptr = (reject_buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);
nak_buf_ptr->data_ptr = (nak_buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);
ack_buf_ptr->data_ptr = (ack_buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);
/* Set the lcp layer pointers to point at the data section of the
packet. */
ncp_reject_pkt = (LCP_HEADER *) reject_buf_ptr->data_ptr;
ncp_nak_pkt = (LCP_HEADER *) nak_buf_ptr->data_ptr;
ncp_ack_pkt = (LCP_HEADER *) ack_buf_ptr->data_ptr;
/* Point to the nak and reject packet data in case we have to
reject or nak something */
ncp_nak_ptr = &ncp_nak_pkt->data;
nak_length = LCP_HEADER_LENGTH;
ncp_reject_ptr = &ncp_reject_pkt->data;
reject_length = LCP_HEADER_LENGTH;
/* This will be used to tell if all the config options are unacceptable */
options_ok = NU_TRUE;
dont_need_to_reject = NU_TRUE;
/* Get the ID of this pkt */
identifier = ncp_pkt[LCP_ID_OFFSET];
/* Put the LCP structure on the packet and get the length */
ncp_pkt_ptr = ncp_pkt;
length = (UINT16) ( (*(ncp_pkt_ptr + LCP_LENGTH_OFFSET)) << 8);
length = length | *(ncp_pkt_ptr + LCP_LENGTH_OFFSET + 1);
/* Save the length before we take off the header. This will be used
if the options are ok */
ncp_ack_pkt->length = INTSWAP (length);
/* Now remove the header */
length -= LCP_HEADER_LENGTH;
/* Get a pointer to the data inside the LCP pkt */
ncp_pkt_ptr = ncp_pkt_ptr + LCP_DATA_OFFSET;
while (length > 0)
{
/* Check out what the option is and see if we can handle it */
switch (ncp_pkt_ptr[0])
{
case NCP_IP_ADDRESS :
/* Put the address in a temp var */
temp_ip_address[0][0] = ncp_pkt_ptr[LCP_CONFIG_OPTS];
temp_ip_address[0][1] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 1];
temp_ip_address[0][2] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 2];
temp_ip_address[0][3] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 3];
/* See if the address given to us is zero, this indicates
a request for IP assignment. */
if ((temp_ip_address[0][0] == 0) && (temp_ip_address[0][1] == 0) &&
(temp_ip_address[0][2] == 0) && (temp_ip_address[0][3] == 0))
{
/* We must be in server mode to assign an address */
if (ipcp->mode == NCP_SERVER)
{
#ifdef NU_DEBUG_PPP
_PRINT ("assigning client IP\r\n");
#endif
/* This will be done by a NAK pkt. So all we need to
do is to replace the zero IP address with the
assigned one. */
/* Put it in the NAK packet */
memcpy (ncp_nak_ptr, ncp_pkt_ptr,
NCP_IP_ADDRESS_LENGTH);
/* Replace the zeros with the new IP address */
ncp_nak_ptr[LCP_CONFIG_OPTS]
= ipcp->assigned_peer_ip_address[0];
ncp_nak_ptr[LCP_CONFIG_OPTS + 1]
= ipcp->assigned_peer_ip_address[1];
ncp_nak_ptr[LCP_CONFIG_OPTS + 2]
= ipcp->assigned_peer_ip_address[2];
ncp_nak_ptr[LCP_CONFIG_OPTS + 3]
= ipcp->assigned_peer_ip_address[3];
/* Update the length and the ptr */
ncp_pkt_ptr += NCP_IP_ADDRESS_LENGTH;
length -= NCP_IP_ADDRESS_LENGTH;
/* Set the NAK flag and length */
options_ok = NU_FALSE;
nak_length += NCP_IP_ADDRESS_LENGTH;
ncp_nak_ptr += NCP_IP_ADDRESS_LENGTH;
}
else
{
/* This should never happen, so just discard it and
bump the ptr and length. */
((LINK_LAYER *)in_buf_ptr->mem_buf_device->link_layer)->silent_discards++;
ncp_pkt_ptr += NCP_IP_ADDRESS_LENGTH;
length -= NCP_IP_ADDRESS_LENGTH;
}
} /* if */
else
{
/* If the address is not zeros and we are acting as a server
then the peer is asking to use a specific address. We
only want him to use an address that we assigned to him.
So NAK the peer with a valid address if the address
contained in this request is not the one we assigned. */
if ((ipcp->mode == NCP_SERVER) && (memcmp (temp_ip_address[0],
ipcp->assigned_peer_ip_address, IP_ADDR_LEN)))
{
/* This will be done by a NAK pkt. So all we need to
do is to replace the IP address with the
assigned one. */
/* Put it in the NAK packet */
memcpy (ncp_nak_ptr, ncp_pkt_ptr,
NCP_IP_ADDRESS_LENGTH);
/* Replace with the new IP address */
ncp_nak_ptr[LCP_CONFIG_OPTS]
= ipcp->assigned_peer_ip_address[0];
ncp_nak_ptr[LCP_CONFIG_OPTS + 1]
= ipcp->assigned_peer_ip_address[1];
ncp_nak_ptr[LCP_CONFIG_OPTS + 2]
= ipcp->assigned_peer_ip_address[2];
ncp_nak_ptr[LCP_CONFIG_OPTS + 3]
= ipcp->assigned_peer_ip_address[3];
/* Update the length and the ptr */
ncp_pkt_ptr += NCP_IP_ADDRESS_LENGTH;
length -= NCP_IP_ADDRESS_LENGTH;
/* Set the NAK flag and length */
options_ok = NU_FALSE;
nak_length += NCP_IP_ADDRESS_LENGTH;
ncp_nak_ptr += NCP_IP_ADDRESS_LENGTH;
}
else if (ipcp->mode == NCP_CLIENT)
{
#ifdef NU_DEBUG_PPP
_PRINT ("got servers IP\r\n");
#endif
/* Get the IP address out. This is the IP address of
the server. Store it in the device structure
for this link. */
in_buf_ptr->mem_buf_device->dev_addr.dev_dst_ip_addr =
IP_ADDR(temp_ip_address[0]);
ncp_pkt_ptr += NCP_IP_ADDRESS_LENGTH;
length -= NCP_IP_ADDRESS_LENGTH;
}
else
{
/* This is a valid request. Just bump the length
and pointer. */
ncp_pkt_ptr += NCP_IP_ADDRESS_LENGTH;
length -= NCP_IP_ADDRESS_LENGTH;
}
} /* else */
break;
case NCP_PRIMARY_DNS_ADDRESS :
/* Put the address in a temp var */
temp_ip_address[0][0] = ncp_pkt_ptr[LCP_CONFIG_OPTS];
temp_ip_address[0][1] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 1];
temp_ip_address[0][2] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 2];
temp_ip_address[0][3] = ncp_pkt_ptr[LCP_CONFIG_OPTS + 3];
/* If it is zero then the host is requesting a DNS
server address. */
if ((temp_ip_address[0][0] == 0) && (temp_ip_address[0][1] == 0) &&
(temp_ip_address[0][2] == 0) && (temp_ip_address[0][3] == 0))
{
/* Get the first DNS server in our DNS server list. */
num_dns_servers = NU_Get_DNS_Servers (temp_ip_address[0],
IP_ADDR_LEN);
/* Make sure we got one. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -