📄 lcp.c
字号:
buf_ptr->mem_flags = NET_LCP;
/* Set the size of the buffer. */
buf_ptr->data_len = buf_ptr->mem_total_data_len = len;
/* Set the dlist to NULL so this buffer will not be
put on the free list. */
buf_ptr->mem_dlist = NU_NULL;
/* Send the terminate request packet. */
dev_ptr->dev_output (buf_ptr, dev_ptr, NU_NULL, NU_NULL);
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Configure_Reject_Check
*
* DESCRIPTION
*
* This function checks a configure reject packet and updates the
* peers allowed options based on what was rejected. The next
* configure request sent will reflect these changes.
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the code reject
* packet
*
* OUTPUTS
*
* STATUS
*
****************************************************************************/
VOID LCP_Configure_Reject_Check (NET_BUFFER *buf_ptr)
{
LCP_LAYER *lcp;
UINT8 HUGE *lcp_pkt_ptr;
UINT8 identifier;
UINT16 length;
UINT8 HUGE *lcp_pkt = buf_ptr->data_ptr;
LINK_LAYER *link_layer;
link_layer = (LINK_LAYER*)buf_ptr->mem_buf_device->link_layer;
/* Get a pointer to the LCP structure for this device. */
lcp = &link_layer->lcp;
/* Get the ID of this pkt */
identifier = lcp_pkt[LCP_ID_OFFSET];
/* The id must match that of the last sent config pkt. */
if (identifier == lcp->identifier)
{
/* Put the LCP structure on the packet and get the length */
lcp_pkt_ptr = lcp_pkt;
length = (UINT16) ( (*(lcp_pkt_ptr + LCP_LENGTH_OFFSET)) << 8 );
length = length | *(lcp_pkt_ptr + LCP_LENGTH_OFFSET + 1);
/* Now remove the header */
length -= LCP_HEADER_LENGTH;
/* Get a pointer to the data inside the LCP pkt */
lcp_pkt_ptr = lcp_pkt_ptr + LCP_DATA_OFFSET;
while (length > 0)
{
/* Check out what option is rejected and see if we can handle it */
switch (lcp_pkt_ptr[0])
{
case LCP_MAX_RX_UNIT :
/* Set the option to false */
lcp->local_options.use_max_rx_unit = NU_FALSE;
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_MRU_LENGTH;
length -= LCP_MRU_LENGTH;
break;
case LCP_ASYNC_CONTROL_CHAR_MAP :
/* Set the option to false */
lcp->local_options.use_accm = NU_FALSE;
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_ACCM_LENGTH;
length -= LCP_ACCM_LENGTH;
break;
case LCP_MAGIC_NUMBER :
/* Set this option to false */
lcp->local_options.magic_number = NU_FALSE;
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_MAGIC_NUMBER_LENGTH;
length -= LCP_MAGIC_NUMBER_LENGTH;
break;
case LCP_PROTOCOL_FIELD_COMPRESS :
/* This option is not required. Turn the option off
for us and our peer. */
lcp->foreign_options.protocol_field_compression = NU_FALSE;
lcp->local_options.protocol_field_compression = NU_FALSE;
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_PROTOCOL_COMPRESS_LENGTH;
length -= LCP_PROTOCOL_COMPRESS_LENGTH;
break;
case LCP_ADDRESS_FIELD_COMPRESS :
/* This option is not required. Turn the option off
for us and our peer. */
lcp->foreign_options.address_field_compression = NU_FALSE;
lcp->local_options.address_field_compression = NU_FALSE;
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_ADDRESS_COMPRESS_LENGTH;
length -= LCP_ADDRESS_COMPRESS_LENGTH;
break;
case LCP_AUTHENTICATION_PROTOCOL :
/* Check which authentication protocol we tried and
switch to the other. */
if (lcp->local_options.authentication_protocol ==
PPP_CHAP_PROTOCOL)
{
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_CHAP_LENGTH;
length -= LCP_CHAP_LENGTH;
/* Switch to the other protocol */
lcp->local_options.authentication_protocol =
PPP_PAP_PROTOCOL;
}
else
{
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_PAP_LENGTH;
length -= LCP_PAP_LENGTH;
/* Switch to the other protocol */
lcp->local_options.authentication_protocol =
PPP_CHAP_PROTOCOL;
}
break;
default :
/* We should never get here since all of the above
covers any options that we would send in a
configure request. This could be a bad packet,
bad implementation, or conflict in PPP RFC versions.
Just bump ahead the pointer and decrement the
length. */
/* Just in case this is garbage make sure the length
to decrement by is not greater than what is
left. */
if (lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET] <= length)
{
length -= lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
lcp_pkt_ptr += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
}
else
/* Otherwise just get out. */
length = 0;
break;
} /* switch */
} /* while */
} /* if */
else
{
#ifdef NU_DEBUG_PPP
_PRINT ("discarded - invalid ID ");
#endif
/* This reject is not for the last configure pkt we sent. So
drop it. */
link_layer->silent_discards++;
}
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Code_Reject_Check
*
* DESCRIPTION
*
* This function checks a code reject packet. If it is rejecting any
* codes that PPP needs to work NU_FALSE is returned. If all rejected
* codes are allowed by this implementation then NU_TRUE is returned.
* Note that most codes specified in RFC1661 are required. Any codes
* that are not required by this implementation are never transmitted
* and thus will never be rejected.
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the code reject
* packet
*
* OUTPUTS
*
* STATUS
*
****************************************************************************/
STATUS LCP_Code_Reject_Check (NET_BUFFER *buf_ptr)
{
UINT8 HUGE *lcp_pkt_ptr;
UINT8 codes_ok;
UINT8 HUGE *lcp_pkt = buf_ptr->data_ptr;
/* Assume that the code rejected is ok. */
codes_ok = NU_TRUE;
/* Put the LCP structure on the packet */
lcp_pkt_ptr = lcp_pkt;
/* Get a pointer to the data inside the LCP pkt */
lcp_pkt_ptr = lcp_pkt_ptr + LCP_DATA_OFFSET;
/* Check out what code is rejected and see if we can handle it. If it
is one of the codes below the link will be terminated. */
switch (lcp_pkt_ptr[0])
{
case LCP_CONFIGURE_REQUEST :
case LCP_CONFIGURE_ACK :
case LCP_CONFIGURE_NAK :
case LCP_CONFIGURE_REJECT :
case LCP_TERMINATE_REQUEST :
case LCP_TERMINATE_ACK :
case LCP_CODE_REJECT : /* This one doesn't make sense. */
case LCP_PROTOCOL_REJECT :
case LCP_ECHO_REQUEST :
case LCP_ECHO_REPLY : /* This one doesn't make sense. */
case LCP_DISCARD_REQUEST :
/* If it was one of the above codes then we must
terminate the link. */
codes_ok = NU_FALSE;
break;
default :
/* It is some unknown code and thus is ok to be rejected. We
did not send it anyway. This packet is probably a response by an
incorrect implementation, poor parsing of a received packet. */
break;
} /* switch */
return (codes_ok);
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Send_Code_Reject
*
* DESCRIPTION
*
* Sends a code reject to the peer telling it that an option was received
* that is unknown to this implementation.
*
* INPUTS
*
* UINT8 *in_buf_ptr Pointer to that packet that is
* unknown to PPP
* UINT16 protocol_type Which protocol is sending it,
* LCP or NCP
*
* OUTPUTS
*
* None
*
****************************************************************************/
VOID LCP_Send_Code_Reject (NET_BUFFER *in_buf_ptr, UINT16 protocol_type)
{
NET_BUFFER *buf_ptr;
LCP_HEADER *lcp_reject_pkt;
UINT8 *lcp_pkt_ptr;
UINT16 len;
UINT8 HUGE *lcp_pkt = in_buf_ptr->data_ptr;
#ifdef NU_DEBUG_PPP
_PRINT ("send code reject\r\n");
#endif
/* Allocate a buffer to send. */
buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
/* Make sure a buffer was available */
if (buf_ptr == NU_NULL)
{
NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);
/* Get out */
return;
}
/* Set the data pointer and the reject packet pointer. */
buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);
lcp_reject_pkt = (LCP_HEADER *) buf_ptr->data_ptr;
/* Set up the configure pkt. */
lcp_reject_pkt->code = LCP_CODE_REJECT;
lcp_reject_pkt->identifier = LCP_Random_Number();
/* Get the length */
len = (UINT8) ( (*(lcp_pkt + LCP_LENGTH_OFFSET)) << 8 );
len = len | *(lcp_pkt + LCP_LENGTH_OFFSET + 1);
/* Get a pointer to the data part of the RX lcp packet. */
lcp_pkt_ptr = &lcp_reject_pkt->data;
/* Copy the rejected pkt over. */
memcpy (lcp_pkt_ptr, lcp_pkt, (unsigned int)len);
/* Fill in the length for the lcp packet. */
len += LCP_HEADER_LENGTH;
lcp_reject_pkt->length = INTSWAP (len);
buf_ptr->data_len = buf_ptr->mem_total_data_len = len;
/* Set the protocol type */
if (protocol_type == PPP_LINK_CONTROL_PROTOCOL)
buf_ptr->mem_flags = NET_LCP;
else
if (protocol_type == PPP_IP_CONTROL_PROTOCOL)
buf_ptr->mem_flags = NET_IPCP;
/* Set the dlist for this buffer. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the code reject packet. */
in_buf_ptr->mem_buf_device->dev_output (buf_ptr, in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Ack_Sent_State
*
* DESCRIPTION
*
* Handles processing of an incoming LCP packet.
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the incoming LCP
* packet
*
* OUTPUTS
*
* None
*
*******************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -