📄 ppp.c
字号:
/* Make sure we logged in before try NCP */
if (status == PPP_SUCCESS)
{
#ifdef NU_DEBUG_PPP
_PRINT ("\ndone with authentication, starting NCP\n");
#endif
/* Set the status of the PPP connection attempt. */
((PPP_LAYER *)dev_ptr->link_layer)->connection_status = NU_PPP_NETWORK_NEGOTIATION;
/* Copy the local IP address to the IPCP structure. */
memcpy (ipcp->local_ip_address, ip_address, IP_ADDRESS_LENGTH);
/* Init the transmission counter. */
ipcp->num_transmissions = LCP_MAX_CONFIGURE;
/* Send the NCP configure request pkt. */
NCP_IP_Send_Config_Req(ip_address, dev_ptr);
/* Start the timer */
NU_Reset_Timer (&ipcp->restart_timer, NCP_Timer_Expire,
LCP_TIMEOUT_VALUE, LCP_TIMEOUT_VALUE, NU_ENABLE_TIMER);
/* We wait for the event to tell us that NCP is done. */
status = NU_Retrieve_Events(&link->negotiation_progression, (NCP_CONFIG_DONE | PPP_NEG_TIMEOUT),
NU_OR_CONSUME, &bufs_ava, NU_SUSPEND);
/* If we didn't timeout then unset the timer event. */
if (!(bufs_ava & PPP_NEG_TIMEOUT))
UTL_Timerunset(PPP_STOP_NEGOTIATION, (UNSIGNED)dev_ptr, 0);
/* Stop the timer */
NU_Control_Timer (&ipcp->restart_timer, NU_DISABLE_TIMER);
if (bufs_ava & PPP_NEG_TIMEOUT)
status = NU_NEGOTIATION_TIMEOUT;
/* Check to see if it completed succcessfully. */
else if (!(!(bufs_ava & NCP_CONFIG_SUCCESS) || (status != NU_SUCCESS)))
{
/* Set the status of the PPP connection attempt. */
((PPP_LAYER *)dev_ptr->link_layer)->connection_status = NU_PPP_CONNECTED;
status = PPP_SUCCESS;
}
else
status = NU_NCP_FAILED;
} /* if login completed successfully */
} /* if LCP completed successfully */
else
status = NU_LCP_FAILED;
/* Release the buffers used by the PPP negotiation. */
if (lcp->negotiation_pkt != NU_NULL)
{
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, lcp->negotiation_pkt);
lcp->negotiation_pkt = NU_NULL;
}
if (auth->negotiation_pkt != NU_NULL)
{
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, auth->negotiation_pkt);
auth->negotiation_pkt = NU_NULL;
}
if (ipcp->negotiation_pkt != NU_NULL)
{
MEM_Buffer_Enqueue (&MEM_Buffer_Freelist, ipcp->negotiation_pkt);
ipcp->negotiation_pkt = NU_NULL;
}
return (status);
}
/************************************************************************
* FUNCTION
*
* PPP_Set_Login
*
* DESCRIPTION
*
* Sets the ID and password to be used when dialing up a PPP server.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* CHAR id[] ID to be used
* CHAR pw[] Password to be used
* CHAR *link_name Pointer to the PPP link name.
*
* OUTPUTS
*
* STATUS
*
************************************************************************/
STATUS PPP_Set_Login (CHAR id[PPP_MAX_ID_LENGTH], CHAR pw[PPP_MAX_PW_LENGTH],
CHAR *link_name)
{
DV_DEVICE_ENTRY *dev_ptr;
AUTHENTICATION_LAYER *auth;
STATUS ret_status = NU_SUCCESS;
/* Find the device that we want to hangup. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure the device was found and that it is a PPP device. */
if ((dev_ptr) && (dev_ptr->dev_type == DVT_PPP))
{
/* Get a pointer to the authentication layer structure. */
auth = &((LINK_LAYER *)dev_ptr->link_layer)->authentication;
/* Simply copy the ID and PW pair into our internal variables. */
strcpy (auth->login_name, id);
strcpy (auth->login_pw, pw);
}
else
ret_status = NU_INVALID_LINK;
return (ret_status);
}
/************************************************************************
* FUNCTION
*
* PPP_Hangup
*
* DESCRIPTION
*
* Starts the link termination phase and hangs up the physical device.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* UINT8 mode Should the link be closed even
* if it is active.
* CHAR *link_name Pointer to the PPP link name.
*
* OUTPUTS
*
* STATUS Was the link closed or not
*
************************************************************************/
STATUS PPP_Hangup (UINT8 mode, CHAR *link_name)
{
STATUS ret_status;
DV_DEVICE_ENTRY *dev_ptr;
LCP_LAYER *lcp;
LINK_LAYER *link_layer;
UNSIGNED ack_timeout;
#ifdef NU_DEBUG_PPP
_PRINT ("\nhangup ");
#endif
ret_status = PPP_TRUE;
/* Find the device that we want to hangup. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure the device was found. */
if ((dev_ptr) && (dev_ptr->dev_type == DVT_PPP))
{
/* Grab a pointer to the LCP layer stucture. */
link_layer = (LINK_LAYER*)dev_ptr->dev_ppp_layer;
lcp = &link_layer->lcp;
/* If the caller wants to force it, then we will close the whole network
without warning. */
if (mode == PPP_FORCE)
{
/* Get the network resource. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
/* Remove the PPP link information. */
PPP_Terminate_Link(dev_ptr);
/* Give the resource back. */
NU_Release_Semaphore(&TCP_Resource);
/* Hang up the modem. */
link_layer->disconnect(link_layer, NU_TRUE);
}
else
{
/* Otherwise we will see if it is safe to hangup the phone. If any
sockets are in the process of closing, this function will wait until
they are closed. */
ret_status = PPP_Safe_To_Hangup(dev_ptr);
/* If it is ok to hangup then we will start by terminating the link
and we will hangup the modem. */
if (ret_status == PPP_TRUE)
{
/* Stop any PPP timer that may still be running */
PPP_Stop_All_Timers(dev_ptr);
/* Everything depends on our state */
switch (lcp->state)
{
case INITIAL :
case STARTING :
case CLOSED : /* Don't need to do anything for these states */
case STOPPED :
case CLOSING :
case STOPPING : break;
case OPENED :
case REQ_SENT : /* These are all the same */
case ACK_RCVD :
case ACK_SENT :
/* Get the network resource. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
/* Reset the restart counter */
lcp->num_transmissions = LCP_MAX_TERMINATE;
/* Reset the restart timer */
NU_Control_Timer (&lcp->restart_timer, NU_DISABLE_TIMER);
/* Send a terminate request */
LCP_Send_Terminate_Req(dev_ptr);
lcp->state = CLOSING;
/* Start the timer */
NU_Reset_Timer (&lcp->restart_timer, LCP_Timer_Expire,
LCP_TIMEOUT_VALUE, LCP_TIMEOUT_VALUE, NU_ENABLE_TIMER);
/* Give the resource back. */
NU_Release_Semaphore(&TCP_Resource);
/* Compute the timeout */
ack_timeout = NU_Retrieve_Clock() + (LCP_LINK_CLOSE_TIMEOUT);
/* Wait for an ACK or for a timeout. */
while ((lcp->state != INITIAL) &&
(lcp->state != STARTING) &&
(INT32_CMP(ack_timeout,
NU_Retrieve_Clock()) > 0))
NU_Sleep(1);
}
/* Reset the restart timer */
NU_Control_Timer (&lcp->restart_timer, NU_DISABLE_TIMER);
/* Grab the stack semaphore before playing with stack
globals. */
NU_Obtain_Semaphore (&TCP_Resource, NU_SUSPEND);
/* Clean up routes, etc. */
PPP_Clean_Up_Link (dev_ptr);
/* Detach the IP address from this device. */
DEV_Detach_IP_From_Device (dev_ptr->dev_net_if_name);
/* Set the status of the PPP connection attempt. */
link_layer->connection_status = NU_PPP_DISCONNECTED;
/* Clear out any messages left in the transmit queue. */
MEM_Buffer_Cleanup(&dev_ptr->dev_transq);
dev_ptr->dev_transq_length = 0;
/* Give the resource back. */
NU_Release_Semaphore(&TCP_Resource);
} /* if it is safe to hangup */
} /* else we want no force */
} /* if a device was found */
else
ret_status = NU_INVALID_LINK;
return (ret_status);
} /* end PPP_Hangup */
/************************************************************************
* FUNCTION
*
* PPP_Safe_To_Hangup
*
* DESCRIPTION
*
* Checks the port lists for active sockets on a particular device.
* Returns TRUE if none are active and FALSE if one or more is active.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* DV_DEVICE_ENTRY *dev_ptr Pointer to the device to check
* for active ports on.
*
* OUTPUTS
*
* STATUS Was the link active or not
*
************************************************************************/
STATUS PPP_Safe_To_Hangup (DV_DEVICE_ENTRY *dev_ptr)
{
UINT16 index;
STATUS ret_status;
/* Assume all if safe. */
ret_status = NU_TRUE;
/* Init the index. */
index = 0;
/* Go through the UDP ports first and check for an active port */
do
{
if (UDP_Ports[index] != NU_NULL)
{
/* Is this port using this device. */
if (UDP_Ports[index]->up_route.rt_route != NU_NULL &&
UDP_Ports[index]->up_route.rt_route->rt_device == dev_ptr)
{
/* Set the return value, there is still an active port. */
ret_status = NU_FALSE;
}
}
} while (ret_status && (++index < UDP_MAX_PORTS));
/* Reset the index */
index = 0;
/* The UDP ports checked out ok, look at the TCP ports. */
while (ret_status && (index < TCP_MAX_PORTS))
{
/* See if there is an entry. */
if (TCP_Ports [index] != NU_NULL)
{
/* Is this port using this device. */
if (TCP_Ports[index]->tp_route.rt_route != NU_NULL &&
TCP_Ports[index]->tp_route.rt_route->rt_device == dev_ptr)
{
/* See if the port is already in the closed state */
if ((TCP_Ports [index]->state != SCLOSED) &&
(TCP_Ports [index]->state != STWAIT))
{
/* It may be in a closing state, if so we will wait for
TCP to finish closing. */
if ((TCP_Ports[index]->state == SFW1) ||
(TCP_Ports[index]->state == SFW2) ||
(TCP_Ports[index]->state == SCLOSING) ||
(TCP_Ports[index]->state == SCWAIT) ||
(TCP_Ports[index]->state == SLAST))
{
while (((TCP_Ports[index]->state == SFW1) ||
(TCP_Ports[index]->state == SFW2) ||
(TCP_Ports[index]->state == SCLOSING) ||
(TCP_Ports[index]->state == SCWAIT) ||
(TCP_Ports[index]->state == SLAST)) &&
((TCP_Ports[index]->state != SCLOSED) &&
(TCP_Ports[index]->state != STWAIT)))
NU_Sleep(TICKS_PER_SECOND / 4);
}
else
{
/* Otherwise it is in an opening or established state.
Return false. */
ret_status = NU_FALSE;
}
}
else
index++;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -