mirror of
https://github.com/azure-rtos/netx.git
synced 2023-08-10 07:57:54 +08:00
046863e95 Added error state in notification callback to let user application have the chance to retry new update 3a020aecc [PPP] Supported processing compressed data (PFC and ACFC). 92a7311b0 Correct error checking for the function _nxe_dhcp_state_change_notify 766068878 Onboard to Central Feed Services
12361 lines
571 KiB
C
12361 lines
571 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
|
/* */
|
|
/* This software is licensed under the Microsoft Software License */
|
|
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
|
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
|
/* and in the root directory of this software. */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
/** */
|
|
/** NetX Component */
|
|
/** */
|
|
/** Point-to-Point Protocol (PPP) */
|
|
/** */
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
#define NX_PPP_SOURCE_CODE
|
|
|
|
|
|
/* Force error checking to be disabled in this module */
|
|
#include "tx_port.h"
|
|
|
|
#ifndef NX_DISABLE_ERROR_CHECKING
|
|
#define NX_DISABLE_ERROR_CHECKING
|
|
#endif
|
|
|
|
#ifndef TX_SAFETY_CRITICAL
|
|
#ifndef TX_DISABLE_ERROR_CHECKING
|
|
#define TX_DISABLE_ERROR_CHECKING
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Include necessary system files. */
|
|
|
|
#include "nx_api.h"
|
|
#include "nx_ppp.h"
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
#include "nx_md5.h"
|
|
#endif
|
|
|
|
/* Define global PPP variables and data structures. */
|
|
|
|
/* Define the PPP created list head pointer and count. */
|
|
|
|
NX_PPP *_nx_ppp_created_ptr = NX_NULL;
|
|
ULONG _nx_ppp_created_count = 0;
|
|
|
|
|
|
/* Define the CRC lookup table. This is used to improve the
|
|
CRC calculation performance. */
|
|
|
|
const USHORT _nx_ppp_crc_table[256] =
|
|
{
|
|
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
|
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
|
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
|
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
|
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
|
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
|
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
|
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
|
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
|
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
|
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
|
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
|
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
|
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
|
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
|
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
|
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
|
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
|
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
|
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
|
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
|
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
|
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
|
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
|
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
|
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
|
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
|
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
|
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
|
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
|
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
|
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
|
};
|
|
|
|
|
|
/* Bring in externs for caller checking code. */
|
|
|
|
NX_CALLER_CHECKING_EXTERNS
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_thread_entry PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function handles all PPP processing, including assembly of */
|
|
/* PPP requests and dispatching them. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_addr Address of PPP instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_get Get PPP event flags */
|
|
/* nx_packet_release Release packet */
|
|
/* _nx_ppp_chap_state_machine_update Update CHAP state machine */
|
|
/* _nx_ppp_lcp_state_machine_update Update LCP state machine */
|
|
/* _nx_ppp_process_deferred_ip_packet_send */
|
|
/* Process deferred IP packet */
|
|
/* send */
|
|
/* _nx_ppp_process_deferred_raw_string_send */
|
|
/* Process deferred raw string */
|
|
/* send */
|
|
/* _nx_ppp_receive_packet_get Get PPP receive packet */
|
|
/* _nx_ppp_receive_packet_process Process received PPP packet */
|
|
/* _nx_ppp_timeout Process PPP timeout */
|
|
/* [_nx_ppp_debug_log_capture] Optional PPP debug log */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* ThreadX */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_thread_entry(ULONG ppp_addr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
NX_PPP *ppp_ptr;
|
|
ULONG ppp_events;
|
|
NX_PACKET *packet_ptr;
|
|
NX_PACKET *next_packet_ptr;
|
|
ULONG count;
|
|
|
|
|
|
/* Setup the PPP pointer. */
|
|
ppp_ptr = (NX_PPP *) ppp_addr;
|
|
|
|
/* Loop to continue processing incoming bytes. */
|
|
while(NX_FOREVER)
|
|
{
|
|
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_PRINT_PROTOCOL
|
|
/* Display debug output of PPP protocol status. */
|
|
_nx_ppp_debug_log_capture_protocol(ppp_ptr);
|
|
#endif
|
|
|
|
/* Wait for PPP event(s). The timeout on the wait will drive PPP timeout processing
|
|
as well. */
|
|
tx_event_flags_get(&(ppp_ptr -> nx_ppp_event), (ULONG) 0xFFFFFFFF, TX_OR_CLEAR, &ppp_events, NX_WAIT_FOREVER);
|
|
|
|
/* Check for PPP stop event. */
|
|
if (ppp_events & NX_PPP_EVENT_STOP)
|
|
{
|
|
|
|
/* Is PPP already stopped? */
|
|
if (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* No, stop this PPP instance an prepare for the next start operation. */
|
|
|
|
/* Set state to stopped. */
|
|
ppp_ptr -> nx_ppp_state = NX_PPP_STOPPED;
|
|
|
|
/* Clean up resources and prepare for next PPP start. */
|
|
|
|
/* Release any packets queued up for the PPP instance. */
|
|
|
|
/* Release any partial receive packets. */
|
|
if (ppp_ptr -> nx_ppp_receive_partial_packet)
|
|
nx_packet_release(ppp_ptr -> nx_ppp_receive_partial_packet);
|
|
|
|
/* Clear the saved receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Setup the receive buffer processing. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_write_index = 0;
|
|
ppp_ptr -> nx_ppp_serial_buffer_read_index = 0;
|
|
ppp_ptr -> nx_ppp_serial_buffer_byte_count = 0;
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
|
|
/* Loop to release all packets in the deferred processing queue.. */
|
|
while (ppp_ptr -> nx_ppp_deferred_received_packet_head)
|
|
{
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Pickup the packet. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_deferred_received_packet_head;
|
|
|
|
/* Move the head pointer to the next packet. */
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_head = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Check for end of deferred processing queue. */
|
|
if (ppp_ptr -> nx_ppp_deferred_received_packet_head == NX_NULL)
|
|
{
|
|
|
|
/* Yes, the queue is empty. Set the tail pointer to NULL. */
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_tail = NX_NULL;
|
|
}
|
|
|
|
/* Release all packets in the raw packet queue. */
|
|
TX_DISABLE
|
|
|
|
/* Release packet. */
|
|
nx_packet_release(packet_ptr);
|
|
}
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
/* Release all packets in the IP packet queue. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the head pointer and count. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_ip_packet_queue_head;
|
|
|
|
/* Set the list head and tail pointers to NULL. */
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_head = NX_NULL;
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_tail = NX_NULL;
|
|
|
|
/* Pickup the count. */
|
|
count = ppp_ptr -> nx_ppp_ip_packet_queue_count;
|
|
|
|
/* Clear the count. */
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_count = 0;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Loop to release all packets. */
|
|
while (count)
|
|
{
|
|
/* Pickup next packet. */
|
|
next_packet_ptr = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Release packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Move to next packet. */
|
|
packet_ptr = next_packet_ptr;
|
|
|
|
/* Decrement the count. */
|
|
count--;
|
|
}
|
|
|
|
/* Release all packets in the raw packet queue. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the head pointer and count. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_raw_packet_queue_head;
|
|
|
|
/* Set the list head and tail pointers to NULL. */
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_head = NX_NULL;
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_tail = NX_NULL;
|
|
|
|
/* Pickup the count. */
|
|
count = ppp_ptr -> nx_ppp_raw_packet_queue_count;
|
|
|
|
/* Clear the count. */
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_count = 0;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Loop to release all packets. */
|
|
while (count)
|
|
{
|
|
/* Pickup next packet. */
|
|
next_packet_ptr = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Release packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Move to next packet. */
|
|
packet_ptr = next_packet_ptr;
|
|
|
|
/* Decrement the count. */
|
|
count--;
|
|
}
|
|
|
|
/* Reset all state machines. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_INITIAL_STATE;
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_INITIAL_STATE;
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_INITIAL_STATE;
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_INITIAL_STATE;
|
|
|
|
/* Determine how to setup the initial authenticated field. */
|
|
if ((ppp_ptr -> nx_ppp_pap_verify_login) ||
|
|
(ppp_ptr -> nx_ppp_pap_generate_login) ||
|
|
(ppp_ptr -> nx_ppp_chap_get_verification_values))
|
|
{
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
}
|
|
else
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Clear the IP address. */
|
|
nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index, 0, 0);
|
|
|
|
/* Clear the local information for PPP client. */
|
|
if (ppp_ptr -> nx_ppp_server == NX_FALSE)
|
|
{
|
|
|
|
/* Clear the IP addresses. */
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[0] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[1] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[2] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[3] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[0] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[1] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[2] = 0;
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[3] = 0;
|
|
|
|
/* Clear the DNS addresses. */
|
|
ppp_ptr -> nx_ppp_primary_dns_address = 0;
|
|
ppp_ptr -> nx_ppp_secondary_dns_address = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Check for PPP start event. */
|
|
if (ppp_events & NX_PPP_EVENT_START)
|
|
{
|
|
|
|
/* Is PPP in a stopped state? */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Update the PPP state. */
|
|
ppp_ptr -> nx_ppp_state = NX_PPP_STARTED;
|
|
|
|
/* Yes, move to the initial LCP state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_START_STATE;
|
|
|
|
/* Initiate the PPP protocol. */
|
|
_nx_ppp_lcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
|
|
/* Check for PPP raw packet send request. */
|
|
if (ppp_events & NX_PPP_EVENT_RAW_STRING_SEND)
|
|
{
|
|
|
|
/* Process deferred raw string send requests. */
|
|
_nx_ppp_process_deferred_raw_string_send(ppp_ptr);
|
|
}
|
|
|
|
/* Check for deferred IP transmit requests. */
|
|
if (ppp_events & NX_PPP_EVENT_IP_PACKET_SEND)
|
|
{
|
|
|
|
/* Process deferred IP transmit packets. */
|
|
_nx_ppp_process_deferred_ip_packet_send(ppp_ptr);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Check for CHAP challenge event. */
|
|
if (ppp_events & NX_PPP_EVENT_CHAP_CHALLENGE)
|
|
{
|
|
|
|
/* Determine if CHAP is in a completed state. */
|
|
if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_COMPLETED_STATE)
|
|
{
|
|
|
|
/* Move the state to the new challenge state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_NEW_STATE;
|
|
|
|
/* Now update the CHAP state machine in order to force the
|
|
new CHAP challenge out. */
|
|
_nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* Now check for timeout processing. */
|
|
if (ppp_events & NX_PPP_EVENT_TIMEOUT)
|
|
{
|
|
|
|
/* Timeout occurred. Is there are PPP timeout active? */
|
|
if (ppp_ptr -> nx_ppp_timeout)
|
|
{
|
|
|
|
/* Decrement the timeout count. */
|
|
ppp_ptr -> nx_ppp_timeout--;
|
|
|
|
/* Has the timeout expired? */
|
|
if (ppp_ptr -> nx_ppp_timeout == 0)
|
|
{
|
|
|
|
/* Process timeout request. */
|
|
_nx_ppp_timeout(ppp_ptr);
|
|
}
|
|
}
|
|
|
|
/* Increment the receive timeout processing. */
|
|
ppp_ptr -> nx_ppp_receive_timeouts++;
|
|
}
|
|
|
|
/* Check for PPP Packet receive event. */
|
|
if (ppp_events & NX_PPP_EVENT_PACKET_RECEIVE)
|
|
{
|
|
|
|
/* Pickup the next PPP packet from serial port to process. This is called whether an event was set or not
|
|
simply to handle the case when a non-PPP frame is received. */
|
|
_nx_ppp_receive_packet_get(ppp_ptr, &packet_ptr);
|
|
|
|
/* Now determine if there is a packet to process. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_ENABLE
|
|
|
|
/* Insert an entry into the PPP frame debug log. */
|
|
_nx_ppp_debug_log_capture(ppp_ptr, 'R', packet_ptr);
|
|
#endif
|
|
|
|
/* Yes, call the PPP packet processing routine. */
|
|
_nx_ppp_receive_packet_process(ppp_ptr, packet_ptr);
|
|
}
|
|
}
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
|
|
/* Check for PPP Packet receive event. */
|
|
if (ppp_events & NX_PPP_EVENT_PPPOE_PACKET_RECEIVE)
|
|
{
|
|
|
|
/* Loop to process all deferred packet requests. */
|
|
while (ppp_ptr -> nx_ppp_deferred_received_packet_head)
|
|
{
|
|
|
|
/* Remove the first packet and process it! */
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the first packet. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_deferred_received_packet_head;
|
|
|
|
/* Move the head pointer to the next packet. */
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_head = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Check for end of deferred processing queue. */
|
|
if (ppp_ptr -> nx_ppp_deferred_received_packet_head == NX_NULL)
|
|
{
|
|
|
|
/* Yes, the queue is empty. Set the tail pointer to NULL. */
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_tail = NX_NULL;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_ENABLE
|
|
|
|
/* Insert an entry into the PPP frame debug log. */
|
|
_nx_ppp_debug_log_capture(ppp_ptr, 'R', packet_ptr);
|
|
#endif
|
|
|
|
/* Yes, call the PPP packet processing routine. */
|
|
_nx_ppp_receive_packet_process(ppp_ptr, packet_ptr);
|
|
}
|
|
}
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_driver PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function provides the basic interface to the NetX TCP/IP */
|
|
/* network stack. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* driver_req_ptr NetX driver request structure */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_transmit_release Release transmit packet */
|
|
/* tx_event_flags_set Set PPP events */
|
|
/* tx_thread_resume Resume PPP thread */
|
|
/* tx_timer_activate Activate PPP timer */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* NetX */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
NX_IP *ip_ptr;
|
|
NX_INTERFACE *interface_ptr;
|
|
NX_PPP *ppp_ptr;
|
|
NX_PACKET *packet_ptr;
|
|
UINT i;
|
|
|
|
|
|
/* Setup the IP pointer from the driver request. */
|
|
ip_ptr = driver_req_ptr -> nx_ip_driver_ptr;
|
|
|
|
/* Pickup the interface pointer. */
|
|
interface_ptr = driver_req_ptr -> nx_ip_driver_interface;
|
|
|
|
/* Default to successful return. */
|
|
driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS;
|
|
|
|
/* Process according to the driver request type in the driver control
|
|
block. */
|
|
switch (driver_req_ptr -> nx_ip_driver_command)
|
|
{
|
|
|
|
case NX_LINK_INTERFACE_ATTACH:
|
|
{
|
|
|
|
/* First, we need to find the PPP instance that is mapped to
|
|
this IP instance and that doesn't have its interface attach
|
|
complete yet. This requires that PPP is created prior to
|
|
IP creation. */
|
|
ppp_ptr = _nx_ppp_created_ptr;
|
|
i = 0;
|
|
while (i < _nx_ppp_created_count)
|
|
{
|
|
|
|
/* Does this PPP instance point to the current IP instance? */
|
|
if ((ppp_ptr -> nx_ppp_ip_ptr == ip_ptr) && (ppp_ptr -> nx_ppp_interface_ptr == NX_NULL))
|
|
{
|
|
|
|
/* Yes, we found an un-attached PPP instance for this IP interface instance. Get out of
|
|
the search loop. */
|
|
break;
|
|
}
|
|
|
|
/* Move the next PPP instance. */
|
|
ppp_ptr = ppp_ptr -> nx_ppp_created_next;
|
|
|
|
/* Increment counter. */
|
|
i++;
|
|
}
|
|
|
|
/* Determine if a PPP instance was found. */
|
|
if (i >= _nx_ppp_created_count)
|
|
{
|
|
|
|
/* Return an error to NetX. */
|
|
driver_req_ptr -> nx_ip_driver_status = NX_IP_INTERNAL_ERROR;
|
|
return;
|
|
}
|
|
|
|
/* Now find interface index. */
|
|
i = 0;
|
|
while (i < NX_MAX_PHYSICAL_INTERFACES)
|
|
{
|
|
|
|
/* Is this the interface index? */
|
|
if (&(ip_ptr -> nx_ip_interface[i]) == interface_ptr)
|
|
{
|
|
|
|
/* Found the index, get out of the loop. */
|
|
break;
|
|
}
|
|
|
|
/* Move to next interface. */
|
|
i++;
|
|
}
|
|
|
|
/* Determine if the interface index was found. */
|
|
if (i >= NX_MAX_PHYSICAL_INTERFACES)
|
|
{
|
|
|
|
/* Return an error to NetX. */
|
|
driver_req_ptr -> nx_ip_driver_status = NX_IP_INTERNAL_ERROR;
|
|
return;
|
|
}
|
|
|
|
/* Otherwise, we have everything we need to perform the attachment. */
|
|
|
|
/* Remember the PPP instance pointer in the IP interface pointer. */
|
|
interface_ptr -> nx_interface_additional_link_info = (void *) ppp_ptr;
|
|
|
|
/* Remember the interface pointer and index in the PPP structure. */
|
|
ppp_ptr -> nx_ppp_interface_ptr = interface_ptr;
|
|
ppp_ptr -> nx_ppp_interface_index = i;
|
|
break;
|
|
}
|
|
|
|
case NX_LINK_INITIALIZE:
|
|
{
|
|
|
|
/* Process driver initialization. */
|
|
|
|
|
|
/* Otherwise, we have found the PPP instance, continue initialization. */
|
|
|
|
/* Pickup the associated PPP instance address. */
|
|
ppp_ptr = (NX_PPP *) interface_ptr-> nx_interface_additional_link_info;
|
|
|
|
/* Setup the link maximum transfer unit. */
|
|
interface_ptr -> nx_interface_ip_mtu_size = NX_PPP_MRU;
|
|
|
|
/* Clear the hardware physical address, since there is no
|
|
such thing in PPP. */
|
|
interface_ptr -> nx_interface_physical_address_msw = 0;
|
|
interface_ptr -> nx_interface_physical_address_lsw = 0;
|
|
|
|
/* Indicate to the IP software that IP to physical mapping
|
|
is not required in PPP. */
|
|
interface_ptr -> nx_interface_address_mapping_needed = NX_FALSE;
|
|
|
|
/* Set the link up to false. */
|
|
interface_ptr -> nx_interface_link_up = NX_FALSE;
|
|
|
|
/* Resume the PPP thread. */
|
|
tx_thread_resume(&(ppp_ptr -> nx_ppp_thread));
|
|
|
|
/* Activate the PPP timer. */
|
|
tx_timer_activate(&(ppp_ptr -> nx_ppp_timer));
|
|
break;
|
|
}
|
|
|
|
|
|
case NX_LINK_ENABLE:
|
|
{
|
|
|
|
/* Pickup the associated PPP instance address. */
|
|
ppp_ptr = (NX_PPP *) interface_ptr-> nx_interface_additional_link_info;
|
|
|
|
/* Now set event flag to start PPP. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
|
|
break;
|
|
}
|
|
|
|
case NX_LINK_DISABLE:
|
|
{
|
|
|
|
/* Process driver link disable. */
|
|
|
|
/* Pickup the associated PPP instance address. */
|
|
ppp_ptr = (NX_PPP*) interface_ptr-> nx_interface_additional_link_info;
|
|
|
|
/* Now set event flag to start PPP. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
break;
|
|
}
|
|
|
|
case NX_LINK_PACKET_SEND:
|
|
{
|
|
|
|
/* Pickup the associated PPP instance address. */
|
|
ppp_ptr = (NX_PPP*) interface_ptr -> nx_interface_additional_link_info;
|
|
|
|
/* Pickup packet pointer. */
|
|
packet_ptr = driver_req_ptr -> nx_ip_driver_packet;
|
|
|
|
/* Determine if the interface link is still up. */
|
|
if (interface_ptr -> nx_interface_link_up == NX_FALSE)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the transmit frames dropped counter. */
|
|
ppp_ptr -> nx_ppp_transmit_frames_dropped++;
|
|
#endif
|
|
/* No, release the packet. */
|
|
nx_packet_transmit_release(packet_ptr);
|
|
break;
|
|
}
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Determine if the transmit queue is empty. */
|
|
if (ppp_ptr -> nx_ppp_ip_packet_queue_count++)
|
|
{
|
|
|
|
/* Not empty, simply link the new packet to the tail and update the tail. */
|
|
(ppp_ptr -> nx_ppp_ip_packet_queue_tail) -> nx_packet_queue_next = packet_ptr;
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_tail = packet_ptr;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* List is empty, set the head and tail to this packet. */
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_head = packet_ptr;
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_tail = packet_ptr;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Set event flag to wake up PPP thread for processing. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_IP_PACKET_SEND, TX_OR);
|
|
break;
|
|
}
|
|
|
|
case NX_LINK_GET_STATUS:
|
|
{
|
|
|
|
/* Return the link status in the supplied return pointer. */
|
|
*(driver_req_ptr -> nx_ip_driver_return_ptr) = interface_ptr -> nx_interface_link_up;
|
|
break;
|
|
}
|
|
|
|
case NX_LINK_UNINITIALIZE:
|
|
{
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
|
|
/* Invalid driver request. */
|
|
|
|
/* Return the unhandled command status. */
|
|
driver_req_ptr -> nx_ip_driver_status = NX_UNHANDLED_COMMAND;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_get PORTABLE C */
|
|
/* 6.x */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function assembles the PPP frame, which involves moving bytes */
|
|
/* from the serial buffer, converting the escape sequences, and */
|
|
/* returning the formed PPP packet to the caller. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* return_packet_ptr Return packet pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_check_crc Check HDLC frame CRC */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* nx_packet_release Release packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* ThreadX */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* xx-xx-xxxx Wenhui Xie Modified comment(s), and */
|
|
/* supported processing */
|
|
/* compressed data, */
|
|
/* resulting in version 6.x */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_receive_packet_get(NX_PPP *ppp_ptr, NX_PACKET **return_packet_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
NX_PACKET *packet_head_ptr;
|
|
NX_PACKET *next_packet_ptr;
|
|
UCHAR byte;
|
|
UCHAR *buffer_ptr;
|
|
ULONG buffer_size;
|
|
ULONG timeouts;
|
|
NX_PACKET *packet_ptr;
|
|
UINT status;
|
|
|
|
|
|
/* Default the return packet pointer NULL. */
|
|
*return_packet_ptr = NX_NULL;
|
|
|
|
/* Pickup the current working packet. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_receive_partial_packet;
|
|
|
|
/* Determine if there is a working receive packet. */
|
|
if (packet_ptr == NX_NULL)
|
|
{
|
|
|
|
/* No, setup new working receive packet. */
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Save the working receive packet pointer. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = packet_ptr;
|
|
ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
|
|
|
|
/* Setup packet payload pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Setup packet size. */
|
|
buffer_size = 0;
|
|
|
|
/* Initialize the timeout counter. */
|
|
timeouts = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Pickup saved buffer ptr, size and timeout counter. */
|
|
buffer_ptr = ppp_ptr -> nx_ppp_receive_buffer_ptr;
|
|
buffer_size = ppp_ptr -> nx_ppp_receive_buffer_size;
|
|
|
|
/* Pickup saved timeout count. */
|
|
timeouts = ppp_ptr -> nx_ppp_receive_timeouts;
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = ppp_ptr -> nx_ppp_head_packet;
|
|
}
|
|
|
|
/* Loop to drain the serial buffer. */
|
|
do
|
|
{
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Determine if there are any characters in the serial receive buffer. */
|
|
if (ppp_ptr -> nx_ppp_serial_buffer_byte_count)
|
|
{
|
|
|
|
/* Yes, there are one or more characters. */
|
|
|
|
/* Pickup the character. */
|
|
byte = ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_read_index];
|
|
|
|
/* Now determine if there is an escape sequence character and we don't have the following
|
|
character. */
|
|
if ((byte == 0x7d) && (ppp_ptr -> nx_ppp_serial_buffer_byte_count == 1))
|
|
{
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* We need to wait for another character. */
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Nothing is left in the buffer. */
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Determine if the timeout count has been exceeded. */
|
|
if (timeouts > NX_PPP_RECEIVE_TIMEOUTS)
|
|
{
|
|
|
|
/* Timeout count has been exceeded. */
|
|
|
|
/* Determine if the packet is non-PPP. If so, we should dispatch it to
|
|
the non-PPP packet handler. */
|
|
if ((buffer_size) && (packet_head_ptr -> nx_packet_prepend_ptr[0] != 0x7e))
|
|
{
|
|
|
|
/* Determine if there is a user handler for non-PPP packets. */
|
|
if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
|
|
{
|
|
|
|
/* Adjust the packet parameters. */
|
|
packet_head_ptr -> nx_packet_length = buffer_size;
|
|
packet_ptr -> nx_packet_append_ptr = buffer_ptr;
|
|
|
|
/* Dispatch packet to user's handler for non-PPP packets. */
|
|
(ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the frame timeout counter. */
|
|
ppp_ptr -> nx_ppp_frame_timeouts++;
|
|
#endif
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
}
|
|
|
|
/* Clear the saved receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Save the new receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = packet_ptr;
|
|
ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
|
|
|
|
/* Setup packet payload pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Setup packet size. */
|
|
buffer_size = 0;
|
|
|
|
/* Initialize the timeout counter. */
|
|
timeouts = 0;
|
|
}
|
|
|
|
/* We need to wait for another character. */
|
|
break;
|
|
}
|
|
|
|
/* At this point, we have a character. Adjust the serial buffer information. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_read_index++;
|
|
|
|
/* Check for serial buffer wrap-around condition. */
|
|
if (ppp_ptr -> nx_ppp_serial_buffer_read_index >= NX_PPP_SERIAL_BUFFER_SIZE)
|
|
{
|
|
|
|
/* Reset the buffer read index. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_read_index = 0;
|
|
}
|
|
|
|
/* Adjust the serial buffer count. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_byte_count--;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Clear the timeouts counter. */
|
|
timeouts = 0;
|
|
|
|
/* Determine if we are at the beginning of the packet. */
|
|
if (buffer_size == 0)
|
|
{
|
|
|
|
/* Determine if we should add a PPP frame header. */
|
|
if (byte == 0xFF)
|
|
{
|
|
|
|
/* Yes, a packet is present without a leading 0x7e. Simply place it in the buffer. */
|
|
*buffer_ptr++ = 0x7e;
|
|
|
|
/* Increment the buffer size. */
|
|
buffer_size++;
|
|
}
|
|
}
|
|
|
|
/* Determine if we are at the end of the PPP frame. */
|
|
else if (byte == 0x7e)
|
|
{
|
|
|
|
/* Yes, we are at the end of the PPP frame. */
|
|
|
|
/* Determine if a non-PPP frame preceded this end of frame marker. */
|
|
if (packet_head_ptr -> nx_packet_prepend_ptr[0] != 0x7e)
|
|
{
|
|
|
|
/* Determine if there is a handler for non-PPP packets. */
|
|
if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
|
|
{
|
|
|
|
/* Adjust the packet parameters. */
|
|
packet_head_ptr -> nx_packet_length = buffer_size;
|
|
packet_ptr -> nx_packet_append_ptr = buffer_ptr;
|
|
|
|
/* Dispatch packet to user's handler for non-PPP packets. */
|
|
(ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
}
|
|
|
|
/* Clear the saved receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Save the current receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = packet_ptr;
|
|
ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
|
|
|
|
/* Setup packet payload pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Setup packet size. */
|
|
buffer_size = 0;
|
|
|
|
/* Initialize the timeout counter. */
|
|
timeouts = 0;
|
|
|
|
/* Continue to get the next byte. */
|
|
continue;
|
|
}
|
|
|
|
/* A PPP frame is present. Put the 0x7e into the frame. */
|
|
|
|
/* Yes, place the final 0x7e in the buffer. */
|
|
*buffer_ptr++ = 0x7e;
|
|
|
|
/* Increment the buffer size. */
|
|
buffer_size++;
|
|
|
|
/* Adjust the packet parameters. */
|
|
packet_head_ptr -> nx_packet_length = buffer_size;
|
|
packet_ptr -> nx_packet_append_ptr = buffer_ptr;
|
|
|
|
/* Check the CRC of the packet. */
|
|
status = _nx_ppp_check_crc(packet_head_ptr);
|
|
|
|
if (status == NX_SUCCESS)
|
|
{
|
|
|
|
/* Remove the FCS (2 bytes) and Flag (1 byte). */
|
|
packet_head_ptr -> nx_packet_length = packet_head_ptr -> nx_packet_length - 3;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_append_ptr - 3;
|
|
|
|
/* Check for the condition where there is essentially no data in the last packet. */
|
|
if (packet_ptr -> nx_packet_append_ptr <= packet_ptr -> nx_packet_prepend_ptr)
|
|
{
|
|
ULONG diff = (ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_append_ptr);
|
|
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
if (packet_head_ptr != packet_ptr)
|
|
{
|
|
|
|
|
|
NX_PACKET *tmp_packet_ptr = packet_head_ptr;
|
|
NX_PACKET *prev_packet_ptr = tmp_packet_ptr;
|
|
while (tmp_packet_ptr -> nx_packet_next != 0x0)
|
|
{
|
|
prev_packet_ptr = tmp_packet_ptr;
|
|
tmp_packet_ptr = tmp_packet_ptr -> nx_packet_next;
|
|
}
|
|
|
|
nx_packet_release(tmp_packet_ptr);
|
|
prev_packet_ptr -> nx_packet_next = NX_NULL;
|
|
prev_packet_ptr -> nx_packet_append_ptr -= diff;
|
|
}
|
|
}
|
|
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
if (((UINT)(packet_head_ptr -> nx_packet_append_ptr - packet_head_ptr -> nx_packet_prepend_ptr) < 3) ||
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[1] != 0xff) ||
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[2] != 0x03))
|
|
{
|
|
|
|
/* Address and control fields are compressed. Remove the compressed HDLC header. */
|
|
packet_head_ptr -> nx_packet_prepend_ptr++;
|
|
packet_head_ptr -> nx_packet_length--;
|
|
}
|
|
#else
|
|
if ((UINT)(packet_head_ptr -> nx_packet_append_ptr - packet_head_ptr -> nx_packet_prepend_ptr) < 3)
|
|
{
|
|
status = NX_PPP_BAD_PACKET;
|
|
}
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
else
|
|
{
|
|
|
|
/* Remove the HDLC header. */
|
|
packet_head_ptr -> nx_packet_prepend_ptr += 3;
|
|
packet_head_ptr -> nx_packet_length -= 3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* CRC error is present, just give up on the current frame. */
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the frame CRC error counter. */
|
|
ppp_ptr -> nx_ppp_frame_crc_errors++;
|
|
#endif
|
|
}
|
|
|
|
/* Determine if there was an error. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
|
|
/* Clear the saved receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Save the current receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = packet_ptr;
|
|
ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
|
|
|
|
/* Setup packet payload pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Setup packet size. */
|
|
buffer_size = 0;
|
|
|
|
/* Initialize the timeout counter. */
|
|
timeouts = 0;
|
|
|
|
break;
|
|
}
|
|
|
|
/* Return the pointer. */
|
|
*return_packet_ptr = packet_head_ptr;
|
|
|
|
/* Set the receive packet to NULL to indicate there is no partial packet being
|
|
processed. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Return to caller. */
|
|
return;
|
|
}
|
|
|
|
/* Determine if an escape byte is present. */
|
|
if (byte == 0x7d)
|
|
{
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the character - we know there is one because of earlier logic. */
|
|
byte = ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_read_index++];
|
|
|
|
/* Check for serial buffer wrap-around condition. */
|
|
if (ppp_ptr -> nx_ppp_serial_buffer_read_index >= NX_PPP_SERIAL_BUFFER_SIZE)
|
|
{
|
|
|
|
/* Reset the buffer read index. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_read_index = 0;
|
|
}
|
|
|
|
/* Adjust the serial buffer count. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_byte_count--;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Convert the escape sequence character. */
|
|
byte = byte ^ 0x20;
|
|
}
|
|
|
|
/* Determine if there is room in the payload. */
|
|
if (buffer_ptr < (packet_ptr -> nx_packet_data_end - 4))
|
|
{
|
|
|
|
/* Put the character in the packet payload. */
|
|
*buffer_ptr++ = byte;
|
|
|
|
/* Increment the buffer size. */
|
|
buffer_size++;
|
|
}
|
|
|
|
|
|
/* We need to perform packet chaining at this point, but only for IP data frames. Non PPP data and
|
|
the other PPP protocol packets must fit within the payload of one packet. */
|
|
else if (((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[1] == 0xff) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x03) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[3] == 0x00) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[4] == 0x21)) /* 0x0021 is NX_PPP_DATA */
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
|| ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[1] == 0xff) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x03) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[3] == 0x21)) /* Protocol field is compressed */
|
|
|| ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[1] == 0x00) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x21)) /* Address and Control fields are compressed */
|
|
|| ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
|
|
(packet_head_ptr -> nx_packet_prepend_ptr[1] == 0x21)) /* Protocol, Address and Control fields are compressed */
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
)
|
|
{
|
|
|
|
/* We need to move to the next packet and chain them. */
|
|
packet_ptr -> nx_packet_append_ptr = buffer_ptr;
|
|
|
|
/* Allocate a new packet to for packet chaining. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &next_packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* Clear the partial receive packet pointer. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Adjust the next packet pointer. */
|
|
packet_ptr -> nx_packet_next = next_packet_ptr;
|
|
|
|
/* Setup the last pointer. */
|
|
packet_head_ptr -> nx_packet_last = next_packet_ptr;
|
|
|
|
/* Use the packet pointer. */
|
|
packet_ptr = next_packet_ptr;
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup buffer pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Put the character in the packet payload. */
|
|
*buffer_ptr++ = byte;
|
|
|
|
/* Increment the buffer size. */
|
|
buffer_size++;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* At this point we know we have a buffer full of non-PPP characters, in
|
|
most cases this is simply noise. */
|
|
|
|
/* Determine if there is a non-PPP handler. */
|
|
if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
|
|
{
|
|
|
|
/* Adjust the packet parameters. */
|
|
packet_head_ptr -> nx_packet_length = buffer_size;
|
|
packet_ptr -> nx_packet_append_ptr = buffer_ptr;
|
|
|
|
/* Dispatch packet to user's handler for non-PPP packets. */
|
|
(ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Release the current packet. */
|
|
nx_packet_release(packet_head_ptr);
|
|
}
|
|
|
|
/* Clear the partial receive packet pointer. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = NX_NULL;
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Save the current receive packet. */
|
|
ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
|
|
|
|
/* Setup the packet head pointer. */
|
|
packet_head_ptr = packet_ptr;
|
|
ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
|
|
|
|
/* Setup packet payload pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Setup packet size. */
|
|
buffer_size = 0;
|
|
|
|
/* Initialize the timeout counter. */
|
|
timeouts = 0;
|
|
}
|
|
} while(ppp_ptr -> nx_ppp_serial_buffer_byte_count);
|
|
|
|
/* Save the buffer size, buffer pointer, and timeout count. */
|
|
ppp_ptr -> nx_ppp_receive_buffer_size = buffer_size;
|
|
ppp_ptr -> nx_ppp_receive_buffer_ptr = buffer_ptr;
|
|
ppp_ptr -> nx_ppp_receive_timeouts = timeouts;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process PORTABLE C */
|
|
/* 6.x */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes a received PPP request and dispatches it */
|
|
/* to the appropriate protocol or to NetX. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to PPP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_release Release packet */
|
|
/* _nx_ppp_lcp_state_machine_update Process LCP message */
|
|
/* _nx_ppp_pap_state_machine_update Process PAP message */
|
|
/* _nx_ppp_chap_state_machine_update Process CHAP message */
|
|
/* _nx_ppp_ipcp_state_machine_update Process IPCP message */
|
|
/* _nx_ppp_netx_packet_transfer Transfer packet to NetX */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_thread_entry PPP thread entry */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* improved packet length */
|
|
/* verification, */
|
|
/* resulting in version 6.1.2 */
|
|
/* xx-xx-xxxx Wenhui Xie Modified comment(s), and */
|
|
/* supported processing */
|
|
/* compressed data, */
|
|
/* resulting in version 6.x */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_receive_packet_process(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT protocol;
|
|
UINT ppp_ipcp_state;
|
|
UINT code;
|
|
UINT length;
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IP frames sent. */
|
|
ppp_ptr -> nx_ppp_total_frames_received++;
|
|
#endif
|
|
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
|
|
/* Check for valid packet length for Protocol (if compressed, it should be 1 byte). */
|
|
if (packet_ptr -> nx_packet_length < 1)
|
|
#else
|
|
|
|
/* Check for valid packet length for Protocol (2 bytes). */
|
|
if (packet_ptr -> nx_packet_length < 2)
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Return. */
|
|
return;
|
|
}
|
|
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
|
|
/* Pickup the protocol type. */
|
|
if (packet_ptr -> nx_packet_prepend_ptr[0] & NX_PPP_PROTOCOL_LSB_MARK)
|
|
{
|
|
|
|
/* The protocol field is compressed to 1 byte. */
|
|
protocol = (UINT) packet_ptr -> nx_packet_prepend_ptr[0];
|
|
}
|
|
else
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
{
|
|
|
|
/* The protocol field is 2 bytes. */
|
|
protocol = (((UINT) packet_ptr -> nx_packet_prepend_ptr[0]) << 8) | ((UINT) packet_ptr -> nx_packet_prepend_ptr[1]);
|
|
}
|
|
|
|
/* Check protocol. */
|
|
if (protocol != NX_PPP_DATA)
|
|
{
|
|
|
|
|
|
/* Discard the chained packets. */
|
|
if (packet_ptr -> nx_packet_next)
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Return. */
|
|
return;
|
|
}
|
|
|
|
/* Other Protocols must also have Code:1 byte, Identifier:1 bytes, Length: 2 bytes. */
|
|
if (packet_ptr -> nx_packet_length < 6)
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Return. */
|
|
return;
|
|
}
|
|
|
|
/* Get the message length. */
|
|
length = (((UINT) packet_ptr -> nx_packet_prepend_ptr[4]) << 8) | ((UINT) packet_ptr -> nx_packet_prepend_ptr[5]);
|
|
|
|
/* Check if the packet length is equal to message length plus 2 bytes protocal type. */
|
|
if ((length + 2) != packet_ptr -> nx_packet_length)
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Return. */
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Determine if the packet is LCP. */
|
|
if (protocol == NX_PPP_LCP_PROTOCOL)
|
|
{
|
|
|
|
/* Pickup the type of received LCP code. */
|
|
code = packet_ptr -> nx_packet_prepend_ptr[2];
|
|
|
|
/* Process the LCP message, updating the LCP state machine. */
|
|
_nx_ppp_lcp_state_machine_update(ppp_ptr, packet_ptr);
|
|
|
|
/* Determine if the LCP is now complete. */
|
|
if (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_COMPLETED_STATE)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_PAP
|
|
|
|
/* Determine if the PAP state machine should be started. */
|
|
if ((ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_PAP_PROTOCOL) ||
|
|
(ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_PAP_PROTOCOL))
|
|
{
|
|
|
|
/* Check if PAP already start. */
|
|
if (ppp_ptr -> nx_ppp_pap_state == NX_PPP_PAP_INITIAL_STATE)
|
|
{
|
|
|
|
/* Yes, change state to PAP start state and update the PAP state machine. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_START_STATE;
|
|
|
|
/* Process the PAP message. */
|
|
_nx_ppp_pap_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Determine if the CHAP state machine should be started. */
|
|
if ((ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL) ||
|
|
(ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_CHAP_PROTOCOL))
|
|
{
|
|
|
|
/* Check if CHAP already start. */
|
|
if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_INITIAL_STATE)
|
|
{
|
|
|
|
/* Yes, change state to CHAP start state and update the CHAP state machine. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_START_STATE;
|
|
|
|
/* Process the CHAP message. */
|
|
_nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* Do not set the IPCP state to INIT on receipt of an LCP echo request or reply! */
|
|
if ((code != NX_PPP_LCP_ECHO_REQUEST) && (code != NX_PPP_LCP_ECHO_REPLY))
|
|
{
|
|
|
|
/* Check for authentication. */
|
|
if (ppp_ptr -> nx_ppp_authenticated)
|
|
{
|
|
|
|
/* Check if IPCP already start. */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
|
|
{
|
|
|
|
/* Yes, change state to IPCP start state and update the PAP state machine. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
|
|
|
|
/* Process the IPCP message. */
|
|
_nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Check if the packet is Echo Request. */
|
|
if (code == NX_PPP_LCP_ECHO_REQUEST)
|
|
{
|
|
|
|
/* Clear the pointer since it was sent out as Echo Reply. */
|
|
packet_ptr = NX_NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_PAP
|
|
|
|
/* Determine if the packet is PAP. */
|
|
else if (protocol == NX_PPP_PAP_PROTOCOL)
|
|
{
|
|
|
|
/* Process the PAP message. */
|
|
_nx_ppp_pap_state_machine_update(ppp_ptr, packet_ptr);
|
|
|
|
/* Check for authentication. */
|
|
if (ppp_ptr -> nx_ppp_authenticated)
|
|
{
|
|
|
|
/* Check if IPCP already start. */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
|
|
{
|
|
|
|
/* Yes, change state to IPCP start state and update the IPCP state machine. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
|
|
|
|
/* Process the IPCP message. */
|
|
_nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Determine if the packet is CHAP. */
|
|
else if (protocol == NX_PPP_CHAP_PROTOCOL)
|
|
{
|
|
|
|
/* Process the CHAP message. */
|
|
_nx_ppp_chap_state_machine_update(ppp_ptr, packet_ptr);
|
|
|
|
/* Check for authentication. */
|
|
if (ppp_ptr -> nx_ppp_authenticated)
|
|
{
|
|
|
|
/* Check if IPCP already start. */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
|
|
{
|
|
|
|
/* Yes, change state to IPCP start state and update the IPCP state machine. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
|
|
|
|
/* Process the IPCP message. */
|
|
_nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* Determine if packet is IPCP. */
|
|
else if (protocol == NX_PPP_IPCP_PROTOCOL)
|
|
{
|
|
|
|
/* Process the IPCP message. */
|
|
ppp_ipcp_state = ppp_ptr -> nx_ppp_ipcp_state;
|
|
|
|
_nx_ppp_ipcp_state_machine_update(ppp_ptr, packet_ptr);
|
|
|
|
/* Check for IPCP completion... when this happens, the link is up! */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_COMPLETED_STATE)
|
|
{
|
|
|
|
/* Set the PPP state machine to indicate it is complete. */
|
|
ppp_ptr -> nx_ppp_state = NX_PPP_ESTABLISHED;
|
|
|
|
/* Mark the IP interface instance as link up. */
|
|
(ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_link_up = NX_TRUE;
|
|
|
|
/* Determine if the application has registered a link up notification
|
|
callback. */
|
|
if ((ppp_ptr -> nx_ppp_link_up_callback) && (ppp_ipcp_state!=NX_PPP_IPCP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_up_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Check for normal data packet. */
|
|
else if (protocol == NX_PPP_DATA)
|
|
{
|
|
|
|
/* Transfer the packet to NetX. */
|
|
_nx_ppp_netx_packet_transfer(ppp_ptr, packet_ptr);
|
|
|
|
/* Clear the pointer since it was passed to NetX. */
|
|
packet_ptr = NX_NULL;
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
else
|
|
/* Increment the number of frames dropped. */
|
|
ppp_ptr -> nx_ppp_receive_frames_dropped++;
|
|
#endif
|
|
|
|
/* Determine if the packet needs to be released. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_timeout PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes PPP time-out events, which includes */
|
|
/* updating the responsible state machine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update PPP state machine update */
|
|
/* _nx_ppp_pap_state_machine_update PPP PAP state machine update */
|
|
/* _nx_ppp_chap_state_machine_update PPP CHAP state machine update */
|
|
/* _nx_ppp_ipcp_state_machine_update PPP IPCP state machine update */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* ThreadX */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_timeout(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
/* Determine if the LCP state machine needs updating. */
|
|
if ((ppp_ptr -> nx_ppp_lcp_state >= NX_PPP_LCP_START_STATE) &&
|
|
(ppp_ptr -> nx_ppp_lcp_state < NX_PPP_LCP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Update the PPP state machine. */
|
|
_nx_ppp_lcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_PAP
|
|
|
|
/* Determine if the PAP state machine needs updating. */
|
|
if ((ppp_ptr -> nx_ppp_pap_state >= NX_PPP_PAP_START_STATE) &&
|
|
(ppp_ptr -> nx_ppp_pap_state < NX_PPP_PAP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Update the PAP state machine. */
|
|
_nx_ppp_pap_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
#endif
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Determine if the CHAP state machine needs updating. */
|
|
if ((ppp_ptr -> nx_ppp_chap_state >= NX_PPP_CHAP_START_STATE) &&
|
|
(ppp_ptr -> nx_ppp_chap_state < NX_PPP_CHAP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Update the CHAP state machine. */
|
|
_nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
#endif
|
|
|
|
/* Determine if the IPCP state machine needs updating. */
|
|
if ((ppp_ptr -> nx_ppp_ipcp_state >= NX_PPP_IPCP_START_STATE) &&
|
|
(ppp_ptr -> nx_ppp_ipcp_state < NX_PPP_IPCP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Update the IPCP state machine. */
|
|
_nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_timer_entry PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes PPP time-outs, which sets a time-out event */
|
|
/* that wakes up the PPP processing thread. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Set timeout event flag */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* ThreadX */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_timer_entry(ULONG id)
|
|
{
|
|
|
|
NX_PPP *ppp_ptr;
|
|
|
|
|
|
/* Pickup the PPP pointer. */
|
|
ppp_ptr = (NX_PPP *) id;
|
|
|
|
/* Make sure the PPP pointer is good. */
|
|
if ((ppp_ptr != NX_NULL) && (ppp_ptr -> nx_ppp_id == NX_PPP_ID))
|
|
{
|
|
|
|
/* Set the timeout event for the PPP thread. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_TIMEOUT, TX_OR);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_netx_packet_transfer PORTABLE C */
|
|
/* 6.x */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function removes the PPP header and passes the packet to */
|
|
/* NetX. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ip_packet_deferred_receive Deferred IP packet receive */
|
|
/* _nx_ip_packet_receive IP packet receive */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process Receive packet processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), and */
|
|
/* verified memmove use cases, */
|
|
/* resulting in version 6.1 */
|
|
/* xx-xx-xxxx Wenhui Xie Modified comment(s), and */
|
|
/* supported processing */
|
|
/* compressed data, */
|
|
/* resulting in version 6.x */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_netx_packet_transfer(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
ULONG offset;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
/* Increment the number of IP frames received. */
|
|
ppp_ptr -> nx_ppp_ip_frames_received++;
|
|
#endif
|
|
|
|
/* Add the incoming interface pointer. */
|
|
packet_ptr -> nx_packet_ip_interface = ppp_ptr -> nx_ppp_interface_ptr;
|
|
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
|
|
/* Check whether the protocol field is 1 byte or 2 bytes. */
|
|
if (packet_ptr -> nx_packet_prepend_ptr[0] & NX_PPP_PROTOCOL_LSB_MARK)
|
|
{
|
|
|
|
/* Remove the PPP header [21] in the front of the IP packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 1;
|
|
|
|
/* Adjust the packet length. */
|
|
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 1;
|
|
|
|
}
|
|
else
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
{
|
|
|
|
/* Remove the PPP header [00,21] in the front of the IP packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
|
|
|
|
/* Adjust the packet length. */
|
|
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
|
|
}
|
|
|
|
/* Calculate the offset for four byte alignment. */
|
|
offset = (((ULONG)packet_ptr -> nx_packet_prepend_ptr) & 3);
|
|
|
|
/* Move the data to keep four byte alignment for first packet. */
|
|
if (offset)
|
|
{
|
|
memmove(packet_ptr -> nx_packet_prepend_ptr - offset, packet_ptr -> nx_packet_prepend_ptr, /* Use case of memmove is verified. */
|
|
(UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr));
|
|
packet_ptr -> nx_packet_prepend_ptr -= offset;
|
|
packet_ptr -> nx_packet_append_ptr -= offset;
|
|
}
|
|
|
|
/* Transfer the receive packet to NetX. */
|
|
#ifdef NX_DIRECT_ISR_CALL
|
|
_nx_ip_packet_receive(ppp_ptr -> nx_ppp_ip_ptr, packet_ptr);
|
|
#else
|
|
_nx_ip_packet_deferred_receive(ppp_ptr -> nx_ppp_ip_ptr, packet_ptr);
|
|
#endif
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_process_deferred_raw_string_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function takes all the raw string packets from the deferred raw*/
|
|
/* string packet queue and then sends them out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* (nx_ppp_byte_send) User's byte output routine */
|
|
/* nx_packet_release Release packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_thread_entry PPP processing thread */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_process_deferred_raw_string_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
NX_PACKET *packet_ptr;
|
|
ULONG i;
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
UINT release_packet;
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
|
|
/* Loop to process all queued packets. */
|
|
do
|
|
{
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the number of queued packets. */
|
|
if (ppp_ptr -> nx_ppp_raw_packet_queue_count)
|
|
{
|
|
|
|
/* Pickup the oldest packet. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_raw_packet_queue_head;
|
|
|
|
/* Update the head pointer to the next packet. */
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_head = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Decrement the number of queued packets. */
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_count--;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* No packet just set the packet pointer to NULL. */
|
|
packet_ptr = NX_NULL;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Is there a packet to process? */
|
|
if (packet_ptr == NX_NULL)
|
|
{
|
|
|
|
/* No, just get out of the loop! */
|
|
break;
|
|
}
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
release_packet = NX_TRUE;
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
if (ppp_ptr -> nx_ppp_byte_send)
|
|
{
|
|
|
|
/* Loop to send all the bytes of the packet out. */
|
|
for (i = 0; i < packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Send each byte out. */
|
|
(ppp_ptr -> nx_ppp_byte_send)(packet_ptr -> nx_packet_prepend_ptr[i]);
|
|
}
|
|
}
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
|
|
/* Check the PPPoE packet send function. */
|
|
if (ppp_ptr -> nx_ppp_packet_send)
|
|
{
|
|
|
|
/* Send the packet out. */
|
|
(ppp_ptr -> nx_ppp_packet_send)(packet_ptr);
|
|
|
|
/* Update the flag since this packet should been released in PPPoE. */
|
|
release_packet = NX_FALSE;
|
|
}
|
|
|
|
/* Check if need to release the packet. */
|
|
if (release_packet == NX_TRUE)
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
nx_packet_release(packet_ptr);
|
|
|
|
} while (1);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_process_deferred_ip_packet_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function takes all the packets from the deferred IP packet */
|
|
/* queue, packages them in an PPP frame, and then sends them out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_packet_transmit Send AHDLC packet */
|
|
/* nx_packet_transmit_release Release NetX packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_thread_entry PPP processing thread */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_process_deferred_ip_packet_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Loop to process all queued packets. */
|
|
do
|
|
{
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Pickup the number of queued packets. */
|
|
if (ppp_ptr -> nx_ppp_ip_packet_queue_count)
|
|
{
|
|
|
|
/* Pickup the oldest packet. */
|
|
packet_ptr = ppp_ptr -> nx_ppp_ip_packet_queue_head;
|
|
|
|
/* Update the head pointer to the next packet. */
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_head = packet_ptr -> nx_packet_queue_next;
|
|
|
|
/* Decrement the number of queued packets. */
|
|
ppp_ptr -> nx_ppp_ip_packet_queue_count--;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* No packet just set the packet pointer to NULL. */
|
|
packet_ptr = NX_NULL;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Is there a packet to process? */
|
|
if (packet_ptr == NX_NULL)
|
|
{
|
|
|
|
/* No, just get out of the loop! */
|
|
break;
|
|
}
|
|
|
|
/* Determine if there is room in the front of the packet for the PPP header. */
|
|
if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < 2)
|
|
{
|
|
|
|
/* Error, there is no room at the front of the packet to prepend the PPP header. */
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* Release the NetX packet. */
|
|
nx_packet_transmit_release(packet_ptr);
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Otherwise, backup the prepend pointer. */
|
|
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - 2;
|
|
|
|
/* Place the PPP header in the packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_DATA & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_DATA & 0xFF;
|
|
|
|
/* Adjust the length of the packet. */
|
|
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + 2;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IP frames sent. */
|
|
ppp_ptr -> nx_ppp_ip_frames_sent++;
|
|
#endif
|
|
|
|
/* Send the packet! */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
} while (1);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update PORTABLE C */
|
|
/* 6.1.8 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes LCP messages and updates the LCP state */
|
|
/* machine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to LCP packet. If the */
|
|
/* packet is NULL, a timeout is*/
|
|
/* present */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_lcp_code_reject Reject received code */
|
|
/* _nx_ppp_lcp_configuration_retrieve Retrieve configuration info */
|
|
/* _nx_ppp_lcp_configure_reply_send Send configure reply */
|
|
/* _nx_ppp_lcp_configure_request_send Send configure request */
|
|
/* _nx_ppp_lcp_nak_configure_list Get options naked */
|
|
/* _nx_ppp_lcp_terminate_ack_send Send terminate ack */
|
|
/* _nx_ppp_lcp_terminate_request_send Send terminate request */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process Receive packet processing */
|
|
/* _nx_ppp_timeout PPP timeout */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* improved packet length */
|
|
/* verification, */
|
|
/* resulting in version 6.1.2 */
|
|
/* 08-02-2021 Yuxin Zhou Modified comment(s), fixed */
|
|
/* the logic of retransmission,*/
|
|
/* resulting in version 6.1.8 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT configure_status;
|
|
UCHAR *lcp_message_ptr;
|
|
UCHAR code;
|
|
UINT status;
|
|
|
|
/* Determine if a packet is present. If so, derive the event from the packet. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames received. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_received++;
|
|
#endif
|
|
|
|
/* Setup a pointer to the LCP pointer. */
|
|
lcp_message_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Pickup the type of received LCP code. */
|
|
code = packet_ptr -> nx_packet_prepend_ptr[2];
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Count the number of specific LCP requests. */
|
|
switch (code)
|
|
{
|
|
|
|
case NX_PPP_LCP_CONFIGURE_REQUEST:
|
|
|
|
/* Increment the number of LCP configure requests received. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_CONFIGURE_ACK:
|
|
|
|
/* Increment the number of LCP configure ACKs received. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_acks_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_CONFIGURE_NAK:
|
|
|
|
/* Increment the number of LCP configure NAKs received. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_naks_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_CONFIGURE_REJECT:
|
|
|
|
/* Increment the number of LCP configure rejects received. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_rejects_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_TERMINATE_REQUEST:
|
|
|
|
/* Increment the number of LCP terminate requests received. */
|
|
ppp_ptr -> nx_ppp_lcp_terminate_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_TERMINATE_ACK:
|
|
|
|
/* Increment the number of LCP terminate ACKs received. */
|
|
ppp_ptr -> nx_ppp_lcp_terminate_acks_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_CODE_REJECT:
|
|
|
|
/* Increment the number of LCP code rejects received. */
|
|
ppp_ptr -> nx_ppp_lcp_code_rejects_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_PROTOCOL_REJECT:
|
|
|
|
/* Increment the number of LCP protocol rejects received. */
|
|
ppp_ptr -> nx_ppp_lcp_protocol_rejects_received++;
|
|
break;
|
|
|
|
case NX_PPP_LCP_ECHO_REQUEST:
|
|
|
|
/* Increment the number of LCP echo requests received. */
|
|
ppp_ptr -> nx_ppp_lcp_echo_requests_received++;
|
|
|
|
break;
|
|
|
|
case NX_PPP_LCP_ECHO_REPLY:
|
|
|
|
/* Increment the number of LCP echo replies received. */
|
|
break;
|
|
|
|
case NX_PPP_LCP_DISCARD_REQUEST:
|
|
|
|
/* Increment the number of LCP discard requests received. */
|
|
ppp_ptr -> nx_ppp_lcp_discard_requests_received++;
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Increment the number of LCP unknown (unhandled) requests received. */
|
|
ppp_ptr -> nx_ppp_lcp_unknown_requests_received++;
|
|
}
|
|
#endif
|
|
|
|
/* Remember receive id. */
|
|
ppp_ptr -> nx_ppp_receive_id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Is the code supported by PPP? */
|
|
if ((code < NX_PPP_LCP_CONFIGURE_REQUEST) ||
|
|
(code > NX_PPP_LCP_DISCARD_REQUEST))
|
|
{
|
|
|
|
/* No, this code is not supported. Reject the code. */
|
|
_nx_ppp_lcp_code_reject(ppp_ptr, lcp_message_ptr);
|
|
|
|
/* Return. */
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the LCP pointer to NULL. */
|
|
lcp_message_ptr = NX_NULL;
|
|
|
|
/* Set the code to timeout to indicate a timeout has occurred. */
|
|
code = NX_PPP_LCP_TIMEOUT;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Determine if we are in the initial state. If so, this really isn't a timeout. */
|
|
if (ppp_ptr -> nx_ppp_lcp_state != NX_PPP_LCP_START_STATE)
|
|
{
|
|
|
|
/* Increment the LCP timeout counter. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_timeouts++;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Process relative to the current state. */
|
|
switch (ppp_ptr -> nx_ppp_lcp_state)
|
|
{
|
|
|
|
case NX_PPP_LCP_START_STATE:
|
|
{
|
|
|
|
/* Initial LCP state. */
|
|
|
|
/* Initialize the NAK and rejected lists. */
|
|
#ifndef NX_PPP_DNS_OPTION_DISABLE
|
|
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 0;
|
|
#else
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 1;
|
|
#endif
|
|
ppp_ptr -> nx_ppp_peer_naked_list[0] = 0;
|
|
ppp_ptr -> nx_ppp_rejected_list[0] = 0;
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send configuration request to peer. */
|
|
_nx_ppp_lcp_configure_request_send(ppp_ptr);
|
|
|
|
/* Move to the next state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE;
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE:
|
|
{
|
|
|
|
/* In this state, we have sent a configuration request but had not received an ACK
|
|
or a configuration request from the peer. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if (code == NX_PPP_LCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* The peer has ACKed our configuration request. Move to the
|
|
configure request ACKed state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE;
|
|
|
|
/* Turn off the timeout for the configuration request. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
else if (code == NX_PPP_LCP_CONFIGURE_NAK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Figure out what options were naked. */
|
|
_nx_ppp_lcp_nak_configure_list(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
|
|
/* Send new configure request. */
|
|
_nx_ppp_lcp_configure_request_send(ppp_ptr);
|
|
}
|
|
|
|
else if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Retrieve configuration. */
|
|
status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
|
|
|
|
/* Discard invalid packet. */
|
|
if (status)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Determine if the configuration request is fine or needs to be negotiated further. */
|
|
if (configure_status == 0)
|
|
{
|
|
|
|
/* The peer's request is acceptable, move into peer configuration request ACKed state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE;
|
|
}
|
|
|
|
/* Send configuration reply. */
|
|
_nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
|
|
}
|
|
else if (code == NX_PPP_LCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the LCP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Timeout, send configuration request again. */
|
|
_nx_ppp_lcp_configure_request_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter LCP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE:
|
|
{
|
|
|
|
/* In this state, we have received the ACK for our configuration request, but have not yet
|
|
received a configuration request from the peer. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Retrieve configuration. */
|
|
status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
|
|
|
|
/* Discard invalid packet. */
|
|
if (status)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Determine if the configuration request is fine or needs to be negotiated further. */
|
|
if (configure_status == 0)
|
|
{
|
|
|
|
/* The peer's request is acceptable, move into the LCP done state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_COMPLETED_STATE;
|
|
|
|
/* Determine if we need to update the IP's MTU. */
|
|
if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
|
|
{
|
|
|
|
/* Yes, the peer can accept larger messages than the default. */
|
|
(ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size = ppp_ptr -> nx_ppp_mru;
|
|
}
|
|
|
|
/* Disable the LCP timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
/* Send configuration reply. */
|
|
_nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE:
|
|
{
|
|
|
|
/* In this state, we have sent our configuration request, but haven't received an ACK. We have also received
|
|
a peer configuration request and have ACKed that request. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if (code == NX_PPP_LCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* The peer has ACKed our configuration request. Move to the
|
|
LCP completed state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_COMPLETED_STATE;
|
|
|
|
/* Determine if we need to update the IP's MTU. */
|
|
if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
|
|
{
|
|
|
|
/* Yes, the peer can accept larger messages than the default. */
|
|
(ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size = ppp_ptr -> nx_ppp_mru;
|
|
}
|
|
|
|
/* Turn off the timeout for the configuration request. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
else if (code == NX_PPP_LCP_CONFIGURE_NAK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Figure out what options were naked. */
|
|
_nx_ppp_lcp_nak_configure_list(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
|
|
/* Send new configure request. */
|
|
_nx_ppp_lcp_configure_request_send(ppp_ptr);
|
|
}
|
|
|
|
else if (code == NX_PPP_LCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the LCP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Timeout, send configuration request again. */
|
|
_nx_ppp_lcp_configure_request_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter LCP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_COMPLETED_STATE:
|
|
{
|
|
|
|
/* PPP is up and operational at this point. */
|
|
|
|
/* Process relative to incoming code. */
|
|
if (code == NX_PPP_LCP_TERMINATE_REQUEST)
|
|
{
|
|
|
|
/* ACK the terminate request. */
|
|
_nx_ppp_lcp_terminate_ack_send(ppp_ptr);
|
|
|
|
/* Move to stopped state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_STOPPED_STATE;
|
|
|
|
/* Set the event to stop the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
else if ((code == NX_PPP_LCP_ECHO_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Respond to the echo request. */
|
|
_nx_ppp_lcp_ping_reply(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
else if ((code == NX_PPP_LCP_ECHO_REPLY) && (packet_ptr))
|
|
{
|
|
|
|
/* Check if the PPP instance is waiting on an echo reply. */
|
|
if (ppp_ptr -> nx_ppp_lcp_echo_reply_id)
|
|
{
|
|
|
|
/* It is. Check if this is a valid reply. */
|
|
_nx_ppp_lcp_ping_process_echo_reply(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
/* In this state, we have received the ACK for our configuration request/completed LCP, but are expecting
|
|
a configuration request from the peer. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
else if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Retrieve configuration. */
|
|
status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
|
|
|
|
/* Discard invalid packet. */
|
|
if (status)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Determine if the configuration request is fine or needs to be negotiated further. */
|
|
if (configure_status == 0)
|
|
{
|
|
|
|
|
|
/* The peer's request is acceptable, move into the LCP done state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_COMPLETED_STATE;
|
|
|
|
/* Determine if we need to update the IP's MTU. */
|
|
if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
|
|
{
|
|
|
|
/* Yes, the peer can accept larger messages than the default. */
|
|
(ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size = ppp_ptr -> nx_ppp_mru;
|
|
}
|
|
}
|
|
|
|
/* Send configuration reply. */
|
|
_nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_STOPPING_STATE:
|
|
{
|
|
|
|
/* We received a terminate request from the other side and just need to get the ACK. */
|
|
|
|
/* Process relative to incoming code. */
|
|
if (code == NX_PPP_LCP_TERMINATE_ACK)
|
|
{
|
|
|
|
/* Move to stopped state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_STOPPED_STATE;
|
|
|
|
/* Set the event to stop the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
else if (code == NX_PPP_LCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the LCP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send terminate request. */
|
|
_nx_ppp_lcp_terminate_request_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter LCP failed state. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_FAILED_STATE;
|
|
|
|
/* Set the event to stop the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
if (code == NX_PPP_LCP_ECHO_REQUEST)
|
|
{
|
|
|
|
|
|
ppp_ptr -> nx_ppp_lcp_echo_requests_dropped++;
|
|
}
|
|
#endif
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_code_reject PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a code reject message and sends it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* lcp_ptr Pointer to LCP message */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send PPP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_code_reject(NX_PPP *ppp_ptr, UCHAR *lcp_ptr)
|
|
{
|
|
|
|
UINT i;
|
|
UINT status;
|
|
UINT length;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return. */
|
|
return;
|
|
}
|
|
|
|
/* Build the configuration request. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_CODE_REJECT;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = lcp_ptr[4];
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = lcp_ptr[5];
|
|
|
|
length = (((UINT) lcp_ptr[4]) << 8) | ((UINT) lcp_ptr[5]);
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (length + 2))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Send the options that were received with RCR. */
|
|
for(i = 0; i < (length - 4); i++)
|
|
{
|
|
|
|
/* Copy option byte into new packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6+i] = lcp_ptr[6+i];
|
|
}
|
|
|
|
/* Setup the packet length and append pointer. */
|
|
packet_ptr -> nx_packet_length = length + 2;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
|
|
/* Increment code rejects sent counter. */
|
|
ppp_ptr -> nx_ppp_lcp_code_rejects_sent++;
|
|
#endif
|
|
|
|
/* Send code reject message. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_configure_reply_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends a configuration reply. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* configure_status Status from configure request */
|
|
/* lcp_ptr Pointer to LCP message */
|
|
/* naked_list List of NAKed options */
|
|
/* rejected_list List of rejected options */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send PPP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_configure_reply_send(NX_PPP *ppp_ptr, UINT configure_status, UCHAR *lcp_ptr, UCHAR *naked_list, UCHAR *rejected_list)
|
|
{
|
|
|
|
UINT i;
|
|
UINT status;
|
|
UINT length;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build the configuration reply. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
|
|
/* Process relative to the supplied status. */
|
|
if (configure_status == 0)
|
|
{
|
|
/* Send ACK. */
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_CONFIGURE_ACK;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP ACKs sent. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_acks_sent++;
|
|
#endif
|
|
}
|
|
else if (configure_status & 2)
|
|
{
|
|
/* Send reject. */
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_CONFIGURE_REJECT;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP rejects sent. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_rejects_sent++;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/* Send NAK. */
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_CONFIGURE_NAK;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP NAKs sent. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_naks_sent++;
|
|
#endif
|
|
}
|
|
|
|
/* Insert the id. */
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
|
|
/* Process again according to the status. */
|
|
if (configure_status == 0)
|
|
{
|
|
|
|
/* Setup the options list. */
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = lcp_ptr[4];
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = lcp_ptr[5];
|
|
|
|
length = (((UINT) lcp_ptr[4]) << 8) | ((UINT) lcp_ptr[5]);
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (length + 2))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Send the options that were received with the request. */
|
|
for(i = 0; i < (length - 4); i++)
|
|
{
|
|
|
|
/* Copy option byte into new packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6+i] = lcp_ptr[6+i];
|
|
}
|
|
|
|
/* Setup the packet length and append pointer. */
|
|
packet_ptr -> nx_packet_length = length + 2;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
}
|
|
else if (configure_status & 2)
|
|
{
|
|
|
|
/* Rejected options. */
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(rejected_list[0] + 4);
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(rejected_list[0] + 6))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Load entire rejected list. */
|
|
for(i = 1; i < (UCHAR)(rejected_list[0] + 1); i++)
|
|
{
|
|
/* Copy option byte into new packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6+i-1] = rejected_list[i];
|
|
}
|
|
|
|
/* Setup the packet length and append pointer. */
|
|
packet_ptr -> nx_packet_length = (ULONG)(rejected_list[0] + 6);
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* NAKed options. */
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(naked_list[0] + 4);
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(naked_list[0] + 6))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Load entire naked list. */
|
|
for(i = 1; i < (UCHAR)(naked_list[0] + 1); i++)
|
|
{
|
|
/* Copy option byte into new packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6+i-1] = naked_list[i];
|
|
}
|
|
|
|
/* Setup the packet length and append pointer. */
|
|
packet_ptr -> nx_packet_length = (ULONG)(naked_list[0] + 6);
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
#endif
|
|
|
|
/* Send the reply out. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_configure_request_send PORTABLE C */
|
|
/* 6.x */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends a LCP configuration request. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate PPP packet */
|
|
/* _nx_ppp_packet_transmit Send LCP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* xx-xx-xxxx Wenhui Xie Modified comment(s), and */
|
|
/* supported processing */
|
|
/* compressed data, */
|
|
/* resulting in version 6.x */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_configure_request_send(NX_PPP *ppp_ptr)
|
|
{
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
UINT index = 0;
|
|
UINT length_index = 0;
|
|
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Increment the transmit ID. */
|
|
ppp_ptr -> nx_ppp_transmit_id++;
|
|
|
|
/* Build the configuration request. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = NX_PPP_LCP_CONFIGURE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = ppp_ptr -> nx_ppp_transmit_id;
|
|
|
|
/* Store the index of length field and skip the length field. */
|
|
length_index = index;
|
|
index += 2;
|
|
|
|
/* Load the MRU. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 1;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 4;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = (UCHAR) ((NX_PPP_MRU) >> 8);
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = (UCHAR) ((NX_PPP_MRU) & 0xff);
|
|
|
|
/* Load the authentication protocol type. */
|
|
if ((ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_PAP_PROTOCOL) && (ppp_ptr -> nx_ppp_pap_verify_login))
|
|
{
|
|
|
|
/* Set the PAP authentication protocol. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 3;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 4;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = NX_PPP_PAP_PROTOCOL & 0xFF;
|
|
}
|
|
else if ((ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_CHAP_PROTOCOL) &&
|
|
(ppp_ptr -> nx_ppp_chap_get_challenge_values) && (ppp_ptr -> nx_ppp_chap_get_verification_values))
|
|
{
|
|
|
|
/* Set the CHAP authentication protocol. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 3;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 5;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 0x05;
|
|
}
|
|
|
|
#ifdef NX_PPP_COMPRESSION_ENABLE
|
|
|
|
/* Add PFC and ACFC options. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 7;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 2;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[index++] = 2;
|
|
#endif /* NX_PPP_COMPRESSION_ENABLE */
|
|
|
|
/* Update the length field. */
|
|
packet_ptr -> nx_packet_prepend_ptr[length_index] = (UCHAR)((index - 2) >> 8);
|
|
packet_ptr -> nx_packet_prepend_ptr[length_index + 1] = (UCHAR)((index - 2) & 0xff);
|
|
|
|
/* Setup the append pointer and the packet length (LCP length + PPP header). */
|
|
packet_ptr -> nx_packet_length = (ULONG)(index);
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
|
|
/* Increment the number of LCP configure requests sent. */
|
|
ppp_ptr -> nx_ppp_lcp_configure_requests_sent++;
|
|
#endif
|
|
|
|
/* Send the configure request packet. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_configuration_retrieve PORTABLE C */
|
|
/* 6.1.2 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function pickup the configuration options. Unhandled options */
|
|
/* are placed in NAKed or Rejected lists. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* naked_list List of NAKed options */
|
|
/* rejected_list List of rejected options */
|
|
/* configure_status Returned configration status: */
|
|
/* 0 -> Success */
|
|
/* 1 -> NAKed options */
|
|
/* 2 -> Rejected options */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* improved packet length */
|
|
/* verification, */
|
|
/* resulting in version 6.1.2 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_lcp_configuration_retrieve(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr, UCHAR *naked_list, UCHAR *rejected_list, UINT *configure_status)
|
|
{
|
|
|
|
UINT option_index, nak_list_index, rejected_list_index;
|
|
UINT len;
|
|
UINT type;
|
|
UINT counter;
|
|
ULONG authentication_protocol;
|
|
UCHAR *option_data;
|
|
|
|
|
|
/* Initialize the configure status. */
|
|
*configure_status = 0;
|
|
|
|
/* Clear both the NAKed and rejected list length. */
|
|
naked_list[0] = 0;
|
|
rejected_list[0] = 0;
|
|
|
|
/* Start indexes at 1, since byte 0 contains length. */
|
|
nak_list_index = 1;
|
|
rejected_list_index = 1;
|
|
|
|
/* Process the options in the LCP message. */
|
|
for (option_index = 6; (option_index + 2) <= packet_ptr -> nx_packet_length; )
|
|
{
|
|
|
|
/* Pickup the option type - section 6 of RFC1661. */
|
|
type = packet_ptr -> nx_packet_prepend_ptr[option_index++];
|
|
|
|
/* Get the length of the option. The length also includes the type and length fields. */
|
|
len = packet_ptr -> nx_packet_prepend_ptr[option_index++];
|
|
|
|
/* Check if the length is valid. */
|
|
if ((len < 2) || (len > (packet_ptr -> nx_packet_length - (option_index - 2))))
|
|
{
|
|
return(NX_PPP_BAD_PACKET);
|
|
}
|
|
|
|
/* Set a pointer to option data. */
|
|
option_data = &packet_ptr -> nx_packet_prepend_ptr[option_index];
|
|
|
|
/* Advance the index to next option. */
|
|
option_index += len - 2;
|
|
|
|
/* Process relative to the option type. */
|
|
switch (type)
|
|
{
|
|
|
|
case 1:
|
|
|
|
/* Maximum Receive Unit (MRU) option. */
|
|
ppp_ptr -> nx_ppp_mru = (ULONG)((((USHORT) option_data[0]) << 8) | ((USHORT) option_data[1]));
|
|
|
|
/* Determine if the MRU is too small. */
|
|
if (ppp_ptr -> nx_ppp_mru < NX_PPP_MINIMUM_MRU)
|
|
{
|
|
*configure_status |= 1;
|
|
|
|
/* Default the MRU. */
|
|
ppp_ptr -> nx_ppp_mru = NX_PPP_MRU;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((nak_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* Yes, enter it in the NAK list. */
|
|
naked_list[nak_list_index++] = (UCHAR)type;
|
|
naked_list[nak_list_index++] = (UCHAR)len;
|
|
for (counter = 0; counter < (len-2); counter++)
|
|
naked_list[nak_list_index++] = option_data[counter];
|
|
naked_list[0] = (UCHAR)(nak_list_index - 1);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
|
|
/* Authentication protocol selection. */
|
|
|
|
/* Pickup the authentication protocol. */
|
|
authentication_protocol = (((UINT) option_data[0]) << 8) | ((UINT) option_data[1]);
|
|
|
|
/* Determine if the authentication protocol specified by the peer is PAP and we have a generate
|
|
routine defined. */
|
|
if ((authentication_protocol == NX_PPP_PAP_PROTOCOL) && (ppp_ptr -> nx_ppp_pap_generate_login))
|
|
{
|
|
|
|
/* Yes, enable the PAP protocol. */
|
|
ppp_ptr -> nx_ppp_generate_authentication_protocol = NX_PPP_PAP_PROTOCOL;
|
|
}
|
|
|
|
/* Determine if the authentication protocol specified by the peer is CHAP and we have a generate
|
|
response routine defined. */
|
|
if ((authentication_protocol == NX_PPP_CHAP_PROTOCOL) && (ppp_ptr -> nx_ppp_chap_get_responder_values))
|
|
{
|
|
|
|
/* Yes, enable the CHAP protocol. */
|
|
ppp_ptr -> nx_ppp_generate_authentication_protocol = NX_PPP_CHAP_PROTOCOL;
|
|
}
|
|
|
|
/* Determine if the required authentication at the peer is the same as what this peer can generate
|
|
login information for. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol != authentication_protocol)
|
|
{
|
|
|
|
/* We do not support the requested authentication by the peer. */
|
|
|
|
/* Check to see if we don't have any authentication protocols enabled. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol == 0)
|
|
{
|
|
*configure_status |= 2;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((rejected_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* No authentication is supported, simply include requested authentication
|
|
option in the rejected list. */
|
|
rejected_list[rejected_list_index++] = (UCHAR)type;
|
|
rejected_list[rejected_list_index++] = (UCHAR)len;
|
|
for (counter = 0; counter < (len-2); counter++)
|
|
rejected_list[rejected_list_index++] = option_data[counter];
|
|
rejected_list[0] = (UCHAR)(rejected_list_index - 1);
|
|
}
|
|
|
|
/* Determine if this peer has PAP enabled. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_PAP_PROTOCOL)
|
|
{
|
|
*configure_status |= 1;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((nak_list_index + 4) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* PAP enabled but something different is requested by the peer, build NAK entry with PAP hint. */
|
|
naked_list[nak_list_index++] = 3;
|
|
naked_list[nak_list_index++] = NX_PPP_PAP_AUTHENTICATE_NAK;
|
|
naked_list[nak_list_index++] = (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
|
|
naked_list[nak_list_index++] = NX_PPP_PAP_PROTOCOL & 0xFF;
|
|
naked_list[0] = (UCHAR)(nak_list_index - 1);
|
|
|
|
/* Clear authentication protocol. */
|
|
ppp_ptr -> nx_ppp_verify_authentication_protocol = 0;
|
|
}
|
|
|
|
/* Determine if this peer has CHAP enabled. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL)
|
|
{
|
|
*configure_status |= 1;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((nak_list_index + 5) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* CHAP enabled but something different is requested by the peer, build NAK entry with CHAP hint. */
|
|
naked_list[nak_list_index++] = 3;
|
|
naked_list[nak_list_index++] = 5;
|
|
naked_list[nak_list_index++] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
naked_list[nak_list_index++] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
naked_list[nak_list_index++] = 0x05;
|
|
naked_list[0] = (UCHAR)(nak_list_index - 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Matching authentication protocol. */
|
|
|
|
/* Check to see if we have the CHAP authentication protocol enabled. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL)
|
|
{
|
|
|
|
/* Now determine if something other than CHAP MD5 was requested. */
|
|
if (option_data[2] != 0x05)
|
|
{
|
|
*configure_status |= 1;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((nak_list_index + 5) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* CHAP enabled but something different is requested by the peer, build NAK entry with CHAP hint. */
|
|
naked_list[nak_list_index++] = 3;
|
|
naked_list[nak_list_index++] = 5;
|
|
naked_list[nak_list_index++] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
naked_list[nak_list_index++] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
naked_list[nak_list_index++] = 0x05;
|
|
naked_list[0] = (UCHAR)(nak_list_index - 1);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Clear the authenticated flag since peer requires CHAP authentication. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Clear the authenticated flag since peer requires PAP authentication. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2: /* ACCM, Not implemented. */
|
|
case 5: /* Magic number - just acknowledge, we do not send out magic number. */
|
|
case 7: /* The sender can receive protocol compression. */
|
|
case 8: /* The sender can receive address compression. */
|
|
|
|
/* Skip these options, since we don't care to object. */
|
|
break;
|
|
|
|
default:
|
|
|
|
*configure_status |= 2;
|
|
|
|
/* Check if out of boundary. */
|
|
if ((rejected_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
break;
|
|
|
|
/* All other options we must reject since we do not negotiate. */
|
|
rejected_list[rejected_list_index++] = (UCHAR)type;
|
|
rejected_list[rejected_list_index++] = (UCHAR)len;
|
|
for (counter = 0; counter < (len-2); counter++)
|
|
rejected_list[rejected_list_index++] = option_data[counter];
|
|
rejected_list[0] = (UCHAR)(rejected_list_index - 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Check if packet length is valid. */
|
|
if (option_index != packet_ptr -> nx_packet_length)
|
|
{
|
|
return(NX_PPP_BAD_PACKET);
|
|
}
|
|
|
|
/* Return status. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_nak_configure_list PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes the NAKed option list. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* naked_list List of NAKed options */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_nak_configure_list(NX_PPP *ppp_ptr, UCHAR *naked_list)
|
|
{
|
|
|
|
UINT i;
|
|
|
|
NX_PARAMETER_NOT_USED(ppp_ptr);
|
|
|
|
/* Currently, nothing needs to be done in this routine since the options
|
|
we are asking for are basic and must be supported. If additional options
|
|
are added, we will need to process the NAK list. */
|
|
|
|
/* Just clear the naked list for now. */
|
|
for(i = 0; i < NX_PPP_OPTION_MESSAGE_LENGTH; i++)
|
|
naked_list[i] = 0;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_terminate_ack_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a terminate ACK LCP message and sends it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send AHDLC packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_terminate_ack_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build terminate ACK LCP message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_TERMINATE_ACK;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 4;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 6;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
|
|
/* Increment the number of LCP terminate ACKs sent. */
|
|
ppp_ptr -> nx_ppp_lcp_terminate_acks_sent++;
|
|
#endif
|
|
|
|
/* Send the packet out. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_terminate_request_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a LCP terminate message and sends it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send PPP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update LCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_terminate_request_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build terminate request message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_TERMINATE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_transmit_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 4;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 6;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
|
|
/* Increment the number of LCP terminate requests sent. */
|
|
ppp_ptr -> nx_ppp_lcp_terminate_requests_sent++;
|
|
#endif
|
|
|
|
/* Send terminate request. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_PAP
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_state_machine_update PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes events and state changes in the PPP PAP */
|
|
/* state machine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to PAP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_pap_login_valid Check for valid peer login */
|
|
/* _nx_ppp_pap_authentication_request Send authentication request */
|
|
/* _nx_ppp_pap_authentication_ack Send authentication ACK */
|
|
/* _nx_ppp_pap_authentication_nak Send authentication NAK */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process Receive PPP packet processing */
|
|
/* _nx_ppp_timeout PPP timeout */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_pap_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UCHAR code;
|
|
UINT valid;
|
|
|
|
|
|
/* Determine if a packet is present. If so, drive the event from the packet. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of PAP frames received. */
|
|
ppp_ptr -> nx_ppp_pap_frames_received++;
|
|
#endif
|
|
|
|
/* Pickup the type of received PAP code. */
|
|
code = packet_ptr -> nx_packet_prepend_ptr[2];
|
|
|
|
/* Remember receive id. */
|
|
ppp_ptr -> nx_ppp_receive_id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Check the incoming code. */
|
|
if ((code < NX_PPP_PAP_AUTHENTICATE_REQUEST) || (code > NX_PPP_PAP_AUTHENTICATE_NAK))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
|
|
/* Increment the PAP unknown requests counter. */
|
|
ppp_ptr -> nx_ppp_pap_unknown_requests_received++;
|
|
#endif
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the code to timeout. */
|
|
code = NX_PPP_PAP_AUTHENTICATE_TIMEOUT;
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the appropriate counter. */
|
|
switch (code)
|
|
{
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_REQUEST:
|
|
|
|
/* Increment the authenticate requests counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_ACK:
|
|
|
|
/* Increment the authenticate acks counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_acks_received++;
|
|
break;
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_NAK:
|
|
|
|
/* Increment the authenticate naks counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_naks_received++;
|
|
break;
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_TIMEOUT:
|
|
|
|
/* Determine if we are in the initial state. If so, this really isn't a timeout. */
|
|
if (ppp_ptr -> nx_ppp_pap_state != NX_PPP_PAP_START_STATE)
|
|
{
|
|
|
|
/* Increment the authenticate timeout counter. */
|
|
ppp_ptr -> nx_ppp_pap_state_machine_timeouts++;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
/* Process relative to the current state. */
|
|
switch (ppp_ptr -> nx_ppp_pap_state)
|
|
{
|
|
|
|
/* Starting state. */
|
|
case NX_PPP_PAP_START_STATE:
|
|
{
|
|
|
|
/* Determine if we need to generate a login for the peer to verify. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
|
|
{
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Generate PAP login request and send to the peer. */
|
|
_nx_ppp_pap_authentication_request(ppp_ptr);
|
|
|
|
/* Move to the authenticate request sent state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_AUTHENTICATE_REQUEST_SENT_STATE;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Move to the authenticate wait state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_REQUEST_SENT_STATE:
|
|
{
|
|
|
|
/* In this state, this peer has sent an authentication request and is waiting for
|
|
an ACK or NAK from the peer. */
|
|
if ((code == NX_PPP_PAP_AUTHENTICATE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the login information is valid. */
|
|
valid = _nx_ppp_pap_login_valid(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_TRUE)
|
|
{
|
|
|
|
/* Send an ACK message. */
|
|
_nx_ppp_pap_authentication_ack(ppp_ptr);
|
|
|
|
/* Now determine if we need to authenticate ourselves. */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol != NX_PPP_PAP_PROTOCOL)
|
|
{
|
|
|
|
/* We do not need to authenticate ourselves, so we can move into PAP completed state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Send NAK to tell peer the authentication failed. */
|
|
_nx_ppp_pap_authentication_nak(ppp_ptr);
|
|
|
|
/* No state change, just stay here! */
|
|
}
|
|
}
|
|
|
|
/* Was a NAK received? */
|
|
else if (code == NX_PPP_PAP_AUTHENTICATE_NAK)
|
|
{
|
|
|
|
/* Determine if there is an application NAK callback. */
|
|
if (ppp_ptr -> nx_ppp_nak_authentication_notify)
|
|
{
|
|
|
|
/* Yes, call the application's authentication NAK notify callback function. */
|
|
(ppp_ptr -> nx_ppp_nak_authentication_notify)();
|
|
}
|
|
|
|
/* Generate a new PAP login request and send to the peer. */
|
|
_nx_ppp_pap_authentication_request(ppp_ptr);
|
|
}
|
|
|
|
/* Was an ACK received? */
|
|
else if (code == NX_PPP_PAP_AUTHENTICATE_ACK)
|
|
{
|
|
|
|
/* Determine if this peer requires authentication. */
|
|
if (ppp_ptr -> nx_ppp_pap_verify_login)
|
|
{
|
|
|
|
/* Yes, we require PAP verification so move to the request wait state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Otherwise, we have completed the PAP authentication. Move to the completed
|
|
state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
}
|
|
|
|
/* Was a timeout received? */
|
|
else if (code == NX_PPP_PAP_AUTHENTICATE_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the PAP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_PAP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Generate a new PAP login request and send to the peer. */
|
|
_nx_ppp_pap_authentication_request(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter PAP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE:
|
|
{
|
|
|
|
/* In this state, this peer must send an authenticate request. There is no
|
|
authentication required by the peer. */
|
|
if ((code == NX_PPP_PAP_AUTHENTICATE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the login information is valid. */
|
|
valid = _nx_ppp_pap_login_valid(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_TRUE)
|
|
{
|
|
|
|
/* Send an ACK message. */
|
|
_nx_ppp_pap_authentication_ack(ppp_ptr);
|
|
|
|
/* No authentication is required by peer, so we can move into PAP completed state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Send NAK to tell peer the authentication failed. */
|
|
_nx_ppp_pap_authentication_nak(ppp_ptr);
|
|
|
|
/* No state change, just stay here! */
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
default:
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_authentication_request PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends an authentication request message */
|
|
/* the peer. The peer will then either ACK or NAK the request. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* (nx_ppp_pap_generate_login) Pickup name and password */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* _nx_utility_string_length_check Check string length */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_pap_state_machine_update PPP state machine update */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_pap_authentication_request(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT length, password_length, i, j;
|
|
UCHAR name[NX_PPP_NAME_SIZE + 1];
|
|
UCHAR password[NX_PPP_PASSWORD_SIZE + 1];
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Initialize name and password. */
|
|
name[0] = 0;
|
|
password[0] = 0;
|
|
|
|
/* Determine if there is a login name/password generation routine. */
|
|
if (ppp_ptr -> nx_ppp_pap_generate_login)
|
|
{
|
|
|
|
/* Get the name and password */
|
|
ppp_ptr -> nx_ppp_pap_generate_login((CHAR *) name, (CHAR *) password);
|
|
}
|
|
|
|
/* Allocate a packet for the PPP PAP response packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Calculate the size of the name and password. */
|
|
if (_nx_utility_string_length_check((CHAR *)name, &length, NX_PPP_NAME_SIZE) ||
|
|
_nx_utility_string_length_check((CHAR *)password, &password_length, NX_PPP_PASSWORD_SIZE))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 1 + password_length + 1 + 6))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Set PAP authentication request, ID, and length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_PAP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_PAP_AUTHENTICATE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_transmit_id; /* ID */
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR) (((length) + 1 + (password_length) + 1 + 4) >> 8);
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR) (((length) + 1 + (password_length) + 1 + 4) & 0xFF);
|
|
|
|
/* Store the PAP name. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = (UCHAR)(length & 0xFF);
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Store byte of name. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+7] = name[i];
|
|
}
|
|
|
|
/* Store PAP password. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+7] = (password_length & 0xFF);
|
|
for (j = 0; j < password_length; j++)
|
|
{
|
|
|
|
/* Store byte of name. */
|
|
packet_ptr -> nx_packet_prepend_ptr[j+i+8] = password[j];
|
|
}
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = (length) + 1 + (password_length) + 1 + 4 + 2;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of PAP frames sent. */
|
|
ppp_ptr -> nx_ppp_pap_frames_sent++;
|
|
|
|
/* Increment the authentication requests sent counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_requests_sent++;
|
|
#endif
|
|
|
|
/* Send the PAP request. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_login_valid PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function validates the login information supplied by the */
|
|
/* peer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to PAP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* NX_TRUE Valid login */
|
|
/* NX_FALSE Invalid login */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* (nx_ppp_pap_verify_login) Verify name and password */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_pap_state_machine_update PAP state machine update */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_pap_login_valid(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UCHAR length, password_length, i, j;
|
|
UCHAR name[NX_PPP_NAME_SIZE + 1];
|
|
UCHAR password[NX_PPP_PASSWORD_SIZE + 1];
|
|
UINT status;
|
|
|
|
|
|
/* Get the name length. */
|
|
length = packet_ptr -> nx_packet_prepend_ptr[6];
|
|
|
|
/* Check for valid packet length. */
|
|
if ((ULONG)(length + 7) > packet_ptr -> nx_packet_length)
|
|
{
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Determine if the length is greater than the name size. */
|
|
if (length > NX_PPP_NAME_SIZE)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Get the name. */
|
|
for(i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Get a character of the name. */
|
|
name[i] = packet_ptr -> nx_packet_prepend_ptr[i+7];
|
|
}
|
|
|
|
/* Null terminate the name. */
|
|
name[i] = 0;
|
|
|
|
/* Get length of password. */
|
|
password_length = packet_ptr -> nx_packet_prepend_ptr[i+7];
|
|
|
|
/* Check for valid packet length. */
|
|
if ((ULONG)(password_length + i + 8) > packet_ptr -> nx_packet_length)
|
|
{
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Determine if the length is greater than the password size. */
|
|
if (password_length > NX_PPP_PASSWORD_SIZE)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Get the password. */
|
|
for(j = 0; j < password_length; j++)
|
|
{
|
|
|
|
/* Get a character of the password. */
|
|
password[j] = packet_ptr -> nx_packet_prepend_ptr[j+i+8];
|
|
}
|
|
|
|
/* Null terminate the password. */
|
|
password[j] = 0;
|
|
|
|
/* Determine if there is an authentication routine. */
|
|
if (ppp_ptr -> nx_ppp_pap_verify_login)
|
|
{
|
|
|
|
/* Call the user supplied PAP authentication routine. */
|
|
status = ppp_ptr -> nx_ppp_pap_verify_login((CHAR *) name, (CHAR *) password);
|
|
|
|
/* Check to see if it is valid. */
|
|
if (status)
|
|
{
|
|
|
|
/* Return NX_FALSE, which indicates the password is invalid. */
|
|
return (NX_FALSE);
|
|
}
|
|
}
|
|
|
|
/* Return NX_TRUE. */
|
|
return(NX_TRUE);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_authentication_ack PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends an authentication ACK message to */
|
|
/* the peer in response to the peer's authentication request. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_pap_state_machine_update PPP state machine update */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_pap_authentication_ack(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the PPP PAP response packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build the PAP ACK response message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_PAP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_PAP_AUTHENTICATE_ACK;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 5;
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = 0;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 7;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
/* Set the authenticated flag to true. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of PAP frames sent. */
|
|
ppp_ptr -> nx_ppp_pap_frames_sent++;
|
|
|
|
/* Increment the number of authentication ACKs sent counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_acks_sent++;
|
|
#endif
|
|
|
|
/* Send the ACK message out. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_authentication_nak PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends an authentication NAK message to */
|
|
/* the peer in response to the peer's authentication request. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_pap_state_machine_update PPP state machine update */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_pap_authentication_nak(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the PPP PAP response packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build the PAP ACK response message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_PAP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_PAP_AUTHENTICATE_NAK;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 5;
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = 0;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 7;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of PAP frames sent. */
|
|
ppp_ptr -> nx_ppp_pap_frames_sent++;
|
|
|
|
/* Increment the authentication NAKs sent counter. */
|
|
ppp_ptr -> nx_ppp_pap_authenticate_naks_sent++;
|
|
#endif
|
|
|
|
/* Send the authentication NAK message out. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_state_machine_update PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes events and state changes in the PPP CHAP */
|
|
/* state machine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr CHAP packet pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge_send Send CHAP challenge to peer */
|
|
/* _nx_ppp_chap_challenge_respond Respond to challenge from peer*/
|
|
/* _nx_ppp_chap_challenge_validate Validate challenge response */
|
|
/* from peer */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process Receive PPP packet processing */
|
|
/* _nx_ppp_timeout PPP timeout */
|
|
/* _nx_ppp_thread_entry PPP processing thread */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_chap_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UCHAR code;
|
|
UINT valid;
|
|
|
|
|
|
/* Determine if a packet is present. If so, derive the event from the packet. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of CHAP frames received. */
|
|
ppp_ptr -> nx_ppp_chap_frames_received++;
|
|
#endif
|
|
|
|
/* Pickup the type of received CHAP code. */
|
|
code = packet_ptr -> nx_packet_prepend_ptr[2];
|
|
|
|
/* Remember receive id. */
|
|
ppp_ptr -> nx_ppp_receive_id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Check the incoming code. */
|
|
if ((code < NX_PPP_CHAP_CHALLENGE_REQUEST) || (code > NX_PPP_CHAP_CHALLENGE_FAILURE))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
|
|
/* Increment the number of unknown CHAP requests received. */
|
|
ppp_ptr -> nx_ppp_chap_unknown_requests_received++;
|
|
#endif
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the code to timeout. */
|
|
code = NX_PPP_CHAP_CHALLENGE_TIMEOUT;
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Update receive counters. */
|
|
switch (code)
|
|
{
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_REQUEST:
|
|
|
|
/* Increment the number of CHAP challenge requests received. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_RESPONSE:
|
|
|
|
/* Increment the number of CHAP challenge responses received. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_responses_received++;
|
|
break;
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_SUCCESS:
|
|
|
|
/* Increment the number of CHAP challenge successful notifications received. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_successes_received++;
|
|
break;
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_FAILURE:
|
|
|
|
/* Increment the number of CHAP challenge failures received. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_failures_received++;
|
|
break;
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_TIMEOUT:
|
|
|
|
|
|
/* Determine if we are in the initial state. If so, this really isn't a timeout. */
|
|
if (ppp_ptr -> nx_ppp_chap_state != NX_PPP_CHAP_START_STATE)
|
|
{
|
|
|
|
/* Increment the number of CHAP timeouts received. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_timeouts++;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
/* Process relative to the current state. */
|
|
switch (ppp_ptr -> nx_ppp_chap_state)
|
|
{
|
|
/* Starting state. */
|
|
case NX_PPP_CHAP_START_STATE:
|
|
{
|
|
|
|
/* Determine if we need to challenge the peer. */
|
|
if (ppp_ptr -> nx_ppp_verify_authentication_protocol)
|
|
{
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send(ppp_ptr);
|
|
|
|
/* Move to the challenge request sent state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_STATE;
|
|
}
|
|
else if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
|
|
{
|
|
|
|
/* Move to the challenge wait state, since the peer must challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE;
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_STATE:
|
|
{
|
|
|
|
/* In this state, this peer has sent a challenge request and is waiting for
|
|
response from the peer. */
|
|
if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Generate a challenge response and send it to the peer. */
|
|
_nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
|
|
|
|
/* Move to the sent both challenge and response sent state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_BOTH_STATE;
|
|
}
|
|
|
|
else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the challenge response is valid. Note this function all sends the Success or
|
|
Failure to the peer. */
|
|
valid = _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_TRUE)
|
|
{
|
|
|
|
/* Does the peer need to perform an initial challenge? */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
|
|
{
|
|
|
|
/* Move to the challenge wait state, since the peer must challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Since the peer does not need to challenge, the initial CHAP protocol is complete. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Determine if there is an application NAK callback. */
|
|
if (ppp_ptr -> nx_ppp_nak_authentication_notify)
|
|
{
|
|
|
|
/* Yes, call the application's authentication NAK notify callback function. */
|
|
(ppp_ptr -> nx_ppp_nak_authentication_notify)();
|
|
}
|
|
|
|
/* Enter into a failed state since challenge failed. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Was a timeout received? */
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the CHAP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter CHAP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_BOTH_STATE:
|
|
{
|
|
|
|
/* In this state, this peer has sent a challenge request and a challenge response and is waiting for
|
|
response from the peer. */
|
|
if (code == NX_PPP_CHAP_CHALLENGE_SUCCESS)
|
|
{
|
|
|
|
/* Move to the challenge sent received response state, since the original challenge is still pending. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_RESPONDED_STATE;
|
|
}
|
|
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
|
|
{
|
|
|
|
/* Move to the failed state since our response failed to satisfy the peer's challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
|
|
else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the challenge response is valid. Note this function all sends the Success or
|
|
Failure to the peer. */
|
|
valid = _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_TRUE)
|
|
{
|
|
|
|
/* Does the peer need to perform an initial challenge? */
|
|
if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
|
|
{
|
|
|
|
/* Move to the challenge wait state, since the peer must challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Since the peer does not need to challenge, the initial CHAP protocol is complete. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Enter into a failed state since challenge failed. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Was a timeout received? */
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the CHAP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter CHAP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_RESPONDED_STATE:
|
|
{
|
|
|
|
/* In this state, we have already successfully responded to a challenge from the peer
|
|
but are still waiting for the initial reply from the peer to our challenge request. */
|
|
if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the challenge response is valid. Note this function all sends the Success or
|
|
Failure to the peer. */
|
|
valid = _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_TRUE)
|
|
{
|
|
|
|
/* Since the peer does not need to challenge, the initial CHAP protocol is complete. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Enter into a failed state since challenge failed. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Was a timeout received? */
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the CHAP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter CHAP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE:
|
|
{
|
|
|
|
/* In this state we only need the challenge from peer, either this peer doesn't challenge or
|
|
the initial challenge has already successfully completed. */
|
|
if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Generate a challenge response and send it to the peer. */
|
|
_nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
|
|
|
|
/* Move to the wait for challenge response state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE;
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE:
|
|
{
|
|
|
|
/* In this state, this peer has sent a challenge response and is waiting for
|
|
response from the peer. */
|
|
if (code == NX_PPP_CHAP_CHALLENGE_SUCCESS)
|
|
{
|
|
|
|
/* Since the peer does not need to challenge, the initial CHAP protocol is complete. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_STATE;
|
|
|
|
/* Mark the PPP instance as authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
|
|
{
|
|
|
|
/* Move to the failed state since our response failed to satisfy the peer's challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_COMPLETED_STATE:
|
|
{
|
|
|
|
/* In this state the initial challenge(s) have been processed... This state is used to field
|
|
additional challenges during the life of the link. */
|
|
if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Generate a challenge response and send it to the peer. */
|
|
_nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
|
|
|
|
/* Stay in this state. */
|
|
}
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
|
|
{
|
|
|
|
/* Move to the failed state since our response failed to satisfy the peer's challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_COMPLETED_NEW_STATE:
|
|
{
|
|
|
|
/* In this state the new challenge(s) is issued... */
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send (ppp_ptr);
|
|
|
|
/* Move to the new challenge request sent state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_NEW_SENT_STATE;
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_CHAP_COMPLETED_NEW_SENT_STATE:
|
|
{
|
|
|
|
/* In this state the initial challenge(s) have been processed... This state is used to field
|
|
additional challenges during the life of the link. */
|
|
if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* Generate a challenge response and send it to the peer. */
|
|
_nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
|
|
|
|
/* Stay in this state. */
|
|
}
|
|
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
|
|
{
|
|
|
|
/* Determine if there is an application NAK callback. */
|
|
if (ppp_ptr -> nx_ppp_nak_authentication_notify)
|
|
{
|
|
|
|
/* Yes, call the application's authentication NAK notify callback function. */
|
|
(ppp_ptr -> nx_ppp_nak_authentication_notify)();
|
|
}
|
|
|
|
/* Move to the failed state since our response failed to satisfy the peer's challenge. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Mark the PPP instance as not authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
|
|
else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the challenge response is valid. Note this function all sends the Success or
|
|
Failure to the peer. */
|
|
valid = _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
|
|
|
|
/* Is the login valid? */
|
|
if (valid == NX_FALSE)
|
|
{
|
|
|
|
/* No: Determine if there is an application NAK callback. */
|
|
if (ppp_ptr -> nx_ppp_nak_authentication_notify)
|
|
{
|
|
|
|
/* Yes, call the application's authentication NAK notify callback function. */
|
|
(ppp_ptr -> nx_ppp_nak_authentication_notify)();
|
|
}
|
|
|
|
/* Enter into a failed state since challenge failed. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Mark the PPP instance as not authenticated. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Simply move back to the completed state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_COMPLETED_STATE;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
}
|
|
/* Was a timeout received? */
|
|
else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the CHAP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send challenge request to peer. */
|
|
_nx_ppp_chap_challenge_send (ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter CHAP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function sends a CHAP challenge to the peer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* (nx_ppp_chap_get_challenge_values) Get values for challenge */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* _nx_utility_string_length_check Check string length */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_chap_state_machine_update Update CHAP state machine */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_chap_challenge_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UCHAR id;
|
|
UINT length, length1, i, j;
|
|
NX_PACKET *packet_ptr;
|
|
UINT status;
|
|
|
|
|
|
/* Determine if there is a challenge generation routine. */
|
|
if (ppp_ptr -> nx_ppp_chap_get_challenge_values)
|
|
{
|
|
|
|
/* Yes, get the challenge values. */
|
|
ppp_ptr -> nx_ppp_chap_get_challenge_values(ppp_ptr -> nx_ppp_chap_random_value,
|
|
(CHAR *) &id, ppp_ptr -> nx_ppp_chap_challenger_name);
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return. */
|
|
return;
|
|
}
|
|
|
|
/* Allocate a packet for the PPP CHAP challenge packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Calculate the lengths of the challenger name and random value. */
|
|
if (_nx_utility_string_length_check(ppp_ptr -> nx_ppp_chap_challenger_name, &length1, NX_PPP_NAME_SIZE) ||
|
|
_nx_utility_string_length_check(ppp_ptr -> nx_ppp_chap_random_value, &length, NX_PPP_VALUE_SIZE))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 1 + length1 + 6))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Build CHAP challenge message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_CHAP_CHALLENGE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = id; /* ID */
|
|
|
|
/* Setup the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR) ((((UINT) length) + 1 + ((UINT) length1) + 4) >> 8);
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR) ((((UINT) length) + 1 + ((UINT) length1) + 4) & 0xFF);
|
|
|
|
/* Store the CHAP random value. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = (UCHAR)length;
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Store byte of name. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+7] = (UCHAR)(ppp_ptr -> nx_ppp_chap_random_value[i]);
|
|
}
|
|
|
|
/* Store CHAP challenge name. */
|
|
for (j = 0; j < length1; j++)
|
|
{
|
|
|
|
/* Store byte of name. */
|
|
packet_ptr -> nx_packet_prepend_ptr[j+i+7] = (UCHAR)(ppp_ptr -> nx_ppp_chap_challenger_name[j]);
|
|
}
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = ((UINT) length) + 1 + ((UINT) length1) + 4 + 2;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of CHAP frames sent. */
|
|
ppp_ptr -> nx_ppp_chap_frames_sent++;
|
|
|
|
/* Increment the number of CHAP challenge requests. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_requests_sent++;
|
|
#endif
|
|
|
|
/* Send challenge message. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge_respond PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes the CHAP challenge request from the peer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to CHAP challenge */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* (nx_ppp_chap_get_responder_values) Get responder values for reply*/
|
|
/* _nx_ppp_hash_generator Generate MD5 hash */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_chap_state_machine_update Update CHAP state machine */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_chap_challenge_respond(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UCHAR name[NX_PPP_NAME_SIZE + 1], secret[NX_PPP_NAME_SIZE + 1];
|
|
UCHAR value[NX_PPP_VALUE_SIZE + 1], hvalue[NX_PPP_HASHED_VALUE_SIZE + 1];
|
|
UCHAR id;
|
|
UINT length, length1, i, j;
|
|
NX_PACKET *response_packet_ptr;
|
|
UINT status;
|
|
UINT name_length;
|
|
|
|
|
|
/* Pickup the id and length. */
|
|
id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Pickup the length. */
|
|
length = (UINT) packet_ptr -> nx_packet_prepend_ptr[4];
|
|
length1 = (UINT) packet_ptr -> nx_packet_prepend_ptr[5];
|
|
length1 = (length << 8) | (length1) ;
|
|
|
|
/* Check for valid packet length. */
|
|
if ((length1 + 2) > packet_ptr -> nx_packet_length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Pickup the length of the random value. */
|
|
length = (UINT) packet_ptr -> nx_packet_prepend_ptr[6];
|
|
|
|
/* Check for valid packet length. */
|
|
if ((length == 0) || ((ULONG)(length + 7) > packet_ptr -> nx_packet_length))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Determine if the length is greater than the destination. */
|
|
name_length = length1 - length - 5;
|
|
if ((length > NX_PPP_VALUE_SIZE) ||
|
|
(name_length > NX_PPP_NAME_SIZE))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
/* Pickup the random value. */
|
|
for(i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Pickup a byte of the random value. */
|
|
value[i] = packet_ptr -> nx_packet_prepend_ptr[i+7];
|
|
}
|
|
|
|
/* Now pickup the challenge name. */
|
|
for(j = 0; j < name_length; j++)
|
|
{
|
|
|
|
/* Pickup a byte of the challenger name. */
|
|
name[j] = packet_ptr -> nx_packet_prepend_ptr[i+j+7];
|
|
}
|
|
|
|
/* Null terminate it. */
|
|
name[j] = 0;
|
|
|
|
/* Determine if there is a challenge get responder values routine. */
|
|
if (ppp_ptr -> nx_ppp_chap_get_responder_values)
|
|
{
|
|
|
|
/* Get name and password for this server */
|
|
ppp_ptr -> nx_ppp_chap_get_responder_values((CHAR*) name, (CHAR *) name, (CHAR *) secret);
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Generate hash value. */
|
|
_nx_ppp_hash_generator(hvalue, id, secret, value, length);
|
|
|
|
/* Allocate a packet for the PPP CHAP response packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &response_packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Calculate length of the name */
|
|
for(length = 0; name[length]; length++);
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(response_packet_ptr -> nx_packet_data_end - response_packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + NX_PPP_HASHED_VALUE_SIZE + 7))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Build CHAP challenge response message. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_CHAP_CHALLENGE_RESPONSE;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[3] = id; /* ID */
|
|
|
|
/* Setup the length. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR) ((((UINT) length) + NX_PPP_HASHED_VALUE_SIZE + 5) >> 8);
|
|
response_packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR) ((((UINT) length) + NX_PPP_HASHED_VALUE_SIZE + 5) & 0xFF);
|
|
|
|
/* Set the length of the hashed response value. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[6] = (UCHAR) NX_PPP_HASHED_VALUE_SIZE;
|
|
|
|
/* Loop to insert the hashed value. */
|
|
for(i = 0; i < NX_PPP_HASHED_VALUE_SIZE; i++)
|
|
{
|
|
|
|
/* Copy one byte of the hashed value. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[i+7] = hvalue[i];
|
|
}
|
|
|
|
/* Loop to insert the name. */
|
|
for(j = 0; j < length; j++)
|
|
{
|
|
|
|
/* Copy one byte of the name. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[i+j+7] = name[j];
|
|
}
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
response_packet_ptr -> nx_packet_length = length + NX_PPP_HASHED_VALUE_SIZE + 5 + 2;
|
|
response_packet_ptr -> nx_packet_append_ptr = response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of CHAP frames sent. */
|
|
ppp_ptr -> nx_ppp_chap_frames_sent++;
|
|
|
|
/* Increment the number of CHAP responses sent. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_responses_sent++;
|
|
#endif
|
|
|
|
/* Transmit response message. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge_validate PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function validates the CHAP response from the peer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to CHAP challenge */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status NX_TRUE - valid login */
|
|
/* NX_FALSE - invalid login */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate packet */
|
|
/* (nx_ppp_chap_get_verification_values) Get verification values */
|
|
/* _nx_ppp_hash_generator Generate MD5 hash */
|
|
/* _nx_ppp_packet_transmit Send PAP response */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_chap_state_machine_update Update CHAP state machine */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_chap_challenge_validate(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UCHAR name[NX_PPP_NAME_SIZE + 1], secret[NX_PPP_NAME_SIZE + 1];
|
|
UCHAR hvalue[NX_PPP_HASHED_VALUE_SIZE + 1];
|
|
UCHAR hvalue1[NX_PPP_HASHED_VALUE_SIZE + 1];
|
|
UCHAR id;
|
|
UINT length, length1, i, j;
|
|
NX_PACKET *response_packet_ptr;
|
|
UINT status;
|
|
UINT name_length;
|
|
|
|
|
|
/* Pickup the id and length. */
|
|
id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Pickup the length. */
|
|
length = (UINT) packet_ptr -> nx_packet_prepend_ptr[4];
|
|
length1 = (UINT) packet_ptr -> nx_packet_prepend_ptr[5];
|
|
length1 = (length << 8) | (length1) ;
|
|
|
|
/* Check for valid packet length. */
|
|
if ((length1 + 2) > packet_ptr -> nx_packet_length)
|
|
{
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Pickup the length of the hashed value. */
|
|
length = (UINT) packet_ptr -> nx_packet_prepend_ptr[6];
|
|
|
|
/* Check for valid packet length. */
|
|
if ((length == 0) || ((ULONG)(length + 7) > packet_ptr -> nx_packet_length))
|
|
{
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Determine if the length is greater than the destination. */
|
|
name_length = length1 - length - 5;
|
|
if ((length > NX_PPP_HASHED_VALUE_SIZE) ||
|
|
(name_length > NX_PPP_NAME_SIZE))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* Return false in case of internal error. */
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Pickup the hashed value. */
|
|
for(i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Pickup one byte of the hashed value. */
|
|
hvalue[i] = packet_ptr -> nx_packet_prepend_ptr[i+7];
|
|
}
|
|
|
|
/* Pickup the name. */
|
|
for(j = 0; j < name_length; j++)
|
|
{
|
|
|
|
/* Pickup one byte of the hashed value. */
|
|
name[j] = packet_ptr -> nx_packet_prepend_ptr[i+j+7];
|
|
}
|
|
|
|
/* Null terminate the name. */
|
|
name[j] = 0;
|
|
|
|
/* Determine if there is a challenge get verification values routine. */
|
|
if (ppp_ptr -> nx_ppp_chap_get_verification_values)
|
|
{
|
|
|
|
/* Get name and password for this server */
|
|
ppp_ptr -> nx_ppp_chap_get_verification_values(ppp_ptr -> nx_ppp_chap_challenger_name, (CHAR *) name, (CHAR *) secret);
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* Return false in case of internal error. */
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Generate hash value. */
|
|
_nx_ppp_hash_generator(hvalue1, id, secret, (UCHAR *) ppp_ptr -> nx_ppp_chap_random_value, 0);
|
|
|
|
/* Compare the computed hash value with the hash value received. */
|
|
for(i = 0; i < NX_PPP_HASHED_VALUE_SIZE; i++)
|
|
{
|
|
|
|
/* Are the hash values equal? */
|
|
if (hvalue[i] != hvalue1[i])
|
|
{
|
|
/* No, get out of the loop. */
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* Allocate a packet for the PPP CHAP response packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &response_packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* Return false in case of internal error. */
|
|
return(NX_FALSE);
|
|
}
|
|
|
|
/* Determine if challenge was successful. */
|
|
if (i == NX_PPP_HASHED_VALUE_SIZE)
|
|
{
|
|
|
|
/* Build CHAP ACK message. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_CHAP_CHALLENGE_SUCCESS;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[3] = id; /* ID */
|
|
|
|
/* Setup the length. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR) 0;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR) 4;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
response_packet_ptr -> nx_packet_length = 6;
|
|
response_packet_ptr -> nx_packet_append_ptr = response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of CHAP frames sent. */
|
|
ppp_ptr -> nx_ppp_chap_frames_sent++;
|
|
|
|
/* Increment the number of CHAP success notifications sent. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_successes_sent++;
|
|
#endif
|
|
|
|
/* Transmit the message. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
|
|
|
|
/* Return true to indicate the response was valid. */
|
|
return(NX_TRUE);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Build CHAP NAK message. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_CHAP_PROTOCOL & 0xFF;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_CHAP_CHALLENGE_FAILURE;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[3] = id; /* ID */
|
|
|
|
/* Setup the length. */
|
|
response_packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR) 0;
|
|
response_packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR) 4;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
response_packet_ptr -> nx_packet_length = 6;
|
|
response_packet_ptr -> nx_packet_append_ptr = response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of CHAP frames sent. */
|
|
ppp_ptr -> nx_ppp_chap_frames_sent++;
|
|
|
|
/* Increment the number of CHAP failure notifications sent. */
|
|
ppp_ptr -> nx_ppp_chap_challenge_failures_sent++;
|
|
#endif
|
|
|
|
/* Transmit the message. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
|
|
|
|
/* Return false to indicate the response was invalid. */
|
|
return(NX_FALSE);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update PORTABLE C */
|
|
/* 6.1.2 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes events and state changes in the PPP IPCP */
|
|
/* state machine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Packet pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_ipcp_configure_check Check configuration info */
|
|
/* _nx_ppp_ipcp_configure_request_send Send configuration request */
|
|
/* _nx_ppp_ipcp_response_extract Extract info from response */
|
|
/* _nx_ppp_ipcp_response_send Send response */
|
|
/* _nx_ppp_ipcp_terminate_send Send terminate */
|
|
/* _nx_ppp_ipcp_terminate_ack_send Send terminate ack */
|
|
/* nx_ip_interface_address_set Set interface IP address */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_process Receive PPP packet processing */
|
|
/* _nx_ppp_timeout PPP timeout */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* corrected the NAKed list */
|
|
/* pointer, */
|
|
/* resulting in version 6.1.2 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT acceptable_configuration;
|
|
UCHAR good_data[NX_PPP_OPTION_MESSAGE_LENGTH];
|
|
UCHAR code;
|
|
|
|
|
|
/* Determine if a packet is present. If so, derive the event from the packet. */
|
|
if (packet_ptr)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IPCP frames received. */
|
|
ppp_ptr -> nx_ppp_ipcp_frames_received++;
|
|
#endif
|
|
|
|
/* Pickup the type of received IPCP code. */
|
|
code = packet_ptr -> nx_packet_prepend_ptr[2];
|
|
|
|
/* Remember receive id. */
|
|
ppp_ptr -> nx_ppp_receive_id = packet_ptr -> nx_packet_prepend_ptr[3];
|
|
|
|
/* Is the code supported by PPP? */
|
|
if ((code < NX_PPP_IPCP_CONFIGURE_REQUEST) ||
|
|
(code > NX_PPP_IPCP_TERMINATE_ACK))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of internal errors. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
|
|
/* Increment the number of unhandled requests. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
#endif
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the code to timeout to indicate a timeout has occurred. */
|
|
code = NX_PPP_IPCP_TIMEOUT;
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the corresponding request counter. */
|
|
switch (code)
|
|
{
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_REQUEST:
|
|
|
|
/* Increment the number of IPCP configure requests received. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_ACK:
|
|
|
|
/* Increment the number of IPCP configure ACKs received. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_acks_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_NAK:
|
|
|
|
/* Increment the number of IPCP configure NAKs received. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_naks_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_REJECT:
|
|
|
|
/* Increment the number of IPCP configure rejects received. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_rejects_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_TERMINATE_REQUEST:
|
|
|
|
/* Increment the number of IPCP terminate requests received. */
|
|
ppp_ptr -> nx_ppp_ipcp_terminate_requests_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_TERMINATE_ACK:
|
|
|
|
/* Increment the number of IPCP terminate ACKs received. */
|
|
ppp_ptr -> nx_ppp_ipcp_terminate_acks_received++;
|
|
break;
|
|
|
|
case NX_PPP_IPCP_TIMEOUT:
|
|
|
|
/* Determine if we are in the initial state. If so, this really isn't a timeout. */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state != NX_PPP_IPCP_START_STATE)
|
|
{
|
|
|
|
/* Increment the number of IPCP state machine timeouts. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_timeouts++;
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
/* Process relative to the current state. */
|
|
switch (ppp_ptr -> nx_ppp_ipcp_state)
|
|
{
|
|
|
|
case NX_PPP_IPCP_START_STATE:
|
|
{
|
|
|
|
/* Initial IPCP state. */
|
|
|
|
/* Initialize the NAK and rejected list. */
|
|
#ifndef NX_PPP_DNS_OPTION_DISABLE
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 0;
|
|
ppp_ptr -> nx_ppp_naked_list[1] = 0;
|
|
#else
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 1;
|
|
ppp_ptr -> nx_ppp_naked_list[1] = 1;
|
|
#endif
|
|
|
|
ppp_ptr -> nx_ppp_peer_naked_list[0] = 0;
|
|
ppp_ptr -> nx_ppp_rejected_list[0] = 0;
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
|
|
/* Move into the request sent state. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE;
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE:
|
|
{
|
|
|
|
/* In this state, we have sent a configuration request but had not received an ACK
|
|
or a configuration request from the peer. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if (code == NX_PPP_IPCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* The peer has ACKed our configuration request. Move to the
|
|
configure request ACKed state. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE;
|
|
|
|
/* Turn off the timeout for the configuration request. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
else if (code == NX_PPP_IPCP_CONFIGURE_REJECT)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Set the NAK option list, just to indicate to the configure request that
|
|
the IPCP request without DNS option is what we want. */
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 1;
|
|
|
|
/* Send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
|
|
else if ((code == NX_PPP_IPCP_CONFIGURE_NAK) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Extract the information from response... looking for IP address and possibly DNS server IP address. */
|
|
_nx_ppp_ipcp_response_extract(ppp_ptr, packet_ptr);
|
|
|
|
/* Send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
|
|
else if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Check configuration information. */
|
|
acceptable_configuration = _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list,
|
|
ppp_ptr -> nx_ppp_rejected_list,
|
|
good_data);
|
|
|
|
/* Check for acceptable configuration. */
|
|
if (acceptable_configuration == NX_TRUE)
|
|
{
|
|
|
|
/* Yes, send an ack. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
|
|
|
|
/* Move to the state where the peer's configuration has been ACKed. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_PEER_CONFIGURE_REQUEST_ACKED_STATE;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Otherwise, configuration is unacceptable, send a nak. */
|
|
|
|
/* Check rejected list. */
|
|
if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are rejected options so send a configure reject. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT,
|
|
&ppp_ptr -> nx_ppp_rejected_list[1],
|
|
ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
|
|
|
|
}
|
|
else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are naked options so send a new request. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK,
|
|
&ppp_ptr -> nx_ppp_peer_naked_list[1],
|
|
ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
|
|
|
|
}
|
|
}
|
|
}
|
|
else if (code == NX_PPP_IPCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the IPCP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_IPCP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Timeout, send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter IPCP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE:
|
|
{
|
|
|
|
/* In this state, we have received the ACK for our configuration request, but have not yet
|
|
received a configuration request from the peer. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Check configuration information. */
|
|
acceptable_configuration = _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, good_data);
|
|
|
|
/* Check for acceptable configuration. */
|
|
if (acceptable_configuration == NX_TRUE)
|
|
{
|
|
|
|
/* Yes, send an ack. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
|
|
|
|
/* Move to the state where the peer's configuration has been ACKed. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_COMPLETED_STATE;
|
|
|
|
/* Set the IP address for the specific interface from the configuration. */
|
|
nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index,
|
|
IP_ADDRESS(ppp_ptr -> nx_ppp_ipcp_local_ip[0],
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[1],
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[2],
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[3]),
|
|
0xffffffff);
|
|
|
|
/* Set gateway address. */
|
|
(ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_address = (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_address;
|
|
(ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_interface = ppp_ptr -> nx_ppp_interface_ptr;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Otherwise, configuration is unacceptable, send a NAK. */
|
|
|
|
/* Check rejected list. */
|
|
if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are rejected options so send a new request. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT, &ppp_ptr -> nx_ppp_rejected_list[1], ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
|
|
}
|
|
else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are naked options so send a new request. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK, &ppp_ptr -> nx_ppp_peer_naked_list[1], ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_IPCP_PEER_CONFIGURE_REQUEST_ACKED_STATE:
|
|
{
|
|
|
|
/* In this state, we have sent our configuration request, but haven't received an ACK. We have also received
|
|
a peer configuration request and have ACKed that request. */
|
|
|
|
/* Process relative to the incoming code. */
|
|
if (code == NX_PPP_IPCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* The peer has ACKed our configuration request. Move to the
|
|
IPCP completed state. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_COMPLETED_STATE;
|
|
|
|
/* Turn off the timeout for the configuration request. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
|
|
/* Set the IP address for the specific interface from the configuration. */
|
|
nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index,
|
|
IP_ADDRESS(ppp_ptr -> nx_ppp_ipcp_local_ip[0], ppp_ptr -> nx_ppp_ipcp_local_ip[1],
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[2], ppp_ptr -> nx_ppp_ipcp_local_ip[3]),
|
|
0xffffffff);
|
|
|
|
/* Set gateway address. */
|
|
(ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_address = (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_address;
|
|
(ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_interface = ppp_ptr -> nx_ppp_interface_ptr;
|
|
|
|
/* Turn off the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = 0;
|
|
}
|
|
|
|
else if (code == NX_PPP_IPCP_CONFIGURE_REJECT)
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Set the NAK option list, just to indicate to the configure request that
|
|
the IPCP request without DNS option is what we want. */
|
|
ppp_ptr -> nx_ppp_naked_list[0] = 1;
|
|
|
|
/* Send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
|
|
else if ((code == NX_PPP_IPCP_CONFIGURE_NAK) && (packet_ptr))
|
|
{
|
|
|
|
/* Determine if the ID matches our last transmit ID. If not, just discard it. */
|
|
if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the invalid frame ID counter. */
|
|
ppp_ptr -> nx_ppp_invalid_frame_id++;
|
|
#endif
|
|
|
|
/* Discard this request by simply returning! */
|
|
return;
|
|
}
|
|
|
|
/* Extract the information from response... looking for IP address and possibly DNS server IP address. */
|
|
_nx_ppp_ipcp_response_extract(ppp_ptr, packet_ptr);
|
|
|
|
/* Send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
|
|
else if (code == NX_PPP_IPCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Timeout, send the configuration request. */
|
|
_nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_IPCP_COMPLETED_STATE:
|
|
{
|
|
|
|
/* IPCP is up and operational at this point. */
|
|
|
|
/* Process relative to incoming code. */
|
|
if (code == NX_PPP_IPCP_TERMINATE_REQUEST)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* ACK the terminate request. */
|
|
_nx_ppp_ipcp_terminate_ack_send(ppp_ptr);
|
|
|
|
/* Send terminate request. */
|
|
_nx_ppp_ipcp_terminate_send(ppp_ptr);
|
|
|
|
/* Move into the IPCP stopping state. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_STOPPING_STATE;
|
|
}
|
|
else if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
|
|
{
|
|
/* The peer has sent a configuration request. */
|
|
|
|
/* Check configuration information. */
|
|
acceptable_configuration = _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, good_data);
|
|
|
|
/* Check for acceptable configuration. */
|
|
if (acceptable_configuration == NX_TRUE)
|
|
{
|
|
|
|
/* Yes, send an ack. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, configuration is unacceptable, send a nak. */
|
|
|
|
/* Check rejected list. */
|
|
if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are rejected options so send a new request. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT, &ppp_ptr -> nx_ppp_rejected_list[1], ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
|
|
}
|
|
else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
|
|
{
|
|
|
|
/* Yes, there are naked options so send a new request. */
|
|
_nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK, &ppp_ptr -> nx_ppp_peer_naked_list[1], ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_LCP_STOPPING_STATE:
|
|
{
|
|
|
|
/* We received a terminate request from the other side and just need to get the ACK. */
|
|
|
|
/* Process relative to incoming code. */
|
|
if (code == NX_PPP_IPCP_TERMINATE_ACK)
|
|
{
|
|
|
|
/* Move the the stopped state. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_STOPPED_STATE;
|
|
}
|
|
else if (code == NX_PPP_IPCP_TIMEOUT)
|
|
{
|
|
|
|
/* Increment the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter++;
|
|
|
|
/* Determine if the IPCP retry counter has been exceeded. */
|
|
if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_IPCP_PROTOCOL_RETRIES)
|
|
{
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Send terminate request. */
|
|
_nx_ppp_ipcp_terminate_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Retry counter exceeded. */
|
|
|
|
/* Enter IPCP failed state. PPP must be stopped and started to try again. */
|
|
ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_FAILED_STATE;
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
else
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
{
|
|
|
|
/* Increment the number of unhandled state machine events. */
|
|
ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_configure_check PORTABLE C */
|
|
/* 6.1.2 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes the IPCP message options. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr IPCP packet pointer */
|
|
/* naked_list NAKed option list */
|
|
/* rejected_list Rejected option list */
|
|
/* good_data Good options */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status */
|
|
/* NX_TRUE 1 indicates no errors, address obtained */
|
|
/* NX_FALSE 0 indicates an error or unknown option or address */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* improved packet length */
|
|
/* verification, */
|
|
/* resulting in version 6.1.2 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_ipcp_configure_check(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr, UCHAR *naked_list, UCHAR *rejected_list, UCHAR *good_data)
|
|
{
|
|
|
|
UINT length, ip_stat, status;
|
|
UINT i, w, m;
|
|
UINT nak_length = 0;
|
|
UINT rej_length = 0;
|
|
UINT good_index = 0;
|
|
UINT nak_index = 0;
|
|
UINT rej_index = 0;
|
|
UCHAR option;
|
|
|
|
|
|
/* Extract the length. */
|
|
length = ((UINT)(packet_ptr -> nx_packet_prepend_ptr[4] << 8) | (UINT)packet_ptr -> nx_packet_prepend_ptr[5]);
|
|
|
|
/* Subtract 4 to remove the code, id, and length bytes from the length. */
|
|
length = length - 4;
|
|
|
|
/* Initialize the rejected and naked lists. */
|
|
rejected_list[0] = naked_list[0] = good_data[0] = 0;
|
|
|
|
/* Loop to process the IPCP configuration options. */
|
|
for(w = 0, rej_index = 1, status = 1, nak_index = 1; (w + 2) <= length;)
|
|
{
|
|
|
|
UINT opt_length;
|
|
|
|
/* Pickup the IPCP option. */
|
|
option = packet_ptr -> nx_packet_prepend_ptr[w + 6];
|
|
|
|
/* Pickup the IPCP option length. */
|
|
opt_length = (UINT) packet_ptr -> nx_packet_prepend_ptr[w + 7];
|
|
|
|
/* Determine if the length is valid. */
|
|
if ((opt_length < 2) || (opt_length > (length - w)))
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal overflow counter. */
|
|
ppp_ptr -> nx_ppp_packet_overflow++;
|
|
#endif
|
|
|
|
/* Something is wrong, just get out of the loop! */
|
|
return(status);
|
|
}
|
|
|
|
/* Adjust the option length. */
|
|
opt_length -= 2;
|
|
|
|
/* Process relative to the option. */
|
|
switch (option)
|
|
{
|
|
|
|
case NX_PPP_IP_ADDRESS_OPTION:
|
|
{
|
|
|
|
/* Check if out of boundary. */
|
|
if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
|
|
return(NX_FALSE);
|
|
|
|
/* IP address option. */
|
|
good_data[good_index++] = NX_PPP_IP_ADDRESS_OPTION;
|
|
good_data[good_index++] = 6;
|
|
|
|
ip_stat = 0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
|
|
/* Pick up each byte of the IP address. */
|
|
good_data[i + good_index] = packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
|
|
|
|
/* OR in the IP address bytes to make it easy to see if we got something. */
|
|
ip_stat |= good_data[i + good_index];
|
|
}
|
|
|
|
/* Adjust the main index. */
|
|
w += 6;
|
|
|
|
/* Check if we really have an IP address. */
|
|
if (!ip_stat)
|
|
{
|
|
|
|
/* Copy default IP address. */
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
good_data[i + good_index] = ppp_ptr -> nx_ppp_ipcp_peer_ip[i];
|
|
}
|
|
|
|
/* Setup NAK list so we can get the IP address hint. */
|
|
for(i = 0; i < 6; i++)
|
|
{
|
|
naked_list[nak_index++] = good_data[i];
|
|
}
|
|
|
|
nak_length = nak_index - 1;
|
|
|
|
/* Clear status. */
|
|
status = 0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* We did get an IP address for the peer. Remember it! */
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
|
|
/* Remember each byte of peer's IP address. */
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[i] = good_data[i + good_index];
|
|
}
|
|
}
|
|
|
|
good_index += opt_length;
|
|
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_IP_COMPRESSION_OPTION:
|
|
{
|
|
|
|
/* IP Compression Option. Since this is the receiver telling us what they
|
|
support it is not important to us since we don't support compression. */
|
|
|
|
/* Simply adjust the main index into the option list. */
|
|
w += (opt_length + 2); /* skip */
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_DNS_SERVER_OPTION:
|
|
{
|
|
|
|
/* Check if out of boundary. */
|
|
if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
|
|
return(NX_FALSE);
|
|
|
|
/* Only request a hint if we don't have already have a dns address . */
|
|
good_data[good_index++] = NX_PPP_DNS_SERVER_OPTION;
|
|
good_data[good_index++] = 6;
|
|
ip_stat = 0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
|
|
/* Pick up each byte of the primary DNS address. */
|
|
good_data[i + good_index] = packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
|
|
|
|
/* Or in the IP address bytes to make it easy to see if we got something. */
|
|
ip_stat |= good_data[i + good_index];
|
|
}
|
|
|
|
/* Adjust the main index. */
|
|
w += 6;
|
|
|
|
/* Check if we really have an primary DNS address. */
|
|
if (!ip_stat)
|
|
{
|
|
|
|
|
|
/* Update the number of retries on secondary address requests. */
|
|
ppp_ptr -> nx_ppp_dns_address_retries++;
|
|
|
|
/* Check if we have reached the limit on retries. */
|
|
if (ppp_ptr -> nx_ppp_dns_address_retries >= NX_PPP_DNS_ADDRESS_MAX_RETRIES)
|
|
{
|
|
/* We have. Return successful result and let IPCP complete. */
|
|
break;
|
|
}
|
|
|
|
/* Copy default DNS IP address. */
|
|
good_data[good_index] = (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address >> 24);
|
|
good_data[good_index + 1] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 16) & 0xff);
|
|
good_data[good_index + 2] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 8) & 0xff);
|
|
good_data[good_index + 3]= (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address & 0xff);
|
|
|
|
/* Setup NAK list so we can get the DNS IP address hint. */
|
|
for(i = 0; i < 6; i++)
|
|
{
|
|
naked_list[nak_index++] = good_data[good_index + i - 2];
|
|
}
|
|
|
|
/* Clear status. */
|
|
status = 0;
|
|
|
|
/* Update the size of the nak and reject data. */
|
|
nak_length = nak_index - 1;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Copy good IP address. */
|
|
ppp_ptr -> nx_ppp_primary_dns_address = ((ULONG)good_data[good_index] << 24) & 0xFF000000;
|
|
ppp_ptr -> nx_ppp_primary_dns_address |= (good_data[good_index + 1] << 16) & 0x00FF0000;
|
|
ppp_ptr -> nx_ppp_primary_dns_address |= (good_data[good_index + 2] << 8) & 0x0000FF00;
|
|
ppp_ptr -> nx_ppp_primary_dns_address |= good_data[good_index + 3] & 0x000000FF;
|
|
}
|
|
|
|
good_index += opt_length;
|
|
|
|
break;
|
|
}
|
|
|
|
case NX_PPP_DNS_SECONDARY_SERVER_OPTION:
|
|
{
|
|
|
|
/* Check if out of boundary. */
|
|
if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
|
|
return(NX_FALSE);
|
|
|
|
/* Only request a hint if we don't have already have a dns address . */
|
|
good_data[good_index++] = NX_PPP_DNS_SECONDARY_SERVER_OPTION;
|
|
good_data[good_index++] = 6;
|
|
ip_stat = 0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
|
|
/* Pick up each byte of the secondary DNS address. */
|
|
good_data[i + good_index] = packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
|
|
|
|
/* Or in the IP address bytes to make it easy to see if we got something. */
|
|
ip_stat |= good_data[i + good_index];
|
|
}
|
|
|
|
/* Adjust the main index. */
|
|
w += 6;
|
|
|
|
/* Check if we really have an primary DNS address. */
|
|
if (!ip_stat)
|
|
{
|
|
|
|
/* Update the number of retries on primary address requests. */
|
|
ppp_ptr -> nx_ppp_secondary_dns_address_retries++;
|
|
|
|
/* Check if we have reached the limit on retries. */
|
|
if (ppp_ptr -> nx_ppp_secondary_dns_address_retries >= NX_PPP_DNS_ADDRESS_MAX_RETRIES)
|
|
{
|
|
/* We have. Return successful result and let IPCP complete. */
|
|
break;
|
|
}
|
|
|
|
/* Copy the primary DNS IP address from the packet data. */
|
|
good_data[good_index] = (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address >> 24);
|
|
good_data[good_index + 1] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 16) & 0xff);
|
|
good_data[good_index + 2] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 8) & 0xff);
|
|
good_data[good_index + 3]= (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address & 0xff);
|
|
|
|
/* Setup NAK list so we can get the DNS IP address hint. */
|
|
for(i = 0; i < 6; i++)
|
|
{
|
|
naked_list[nak_index++] = good_data[good_index + i - 2];
|
|
}
|
|
|
|
/* Clear status. */
|
|
status = 0;
|
|
|
|
/* Update the size of the nak and reject data. */
|
|
nak_length = nak_index - 1;
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
/* Copy good IP address. */
|
|
ppp_ptr -> nx_ppp_secondary_dns_address = ((ULONG)good_data[good_index] << 24) & 0xFF000000;
|
|
ppp_ptr -> nx_ppp_secondary_dns_address |= (good_data[good_index + 1] << 16) & 0x00FF0000;
|
|
ppp_ptr -> nx_ppp_secondary_dns_address |= (good_data[good_index + 2] << 8) & 0x0000FF00;
|
|
ppp_ptr -> nx_ppp_secondary_dns_address |= good_data[good_index + 3] & 0x000000FF;
|
|
}
|
|
|
|
good_index += opt_length;
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
|
|
/* All other options get NAKed. */
|
|
status = 0;
|
|
|
|
/* Determine if the option will fit. */
|
|
if ((rej_index + opt_length + 2) >= NX_PPP_OPTION_MESSAGE_LENGTH)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal overflow counter. */
|
|
ppp_ptr -> nx_ppp_packet_overflow++;
|
|
#endif
|
|
|
|
/* Return status. */
|
|
return(status);
|
|
}
|
|
|
|
/* Place the option in the rejected list. */
|
|
rejected_list[rej_index++] = option;
|
|
rejected_list[rej_index++] = (UCHAR)(opt_length + 2);
|
|
|
|
/* Loop to copy the rest of the options into the rejected list. */
|
|
for (m = 0; m < opt_length; m++)
|
|
{
|
|
|
|
/* Copy option byte into the rejected option list. */
|
|
rejected_list[rej_index] = packet_ptr -> nx_packet_prepend_ptr[w + m + 8];
|
|
rej_index++;
|
|
}
|
|
|
|
rej_length = rej_index - 1;
|
|
|
|
/* Adjust the main index into the option list. */
|
|
w += (opt_length + 2); /* skip */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Setup the length in the naked and rejected lists. */
|
|
naked_list[0] = (UCHAR)nak_length;
|
|
rejected_list[0] = (UCHAR)rej_length;
|
|
|
|
/* Return status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_configure_request_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a configure request message and sends it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* negotiate_list List of options to negotiate */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send IPCP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_configure_request_send(NX_PPP *ppp_ptr, UCHAR *negotiate_list)
|
|
{
|
|
|
|
UINT status, i;
|
|
NX_PACKET *packet_ptr;
|
|
UINT index;
|
|
|
|
|
|
/* Allocate a packet for the IPCP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Clear the packet memory.*/
|
|
memset(packet_ptr -> nx_packet_prepend_ptr, 0, (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr));
|
|
|
|
/* Adjust the transmit ID. */
|
|
ppp_ptr -> nx_ppp_transmit_id++;
|
|
|
|
/* Build IPCP request message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_IPCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_IPCP_CONFIGURE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_transmit_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0x00;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 0x0A; /* Size of the IPCP data */
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = 0x03;
|
|
packet_ptr -> nx_packet_prepend_ptr[7] = 0x06;
|
|
|
|
/* Load up the default IP address. */
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
|
|
/* Copy byte of IP address. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+8] = ppp_ptr -> nx_ppp_ipcp_local_ip[i];
|
|
}
|
|
|
|
index = i + 8;
|
|
|
|
/* Determine if we want the DNS option ... */
|
|
if (negotiate_list[0] == 0)
|
|
{
|
|
|
|
/* Yes (because it is not obvious from the code style), let's try to get the DNS server. */
|
|
|
|
/* Update the IPCP length for DNS address. */
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(packet_ptr -> nx_packet_prepend_ptr[5] + 6);
|
|
|
|
/* Add the option for retrieving the DNS server as well. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index] = NX_PPP_DNS_SERVER_OPTION;
|
|
packet_ptr -> nx_packet_prepend_ptr[index+1] = 0x06;
|
|
packet_ptr -> nx_packet_prepend_ptr[index+2] = (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address >> 24);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+3] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 16) & 0xff);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+4] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 8) & 0xff);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+5] = (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address & 0xff);
|
|
index += 6;
|
|
|
|
/* Also check for a secondary DNS address request. */
|
|
if (negotiate_list[1] == 0)
|
|
{
|
|
|
|
/* Update the IPCP length for secondary DNS address. */
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(packet_ptr -> nx_packet_prepend_ptr[5] + 6);
|
|
|
|
/* Add the option for retrieving the DNS server as well. */
|
|
packet_ptr -> nx_packet_prepend_ptr[index] = NX_PPP_DNS_SECONDARY_SERVER_OPTION;
|
|
packet_ptr -> nx_packet_prepend_ptr[index+1] = 0x06;
|
|
packet_ptr -> nx_packet_prepend_ptr[index+2] = (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address >> 24);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+3] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 16) & 0xff);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+4] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 8) & 0xff);
|
|
packet_ptr -> nx_packet_prepend_ptr[index+5] = (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address & 0xff);
|
|
index += 6;
|
|
}
|
|
}
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = index;
|
|
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IPCP frames sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_frames_sent++;
|
|
|
|
/* Increment the number of IPCP configure requests sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_requests_sent++;
|
|
#endif
|
|
|
|
/* Send IPCP configure request packet. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_response_extract PORTABLE C */
|
|
/* 6.1.2 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function extracts information from the IPCP response */
|
|
/* message. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* packet_ptr Pointer to IPCP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* 11-09-2020 Yuxin Zhou Modified comment(s), */
|
|
/* improved packet length */
|
|
/* verification, */
|
|
/* resulting in version 6.1.2 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_response_extract(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT i, j;
|
|
ULONG length;
|
|
|
|
|
|
|
|
/* Search for IP address and DNS address in response. */
|
|
|
|
/* Setup the packet length. */
|
|
length = (((ULONG) packet_ptr -> nx_packet_prepend_ptr[4]) << 8) | ((ULONG) packet_ptr -> nx_packet_prepend_ptr[5]);
|
|
|
|
/* Subtract the request type, id, and length. */
|
|
if (length >= 4)
|
|
length = length - 4;
|
|
else
|
|
length = 0;
|
|
|
|
/* Loop to parse the options to look for primary DNS address. */
|
|
i = 6;
|
|
while (length)
|
|
{
|
|
|
|
/* Subtract the length. */
|
|
if (length >= ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]))
|
|
length = length - ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]);
|
|
else
|
|
length = 0;
|
|
|
|
/* Check for the IP address. */
|
|
if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_IP_ADDRESS_OPTION)
|
|
{
|
|
|
|
|
|
/* Copy the IP address bytes into the PPP storage. */
|
|
for(j = 0; j < 4; j++)
|
|
{
|
|
|
|
/* Copy a byte of the IP address. */
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[j] = packet_ptr -> nx_packet_prepend_ptr[i+j+2];
|
|
}
|
|
}
|
|
|
|
/* Check for the primary DNS option. */
|
|
else if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_DNS_SERVER_OPTION)
|
|
{
|
|
|
|
/* Yes, we have a primary DNS address. */
|
|
|
|
/* Let's copy it into the PPP structure in case we need it later. */
|
|
ppp_ptr -> nx_ppp_primary_dns_address = ((((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+2]) << 24) |
|
|
(((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+3]) << 16) |
|
|
(((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+4]) << 8) |
|
|
((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+5]));
|
|
|
|
}
|
|
|
|
/* Check for the primary DNS option. */
|
|
else if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_DNS_SECONDARY_SERVER_OPTION)
|
|
{
|
|
|
|
/* Yes, we have a secondary DNS address. */
|
|
|
|
/* Let's copy it into the PPP structure in case we need it later. */
|
|
ppp_ptr -> nx_ppp_secondary_dns_address = ((((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+2]) << 24) |
|
|
(((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+3]) << 16) |
|
|
(((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+4]) << 8) |
|
|
((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+5]));
|
|
|
|
|
|
/* Break out of the loop. */
|
|
break;
|
|
}
|
|
|
|
/* Otherwise move to the next option. */
|
|
if (length >= ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]))
|
|
{
|
|
|
|
/* Yes, there is another option. */
|
|
|
|
/* Position to the next option. */
|
|
i = i + (((UINT) packet_ptr -> nx_packet_prepend_ptr[i+1]));
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Make sure the length is 0. */
|
|
length = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_response_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends an IPCP response message. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* type ACK or NAK selection */
|
|
/* data Previous IPCP message */
|
|
/* length Length of previous IPCP msg */
|
|
/* packet_ptr Request packet pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send frame */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_response_send(NX_PPP *ppp_ptr, UCHAR type, UCHAR *data, UCHAR length, NX_PACKET *cfg_packet_ptr)
|
|
{
|
|
|
|
UINT status, i;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the IPCP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Determine if an ACK is requested. */
|
|
if (type == NX_PPP_IPCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(cfg_packet_ptr -> nx_packet_length))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Yes, an ACK is requested. Simply copy the config packet into the new packet and change
|
|
the type. */
|
|
for (i = 0; i < cfg_packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Determine if the copy exceeds the payload. */
|
|
if (&packet_ptr -> nx_packet_prepend_ptr[i] >= packet_ptr -> nx_packet_data_end)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
|
|
/* Simply return. */
|
|
return;
|
|
}
|
|
|
|
/* Copy one byte. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i] = cfg_packet_ptr -> nx_packet_prepend_ptr[i];
|
|
}
|
|
|
|
/* Adjust the type of the new packet to represent an ACK. */
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_IPCP_CONFIGURE_ACK;
|
|
|
|
/* Adjust the length and append pointers of the packet. */
|
|
packet_ptr -> nx_packet_length = cfg_packet_ptr -> nx_packet_length;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 6))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return;
|
|
}
|
|
|
|
/* Build IPCP response message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_IPCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = type;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0x00;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(length + 4);
|
|
|
|
/* Load up the default IP address. */
|
|
for(i = 0; i < length; i++)
|
|
{
|
|
|
|
/* Copy byte of IP address. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+6] = data[i];
|
|
}
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = (UCHAR)(length + 4 + 2);
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IPCP frames sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_frames_sent++;
|
|
|
|
/* Increment counters based on type of response. */
|
|
if (type == NX_PPP_IPCP_CONFIGURE_ACK)
|
|
{
|
|
|
|
/* Increment the number of IPCP configure ACKs sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_acks_sent++;
|
|
}
|
|
else if (type == NX_PPP_IPCP_CONFIGURE_NAK)
|
|
{
|
|
|
|
/* Increment the number of IPCP configure NAKs sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_naks_sent++;
|
|
}
|
|
else if (type == NX_PPP_IPCP_CONFIGURE_REJECT)
|
|
{
|
|
|
|
/* Increment the number of IPCP configure rejects sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_configure_rejects_sent++;
|
|
}
|
|
#endif
|
|
|
|
/* Send IPCP response. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_terminate_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a terminate request message and sends */
|
|
/* it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send AHDLC packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_terminate_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the IPCP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build IPCP terminate message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_IPCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_IPCP_TERMINATE_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_transmit_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0x00;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 0x04;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 6;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IPCP frames sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_frames_sent++;
|
|
|
|
/* Increment the number of IPCP terminate sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_terminate_requests_sent++;
|
|
#endif
|
|
|
|
/* Send IPCP terminate packet. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ipcp_terminate_ack_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds a terminate ACK request message and sends */
|
|
/* it out. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send AHDLC packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_ipcp_state_machine_update IPCP state machine processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_ipcp_terminate_ack_send(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Allocate a packet for the IPCP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return;
|
|
}
|
|
|
|
/* Build IPCP terminate ACK message. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_IPCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_IPCP_TERMINATE_ACK;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_receive_id;
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = 0x00;
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = 0x04;
|
|
|
|
/* Setup the append pointer and the packet length. */
|
|
packet_ptr -> nx_packet_length = 6;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of IPCP frames sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_frames_sent++;
|
|
|
|
/* Increment the number of IPCP terminate ACKs sent. */
|
|
ppp_ptr -> nx_ppp_ipcp_terminate_acks_sent++;
|
|
#endif
|
|
|
|
/* Send IPCP terminate ACK packet. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_packet_transmit PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function adds a CRC to the current transmit buffer and then */
|
|
/* sends the buffer via the user supplied byte output routine. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* packet_ptr Pointer to PPP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* [_nx_ppp_debug_log_capture] Put send frame in debug log */
|
|
/* _nx_ppp_crc_append Add PPP CRC */
|
|
/* (nx_ppp_byte_send) User supplied byte send */
|
|
/* nx_packet_transmit_release Release the transmit packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_process_deferred_ip_packet_send Process deferred IP packet */
|
|
/* _nx_ppp_lcp_code_reject Send LCP code reject message */
|
|
/* _nx_ppp_lcp_configure_reply_send Send LCP configure reply */
|
|
/* _nx_ppp_lcp_configure_request_send Send LCP configure request */
|
|
/* _nx_ppp_lcp_terminate_ack_send Send LCP terminate ACK */
|
|
/* _nx_ppp_lcp_terminate_request_send Send LCP terminate request */
|
|
/* _nx_ppp_pap_authentication_request PAP authentication request */
|
|
/* _nx_ppp_pap_authentication_ack PAP authentication ACK */
|
|
/* _nx_ppp_pap_authentication_nak PAP authentication NAK */
|
|
/* _nx_ppp_chap_challenge_send CHAP challenge send */
|
|
/* _nx_ppp_chap_challenge_respond CHAP challenge respond */
|
|
/* _nx_ppp_chap_challenge_validate CHAP challenge validate */
|
|
/* _nx_ppp_ipcp_configure_request_send Send IPCP configure request */
|
|
/* _nx_ppp_ipcp_response_send Send IPCP response */
|
|
/* _nx_ppp_ipcp_terminate_send Send IPCP terminate */
|
|
/* _nx_ppp_ipcp_terminate_ack_send Send IPCP terminate ACK */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_packet_transmit(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
NX_PACKET *current_packet_ptr;
|
|
UINT i;
|
|
UCHAR byte;
|
|
UCHAR *buffer_ptr;
|
|
UCHAR hdlc[3] = {0x7e, 0xff, 0x03};
|
|
UCHAR crc[2];
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
UINT release_packet = NX_TRUE;
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_ENABLE
|
|
|
|
/* Place the outgoing frame into the optional PPP debug log. */
|
|
_nx_ppp_debug_log_capture(ppp_ptr, 'S', packet_ptr);
|
|
#endif
|
|
|
|
/* Check for send function. */
|
|
if (ppp_ptr -> nx_ppp_byte_send)
|
|
{
|
|
|
|
/* Step1. Send the HDLC bytes. */
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
|
|
/* Pickup the byte. */
|
|
byte = hdlc[i];
|
|
|
|
/* Determine if it needs an escape sequence. */
|
|
if ((byte < ((UCHAR) 0x20)) || ((byte == ((UCHAR) 0x7e)) && (i != 0)) || (byte == ((UCHAR) 0x7d)))
|
|
{
|
|
|
|
/* Yes, this byte needs an escape sequence. */
|
|
|
|
/* Change the byte. */
|
|
byte = byte ^ 0x20;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Send the escape sequence byte via the user supplied output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(0x7d);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Call user supplied byte output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(byte);
|
|
}
|
|
|
|
/* Step2. Send the data. */
|
|
/* Initialize the current packet pointer to the packet pointer. */
|
|
current_packet_ptr = packet_ptr;
|
|
|
|
/* Setup the initial buffer pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Loop through the buffer to send each byte out. */
|
|
for(i = 0; i < packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Determine if we need to move to any additional packets. */
|
|
if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
|
|
{
|
|
|
|
|
|
/* Yes, we need to move to the next packet. */
|
|
current_packet_ptr = current_packet_ptr -> nx_packet_next;
|
|
|
|
/* Determine if there is a next packet. */
|
|
if (current_packet_ptr == NX_NULL)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the internal error counter. */
|
|
ppp_ptr -> nx_ppp_internal_errors++;
|
|
#endif
|
|
|
|
/* Get out of the loop. */
|
|
break;
|
|
}
|
|
|
|
/* Otherwise setup new buffer pointer. */
|
|
buffer_ptr = current_packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
}
|
|
|
|
/* Pickup the next byte to be sent. */
|
|
byte = *buffer_ptr++;
|
|
|
|
/* Determine if this byte needs an escape sequence. */
|
|
if ((byte < ((UCHAR) 0x20)) || (byte == 0x7e) || (byte == 0x7d))
|
|
{
|
|
|
|
/* Yes, this byte needs an escape sequence. */
|
|
|
|
/* Change the byte. */
|
|
byte = byte ^ 0x20;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Send the escape sequence byte via the user supplied output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(0x7d);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Call user supplied byte output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(byte);
|
|
}
|
|
|
|
/* Step3. Send CRC. */
|
|
/* Place a CRC at the end of the transmit buffer. */
|
|
_nx_ppp_crc_append(packet_ptr, crc);
|
|
|
|
/* Now send the CRC and end-of-frame bytes. */
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
|
|
/* Pickup the byte. */
|
|
byte = crc[i];
|
|
|
|
/* Determine if it needs an escape sequence. */
|
|
if ((byte < ((UCHAR) 0x20)) || (byte == ((UCHAR) 0x7e)) || (byte == ((UCHAR) 0x7d)))
|
|
{
|
|
|
|
/* Yes, this byte needs an escape sequence. */
|
|
|
|
/* Change the byte. */
|
|
byte = byte ^ 0x20;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Send the escape sequence byte via the user supplied output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(0x7d);
|
|
}
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of bytes sent. */
|
|
ppp_ptr -> nx_ppp_bytes_sent++;
|
|
#endif
|
|
|
|
/* Call user supplied byte output routine. */
|
|
ppp_ptr -> nx_ppp_byte_send(byte);
|
|
}
|
|
|
|
/* Step4. Finally, send an end-of-frame character. */
|
|
ppp_ptr -> nx_ppp_byte_send((UCHAR) 0x7e);
|
|
}
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
|
|
/* Check the PPPoE packet send function. */
|
|
if (ppp_ptr -> nx_ppp_packet_send)
|
|
{
|
|
|
|
/* Send the packet out. */
|
|
(ppp_ptr -> nx_ppp_packet_send)(packet_ptr);
|
|
|
|
/* Update the flag since this packet should been released in PPPoE. */
|
|
release_packet = NX_FALSE;
|
|
|
|
}
|
|
|
|
/* Check if need to release the packet. */
|
|
if (release_packet == NX_TRUE)
|
|
{
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|
|
/* Remove the PPP header. */
|
|
packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
|
|
packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
|
|
|
|
/* Release the packet. */
|
|
nx_packet_transmit_release(packet_ptr);
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
}
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_check_crc PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function processes the CRC of the AHDLC packet in the packet */
|
|
/* payload. If the CRC is correct, the CRC is removed from the receive */
|
|
/* buffer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* packet_ptr Address of PPP instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_receive_packet_get Receive PPP packet processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_check_crc(NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
NX_PACKET *current_packet_ptr;
|
|
UCHAR byte;
|
|
UCHAR *buffer_ptr;
|
|
USHORT i;
|
|
USHORT crc_value;
|
|
|
|
|
|
/* Set initial CRC value. */
|
|
crc_value = 0xffff;
|
|
|
|
/* Setup buffer pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr + 1;
|
|
|
|
/* Setup the current packet pointer. */
|
|
current_packet_ptr = packet_ptr;
|
|
|
|
/* Loop to process the CRC for the receive buffer. */
|
|
for(i = 1; i < (packet_ptr -> nx_packet_length - 1); i++)
|
|
{
|
|
|
|
/* Determine if the buffer pointer is inside the current packet. */
|
|
if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
|
|
{
|
|
|
|
|
|
/* We have exhausted this packet and must move to the next. */
|
|
current_packet_ptr = current_packet_ptr -> nx_packet_next;
|
|
|
|
/* Determine if there is a next packet. */
|
|
if (current_packet_ptr == NX_NULL)
|
|
break;
|
|
|
|
/* Otherwise, we have a valid next packet. Setup the buffer pointer
|
|
to the first byte in the next packet. */
|
|
buffer_ptr = current_packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
}
|
|
|
|
/* Pickup character from buffer. */
|
|
byte = *buffer_ptr++;
|
|
|
|
/* Update the CRC. */
|
|
crc_value = (( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ byte ]);
|
|
}
|
|
|
|
/* At this point, the CRC should be 0xf0b8. */
|
|
if (crc_value != 0xf0b8)
|
|
{
|
|
|
|
/* CRC failed, not a valid PPP packet. */
|
|
return(NX_PPP_BAD_PACKET);
|
|
}
|
|
|
|
/* Return successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_crc_append PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function calculates and appends the two byte CRC to the */
|
|
/* frame. It also adds the end of frame marker after the CRC. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* packet_ptr Pointer to PPP packet */
|
|
/* crc Destination for CRC */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_packet_transmit PPP packet transmit routine */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_crc_append(NX_PACKET *packet_ptr, UCHAR crc[2])
|
|
{
|
|
|
|
NX_PACKET *current_packet_ptr;
|
|
UCHAR *buffer_ptr;
|
|
UINT i;
|
|
USHORT crc_value;
|
|
UCHAR byte;
|
|
UCHAR address = 0xff;
|
|
UCHAR control = 0x03;
|
|
|
|
|
|
/* The FCS field is calculated over all bits of the Address, Control,
|
|
Protocol, Information and Padding fields, not including any start
|
|
and stop bits (asynchronous) nor any bits (synchronous) or octets
|
|
(asynchronous or synchronous) inserted for transparency. This
|
|
also does not include the Flag Sequences nor the FCS field itself.
|
|
RFC1662, Section3.1, Page6. */
|
|
|
|
/* Initialize CRC value. */
|
|
crc_value = 0xffff;
|
|
|
|
/* Step1. Calculate address and control. */
|
|
crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ address ];
|
|
crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ control ];
|
|
|
|
/* Step2. Calculate protocol, information and padding fiedls. */
|
|
|
|
/* Initialize the current packet pointer to the packet pointer. */
|
|
current_packet_ptr = packet_ptr;
|
|
|
|
/* Setup the initial buffer pointer. */
|
|
buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
/* Loop to calculate CRC. */
|
|
for(i = 0; i < packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Determine if we need to move to any additional packets. */
|
|
if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
|
|
{
|
|
|
|
|
|
/* Yes, we need to move to the next packet. */
|
|
current_packet_ptr = current_packet_ptr -> nx_packet_next;
|
|
|
|
/* Determine if there is a next packet. */
|
|
if (current_packet_ptr == NX_NULL)
|
|
{
|
|
|
|
/* Get out of the loop. */
|
|
break;
|
|
}
|
|
|
|
/* Otherwise setup new buffer pointer. */
|
|
buffer_ptr = current_packet_ptr -> nx_packet_prepend_ptr;
|
|
|
|
}
|
|
|
|
/* Pickup the next byte to be sent. */
|
|
byte = *buffer_ptr++;
|
|
|
|
/* Update the CRC. */
|
|
crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ byte ];
|
|
}
|
|
|
|
/* Now complement the CRC value. */
|
|
crc_value = crc_value ^ 0xffff;
|
|
|
|
/* Store first byte of the CRC. */
|
|
crc[0] = (UCHAR) (crc_value & 0xff);
|
|
|
|
/* Store second byte of the CRC. */
|
|
crc[1] = (UCHAR) ((crc_value >> 8) & 0xff);
|
|
|
|
/* Return a successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_ENABLE
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_debug_log_capture PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function places the current frame into the circular debug */
|
|
/* log. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP structure */
|
|
/* packet_type Either a send or receive */
|
|
/* packet_ptr Pointer to PPP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_time_get Get time */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_packet_transmit Transmit packet processing */
|
|
/* _nx_ppp_thread_entry Receive thread processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_debug_log_capture(NX_PPP *ppp_ptr, UCHAR packet_type, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT i;
|
|
ULONG time;
|
|
NX_PPP_DEBUG_ENTRY *entry_ptr;
|
|
|
|
/* Check for a NULL pointer. */
|
|
if (packet_ptr == NX_NULL)
|
|
return;
|
|
|
|
/* Pickup current time. */
|
|
time = tx_time_get();
|
|
|
|
#ifdef NX_PPP_DEBUG_LOG_PRINT_ENABLE
|
|
/* Print out the current time stamp. */
|
|
printf("Time: %lu, ", time);
|
|
|
|
/* Print out the PPP name. */
|
|
printf("PPP Name: %s, ", ppp_ptr -> nx_ppp_name);
|
|
|
|
/* Print out the current PPP state. */
|
|
printf("PPP State: %u, ", ppp_ptr -> nx_ppp_state);
|
|
|
|
/* Print out the current PPP LCP state. */
|
|
printf("PPP LCP State: %u, ", ppp_ptr -> nx_ppp_lcp_state);
|
|
|
|
/* Print out the current PPP PAP state. */
|
|
printf("PPP PAP State: %u, ", ppp_ptr -> nx_ppp_pap_state);
|
|
|
|
/* Print out the current PPP CHAP state. */
|
|
printf("PPP CHAP State: %u, ", ppp_ptr -> nx_ppp_chap_state);
|
|
|
|
/* Print out the current IPCP state. */
|
|
printf("PPP IPCP State: %u, ", ppp_ptr -> nx_ppp_ipcp_state);
|
|
|
|
/* Print out the authentication flag. */
|
|
if (ppp_ptr -> nx_ppp_authenticated)
|
|
printf("Authenticated, ");
|
|
else
|
|
printf("Not Authenticated, ");
|
|
|
|
/* Determine if the packet is a receive packet or a send packet. */
|
|
if (packet_type == 'R')
|
|
printf("Received Packet Length: %lu, Packet: ", packet_ptr -> nx_packet_length);
|
|
else
|
|
printf("Send Packet Length: %lu, Packet: ", packet_ptr -> nx_packet_length);
|
|
|
|
/* Dump out at least part of the packet payload. */
|
|
for (i = 0; i < packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Check for packet spanning multiple packets. */
|
|
if ((packet_ptr -> nx_packet_prepend_ptr+i) >= packet_ptr -> nx_packet_append_ptr)
|
|
break;
|
|
|
|
/* Check for maximum dump size. */
|
|
if (i >= NX_PPP_DEBUG_FRAME_SIZE)
|
|
break;
|
|
|
|
/* Print one character. */
|
|
printf("%02x ", packet_ptr -> nx_packet_prepend_ptr[i]);
|
|
}
|
|
|
|
printf("\n");
|
|
#endif /* NX_PPP_DEBUG_LOG_PRINT_ENABLE */
|
|
|
|
/* Now load the internal PPP log. */
|
|
|
|
/* Setup the debug log entry pointer. */
|
|
entry_ptr = &(ppp_ptr -> nx_ppp_debug_log[ppp_ptr -> nx_ppp_debug_log_oldest_index++]);
|
|
|
|
/* Check for wrap-around of the index. */
|
|
if (ppp_ptr -> nx_ppp_debug_log_oldest_index >= NX_PPP_DEBUG_LOG_SIZE)
|
|
ppp_ptr -> nx_ppp_debug_log_oldest_index = 0;
|
|
|
|
/* Setup the debug log entries. */
|
|
entry_ptr -> nx_ppp_debug_entry_time_stamp = time;
|
|
entry_ptr -> nx_ppp_debug_ppp_state = (UCHAR) ppp_ptr -> nx_ppp_state;
|
|
entry_ptr -> nx_ppp_debug_lcp_state = (UCHAR) ppp_ptr -> nx_ppp_lcp_state;
|
|
entry_ptr -> nx_ppp_debug_pap_state = (UCHAR) ppp_ptr -> nx_ppp_pap_state;
|
|
entry_ptr -> nx_ppp_debug_chap_state = (UCHAR) ppp_ptr -> nx_ppp_chap_state;
|
|
entry_ptr -> nx_ppp_debug_ipcp_state = (UCHAR) ppp_ptr -> nx_ppp_ipcp_state;
|
|
entry_ptr -> nx_ppp_debug_authenticated = ppp_ptr -> nx_ppp_authenticated;
|
|
entry_ptr -> nx_ppp_debug_frame_type = packet_type;
|
|
entry_ptr -> nx_ppp_debug_packet_length = packet_ptr -> nx_packet_length;
|
|
|
|
/* Store at least part of the packet payload. */
|
|
for (i = 0; i < packet_ptr -> nx_packet_length; i++)
|
|
{
|
|
|
|
/* Check for packet spanning multiple packets. */
|
|
if ((packet_ptr -> nx_packet_prepend_ptr+i) >= packet_ptr -> nx_packet_append_ptr)
|
|
break;
|
|
|
|
/* Check for maximum dump size. */
|
|
if (i >= NX_PPP_DEBUG_FRAME_SIZE)
|
|
break;
|
|
|
|
/* Store one character. */
|
|
entry_ptr -> nx_ppp_debug_frame[i] = packet_ptr -> nx_packet_prepend_ptr[i];
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_debug_log_capture_protocol PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function outputs the status of various protocols and timeouts */
|
|
/* of the specified PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP structure */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_thread_entry PPP event processing */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_debug_log_capture_protocol(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
|
|
/* Print out the PPP name. */
|
|
printf("%s: ", ppp_ptr -> nx_ppp_name);
|
|
|
|
/* Print out the current PPP state. */
|
|
printf("State: %u, ", ppp_ptr -> nx_ppp_state);
|
|
|
|
/* Print out the current PPP LCP state. */
|
|
printf("LCP State: %u, ", ppp_ptr -> nx_ppp_lcp_state);
|
|
|
|
/* Print out the current IPCP state. */
|
|
printf("IPCP State: %u, ", ppp_ptr -> nx_ppp_ipcp_state);
|
|
|
|
if ((ppp_ptr -> nx_ppp_chap_enabled) || (ppp_ptr -> nx_ppp_pap_enabled))
|
|
{
|
|
|
|
/* Print out the authentication flag. */
|
|
if (ppp_ptr -> nx_ppp_authenticated)
|
|
printf("Authenticated, ");
|
|
else
|
|
{
|
|
|
|
printf("Not Authenticated, ");
|
|
|
|
/* Print out the current PPP PAP state. */
|
|
printf("PAP State: %u, ", ppp_ptr -> nx_ppp_pap_state);
|
|
|
|
/* Print out the current PPP CHAP state. */
|
|
printf("CHAP State: %u, ", ppp_ptr -> nx_ppp_chap_state);
|
|
}
|
|
}
|
|
|
|
/* Print out the current PPP LCP state. */
|
|
printf("Time remaining: %lu, ", ppp_ptr -> nx_ppp_timeout);
|
|
printf("Timeouts: %lu, ", ppp_ptr -> nx_ppp_receive_timeouts);
|
|
printf("Protocol retries: %lu, ", ppp_ptr -> nx_ppp_protocol_retry_counter);
|
|
|
|
printf("\n");
|
|
}
|
|
#endif /* NX_PPP_DEBUG_LOG_ENABLE */
|
|
|
|
|
|
#ifndef NX_PPP_DISABLE_CHAP
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_hash_generator PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function calculates the MD5 hash value for CHAP authentication */
|
|
/* processing. The input challenge "rand_value" is a stream of octets,*/
|
|
/* including 0x0, so the length option ensures the rand_value length is*/
|
|
/* set correctly. */
|
|
/* */
|
|
/* If the caller is certain there is no 0x0 within the rand_value it */
|
|
/* can send a zero length arguement and this function will compute the */
|
|
/* rand_value length. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* hvalue Hash value return string */
|
|
/* id PPP message ID */
|
|
/* secret Secret input string */
|
|
/* rand_value Random value input string */
|
|
/* length Length of random string, */
|
|
/* if zero, assume null */
|
|
/* terminated */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge_respond CHAP challenge response */
|
|
/* _nx_ppp_chap_challenge_validate CHAP validate response */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_hash_generator(unsigned char *hvalue, unsigned char id,
|
|
unsigned char *secret, unsigned char *rand_value, UINT length)
|
|
{
|
|
|
|
UINT slen, rlen;
|
|
NX_MD5 context;
|
|
|
|
|
|
/* Compute the length of the secret. */
|
|
for(slen = 0; secret[slen]; slen++);
|
|
|
|
/* Compute the length of the rand_value if no length is specified. */
|
|
if(length==0)
|
|
{
|
|
for(rlen = 0; rand_value[rlen]; rlen++);
|
|
}
|
|
else
|
|
{
|
|
rlen = length;
|
|
}
|
|
|
|
/* Initialize the MD5 digest calculation. */
|
|
_nx_md5_initialize(&context);
|
|
|
|
/* Update the digest. */
|
|
_nx_md5_update(&context, &id, 1);
|
|
_nx_md5_update(&context, secret, slen);
|
|
_nx_md5_update(&context, rand_value, rlen);
|
|
|
|
/* Finally, calculate the digest. */
|
|
_nx_md5_digest_calculate(&context, hvalue);
|
|
}
|
|
#endif /* NX_PPP_DISABLE_CHAP */
|
|
|
|
|
|
/* Define externally available API functions. */
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_byte_receive PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP byte receive */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* byte Newly received byte */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_byte_receive Actual PPP byte receive */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_byte_receive(NX_PPP *ppp_ptr, UCHAR byte)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Call actual byte receive function. */
|
|
status = _nx_ppp_byte_receive(ppp_ptr, byte);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_byte_receive PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function receives a byte from the application (usually an */
|
|
/* application ISR), buffers it, and notifies the PPP receive thread. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* byte Newly received byte */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Notify PPP receiving thread */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code (Including ISRs) */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_byte_receive(NX_PPP *ppp_ptr, UCHAR byte)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Check for no longer active PPP instance. */
|
|
if (ppp_ptr -> nx_ppp_id != NX_PPP_ID)
|
|
{
|
|
|
|
/* PPP is no longer active. */
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Return an error. */
|
|
return(NX_PTR_ERROR);
|
|
}
|
|
|
|
/* Check for a stopped PPP instance. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Silently discard byte. */
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
/* Determine if there is enough room in the serial buffer. */
|
|
if (ppp_ptr -> nx_ppp_serial_buffer_byte_count >= NX_PPP_SERIAL_BUFFER_SIZE)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
/* Increment the number of bytes dropped. */
|
|
ppp_ptr -> nx_ppp_bytes_dropped++;
|
|
#endif
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* No, return an error. */
|
|
return(NX_PPP_BUFFER_FULL);
|
|
}
|
|
|
|
/* Otherwise, PPP is active and there is room in the buffer! */
|
|
|
|
/* Place the byte in the buffer. */
|
|
ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_write_index++] = byte;
|
|
|
|
/* Check for a wrap-around of the serial buffer. */
|
|
if (ppp_ptr -> nx_ppp_serial_buffer_write_index >= NX_PPP_SERIAL_BUFFER_SIZE)
|
|
{
|
|
|
|
/* Yes, buffer wrap-around is present. Reset the write pointer to the beginning of the
|
|
buffer. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_write_index = 0;
|
|
}
|
|
|
|
/* Increment the byte count. */
|
|
ppp_ptr -> nx_ppp_serial_buffer_byte_count++;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
/* Increment the number of bytes received. */
|
|
ppp_ptr -> nx_ppp_bytes_received++;
|
|
#endif
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Determine if the PPP receive thread needs to be alerted. */
|
|
if ((ppp_ptr -> nx_ppp_serial_buffer_byte_count >= NX_PPP_SERIAL_BUFFER_ALERT_THRESHOLD) ||
|
|
(byte == 0x7e))
|
|
{
|
|
|
|
/* Yes, alert the receiving thread that a byte is available for processing. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_PACKET_RECEIVE, TX_OR);
|
|
}
|
|
|
|
/* Return successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_create PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP create instance */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* name Pointer to instance name */
|
|
/* ip_ptr Pointer to IP instance */
|
|
/* stack_memory_ptr Pointer to thread stack */
|
|
/* stack_size Pointer to thread stack size */
|
|
/* thread_priority Priority of thread(s) created */
|
|
/* for PPP */
|
|
/* pool_ptr Default packet pool pointer */
|
|
/* ppp_non_ppp_packet_handler Non PPP packet handler */
|
|
/* provided by the application */
|
|
/* ppp_byte_send Byte output function provided */
|
|
/* by the application */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_create Actual PPP create function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_create(NX_PPP *ppp_ptr, CHAR *name, NX_IP *ip_ptr,
|
|
VOID *stack_memory_ptr, ULONG stack_size, UINT thread_priority,
|
|
NX_PACKET_POOL *pool_ptr,
|
|
void (*ppp_non_ppp_packet_handler)(NX_PACKET *packet_ptr),
|
|
void (*ppp_byte_send)(UCHAR byte))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id == NX_PPP_ID) ||
|
|
(ip_ptr == NX_NULL) || (stack_memory_ptr == NX_NULL) || (pool_ptr == NX_NULL))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP create function. */
|
|
status = _nx_ppp_create(ppp_ptr, name, ip_ptr, stack_memory_ptr, stack_size, thread_priority,
|
|
pool_ptr, ppp_non_ppp_packet_handler, ppp_byte_send);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_create PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function creates a PPP instance for the specified IP. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* name Pointer to instance name */
|
|
/* ip_ptr Pointer to IP instance */
|
|
/* stack_memory_ptr Pointer to thread stack */
|
|
/* stack_size Pointer to thread stack size */
|
|
/* thread_priority Priority of thread(s) created */
|
|
/* for PPP */
|
|
/* pool_ptr Default packet pool pointer */
|
|
/* ppp_non_ppp_packet_handler Non PPP packet handler */
|
|
/* provided by the application */
|
|
/* ppp_byte_send Byte output function provided */
|
|
/* by the application */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_create Create PPP event flags group */
|
|
/* tx_thread_create Create PPP helper thread */
|
|
/* tx_time_get Get time for IDs */
|
|
/* tx_timer_create Create PPP timer */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_create(NX_PPP *ppp_ptr, CHAR *name, NX_IP *ip_ptr,
|
|
VOID *stack_memory_ptr, ULONG stack_size, UINT thread_priority,
|
|
NX_PACKET_POOL *pool_ptr,
|
|
void (*ppp_non_ppp_packet_handler)(NX_PACKET *packet_ptr),
|
|
void (*ppp_byte_send)(UCHAR byte))
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
NX_PPP *tail_ptr;
|
|
|
|
|
|
/* Check the supplied packet pool for minimum required payload length. */
|
|
if (pool_ptr -> nx_packet_pool_payload_size < NX_PPP_MIN_PACKET_PAYLOAD)
|
|
{
|
|
return(NX_PPP_BAD_PACKET);
|
|
}
|
|
|
|
/* Initialize the PPP control block to zero. */
|
|
memset((void *) ppp_ptr, 0, sizeof(NX_PPP));
|
|
|
|
/* Save the PPP name. */
|
|
ppp_ptr -> nx_ppp_name = name;
|
|
|
|
/* Save the IP pointer. */
|
|
ppp_ptr -> nx_ppp_ip_ptr = ip_ptr;
|
|
|
|
/* Save the packet pool pointer. */
|
|
ppp_ptr -> nx_ppp_packet_pool_ptr = pool_ptr;
|
|
|
|
/* Save the byte output routine specified by the user. */
|
|
ppp_ptr -> nx_ppp_byte_send = ppp_byte_send;
|
|
ppp_ptr -> nx_ppp_non_ppp_packet_handler = ppp_non_ppp_packet_handler;
|
|
|
|
/* Setup the initial state. */
|
|
ppp_ptr -> nx_ppp_state = NX_PPP_STOPPED;
|
|
|
|
/* Setup the Maximum Receive Unit (MRU). */
|
|
ppp_ptr -> nx_ppp_mru = NX_PPP_MRU;
|
|
|
|
/* Setup receive and transmit IDs. */
|
|
ppp_ptr -> nx_ppp_transmit_id = (UCHAR) tx_time_get();
|
|
|
|
/* Default the authenticated field to true. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_TRUE;
|
|
|
|
/* Create event flag group to control the PPP processing thread. */
|
|
tx_event_flags_create(&(ppp_ptr -> nx_ppp_event), "PPP EVENTS") ;
|
|
|
|
/* Create the PPP processing thread. Note that this thread does not run until the PPP driver is
|
|
initialized during the IP create. */
|
|
tx_thread_create(&(ppp_ptr -> nx_ppp_thread), "PPP THREAD", _nx_ppp_thread_entry, (ULONG) ppp_ptr,
|
|
stack_memory_ptr, stack_size, thread_priority, thread_priority, NX_PPP_THREAD_TIME_SLICE, TX_DONT_START);
|
|
|
|
/* Create the PPP timeout timer. */
|
|
tx_timer_create(&(ppp_ptr -> nx_ppp_timer), "PPP TIMER", _nx_ppp_timer_entry, (ULONG) ppp_ptr, NX_PPP_BASE_TIMEOUT, NX_PPP_BASE_TIMEOUT, TX_NO_ACTIVATE);
|
|
|
|
/* Otherwise, the PPP initialization was successful. Place the
|
|
PPP control block on the list of created PPP instances. */
|
|
TX_DISABLE
|
|
|
|
/* Load the PPP ID field in the PPP control block. */
|
|
ppp_ptr -> nx_ppp_id = NX_PPP_ID;
|
|
|
|
/* Place the new PPP control block on the list of created IPs. First,
|
|
check for an empty list. */
|
|
if (_nx_ppp_created_ptr)
|
|
{
|
|
|
|
/* Pickup tail pointer. */
|
|
tail_ptr = _nx_ppp_created_ptr -> nx_ppp_created_previous;
|
|
|
|
/* Place the new PPP control block in the list. */
|
|
_nx_ppp_created_ptr -> nx_ppp_created_previous = ppp_ptr;
|
|
tail_ptr -> nx_ppp_created_next = ppp_ptr;
|
|
|
|
/* Setup this PPP's created links. */
|
|
ppp_ptr -> nx_ppp_created_previous = tail_ptr;
|
|
ppp_ptr -> nx_ppp_created_next = _nx_ppp_created_ptr;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* The created PPP list is empty. Add PPP control block to empty list. */
|
|
_nx_ppp_created_ptr = ppp_ptr;
|
|
ppp_ptr -> nx_ppp_created_next = ppp_ptr;
|
|
ppp_ptr -> nx_ppp_created_previous = ppp_ptr;
|
|
}
|
|
|
|
/* Increment the created PPP counter. */
|
|
_nx_ppp_created_count++;
|
|
|
|
/* Restore previous interrupt posture. */
|
|
TX_RESTORE
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_delete PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP delete instance */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_delete Actual PPP delete function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_delete(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP delete function. */
|
|
status = _nx_ppp_delete(ppp_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_delete PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function deletes a PPP instance for the specified IP. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_delete Delete PPP event flags group */
|
|
/* tx_event_flags_set Set PPP event flag to stop PPP*/
|
|
/* tx_thread_delete Create PPP helper threads */
|
|
/* tx_thread_identify Identify current thread */
|
|
/* tx_thread_sleep Sleep for a small time */
|
|
/* tx_timer_deactivate Timer deactivate */
|
|
/* tx_timer_delete Delete timer */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_delete(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
|
|
/* Determine if the caller is the PPP thread itself. This is not allowed since
|
|
a thread cannot delete itself in ThreadX. */
|
|
if (&ppp_ptr -> nx_ppp_thread == tx_thread_identify())
|
|
{
|
|
|
|
/* Invalid caller of this routine, return an error! */
|
|
return(NX_CALLER_ERROR);
|
|
}
|
|
|
|
/* Set the event to close the PPP thread. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Now wait until the PPP thread goes to a closed state before proceeding with the delete.
|
|
This will give PPP the opportunity to properly release all packets being worked on. */
|
|
while (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Sleep for a tick. */
|
|
tx_thread_sleep(1);
|
|
}
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Clear the PPP ID to show that it is no longer valid. */
|
|
ppp_ptr -> nx_ppp_id = 0;
|
|
|
|
/* Decrement the number of PPP instances created. */
|
|
_nx_ppp_created_count--;
|
|
|
|
/* See if the PPP instance is the only one on the list. */
|
|
if (ppp_ptr == ppp_ptr -> nx_ppp_created_next)
|
|
{
|
|
|
|
/* Only created PPP instance, just set the created list to NULL. */
|
|
_nx_ppp_created_ptr = TX_NULL;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Link-up the neighbors. */
|
|
(ppp_ptr -> nx_ppp_created_next) -> nx_ppp_created_previous =
|
|
ppp_ptr -> nx_ppp_created_previous;
|
|
(ppp_ptr -> nx_ppp_created_previous) -> nx_ppp_created_next =
|
|
ppp_ptr -> nx_ppp_created_next;
|
|
|
|
/* See if we have to update the created list head pointer. */
|
|
if (_nx_ppp_created_ptr == ppp_ptr)
|
|
|
|
/* Yes, move the head pointer to the next link. */
|
|
_nx_ppp_created_ptr = ppp_ptr -> nx_ppp_created_next;
|
|
}
|
|
|
|
/* Restore previous interrupt posture. */
|
|
TX_RESTORE
|
|
|
|
/* Terminate the thread. */
|
|
tx_thread_terminate(&(ppp_ptr -> nx_ppp_thread));
|
|
|
|
/* Delete the PPP thread. */
|
|
tx_thread_delete(&(ppp_ptr -> nx_ppp_thread));
|
|
|
|
/* Deactivate the PPP timer. */
|
|
tx_timer_deactivate(&(ppp_ptr -> nx_ppp_timer));
|
|
|
|
/* Delete the PPP timer. */
|
|
tx_timer_delete(&(ppp_ptr -> nx_ppp_timer));
|
|
|
|
/* Delete the event flag group. */
|
|
tx_event_flags_delete(&(ppp_ptr -> nx_ppp_event));
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_link_up_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP link up notify callback */
|
|
/* notify set function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* ppp_link_up_callback Pointer to application */
|
|
/* callback function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_link_up_notify Actual PPP link up notify set */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_link_up_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_up_callback)(NX_PPP *ppp_ptr))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP link up notify set function. */
|
|
status = _nx_ppp_link_up_notify(ppp_ptr, ppp_link_up_callback);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_link_up_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function registers an application callback for the link up */
|
|
/* event. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* ppp_link_up_callback Pointer to application */
|
|
/* callback function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_link_up_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_up_callback)(NX_PPP *ppp_ptr))
|
|
{
|
|
|
|
/* Valid PPP pointer, now setup the notification callback. Note that supplying
|
|
a NULL for the callback will disable notification. */
|
|
ppp_ptr -> nx_ppp_link_up_callback = ppp_link_up_callback;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_link_down_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP link down notify callback*/
|
|
/* notify set function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* ppp_link_down_callback Pointer to application */
|
|
/* callback function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_link_down_notify Actual PPP link down notify */
|
|
/* set function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_link_down_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_down_callback)(NX_PPP *ppp_ptr))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP link down notify set function. */
|
|
status = _nx_ppp_link_down_notify(ppp_ptr, ppp_link_down_callback);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_link_down_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function registers an application callback for the link down */
|
|
/* event. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* ppp_link_down_callback Pointer to application */
|
|
/* callback function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_link_down_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_down_callback)(NX_PPP *ppp_ptr))
|
|
{
|
|
|
|
/* Valid PPP pointer, now setup the notification callback. Note that supplying
|
|
a NULL for the callback will disable notification. */
|
|
ppp_ptr -> nx_ppp_link_down_callback = ppp_link_down_callback;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_pap_enable PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP PAP enable */
|
|
/* function call. */
|
|
/* */
|
|
/* Note: The first string lengths of name and password are limited by */
|
|
/* internal buffer size. The second string of name and password are */
|
|
/* NULL terminated. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* generate_login Pointer to login function */
|
|
/* verify_login Pointer to verify function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_pap_enable Actual PPP PAP enable function*/
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_pap_enable(NX_PPP *ppp_ptr, UINT (*generate_login)(CHAR *name, CHAR *password),
|
|
UINT (*verify_login)(CHAR *name, CHAR *password))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer... including not being in the closed state for this configuration API. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED) ||
|
|
((generate_login == NX_NULL) && (verify_login == NX_NULL)))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP PAP enable function. */
|
|
status = _nx_ppp_pap_enable(ppp_ptr, generate_login, verify_login);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_pap_enable PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function enables PAP for the specified PPP instance. */
|
|
/* */
|
|
/* Note: The first string lengths of name and password are limited by */
|
|
/* internal buffer size. The second string of name and password are */
|
|
/* NULL terminated. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* generate_login Pointer to application */
|
|
/* function that generates */
|
|
/* name and password for login */
|
|
/* verify_login Pointer to application */
|
|
/* function that verifies the */
|
|
/* supplied name and password */
|
|
/* are valid */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_pap_enable(NX_PPP *ppp_ptr, UINT (*generate_login)(CHAR *name, CHAR *password),
|
|
UINT (*verify_login)(CHAR *name, CHAR *password))
|
|
{
|
|
|
|
#ifdef NX_PPP_DISABLE_PAP
|
|
|
|
/* Return the non implemented error. */
|
|
return(NX_NOT_IMPLEMENTED);
|
|
|
|
#else
|
|
|
|
/* Setup the PAP information. */
|
|
if (generate_login)
|
|
{
|
|
|
|
/* Setup login generation information. */
|
|
ppp_ptr -> nx_ppp_pap_generate_login = generate_login;
|
|
|
|
/* The authenticated flag is not cleared for the generate login, since the
|
|
peer may choose not to require PAP. */
|
|
}
|
|
|
|
/* Determine if the generate login is provided. */
|
|
if (verify_login)
|
|
{
|
|
/* Setup login verification information. */
|
|
ppp_ptr -> nx_ppp_pap_verify_login = verify_login;
|
|
ppp_ptr -> nx_ppp_verify_authentication_protocol = NX_PPP_PAP_PROTOCOL;
|
|
|
|
/* Authentication is needed, clear the flag. */
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
}
|
|
|
|
/* Show that the PAP is enabled. */
|
|
ppp_ptr -> nx_ppp_pap_enabled = NX_TRUE;
|
|
|
|
/* Set the initial PAP state. */
|
|
ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_INITIAL_STATE;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
#endif
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_chap_challenge PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP CHAP challenge */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge Actual PPP CHAP challenge */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_chap_challenge(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP CHAP challenge function. */
|
|
status = _nx_ppp_chap_challenge(ppp_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_challenge PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function generates a CHAP challenge for the specified PPP */
|
|
/* instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Notify PPP receiving thread */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_chap_challenge(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
#ifdef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Return the non implemented error. */
|
|
return(NX_NOT_IMPLEMENTED);
|
|
|
|
#else
|
|
|
|
/* Determine if the CHAP of the PPP instance is enabled and able to challenge. */
|
|
if ((ppp_ptr -> nx_ppp_chap_enabled) &&
|
|
(ppp_ptr -> nx_ppp_chap_get_challenge_values) &&
|
|
(ppp_ptr -> nx_ppp_chap_get_verification_values))
|
|
{
|
|
|
|
/* Check for the appropriate CHAP state. If the initial CHAP has not yet
|
|
completed, simply discard this request. */
|
|
if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_COMPLETED_STATE)
|
|
{
|
|
|
|
/* Yes, the CHAP protocol is in an open state so another challenge is legal. */
|
|
|
|
/* Initiate CHAP challenge by setting the appropriate event flag to wakeup the PPP thread. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_CHAP_CHALLENGE, TX_OR);
|
|
}
|
|
|
|
/* Return successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* CHAP is either not enabled or is setup only for CHAP response - not a challenge. Return an error! */
|
|
return(NX_PPP_FAILURE);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_chap_enable PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP CHAP enable */
|
|
/* function call. */
|
|
/* */
|
|
/* Note: The string lengths of rand_value, name, system and secret are */
|
|
/* limited by internal buffer size. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* get_challenge_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to make */
|
|
/* a challenge */
|
|
/* get_responder_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to respond */
|
|
/* to a challenge */
|
|
/* get_verification_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to verify */
|
|
/* a challenge */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_chap_enable Actual PPP CHAP enable */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_chap_enable(NX_PPP *ppp_ptr,
|
|
UINT (*get_challenge_values)(CHAR *rand_value, CHAR *id, CHAR *name),
|
|
UINT (*get_responder_values)(CHAR *system, CHAR *name, CHAR *secret),
|
|
UINT (*get_verification_values)(CHAR *system, CHAR *name, CHAR *secret))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer... including not being in the closed state for this configuration API. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED) ||
|
|
((get_challenge_values == NX_NULL) && (get_responder_values == NX_NULL) && (get_verification_values == NX_NULL)))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP CHAP enable function. */
|
|
status = _nx_ppp_chap_enable(ppp_ptr, get_challenge_values, get_responder_values, get_verification_values);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_chap_enable PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function enables CHAP for the specified PPP instance. */
|
|
/* */
|
|
/* Note: The string lengths of rand_value, name, system and secret are */
|
|
/* limited by internal buffer size. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* get_challenge_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to make */
|
|
/* a challenge */
|
|
/* get_responder_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to respond */
|
|
/* to a challenge */
|
|
/* get_verification_values Pointer to application */
|
|
/* function that retrieves */
|
|
/* values required to verify */
|
|
/* a challenge response */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_chap_enable(NX_PPP *ppp_ptr,
|
|
UINT (*get_challenge_values)(CHAR *rand_value, CHAR *id, CHAR *name),
|
|
UINT (*get_responder_values)(CHAR *system, CHAR *name, CHAR *secret),
|
|
UINT (*get_verification_values)(CHAR *system, CHAR *name, CHAR *secret))
|
|
{
|
|
|
|
#ifdef NX_PPP_DISABLE_CHAP
|
|
|
|
/* Return the non implemented error. */
|
|
return(NX_NOT_IMPLEMENTED);
|
|
|
|
#else
|
|
|
|
/* Setup CHAP information. */
|
|
if (get_responder_values)
|
|
{
|
|
|
|
/* Setup challenge response callback. */
|
|
ppp_ptr -> nx_ppp_chap_get_responder_values = get_responder_values;
|
|
|
|
/* The authenticated flag is not cleared for the generate login, since the
|
|
peer may choose not to require CHAP. */
|
|
}
|
|
|
|
/* Determine if we are going to challenge the peer. */
|
|
if ((get_challenge_values) && (get_verification_values))
|
|
{
|
|
|
|
/* Setup the CHAP information. */
|
|
ppp_ptr -> nx_ppp_chap_get_challenge_values = get_challenge_values;
|
|
ppp_ptr -> nx_ppp_chap_get_verification_values = get_verification_values;
|
|
|
|
/* Yes, we must generate a challenge. */
|
|
ppp_ptr -> nx_ppp_verify_authentication_protocol = NX_PPP_CHAP_PROTOCOL;
|
|
ppp_ptr -> nx_ppp_authenticated = NX_FALSE;
|
|
}
|
|
|
|
/* Show that the CHAP is enabled. */
|
|
ppp_ptr -> nx_ppp_chap_enabled = NX_TRUE;
|
|
|
|
/* Set the initial CHAP state. */
|
|
ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_INITIAL_STATE;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
#endif
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_dns_address_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the DNS address of the PPP */
|
|
/* instance get function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* dns_address_ptr Destination for DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_dns_address_get Actual PPP DNS address get */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_dns_address_get(NX_PPP *ppp_ptr, ULONG *dns_address_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer... */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) ||
|
|
(dns_address_ptr == NX_NULL))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP DNS address get function. */
|
|
status = _nx_ppp_dns_address_get(ppp_ptr, dns_address_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_dns_address_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function retrieves the DNS address of the PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* dns_address_ptr Destination for DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_dns_address_get(NX_PPP *ppp_ptr, ULONG *dns_address_ptr)
|
|
{
|
|
|
|
/* Determine if the PPP instance is in an established state. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
|
|
{
|
|
|
|
if (ppp_ptr -> nx_ppp_primary_dns_address == 0x0)
|
|
{
|
|
return NX_PPP_ADDRESS_NOT_ESTABLISHED;
|
|
}
|
|
|
|
/* Return the DNS address ptr. */
|
|
*dns_address_ptr = ppp_ptr -> nx_ppp_primary_dns_address;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the DNS address to 0. */
|
|
*dns_address_ptr = 0;
|
|
|
|
/* The PPP connection has not yet been established. */
|
|
return(NX_PPP_NOT_ESTABLISHED);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_dns_address_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the DNS address of the PPP */
|
|
/* instance set function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* dns_address Primary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_dns_address_set Actual PPP DNS address set */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_dns_address_set(NX_PPP *ppp_ptr, ULONG dns_address)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer... */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for invalid address. */
|
|
if (dns_address == 0x0)
|
|
return(NX_PPP_INVALID_PARAMETER);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP DNS address set function. */
|
|
status = _nx_ppp_dns_address_set(ppp_ptr, dns_address);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_dns_address_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function sets the primary DNS address for the PPP device to */
|
|
/* supply if it receives a DNS option request (129) in the configure */
|
|
/* request NAKed list. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* dns_address Primary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_dns_address_set(NX_PPP *ppp_ptr, ULONG dns_address)
|
|
{
|
|
|
|
/* Set the primary DNS address. */
|
|
ppp_ptr -> nx_ppp_primary_dns_address = dns_address;
|
|
|
|
/* Return success. */
|
|
return NX_SUCCESS;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_secondary_dns_address_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the secondary DNS address of the */
|
|
/* PPP instance get function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* secondary_dns_address_ptr Secondary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_secondary_dns_address_get Actual PPP secondary DNS */
|
|
/* address get function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_secondary_dns_address_get(NX_PPP *ppp_ptr, ULONG *secondary_dns_address_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer... */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) ||
|
|
(secondary_dns_address_ptr == NX_NULL))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP secondary DNS address get function. */
|
|
status = _nx_ppp_secondary_dns_address_get(ppp_ptr, secondary_dns_address_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_secondary_dns_address_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function retrieves the secondary DNS address of the PPP */
|
|
/* instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* secondary_dns_address_ptr Secondary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_secondary_dns_address_get(NX_PPP *ppp_ptr, ULONG *secondary_dns_address_ptr)
|
|
{
|
|
|
|
/* Determine if the PPP instance is in an established state. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
|
|
{
|
|
|
|
if (ppp_ptr -> nx_ppp_secondary_dns_address == 0x0)
|
|
{
|
|
return(NX_PPP_ADDRESS_NOT_ESTABLISHED);
|
|
}
|
|
|
|
/* Return the DNS address ptr. */
|
|
*secondary_dns_address_ptr = ppp_ptr -> nx_ppp_secondary_dns_address;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the DNS address to 0. */
|
|
*secondary_dns_address_ptr = 0;
|
|
|
|
/* The PPP connection has not yet been established. */
|
|
return(NX_PPP_NOT_ESTABLISHED);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_secondary_dns_address_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the secondary DNS address of the */
|
|
/* PPP instance set function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* secondary_dns_address_ptr Secondary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_secondary_dns_address_set Actual PPP secondary DNS */
|
|
/* address set function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_secondary_dns_address_set(NX_PPP *ppp_ptr, ULONG secondary_dns_address)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer... */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for invalid address. */
|
|
if (secondary_dns_address == 0x0)
|
|
return(NX_PPP_INVALID_PARAMETER);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP secondary DNS address set function. */
|
|
status = _nx_ppp_secondary_dns_address_set(ppp_ptr, secondary_dns_address);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_secondary_dns_address_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function sets the secondary DNS address for the PPP device to */
|
|
/* supply if it receives a DNS option request (131) in the configure */
|
|
/* request NAKed list. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* secondary_dns_address_ptr Secondary DNS address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_secondary_dns_address_set(NX_PPP *ppp_ptr, ULONG secondary_dns_address)
|
|
{
|
|
|
|
/* Set the secondary DNS address. */
|
|
ppp_ptr -> nx_ppp_secondary_dns_address = secondary_dns_address;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_interface_index_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP interface index get */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* index_ptr Index of associated interface */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nxe_ppp_interface_index_get Actual PPP interface index get */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_interface_index_get(NX_PPP *ppp_ptr, UINT *index_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP interface idnex get function. */
|
|
status = _nx_ppp_interface_index_get(ppp_ptr, index_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_interface_index_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function retrieves the interface index with a particular PPP */
|
|
/* instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* index_ptr Index of associated interface */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_interface_index_get(NX_PPP *ppp_ptr, UINT *index_ptr)
|
|
{
|
|
|
|
/* Return the interface index. */
|
|
*index_ptr = ppp_ptr -> nx_ppp_interface_index;
|
|
|
|
/* Determine if the interface is actually setup. */
|
|
if (ppp_ptr -> nx_ppp_interface_ptr)
|
|
{
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
/* Return an error. The IP thread has not executed yet which means the
|
|
interface has not be setup. */
|
|
return(NX_IN_PROGRESS);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_ip_address_assign PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP IP address assign */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* local_ip_address Local IP address */
|
|
/* peer_ip_address Peer IP address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_ip_address_assign Actual PPP IP address assign */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_ip_address_assign(NX_PPP *ppp_ptr, ULONG local_ip_address, ULONG peer_ip_address)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer... including not being in the closed state for this configuration API. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP IP address assign function. */
|
|
status = _nx_ppp_ip_address_assign(ppp_ptr, local_ip_address, peer_ip_address);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ip_address_assign PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function assigns a local and peer IP address for the */
|
|
/* specified PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* local_ip_address Local IP address */
|
|
/* peer_ip_address Peer IP address */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_ip_address_assign(NX_PPP *ppp_ptr, ULONG local_ip_address, ULONG peer_ip_address)
|
|
{
|
|
|
|
UINT i;
|
|
|
|
|
|
/* Check if set the local IP address. */
|
|
if (local_ip_address != 0)
|
|
{
|
|
|
|
/* If true, this PPP instance is a Server. Update the flag. */
|
|
ppp_ptr -> nx_ppp_server = NX_TRUE;
|
|
}
|
|
|
|
/* Load the IP addresses into the PPP IPCP arrays. */
|
|
i = 4;
|
|
do
|
|
{
|
|
|
|
/* Load the IP values into the array. */
|
|
ppp_ptr -> nx_ppp_ipcp_local_ip[i-1] = (UCHAR) (local_ip_address & 0xFF);
|
|
ppp_ptr -> nx_ppp_ipcp_peer_ip[i-1] = (UCHAR) (peer_ip_address & 0xFF);
|
|
|
|
/* Shift the IP address down. */
|
|
local_ip_address = local_ip_address >> 8;
|
|
peer_ip_address = peer_ip_address >> 8;
|
|
|
|
/* Decrement the index. */
|
|
i--;
|
|
|
|
} while (i);
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_nak_authentication_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PP NAK authentication notify */
|
|
/* set function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* nak_authentication_notify Authentication NAK callback */
|
|
/* function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_nak_authentication_notify Actual PPP NAK authentication */
|
|
/* notify set function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_nak_authentication_notify(NX_PPP *ppp_ptr, void (*nak_authentication_notify)(void))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer... including not being in the closed state for this configuration API. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_INIT_AND_THREADS_CALLER_CHECKING
|
|
|
|
/* Call actual PPP NAK authentication notify set function. */
|
|
status = _nx_ppp_nak_authentication_notify(ppp_ptr, nak_authentication_notify);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_nak_authentication_notify PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function assigns an application callback function to be */
|
|
/* called if an authentication NAK is received from the peer. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* nak_authentication_notify Authentication NAK callback */
|
|
/* function */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_nak_authentication_notify(NX_PPP *ppp_ptr, void (*nak_authentication_notify)(void))
|
|
{
|
|
|
|
/* Store the callback function pointer in the PPP structure. */
|
|
ppp_ptr -> nx_ppp_nak_authentication_notify = nak_authentication_notify;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_raw_string_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP raw string send */
|
|
/* function call. */
|
|
/* */
|
|
/* Note: The string length of string_ptr is limited by the packet */
|
|
/* payload size. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* string_ptr Pointer to ASCII string */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_raw_string_send Actual PPP raw string send */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_raw_string_send(NX_PPP *ppp_ptr, CHAR *string_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (string_ptr == NX_NULL))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP raw string send function. */
|
|
status = _nx_ppp_raw_string_send(ppp_ptr, string_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_raw_string_send PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function sends a raw ASCII string to through PPP without any */
|
|
/* PPP framing. This is useful to respond to modem commands in some */
|
|
/* applications. */
|
|
/* */
|
|
/* Note: The string length of string_ptr is limited by the packet */
|
|
/* payload size. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* string_ptr Pointer to ASCII string */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet */
|
|
/* tx_event_flags_set Alert PPP thread to process */
|
|
/* raw packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_raw_string_send(NX_PPP *ppp_ptr, CHAR *string_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
UINT i, j;
|
|
UINT status;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Initialize the string index. */
|
|
i = 0;
|
|
|
|
/* Loop to process the raw string send request. */
|
|
while (string_ptr[i])
|
|
{
|
|
|
|
/* Allocate a packet to defer the raw string send to the PPP thread. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
|
|
|
|
/* Determine if there was an error allocating a packet. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of packet allocation timeouts. */
|
|
ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
|
|
#endif
|
|
|
|
/* Just return an error. */
|
|
return(NX_NO_PACKET);
|
|
}
|
|
|
|
/* Initialize the packet index. */
|
|
j = 0;
|
|
|
|
/* Loop through the string copying the characters into the packet. */
|
|
do
|
|
{
|
|
|
|
/* Copy character into the packet. */
|
|
packet_ptr -> nx_packet_prepend_ptr[j++] = (UCHAR)(string_ptr[i++]);
|
|
|
|
} while ((string_ptr[i]) && (&(packet_ptr -> nx_packet_prepend_ptr[j]) < packet_ptr -> nx_packet_data_end));
|
|
|
|
/* Update the append pointer. */
|
|
packet_ptr -> nx_packet_append_ptr = &(packet_ptr -> nx_packet_prepend_ptr[j]);
|
|
|
|
/* Setup the packet length. */
|
|
packet_ptr -> nx_packet_length = j;
|
|
|
|
/* Now place the packet on the raw packet queue. */
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Determine if the raw transmit queue is empty. */
|
|
if (ppp_ptr -> nx_ppp_raw_packet_queue_count++)
|
|
{
|
|
|
|
/* Not empty, simply link the new packet to the tail and update the tail. */
|
|
(ppp_ptr -> nx_ppp_raw_packet_queue_tail) -> nx_packet_queue_next = packet_ptr;
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_tail = packet_ptr;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* List is empty, set the head and tail to this packet. */
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_head = packet_ptr;
|
|
ppp_ptr -> nx_ppp_raw_packet_queue_tail = packet_ptr;
|
|
}
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Set event flag to wake up PPP thread for processing. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_RAW_STRING_SEND, TX_OR);
|
|
}
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_start PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP start function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_start Actual PPP start function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_start(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP start function. */
|
|
status = _nx_ppp_start(ppp_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_start PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function starts the PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Set PPP event flag to */
|
|
/* start PPP */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_start(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
/* Determine the current state. */
|
|
if (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Already started. */
|
|
return(NX_PPP_ALREADY_STARTED);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Now restart the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
|
|
}
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_stop PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP stop function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_stop Actual PPP stop function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_stop(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP stop function. */
|
|
status = _nx_ppp_stop(ppp_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_stop PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function stops the PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Set PPP event flag to stop PPP*/
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_stop(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
|
|
/* Determine the current state. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Already stopped. */
|
|
return(NX_PPP_ALREADY_STOPPED);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Check if LCP connection is already established or in negotiation. */
|
|
if ((ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_COMPLETED_STATE) ||
|
|
(ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE) ||
|
|
(ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE) ||
|
|
(ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE))
|
|
{
|
|
|
|
/* Setup the retry counter. */
|
|
ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
|
|
|
|
/* Setup the timeout. */
|
|
ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
|
|
|
|
/* Move into the stopping to wait for terminate ack. */
|
|
ppp_ptr -> nx_ppp_lcp_state = NX_PPP_LCP_STOPPING_STATE;
|
|
|
|
/* Send terminate request. */
|
|
_nx_ppp_lcp_terminate_request_send(ppp_ptr);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Set the event to stop the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Determine if the application has registered a link down notification
|
|
callback. */
|
|
if (ppp_ptr -> nx_ppp_link_down_callback)
|
|
{
|
|
|
|
/* Yes, call the application's callback function. */
|
|
(ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_restart PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP restart function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_restart Actual PPP restart function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_restart(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP restart function. */
|
|
status = _nx_ppp_restart(ppp_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_restart PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function restarts the PPP instance. This is typically done */
|
|
/* after a link down situation. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to instance */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Set PPP event flag to stop PPP*/
|
|
/* tx_thread_sleep Sleep for a small time */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_restart(NX_PPP *ppp_ptr)
|
|
{
|
|
|
|
/* Set the event to stop the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
|
|
|
|
/* Now restart the PPP instance. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_status_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP status get function call.*/
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* status_ptr Pointer to destination for */
|
|
/* PPP status */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_status_get Actual PPP status get function*/
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_status_get(NX_PPP *ppp_ptr, UINT *status_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (status_ptr == NX_NULL))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for valid caller. */
|
|
NX_THREADS_ONLY_CALLER_CHECKING
|
|
|
|
/* Call actual PPP status get function. */
|
|
status = _nx_ppp_status_get(ppp_ptr, status_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_status_get PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function retrieves the current status of the PPP instance. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* status_ptr Pointer to destination for */
|
|
/* PPP status */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_status_get(NX_PPP *ppp_ptr, UINT *status_ptr)
|
|
{
|
|
|
|
/* Now determine the current state. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
|
|
{
|
|
|
|
/* PPP is up, return established state. */
|
|
*status_ptr = NX_PPP_STATUS_ESTABLISHED;
|
|
|
|
/* Return success! */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else if ((ppp_ptr -> nx_ppp_lcp_state > NX_PPP_LCP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_lcp_state < NX_PPP_LCP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Is LCP in a failed state? */
|
|
if (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_FAILED_STATE)
|
|
{
|
|
|
|
/* Return LCP failed state. */
|
|
*status_ptr = NX_PPP_STATUS_LCP_FAILED;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Return LCP in-progress state. */
|
|
*status_ptr = NX_PPP_STATUS_LCP_IN_PROGRESS;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
}
|
|
else if ((ppp_ptr -> nx_ppp_pap_state > NX_PPP_PAP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_pap_state < NX_PPP_PAP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Is PAP in a failed state? */
|
|
if (ppp_ptr -> nx_ppp_pap_state == NX_PPP_PAP_FAILED_STATE)
|
|
{
|
|
|
|
/* Return PAP failed state. */
|
|
*status_ptr = NX_PPP_STATUS_PAP_FAILED;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Return PAP in-progress state. */
|
|
*status_ptr = NX_PPP_STATUS_PAP_IN_PROGRESS;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
}
|
|
else if ((ppp_ptr -> nx_ppp_chap_state > NX_PPP_CHAP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_chap_state < NX_PPP_CHAP_COMPLETED_STATE))
|
|
{
|
|
|
|
/* Is CHAP in a failed state? */
|
|
if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_CHALLENGE_FAILED_STATE)
|
|
{
|
|
|
|
/* Return CHAP failed state. */
|
|
*status_ptr = NX_PPP_STATUS_CHAP_FAILED;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Return CHAP in-progress state. */
|
|
*status_ptr = NX_PPP_STATUS_CHAP_IN_PROGRESS;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Is IPCP in a failed state? */
|
|
if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_FAILED_STATE)
|
|
{
|
|
|
|
/* Return IPCP failed state. */
|
|
*status_ptr = NX_PPP_STATUS_IPCP_FAILED;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Return IPCP in-progress state. */
|
|
*status_ptr = NX_PPP_STATUS_IPCP_IN_PROGRESS;
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_ping_reply PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function is called when the PPP instance detects an LCP echo */
|
|
/* request is received, and retransmits a response. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* packet_ptr Pointer to echo request packet*/
|
|
/* received */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_packet_transmit Transmit the PPP data */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update Processes events and updates */
|
|
/* the PPP in the LCP state */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_ping_reply(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
|
|
/* Change the coding to indicate an Echo reply. */
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_ECHO_REPLY;
|
|
|
|
/* Set the Magic number as zero. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[7] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[8] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[9] = 0;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
ppp_ptr -> nx_ppp_lcp_echo_replies_sent++;
|
|
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
#endif
|
|
|
|
/* Send the reply out. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_lcp_ping_process_echo_reply PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function is called when the PPP instance detects an LCP echo */
|
|
/* reply is received. It checks if the reply has a matching ID with the */
|
|
/* previous echo request sent out and if so clears the */
|
|
/* nx_ppp_lcp_echo_reply_id to indicate the device received a valid */
|
|
/* reply. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* packet_ptr Pointer to echo request packet*/
|
|
/* received */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* None Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* None */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* _nx_ppp_lcp_state_machine_update Processes events and updates */
|
|
/* the PPP in the LCP state */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
void _nx_ppp_lcp_ping_process_echo_reply(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
/* Verify the PPP ID matches. */
|
|
if (packet_ptr -> nx_packet_prepend_ptr[3] == ppp_ptr -> nx_ppp_lcp_echo_reply_id)
|
|
{
|
|
|
|
/* Successful ping received. */
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
/* Increment the number of LCP echo replies received. */
|
|
ppp_ptr -> nx_ppp_lcp_echo_replies_received++;
|
|
#endif
|
|
|
|
/* Clear the echo ID to indicate we received an LCP echo reply
|
|
matching the one we just sent out. */
|
|
ppp_ptr -> nx_ppp_lcp_echo_reply_id = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_ping_request PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function performs error checking for the nx_ppp_ping_request */
|
|
/* service. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* data_ptr Pointer to data in LCP echo */
|
|
/* data_size Size of data in LCP echo */
|
|
/* wait_option Wait option to transmit echo */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* NX_PTR_ERROR Invalid pointer input */
|
|
/* NX_PPP_INVALID_PARAMETER Invalid non pointer input */
|
|
/* NX_SUCCESS Successful echo request sent */
|
|
/* status Actual completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_ping_request Actual LCP echo service */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_ping_request(NX_PPP *ppp_ptr, CHAR *data_ptr, ULONG data_size, ULONG wait_option)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
if ((ppp_ptr == NX_NULL) || (data_ptr == NX_NULL))
|
|
{
|
|
return NX_PTR_ERROR;
|
|
}
|
|
|
|
if (data_size == 0)
|
|
{
|
|
return NX_PPP_INVALID_PARAMETER;
|
|
}
|
|
|
|
status = _nx_ppp_ping_request(ppp_ptr, data_ptr, data_size, wait_option);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_ping_request PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function builds and sends an LCP echo request, and sets the */
|
|
/* echo ID to the PPP nx_ppp_transmit_id. The caller waits for the echo*/
|
|
/* ID (nx_ppp_lcp_echo_reply_id) to be reset to zero to indicate a */
|
|
/* matching echo reply was received. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr PPP instance pointer */
|
|
/* data_ptr Pointer to data in LCP echo */
|
|
/* data_size Size of data in LCP echo */
|
|
/* wait_option Wait option to transmit echo */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* NX_SUCCESS Echo request successfully sent*/
|
|
/* status Actual completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* nx_packet_allocate Allocate a packet for sending */
|
|
/* _nx_ppp_packet_transmit Send PPP packet */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_ping_request(NX_PPP *ppp_ptr, CHAR *data_ptr, ULONG data_size, ULONG wait_option)
|
|
{
|
|
|
|
UINT status;
|
|
UINT i;
|
|
CHAR *work_ptr;
|
|
NX_PACKET *packet_ptr;
|
|
|
|
|
|
/* Echo request may only be sent in the LCP completed state.. */
|
|
if (ppp_ptr -> nx_ppp_lcp_state != NX_PPP_LCP_COMPLETED_STATE)
|
|
{
|
|
|
|
return NX_PPP_NOT_ESTABLISHED;
|
|
}
|
|
|
|
/* Allocate a packet for the PPP packet. */
|
|
status = nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, wait_option);
|
|
|
|
/* Determine if the packet was allocated successfully. */
|
|
if (status != NX_SUCCESS)
|
|
{
|
|
|
|
/* An error was detected, simply return a NULL pointer. */
|
|
return status;
|
|
}
|
|
|
|
/* Check if out of boundary. */
|
|
if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(data_size + 10))
|
|
{
|
|
|
|
/* Release the packet. */
|
|
nx_packet_release(packet_ptr);
|
|
return(NX_PPP_BAD_PACKET);
|
|
}
|
|
|
|
/* Increment the transmit ID. */
|
|
ppp_ptr -> nx_ppp_transmit_id++;
|
|
|
|
/* Build the configuration request. */
|
|
packet_ptr -> nx_packet_prepend_ptr[0] = (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
|
|
packet_ptr -> nx_packet_prepend_ptr[1] = NX_PPP_LCP_PROTOCOL & 0xFF;
|
|
packet_ptr -> nx_packet_prepend_ptr[2] = NX_PPP_LCP_ECHO_REQUEST;
|
|
packet_ptr -> nx_packet_prepend_ptr[3] = ppp_ptr -> nx_ppp_transmit_id;
|
|
|
|
/* Indicate the PPP instance is waiting on an ECHO reply with this id: */
|
|
ppp_ptr -> nx_ppp_lcp_echo_reply_id = ppp_ptr -> nx_ppp_transmit_id;
|
|
|
|
/* Set up the length. */
|
|
packet_ptr -> nx_packet_prepend_ptr[4] = (UCHAR)(((UINT)(data_size + 8)) >> 8);
|
|
packet_ptr -> nx_packet_prepend_ptr[5] = (UCHAR)(((UINT)(data_size + 8)) & 0xFF);
|
|
|
|
/* Magic number will be all zeroes. */
|
|
packet_ptr -> nx_packet_prepend_ptr[6] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[7] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[8] = 0;
|
|
packet_ptr -> nx_packet_prepend_ptr[9] = 0;
|
|
|
|
/* Load the data */
|
|
work_ptr = data_ptr;
|
|
|
|
/* Loop through the input buffer. */
|
|
for(i = 1; i <= data_size; i++)
|
|
{
|
|
|
|
/* Copy byte of IP address. */
|
|
packet_ptr -> nx_packet_prepend_ptr[i+9] = (UCHAR)(*work_ptr);
|
|
work_ptr++ ;
|
|
}
|
|
|
|
packet_ptr -> nx_packet_length = i + 9;
|
|
packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
|
|
|
|
#ifndef NX_PPP_DISABLE_INFO
|
|
|
|
/* Increment the number of LCP echo requests sent. */
|
|
ppp_ptr -> nx_ppp_lcp_echo_requests_sent++;
|
|
|
|
/* Increment the number of LCP frames sent. */
|
|
ppp_ptr -> nx_ppp_lcp_frames_sent++;
|
|
#endif
|
|
|
|
/* Send the configure request packet. */
|
|
_nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
|
|
|
|
return NX_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_packet_receive PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP packet receive */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* packet_ptr Pointer to packet to receive */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nx_ppp_packet_receive Actual PPP packet receive */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_packet_receive(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for packet pointer. */
|
|
if (packet_ptr == NX_NULL)
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Call actual packet receive function. */
|
|
status = _nx_ppp_packet_receive(ppp_ptr, packet_ptr);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_packet_receive PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function receives packet from the application (usually an */
|
|
/* application ISR), buffers it, and notifies the PPP receive thread. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* packet_ptr Pointer to packet to receive */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* tx_event_flags_set Notify PPP receiving thread */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code (Including ISRs) */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_packet_receive(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
TX_INTERRUPT_SAVE_AREA
|
|
|
|
/* Disable interrupts. */
|
|
TX_DISABLE
|
|
|
|
/* Check for no longer active PPP instance. */
|
|
if (ppp_ptr -> nx_ppp_id != NX_PPP_ID)
|
|
{
|
|
|
|
/* PPP is no longer active. */
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Return an error. */
|
|
return(NX_PTR_ERROR);
|
|
}
|
|
|
|
/* Check for a stopped PPP instance. */
|
|
if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
|
|
{
|
|
|
|
/* Silently discard byte. */
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Return success. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
/* Check to see if the deferred processing queue is empty. */
|
|
if (ppp_ptr -> nx_ppp_deferred_received_packet_head)
|
|
{
|
|
|
|
/* Not empty, just place the packet at the end of the queue. */
|
|
(ppp_ptr -> nx_ppp_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
|
|
packet_ptr -> nx_packet_queue_next = NX_NULL;
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_tail = packet_ptr;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Empty deferred receive processing queue. Just setup the head pointers and
|
|
set the event flags to ensure the PPP helper thread looks at the deferred processing
|
|
queue. */
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_head = packet_ptr;
|
|
ppp_ptr -> nx_ppp_deferred_received_packet_tail = packet_ptr;
|
|
packet_ptr -> nx_packet_queue_next = NX_NULL;
|
|
|
|
/* Restore interrupts. */
|
|
TX_RESTORE
|
|
|
|
/* Wakeup PPP helper thread to process the PPP deferred receive. */
|
|
tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_PPPOE_PACKET_RECEIVE, TX_OR);
|
|
}
|
|
|
|
/* Return successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nxe_ppp_packet_send_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function checks for errors in the PPP set packet send */
|
|
/* function call. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* nx_ppp_packet_send Routine to send PPP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* _nxe_ppp_packet_send_set Actual PPP packet send set */
|
|
/* function */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nxe_ppp_packet_send_set(NX_PPP *ppp_ptr, VOID (*nx_ppp_packet_send)(NX_PACKET *packet_ptr))
|
|
{
|
|
|
|
UINT status;
|
|
|
|
|
|
/* Check for an invalid input pointer. */
|
|
if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Check for packet pointer. */
|
|
if (nx_ppp_packet_send == NX_NULL)
|
|
return(NX_PTR_ERROR);
|
|
|
|
/* Call actual packet send set function. */
|
|
status = _nx_ppp_packet_send_set(ppp_ptr, nx_ppp_packet_send);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
/* */
|
|
/* FUNCTION RELEASE */
|
|
/* */
|
|
/* _nx_ppp_packet_send_set PORTABLE C */
|
|
/* 6.1 */
|
|
/* AUTHOR */
|
|
/* */
|
|
/* Yuxin Zhou, Microsoft Corporation */
|
|
/* */
|
|
/* DESCRIPTION */
|
|
/* */
|
|
/* This function set the PPP packet send function. */
|
|
/* */
|
|
/* INPUT */
|
|
/* */
|
|
/* ppp_ptr Pointer to PPP instance */
|
|
/* nx_ppp_packet_send Routine to send PPP packet */
|
|
/* */
|
|
/* OUTPUT */
|
|
/* */
|
|
/* status Completion status */
|
|
/* */
|
|
/* CALLS */
|
|
/* */
|
|
/* none */
|
|
/* */
|
|
/* CALLED BY */
|
|
/* */
|
|
/* Application Code */
|
|
/* */
|
|
/* RELEASE HISTORY */
|
|
/* */
|
|
/* DATE NAME DESCRIPTION */
|
|
/* */
|
|
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
|
/* 09-30-2020 Yuxin Zhou Modified comment(s), */
|
|
/* resulting in version 6.1 */
|
|
/* */
|
|
/**************************************************************************/
|
|
UINT _nx_ppp_packet_send_set(NX_PPP *ppp_ptr, VOID (*nx_ppp_packet_send)(NX_PACKET *packet_ptr))
|
|
{
|
|
|
|
|
|
/* Set the PPP packet send function. */
|
|
ppp_ptr -> nx_ppp_packet_send = nx_ppp_packet_send;
|
|
|
|
/* Return successful completion. */
|
|
return(NX_SUCCESS);
|
|
}
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|