📄 lcp.c
字号:
(LCP_CLEAR_HIGH & (*(lcp_pkt_ptr + LCP_CONFIG_OPTS + 3)));
/* Make sure they are not the same. Note :
lcp->local_options.magic_number is stored in the endien order
of the processor. Therefore the longswap on it is needed.
lcp->foreign_options.magic_number is stored from the incomming
pkt and will always be in the correct order, so no swapping
is needed. */
if (lcp->foreign_options.magic_number ==
LONGSWAP (lcp->local_options.magic_number))
{
/* Since they are we must NAK with a new number */
/* Put it in the nak packet */
memcpy (lcp_nak_ptr, lcp_pkt_ptr,
LCP_MAGIC_NUMBER_LENGTH);
/* Get a new number */
lcp->local_options.magic_number = LCP_Random_Number32();
/* Move the pointer to the spot where the number goes. */
lcp_nak_ptr += LCP_CONFIG_OPTS;
/* Fill in the new number */
PUT32 (lcp_nak_ptr, 0, lcp->local_options.magic_number);
/* Update the pkt ptr and length */
nak_length += LCP_MAGIC_NUMBER_LENGTH;
lcp_nak_ptr += LCP_MAGIC_NUMBER_LENGTH - LCP_CONFIG_OPTS;
/* Set the status that all options are not ok */
options_ok = 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 :
/* See if we are going to use protocol compression */
if (lcp->local_options.protocol_field_compression)
lcp->foreign_options.protocol_field_compression = NU_TRUE;
else
{
/* We need to reject this option since it is a boolean
option */
/* Put it in the reject packet */
memcpy (lcp_reject_ptr, lcp_pkt_ptr,
LCP_PROTOCOL_COMPRESS_LENGTH);
/* Update the length and the ptr */
lcp_reject_ptr += LCP_PROTOCOL_COMPRESS_LENGTH;
reject_length += LCP_PROTOCOL_COMPRESS_LENGTH;
/* Mark that we need to reject something */
dont_need_to_reject = 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 :
/* See if we are going to use address compression */
if (lcp->local_options.address_field_compression)
lcp->foreign_options.address_field_compression = NU_TRUE;
else
{
/* We need to reject this option since it is a boolean
option */
/* Put it in the reject packet */
memcpy (lcp_reject_ptr, lcp_pkt_ptr,
LCP_ADDRESS_COMPRESS_LENGTH);
/* Update the length and the ptr */
lcp_reject_ptr += LCP_ADDRESS_COMPRESS_LENGTH;
reject_length += LCP_ADDRESS_COMPRESS_LENGTH;
/* Mark that we need to reject something */
dont_need_to_reject = NU_FALSE;
}
/* Update the pkt pointer and the packet size */
lcp_pkt_ptr += LCP_ADDRESS_COMPRESS_LENGTH;
length -= LCP_ADDRESS_COMPRESS_LENGTH;
break;
default :
/* If we make it here then there is a protocol that we
do not understand, send a reject. */
/* Put it in the reject packet */
memcpy (lcp_reject_ptr, lcp_pkt_ptr,
(unsigned int)lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET]);
/* Update the length and the ptr */
lcp_reject_ptr += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
reject_length += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
/* Mark that we need to reject something */
dont_need_to_reject = NU_FALSE;
/* The length is usually the second field in the protocol,
so minus it off and look at the reset of the pkt. */
length -= lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
lcp_pkt_ptr += lcp_pkt_ptr[LCP_CONFIG_LENGTH_OFFSET];
break;
} /* switch */
} /* while */
/* See if all the options are ok, if so send an ack */
if (options_ok && dont_need_to_reject)
{
#ifdef NU_DEBUG_PPP
_PRINT ("acking ");
#endif
/* Every option is ok. The ack pkt is the same as the config pkt.
The only difference is that the pkt code is now config ack. */
/* Change the pkt code and put in the same ID */
lcp_ack_pkt->code = LCP_CONFIGURE_ACK;
lcp_ack_pkt->identifier = identifier;
/* Copy the pkt data over */
memcpy (&lcp_ack_pkt->data, lcp_pkt + LCP_DATA_OFFSET,
((unsigned int)INTSWAP(lcp_ack_pkt->length)));
/* Update the lengths for the buffer. */
ack_buf_ptr->data_len = ack_buf_ptr->mem_total_data_len =
INTSWAP(lcp_ack_pkt->length);
/* Set the packet type. */
ack_buf_ptr->mem_flags = NET_LCP;
/* Set the dlist for this buffer. */
ack_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send it */
buf_ptr->mem_buf_device->dev_output (ack_buf_ptr,
buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
/* Release the buffer for the NAK packet since it was not sent. */
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, nak_buf_ptr);
/* Release the buffer for the reject packet since it was not sent. */
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, reject_buf_ptr);
}
else
{
/* Release the buffer for the ACK packet since it was not sent. */
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, ack_buf_ptr);
/* One or more options were not ok. We must nak or reject them. */
/* See if we need to nak something. Only NAK if we do not have to
reject. */
if ((!options_ok) && (dont_need_to_reject))
{
#ifdef NU_DEBUG_PPP
_PRINT ("naking ");
#endif
/* Put in the pkt indentifier and type */
lcp_nak_pkt->identifier = identifier;
lcp_nak_pkt->code = LCP_CONFIGURE_NAK;
lcp_nak_pkt->length = INTSWAP(nak_length);
/* Update the lengths for the buffer. */
nak_buf_ptr->data_len = nak_buf_ptr->mem_total_data_len =
nak_length;
/* Set the packet type. */
nak_buf_ptr->mem_flags = NET_LCP;
/* Set the dlist for this buffer. */
nak_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the pkt */
buf_ptr->mem_buf_device->dev_output (nak_buf_ptr,
buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
else
/* Release the buffer for the NAK packet since it was not sent. */
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, nak_buf_ptr);
/* See if we need to reject something */
if (!dont_need_to_reject)
{
#ifdef NU_DEBUG_PPP
_PRINT ("rejecting ");
#endif
/* Put in the pkt indentifier and type */
lcp_reject_pkt->identifier = identifier;
lcp_reject_pkt->code = LCP_CONFIGURE_REJECT;
lcp_reject_pkt->length = INTSWAP(reject_length);
/* Update the lengths for the buffer. */
reject_buf_ptr->data_len = reject_buf_ptr->mem_total_data_len =
reject_length;
/* Set the packet type. */
reject_buf_ptr->mem_flags = NET_LCP;
/* Set the dlist for this buffer. */
reject_buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the pkt */
buf_ptr->mem_buf_device->dev_output (reject_buf_ptr,
buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
else
/* Release the buffer for the reject packet since it was not sent. */
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, reject_buf_ptr);
}
return (options_ok && dont_need_to_reject);
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Send_Terminate_Ack
*
* DESCRIPTION
*
* Sends a terminate ack packet to the peer.
*
* INPUTS
*
* UINT8 *in_buf_ptr Pointer to the packet that
* requested termination
* UINT16 protocol_type Which protocol, LCP or NCP, is
* sending the ack
*
* OUTPUTS
*
* None
*
****************************************************************************/
VOID LCP_Send_Terminate_Ack(NET_BUFFER *in_buf_ptr, UINT16 protocol_type)
{
NET_BUFFER *buf_ptr;
UINT16 length;
UINT8 HUGE *lcp_pkt = in_buf_ptr->data_ptr;
LINK_LAYER *link_layer;
link_layer = (LINK_LAYER*)in_buf_ptr->mem_buf_device->link_layer;
#ifdef NU_DEBUG_PPP
_PRINT ("\nsend term ack ");
#endif
/* Is there a negotiation packet that can be reused? */
if (link_layer->lcp.negotiation_pkt != NU_NULL)
buf_ptr = link_layer->lcp.negotiation_pkt;
else
/* Allocate a buffer for the LCP packet. */
link_layer->lcp.negotiation_pkt
= 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 ptr */
buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen);
/* The pkt to be sent is the same as the one RX except the code field is
changed to ACK. */
/* Put in the pkt type */
lcp_pkt [LCP_CODE_OFFSET] = LCP_TERMINATE_ACK;
/* Get the length */
length = (UINT16) ( (*(lcp_pkt + LCP_LENGTH_OFFSET)) << 8 );
length = length | *(lcp_pkt + LCP_LENGTH_OFFSET + 1);
/* Save a copy of this packet for retransmission, if needed. */
memcpy (buf_ptr->data_ptr, lcp_pkt, (unsigned int)length);
/* 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 length */
buf_ptr->data_len = buf_ptr->mem_total_data_len = length;
/* Set the dlist to NULL so this buffer will not be
put on the free list. */
buf_ptr->mem_dlist = NU_NULL;
/* Send the pkt */
in_buf_ptr->mem_buf_device->dev_output (buf_ptr, in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
/***************************************************************************
*
* FUNCTION
*
* LCP_Send_Terminate_Req
*
* DESCRIPTION
*
* Sends a terminate req packet to the peer.
*
* INPUTS
*
* *dev_ptr
*
* OUTPUTS
*
* None
*
****************************************************************************/
VOID LCP_Send_Terminate_Req (DV_DEVICE_ENTRY *dev_ptr)
{
NET_BUFFER *buf_ptr;
LCP_HEADER *lcp_pkt;
UINT16 len;
LINK_LAYER *link_layer;
link_layer = (LINK_LAYER*)dev_ptr->dev_ppp_layer;
#ifdef NU_DEBUG_PPP
_PRINT ("send term req ");
#endif
len = 0;
/* Is there a negotiation packet that can be reused? */
if (link_layer->lcp.negotiation_pkt != NU_NULL)
buf_ptr = link_layer->lcp.negotiation_pkt;
else
/* Allocate a buffer for the LCP packet. */
link_layer->lcp.negotiation_pkt =
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 for the buffer */
buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + dev_ptr->dev_hdrlen);
/* Point the LCP structure to the data part of the outgoing buffer */
lcp_pkt = (LCP_HEADER *) buf_ptr->data_ptr;
/* Set up the terminate pkt. */
lcp_pkt->code = LCP_TERMINATE_REQUEST;
lcp_pkt->identifier = LCP_Random_Number();
/* Fill in the length for the lcp packet. */
len += LCP_HEADER_LENGTH;
lcp_pkt->length = INTSWAP (len);
/* Set the type of packet to be TX*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -