📄 ppp.c
字号:
index++;
}
else
index++;
} /* end while there are more ports to check and
we have not already failed. */
return (ret_status);
}
/************************************************************************
* FUNCTION
*
* PPP_Still_Connected
*
* DESCRIPTION
*
* Checks the state of the PPP link and returns TRUE if it is still
* open. FALSE if it is not open.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* CHAR *link_name Pointer to the PPP link name.
*
* OUTPUTS
*
* STATUS Is the link open or not
*
************************************************************************/
STATUS PPP_Still_Connected (CHAR *link_name)
{
DV_DEVICE_ENTRY *dev_ptr;
LCP_LAYER *lcp;
STATUS ret_status;
/* Find the device that we want to hangup. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure a device was found and that it is a PPP device. */
if ((dev_ptr) && (dev_ptr->dev_type == DVT_PPP))
{
/* Grab a pointer to the LCP layer stucture. */
lcp = &((LINK_LAYER *)dev_ptr->link_layer)->lcp;
if ((lcp->state == INITIAL) || (lcp->state == STARTING))
ret_status = NU_FALSE;
else
ret_status = NU_TRUE;
}
else
ret_status = NU_INVALID_LINK;
return (ret_status);
}
/************************************************************************
* FUNCTION
*
* PPP_Two_To_Power
*
* DESCRIPTION
*
* Raises two to the power of the passed in variable. This function
* is used instead of POW so that math and floating point libraries
* do not have to be linked in.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* UINT8 exponent The exponent to raise two too
*
* OUTPUTS
*
* UINT32 The computed power
*
************************************************************************/
UINT32 PPP_Two_To_Power (UINT8 exponent)
{
UINT32 answer;
#ifdef NU_NON_REENTRANT_CLIB
INT old_state;
#endif
answer = PPP_ONE;
/* Make sure the exponent is not zero */
if (exponent != 0)
{
/* The bit shifting operation below has been seen to cause
problems with non-reentrant C library's. To fix this
turn interrupts off so that the PPP LISR does not
interrupt the shift operation. */
#ifdef NU_NON_REENTRANT_CLIB
old_state = NU_Control_Interrupts (NU_DISABLE_INTERRUPTS);
#endif
answer <<= (UINT32) exponent;
#ifdef NU_NON_REENTRANT_CLIB
NU_Control_Interrupts (old_state);
#endif
}
return (answer);
}
/************************************************************************
* FUNCTION
*
* PPP_Output
*
* DESCRIPTION
*
* Makes sure that the device is active and calls the transmit routine
* for the device. Then deallocates the buffer to the appropriate list.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the packet buffer of
* the packet to send.
* DV_DEVICE_ENTRY *device Pointer to the device to send
* the packet over.
* SCK_SOCKADDR_IP *dest Not used by this routine. Only
* included in order to comply
* with NET 4.0.
* RTAB_ROUTE *ro Not used by this routine. Only
* included in order to comply
* with NET 4.0.
*
* OUTPUTS
*
* STATUS Was the packet sent?
*
************************************************************************/
STATUS PPP_Output (NET_BUFFER *buf_ptr, DV_DEVICE_ENTRY *device,
SCK_SOCKADDR_IP *dest, RTAB_ROUTE *ro)
{
STATUS ret_status;
#ifndef PPP_POLLED_TX
INT old_val;
#endif
/* Remove warnings. */
UNUSED_PARAMETER(dest);
UNUSED_PARAMETER(ro);
/* Verify that the device is up and that this buffer is not an IP
packet. If its not an IP packet then it is a PPP negotiation packet,
in which case we do not care that the device is not up and running.
That is what this packet is trying to accomplish. */
if ( ((device->dev_flags & (DV_UP | DV_RUNNING)) != (DV_UP | DV_RUNNING) )
&& (buf_ptr->mem_flags & NET_IP))
ret_status = NU_HOST_UNREACHABLE;
else /* send the packet */
{
/* Check if the packet to be sent is IP data. If it is, update
the last_activity_time variable which maintains the time
of the last IP activity through the PPP link. */
if (buf_ptr->mem_flags & NET_IP)
{
((PPP_LAYER *)device->link_layer)->last_activity_time =
NU_Retrieve_Clock();
}
#ifndef PPP_POLLED_TX
/* Disable interrupts. */
old_val = NU_Control_Interrupts (NU_DISABLE_INTERRUPTS);
/* Put this packet onto the TX queue. */
MEM_Buffer_Enqueue (&device->dev_transq, buf_ptr);
/* Bump up the counter. */
device->dev_transq_length++;
/* If the packet just added to the TX queue is the only one in the
queue then send it. */
if (device->dev_transq.head == buf_ptr)
{
/* Restore interrupt state */
NU_Control_Interrupts (old_val);
#endif
/* Send the packet */
ret_status = device->dev_start (device, buf_ptr);
#ifndef PPP_POLLED_TX
}
else
{
/* Restore interrupt state */
NU_Control_Interrupts (old_val);
/* Set the status */
ret_status = NU_SUCCESS;
}
#endif
/* Otherwise this packet will get sent by TX interrupts. */
}
#ifdef PPP_POLLED_TX
/* Add it to the buffer list for this buffer. If the dlist
is NULL then this buffer is a PPP control packet. We
do not free these buffers because they are retranmitted and
freed up later by PPP. */
if ((ret_status == NU_SUCCESS) && (buf_ptr->mem_dlist != NU_NULL))
MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);
#endif
return (ret_status);
}
/************************************************************************
* FUNCTION
*
* PPP_Input
*
* DESCRIPTION
*
* This function pulls the first packet off of the incoming packet
* list and calls the correct protocol routine to handle the
* encapsulated packet.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* none
*
* OUTPUTS
*
* STATUS NU_SUCCESS
*
************************************************************************/
STATUS PPP_Input (VOID)
{
LCP_LAYER *lcp_ptr;
IPCP_LAYER *ipcp_ptr;
UINT8 *ppp_compress_protocol;
UINT16 ppp_protocol;
UINT32 *last_activity_time;
/* Set up a pointer to the last_activity_time variable which maintains
the time of the last IP activity through the PPP link. */
last_activity_time = &(((PPP_LAYER *)MEM_Buffer_List.head->
mem_buf_device->link_layer)->last_activity_time);
/* Get a pointer to the head of the packet. */
ppp_compress_protocol = (UINT8 *)MEM_Buffer_List.head->data_ptr;
/* Now we must check to make sure it is a valid packet before
it is passed on to get interpreted. The only compression checked
for here is the PPP protocol. For the first check we will assume
compression is turned on. */
/* Assume the protocol field is compressed, this will be the
case most of the time. */
switch (*ppp_compress_protocol)
{
case PPP_IP_COMPRESS_PROTOCOL :
/* Get a pointer to the LCP and IPCP layers */
lcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->lcp;
ipcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->ipcp;
/* Only allow IP packets if LCP and NCP are in the open state
and the device is up. */
if ( (lcp_ptr->state == OPENED) && (ipcp_ptr->state == OPENED) &&
(MEM_Buffer_List.head->mem_buf_device->dev_flags & DV_UP) )
{
/* Update the last_activity_time variable which maintains the
time of the last IP activity through the PPP link. */
*last_activity_time = NU_Retrieve_Clock();
/* Point the data ptr to the beginning of the IP header. */
MEM_Buffer_List.head->data_ptr += PPP_PROTOCOL_HEADER_1BYTE;
MEM_Buffer_List.head->data_len -= PPP_PROTOCOL_HEADER_1BYTE;
MEM_Buffer_List.head->mem_total_data_len -= PPP_PROTOCOL_HEADER_1BYTE;
IP_Interpret ((IPLAYER *) MEM_Buffer_List.head->data_ptr,
MEM_Buffer_List.head->mem_buf_device, MEM_Buffer_List.head);
}
else
{
/* Bump the number of silent discards and free the buffers */
((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->silent_discards++;
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
}
break;
default :
/* Since it failed on the assumption try checking it one
more time without protocol field compression. */
/* Get the first byte. */
ppp_protocol = MEM_Buffer_List.head->data_ptr[0];
/* Shift it over to the MSB */
ppp_protocol <<= 8;
/* OR in the LSB byte */
ppp_protocol = (ppp_protocol | MEM_Buffer_List.head->data_ptr[1]);
/* Point the data ptr to the beginning of the IP header. */
MEM_Buffer_List.head->data_ptr += PPP_PROTOCOL_HEADER_2BYTES;
MEM_Buffer_List.head->data_len -= PPP_PROTOCOL_HEADER_2BYTES;
MEM_Buffer_List.head->mem_total_data_len -= PPP_PROTOCOL_HEADER_2BYTES;
switch (ppp_protocol)
{
case PPP_IP_PROTOCOL :
/* Get a pointer to the LCP and IPCP layers */
lcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->lcp;
ipcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->ipcp;
/* Only allow IP packets if LCP and NCP are in the open state */
if ( (lcp_ptr->state == OPENED) && (ipcp_ptr->state == OPENED) &&
(MEM_Buffer_List.head->mem_buf_device->dev_flags & DV_UP) )
{
/* Update the last_activity_time variable which maintains the
time of the last IP activity through the PPP link. */
*last_activity_time = NU_Retrieve_Clock();
IP_Interpret ((IPLAYER *) MEM_Buffer_List.head->data_ptr,
MEM_Buffer_List.head->mem_buf_device,
MEM_Buffer_List.head);
}
else
{
/* Bump the number of silent discards and free the buffers */
((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->silent_discards++;
MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
}
break;
case PPP_IP_CONTROL_PROTOCOL :
PPP_NCP_IP_Interpret (MEM_Buffer_List.head);
break;
case PPP_CHAP_PROTOCOL :
PPP_CHAP_Interpret (MEM_Buffer_List.head);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -