FreeCalypso > hg > fc-tourmaline
diff src/g23m-fad/ppp/ppp_ncpf.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:25:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-fad/ppp/ppp_ncpf.c Fri Oct 16 06:25:50 2020 +0000 @@ -0,0 +1,2164 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This modul is part of the entity PPP and implements all +| procedures and functions as described in the +| SDL-documentation (NCP-statemachine) ++----------------------------------------------------------------------------- +*/ + +#define ENTITY_PPP + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" /* to get Condat data types */ +#include "vsi.h" /* to get a lot of macros */ +#include "macdef.h" /* to get a lot of macros */ +#include "custom.h" /* to get a lot of macros */ +#include "gsm.h" /* to get a lot of macros */ +#include "prim.h" /* to get the definitions of used SAP and directions */ +#include "dti.h" /* to get the DTILIB definitions */ +#include "ppp.h" /* to get the global entity definitions */ + +#include <string.h> /* to get memcpy */ +#include "ppp_arbf.h" /* to get function interface from arb */ + +/*==== CONST ================================================================*/ + +#define TYPE_HC 2 +#define TYPE_IP 3 +#define TYPE_PDNS 129 +#define TYPE_SDNS 131 +#define TYPE_ADJUST 125 + +#define MASK_TYPE_HC TYPE_HC +#define MASK_TYPE_IP TYPE_IP +#define MASK_TYPE_PDNS (TYPE_PDNS - TYPE_ADJUST) +#define MASK_TYPE_SDNS (TYPE_SDNS - TYPE_ADJUST) + +#define LENGTH_HC_VJ 6 +#define LENGTH_HC_MAX LENGTH_HC_VJ +#define LENGTH_IP 6 +#define LENGTH_PDNS 6 +#define LENGTH_SDNS 6 + +#define NCP_CONF_REQ_LENGTH_MAX (4 + \ + LENGTH_HC_MAX + \ + LENGTH_IP + \ + LENGTH_PDNS + \ + LENGTH_SDNS) +#define NCP_TERM_REQ_LENGTH 6 + +#define PPP_CSID_YES 1 + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_init ++------------------------------------------------------------------------------ +| Description : The function ncp_init() initialize Network Control Protocol +| +| Parameters : no parameters +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_init () +{ + TRACE_FUNCTION( "ncp_init" ); + /* + * initialize values + */ + ppp_data->ncp.req_hc = PPP_HC_DEFAULT; + ppp_data->ncp.req_msid = PPP_MSID_DEFAULT; + ppp_data->ncp.req_ip = PPP_IP_DEFAULT; + ppp_data->ncp.req_pdns = PPP_PDNS_DEFAULT; + ppp_data->ncp.req_sdns = PPP_SDNS_DEFAULT; + ppp_data->ncp.req_gateway = PPP_GATEWAY_DEFAULT; + + ppp_data->ncp.s_hc = PPP_HC_DEFAULT; + ppp_data->ncp.s_msid = PPP_MSID_DEFAULT; + ppp_data->ncp.r_hc = PPP_HC_DEFAULT; + ppp_data->ncp.r_msid = PPP_MSID_DEFAULT; + ppp_data->ncp.n_ip = PPP_IP_DEFAULT; + ppp_data->ncp.n_pdns = PPP_PDNS_DEFAULT; + ppp_data->ncp.n_sdns = PPP_SDNS_DEFAULT; + ppp_data->ncp.n_gateway = PPP_GATEWAY_DEFAULT; + + ppp_data->ncp.s_rejected = 0; + + ppp_data->ncp.nscri = 0; + ppp_data->ncp.nstri = 0; + ppp_data->ncp.nscji = 0; + + ppp_data->ncp.scr=FALSE; + ppp_data->ncp.str=FALSE; + ppp_data->ncp.rcr=FALSE; + + INIT_STATE( PPP_SERVICE_NCP , NCP_STATE ); +} /* ncp_init() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_get_values ++------------------------------------------------------------------------------ +| Description : The function ncp_get_values() returns negotiated values +| +| Parameters : ptr_hc - returns IP Header Compression +| ptr_msid - returns max slot identifier +| ptr_ip - returns IP address +| ptr_pdns - returns primary DNS server address +| ptr_pdns - returns secondary DNS server address +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_get_values (UBYTE* ptr_hc, UBYTE* ptr_msid, ULONG* ptr_ip, + ULONG* ptr_pdns, ULONG* ptr_sdns) +{ + TRACE_FUNCTION( "ncp_get_values" ); + + *ptr_hc = ppp_data->ncp.r_hc; + if(ppp_data->ncp.r_msid < ppp_data->ncp.s_msid) + *ptr_msid = ppp_data->ncp.r_msid; + else + *ptr_msid = ppp_data->ncp.s_msid; + *ptr_ip = ppp_data->ncp.n_ip; + *ptr_pdns = ppp_data->ncp.n_pdns; + *ptr_sdns = ppp_data->ncp.n_sdns; + +} /* ncp_get_values() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_get_scr ++------------------------------------------------------------------------------ +| Description : The function ncp_get_scr() creates a NCP Configure Request +| packet. +| +| Parameters : ptr_packet - returns the Configure Request packet +| THE MEMORY FOR THE PACKET WILL ALLOCATED BY +| THIS FUNCTION +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_get_scr (T_desc2** ptr_packet) +{ + T_desc2* ret_desc; + USHORT len_pos; + USHORT pos; + + TRACE_FUNCTION( "ncp_get_scr" ); + + /* + * Allocate the necessary size for the data descriptor. The size is + * calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get the size of + * descriptor control information + * - add number of octets of descriptor data + */ + MALLOC (ret_desc, (USHORT)(sizeof(T_desc2) - 1 + NCP_CONF_REQ_LENGTH_MAX)); + /* + * fill the packet + */ + ret_desc->next=(ULONG)NULL; + pos=0; + /* + * Code field + */ + ret_desc->buffer[pos]=CODE_CONF_REQ; + pos++; + /* + * Identifier field + */ + ret_desc->buffer[pos]=ppp_data->ncp.nscri;/*lint !e415 access of out-of-bounds pointer */ + pos++; + /* + * Length field (store the position) + */ + len_pos=pos; + pos++; + pos++; + /* + * Header Compression Protocol (only server mode) + */ + if(((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_HC)) EQ 0) && + (ppp_data->ncp.s_hc NEQ PPP_HC_DEFAULT)) + { + if(ppp_data->ncp.s_hc EQ PPP_HC_VJ) + { + ret_desc->buffer[pos] = TYPE_HC;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = LENGTH_HC_VJ;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = PROTOCOL_VJ_MSB;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = PROTOCOL_VJ_LSB;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = ppp_data->ncp.s_msid;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = PPP_CSID_YES;/*lint !e415 !e416 access of out-of-bounds pointer */ + pos++; + } + /* + * include additional header compression protocols + */ + } + /* + * IP Address (only client mode) + */ + if(((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_IP)) EQ 0) && + (ppp_data->mode EQ PPP_CLIENT)) + { + ret_desc->buffer[pos]=TYPE_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=LENGTH_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_ip >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_ip >> 16) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_ip >> 8) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_ip & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + } + /* + * Gateway Address (only server mode) + */ + if(((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_IP)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + (ppp_data->ncp.n_gateway NEQ PPP_GATEWAY_DEFAULT)) + { + ret_desc->buffer[pos]=TYPE_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=LENGTH_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_gateway >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_gateway >> 16) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_gateway >> 8) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_gateway & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + } + /* + * Primary DNS address (only client mode) + */ + if(((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_PDNS)) EQ 0) && + (ppp_data->mode EQ PPP_CLIENT)) + { + ret_desc->buffer[pos]=TYPE_PDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=LENGTH_PDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_pdns >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_pdns >> 16) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_pdns >> 8) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_pdns & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + } + /* + * Secondary DNS address (only client mode) + */ + if(((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_SDNS)) EQ 0) && + (ppp_data->mode EQ PPP_CLIENT)) + { + ret_desc->buffer[pos]=TYPE_SDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=LENGTH_SDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_sdns >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_sdns >> 16) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)((ppp_data->ncp.n_sdns >> 8) & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + ret_desc->buffer[pos]=(UBYTE)(ppp_data->ncp.n_sdns & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pos++; + } + /* + * insert packet length + */ + ret_desc->len=pos; + ret_desc->buffer[len_pos]=(UBYTE)(pos >> 8);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + len_pos++; + ret_desc->buffer[len_pos]=(UBYTE)(pos & 0x00ff);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + + /* + * return the created packet + */ + ppp_data->ncp.scr=TRUE; + *ptr_packet=ret_desc; + +} /* ncp_get_scr() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_get_str ++------------------------------------------------------------------------------ +| Description : The function ncp_get_str() creates a NCP Terminate Request +| packet. +| +| Parameters : ptr_packet - returns the Terminate Request packet +| THE MEMORY FOR THE PACKET WILL ALLOCATED BY +| THIS FUNCTION +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_get_str (T_desc2** ptr_packet) +{ + T_desc2* ret_desc; + USHORT pos; + + TRACE_FUNCTION( "ncp_get_str" ); + + /* + * Allocate the necessary size for the data descriptor. The size is + * calculated as follows: + * - take the size of a descriptor structure + * - subtract one because of the array buffer[1] to get the size of + * descriptor control information + * - add number of octets of descriptor data + */ + MALLOC (ret_desc, (USHORT)(sizeof(T_desc2) - 1 + NCP_TERM_REQ_LENGTH)); + /* + * fill the packet + */ + ret_desc->next = (ULONG)NULL; + ret_desc->len = NCP_TERM_REQ_LENGTH; + pos = 0; + /* + * Code field + */ + ret_desc->buffer[pos] = CODE_TERM_REQ; + pos++; + /* + * Identifier field + */ + ret_desc->buffer[pos] = ppp_data->ncp.nstri;/*lint !e415 access of out-of-bounds pointer */ + pos++; + /* + * Length field + */ + ret_desc->buffer[pos] = 0;/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = NCP_TERM_REQ_LENGTH;/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + pos++; + /* + * Data field contains the error code + */ + ret_desc->buffer[pos] = (U8)((ppp_data->ppp_cause >> 8) & 0x00ff);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + pos++; + ret_desc->buffer[pos] = (U8)((ppp_data->ppp_cause) & 0x00ff);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + pos++; + + /* + * return the created packet + */ + ppp_data->ncp.str = TRUE; + *ptr_packet = ret_desc; +} /* ncp_get_str() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_analyze_first_ipcp ++------------------------------------------------------------------------------ +| Description : The function ncp_analyze_first_ipcp() determine whether the +| given packet is a Configure Request packet. If so the function +| analyzes the packet, sets some values in the data structure and +| returns the values for header comression. +| +| Parameters : packet - received packet +| ptr_result - returns the result of the analysis +| ptr_hc - returns requested header compression +| ptr_msid - returns requested max slot identifier +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_analyze_first_ipcp(T_desc2* packet, + UBYTE* ptr_result, + UBYTE* ptr_hc, + UBYTE* ptr_msid) +{ + USHORT packet_len; + UBYTE type_len; + USHORT pos; + USHORT analyzed; + USHORT protocol_hc; + ULONG ip; + ULONG pdns; + ULONG sdns; + + TRACE_FUNCTION( "ncp_analyze_first_ipcp" ); + + /* + * check whether it is a Configure Request packet and + * for correct length field + */ + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet->buffer[0] NEQ CODE_CONF_REQ) || + (packet_len > packet->len) || + (packet_len < 4)) + { + *ptr_result = FALSE; + return; + } + /* + * check consistence of length of packet and length of configuration options + */ + pos=5; + while(pos < packet_len) + { + if(packet->buffer[pos] < 2)/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + *ptr_result = FALSE; + return; + } + pos+= packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + } + if((pos - 1) NEQ packet_len) + { + *ptr_result = FALSE; + return; + } + /* + * analyze configuration options + */ + ppp_data->ncp.r_hc = PPP_HC_DEFAULT; + ppp_data->ncp.r_msid = PPP_MSID_DEFAULT; + ppp_data->ncp.n_ip = PPP_IP_DEFAULT; + ppp_data->ncp.n_pdns = PPP_PDNS_DEFAULT; + ppp_data->ncp.n_sdns = PPP_SDNS_DEFAULT; + pos=4; + /* + * analyzed is a bit field and marks all already analyzed + * configuration options in order to reject all configuration options + * which are listed more than once + */ + analyzed=0; + while(pos < packet_len) + { + type_len=packet->buffer[pos + 1];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + switch(packet->buffer[pos])/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + /* + * yet supported configuration options + */ + case TYPE_HC: /* Header Compression */ + protocol_hc = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + protocol_hc <<= 8; + protocol_hc+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if((analyzed & (1UL << MASK_TYPE_HC)) EQ 0) + { + analyzed|= (1UL << MASK_TYPE_HC); + /* + * max slot identifier should be between 3 and 254 + * comp slot identifier may be compressed + */ + if((protocol_hc EQ DTI_PID_CTCP) && + (packet->buffer[pos + 4] >= 3) && + (packet->buffer[pos + 5] EQ PPP_CSID_YES))/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + ppp_data->ncp.r_hc = PPP_HC_VJ; + ppp_data->ncp.r_msid = packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if(ppp_data->ncp.r_msid > 254) + ppp_data->ncp.r_msid = 254; + } + } + break; + case TYPE_IP: + ip = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if((analyzed & (1UL << MASK_TYPE_IP)) EQ 0) + { + analyzed|=(1UL << MASK_TYPE_IP); + ppp_data->ncp.n_ip = ip; + } + break; + case TYPE_PDNS: + pdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if((analyzed & (1UL << MASK_TYPE_PDNS)) EQ 0) + { + analyzed|=(1UL << MASK_TYPE_PDNS); + ppp_data->ncp.n_pdns = pdns; + } + break; + case TYPE_SDNS: + sdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if((analyzed & (1UL << MASK_TYPE_SDNS)) EQ 0) + { + analyzed|=(1UL << MASK_TYPE_SDNS); + ppp_data->ncp.n_sdns = sdns; + } + break; + default: + /* + * not supported configuration options are not analysed + */ + break; + } + pos+= type_len; + } + /* + * all configuration options analyzed + */ + *ptr_hc = ppp_data->ncp.r_hc; + *ptr_msid = ppp_data->ncp.r_msid; + *ptr_result = TRUE; +} /* ncp_analyze_first_ipcp() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_fill_out_packet ++------------------------------------------------------------------------------ +| Description : The function ncp_fill_out_packet() puts a IPCP packet into +| the protocol configuration list +| +| Parameters : pco_buf - pco list buffer +| ptr_pos - position where to write the IPCP packet, this value +| must get back to the calling funtion +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_fill_out_packet (UBYTE pco_buf[], USHORT* ptr_pos) +{ + USHORT pos; + USHORT len_pos1, len_pos2; + + TRACE_FUNCTION( "ncp_fill_out_packet" ); + + if((ppp_data->pco_mask & PPP_PCO_MASK_IPCP_HC) || + (ppp_data->pco_mask & PPP_PCO_MASK_IPCP_IP) || + (ppp_data->pco_mask & PPP_PCO_MASK_IPCP_PDNS) || + (ppp_data->pco_mask & PPP_PCO_MASK_IPCP_SDNS)) + { + pos=*ptr_pos; + /* + * create the Configure-Request packet + */ + /* + * Protocol ID + */ + pco_buf[pos] = PROTOCOL_IPCP_MSB; + pos++; + pco_buf[pos] = PROTOCOL_IPCP_LSB; + pos++; + /* + * Length of Protocol contents (store the position) + */ + len_pos1 = pos; + pos++; + /* + * Code field + */ + pco_buf[pos] = CODE_CONF_REQ; + pos++; + /* + * Identifier field (some value) + */ + pco_buf[pos] = 1; + pos++; + /* + * Length field (store the position) + */ + len_pos2 = pos; + pos++; + pos++; + + if(ppp_data->pco_mask & PPP_PCO_MASK_IPCP_HC) + { + /* + * Header Compression + */ + if(ppp_data->ncp.r_hc EQ PPP_HC_VJ) + { + pco_buf[pos] = TYPE_HC; + pos++; + pco_buf[pos] = LENGTH_HC_VJ; + pos++; + pco_buf[pos] = PROTOCOL_VJ_MSB; + pos++; + pco_buf[pos] = PROTOCOL_VJ_LSB; + pos++; + pco_buf[pos] = ppp_data->ncp.r_msid; + pos++; + pco_buf[pos] = PPP_CSID_YES; + pos++; + } + } + + if(ppp_data->pco_mask & PPP_PCO_MASK_IPCP_IP) + { + /* + * IP Address + */ + pco_buf[pos] = TYPE_IP; + pos++; + pco_buf[pos] = LENGTH_IP; + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_ip >> 24); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_ip >> 16) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_ip >> 8) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_ip & 0x000000ff); + pos++; + } + + if(ppp_data->pco_mask & PPP_PCO_MASK_IPCP_PDNS) + { + /* + * primary DNS Address + */ + pco_buf[pos] = TYPE_PDNS; + pos++; + pco_buf[pos] = LENGTH_PDNS; + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_pdns >> 24); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_pdns >> 16) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_pdns >> 8) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_pdns & 0x000000ff); + pos++; + } + + if(ppp_data->pco_mask & PPP_PCO_MASK_IPCP_SDNS) + { + /* + * secondary DNS Address + */ + pco_buf[pos] = TYPE_SDNS; + pos++; + pco_buf[pos] = LENGTH_SDNS; + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_sdns >> 24); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_sdns >> 16) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)((ppp_data->ncp.n_sdns >> 8) & 0x000000ff); + pos++; + pco_buf[pos] = (UBYTE)(ppp_data->ncp.n_sdns & 0x000000ff); + pos++; + } + + /* + * insert packet length + */ + pco_buf[len_pos2] = 0; + len_pos2++; + pco_buf[len_pos2] = (UBYTE)(pos - len_pos2 + 3); + /* + * insert Length of Protocol Contents + */ + pco_buf[len_pos1] = pco_buf[len_pos2]; + + /* + * return new position + */ + *ptr_pos=pos; + } + + if(ppp_data->pco_mask & PPP_PCO_MASK_IPCP_GATEWAY) + { + pos=*ptr_pos; + /* + * create the Configure-NAK packet + */ + /* + * Protocol ID + */ + pco_buf[pos] = PROTOCOL_IPCP_MSB; + pos++; + pco_buf[pos] = PROTOCOL_IPCP_LSB; + pos++; + /* + * Length of Protocol contents (store the position) + */ + len_pos1 = pos; + pos++; + /* + * Code field + */ + pco_buf[pos] = CODE_CONF_NAK; + pos++; + /* + * Identifier field (some value) + */ + pco_buf[pos] = 1; + pos++; + /* + * Length field (store the position) + */ + len_pos2 = pos; + pos++; + pos++; + + /* + * dynamic Gateway Address + */ + pco_buf[pos] = TYPE_IP; + pos++; + pco_buf[pos] = LENGTH_IP; + pos++; + pco_buf[pos] = 0; + pos++; + pco_buf[pos] = 0; + pos++; + pco_buf[pos] = 0; + pos++; + pco_buf[pos] = 0; + pos++; + + /* + * insert packet length + */ + pco_buf[len_pos2] = 0; + len_pos2++; + pco_buf[len_pos2] = (UBYTE)(pos - len_pos2 + 3); + /* + * insert Length of Protocol Contents + */ + pco_buf[len_pos1] = pco_buf[len_pos2]; + + /* + * return new position + */ + *ptr_pos=pos; + } +} /* ncp_fill_out_packet() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_analyze_pco ++------------------------------------------------------------------------------ +| Description : The function ncp_analyze_pco() analyzes the return packet from +| PDP activation and determines the primary and secondary DNS +| address and the Gateway address. +| +| Parameters : pco_buf - pointer to the protocol configuration options +| pos - position where the IPCP packet starts +| ptr_dns1 - returns primary DNS address +| ptr_dns2 - returns secondary DNS address +| ptr_gateway - returns Gateway address +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_analyze_pco (UBYTE pco_buf[], + USHORT pos, + ULONG* ptr_dns1, + ULONG* ptr_dns2, + ULONG* ptr_gateway) +{ + USHORT packet_len; + USHORT start_pos; + UBYTE type_len; + USHORT analyzed; + ULONG pdns; + ULONG sdns; + ULONG gateway; + + TRACE_FUNCTION( "ncp_analyze_pco" ); + + /* + * check for correct length field + */ + pos+= 2; + packet_len = pco_buf[pos + 3]; + packet_len <<= 8; + packet_len+= pco_buf[pos + 4]; + if(packet_len NEQ pco_buf[pos]) + return; + pos++; + /* + * check of code field + */ + if((pco_buf[pos] NEQ CODE_CONF_REQ) && + (pco_buf[pos] NEQ CODE_CONF_NAK) && + (pco_buf[pos] NEQ CODE_CONF_ACK)) + return; + /* + * analyze configuration options + */ + start_pos = pos; + pos+= 4; + /* + * analyzed is a bit field and marks all already analyzed + * configuration options in order to determine configuration options + * which are listed more than once + */ + analyzed=0; + while((pos - start_pos) < packet_len) + { + type_len=pco_buf[pos + 1]; + switch(pco_buf[pos]) + { + /* + * search for IP configuration option + */ + case TYPE_IP: + gateway = pco_buf[pos + 2]; + gateway = (gateway << 8); + gateway+= pco_buf[pos + 3]; + gateway = (gateway << 8); + gateway+= pco_buf[pos + 4]; + gateway = (gateway << 8); + gateway+= pco_buf[pos + 5]; + if(((analyzed & (1UL << MASK_TYPE_IP)) EQ 0) && + (*ptr_gateway EQ PPP_GATEWAY_DEFAULT) && + (pco_buf[start_pos] EQ CODE_CONF_REQ)) + { + analyzed|=(1UL << MASK_TYPE_IP); + *ptr_gateway = gateway; + } + break; + + /* + * search for DNS configuration options + */ + case TYPE_PDNS: + pdns = pco_buf[pos + 2]; + pdns = (pdns << 8); + pdns+= pco_buf[pos + 3]; + pdns = (pdns << 8); + pdns+= pco_buf[pos + 4]; + pdns = (pdns << 8); + pdns+= pco_buf[pos + 5]; + if(((analyzed & (1UL << MASK_TYPE_PDNS)) EQ 0) && + (*ptr_dns1 EQ PPP_PDNS_DEFAULT) && + ((pco_buf[start_pos] EQ CODE_CONF_NAK) || + (pco_buf[start_pos] EQ CODE_CONF_ACK))) + { + analyzed|=(1UL << MASK_TYPE_PDNS); + *ptr_dns1 = pdns; + } + break; + + case TYPE_SDNS: + sdns = pco_buf[pos + 2]; + sdns = (sdns << 8); + sdns+= pco_buf[pos + 3]; + sdns = (sdns << 8); + sdns+= pco_buf[pos + 4]; + sdns = (sdns << 8); + sdns+= pco_buf[pos + 5]; + if(((analyzed & (1UL << MASK_TYPE_SDNS)) EQ 0) && + (*ptr_dns2 EQ PPP_SDNS_DEFAULT) && + ((pco_buf[start_pos] EQ CODE_CONF_NAK) || + (pco_buf[start_pos] EQ CODE_CONF_ACK))) + { + analyzed|=(1UL << MASK_TYPE_SDNS); + *ptr_dns2 = sdns; + } + break; + default: + /* + * other configuration options are not analysed + */ + break; + } + pos+= type_len; + } +} /* ncp_analyze_pco() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rcr ++------------------------------------------------------------------------------ +| Description : The function ncp_rcr() analyzes the given +| Configure Request packet and returns either FORWARD_RCRP or +| FORWARD_RCRN depend on the result of the analysis. +| The packet pointer points to an appropriate response packet. +| +| Parameters : ptr_packet - pointer to a Configure Request packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rcr (T_desc2** ptr_packet, UBYTE* isnew, UBYTE* forward) +{ + T_desc2* packet; + USHORT packet_len; + UBYTE type_len; + USHORT pos; + USHORT copy_pos; + USHORT analyzed; + UBYTE code_ret; + UBYTE error_found; + USHORT protocol_hc; + UBYTE csid; + ULONG ip; + ULONG pdns; + ULONG sdns; + + TRACE_FUNCTION( "ncp_rcr" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len > packet->len) || (packet_len < 4)) + { + *forward=FORWARD_DISCARD; + return; + } + /* + * check consistence of length of packet and length of configuration options + */ + pos=5; + while(pos < packet_len) + { + if(packet->buffer[pos] < 2)/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + *forward=FORWARD_DISCARD; + return; + } + pos += packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + } + if((pos - 1) NEQ packet_len) + { + *forward=FORWARD_DISCARD; + return; + } + /* + * check whether it is a new identifier + */ + *isnew=TRUE; + if((ppp_data->ncp.rcr) && (ppp_data->ncp.lrcri EQ packet->buffer[1]))/*lint !e415 access of out-of-bounds pointer */ + *isnew=FALSE; + ppp_data->ncp.lrcri=packet->buffer[1];/*lint !e415 access of out-of-bounds pointer */ + ppp_data->ncp.rcr=TRUE; + /* + * analyze configuration options + */ + ppp_data->ncp.r_hc = PPP_HC_DEFAULT; + ppp_data->ncp.r_msid = PPP_MSID_DEFAULT; + csid = 0; + if(ppp_data->mode EQ PPP_SERVER) + { + ppp_data->ncp.n_ip = PPP_IP_DEFAULT; + ppp_data->ncp.n_pdns = PPP_PDNS_DEFAULT; + ppp_data->ncp.n_sdns = PPP_SDNS_DEFAULT; + } + pos=4; + /* + * position where NAKed or Rejected configuration options are copied to + */ + copy_pos=4; + /* + * code_ret contains actually the status of analysis + * states are CODE_CONF_ACK, CODE_CONF_NAK and CODE_CONF_REJ + * this state are also values for the Code-field in the return packet + */ + code_ret=CODE_CONF_ACK; + /* + * analyzed is a bit field and marks all already analyzed + * configuration options in order to reject all configuration options + * which are listed more than once + */ + analyzed=0; + while(pos < packet_len) + { + type_len=packet->buffer[pos + 1];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + switch(packet->buffer[pos])/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + /* + * yet supported configuration options + */ + case TYPE_HC: /* Header Compression */ + protocol_hc = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + protocol_hc <<= 8; + protocol_hc+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if(protocol_hc EQ DTI_PID_CTCP) + { + ppp_data->ncp.r_hc = PPP_HC_VJ; + ppp_data->ncp.r_msid = packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + csid = packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + } + + switch(code_ret) + { + case CODE_CONF_ACK: + if(((analyzed & (1UL << MASK_TYPE_HC)) EQ 0) && + (ppp_data->ncp.r_hc EQ ppp_data->ncp.req_hc)) + { + if((ppp_data->ncp.r_hc EQ PPP_HC_VJ) && + (type_len EQ LENGTH_HC_VJ)) + { + if((ppp_data->mode EQ PPP_SERVER) && + (ppp_data->ncp.r_msid >= ppp_data->ncp.s_msid) && + (csid EQ PPP_CSID_YES) && + (ppp_data->ncp.s_hc EQ PPP_HC_VJ)) + { + analyzed|=(1UL << MASK_TYPE_HC); + pos+= LENGTH_HC_VJ; + break; + } + /* + * include here negotiation in client mode + */ + } + /* + * include here additional header compression protocols + */ + } + code_ret=CODE_CONF_NAK; + /* fall through */ + case CODE_CONF_NAK: + /* + * this configuration option will NAKed only if the compression + * protocol is not Van Jacobson Header Compression + */ + if(((analyzed & (1UL << MASK_TYPE_HC)) EQ 0) && + (ppp_data->ncp.req_hc NEQ PPP_HC_DEFAULT) && + (ppp_data->ncp.s_hc EQ PPP_HC_VJ) && + ((protocol_hc NEQ DTI_PID_CTCP) || + (type_len NEQ LENGTH_HC_VJ) || + ((ppp_data->ncp.r_msid >= ppp_data->ncp.s_msid) && + (csid EQ PPP_CSID_YES)))) + { + analyzed|= (1UL << MASK_TYPE_HC); + + error_found = FALSE; + /* + * this implementation is only for server mode + */ + if(type_len < LENGTH_HC_VJ) + { + T_desc2* temp_desc; + + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + packet_len + + LENGTH_HC_VJ + - type_len)); + temp_desc->next = packet->next; + temp_desc->len = packet_len + LENGTH_HC_VJ - type_len; + memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 possible data overrun*/ + memcpy(&temp_desc->buffer[pos + LENGTH_HC_VJ - type_len], + &packet->buffer[pos], + packet_len - pos);/*lint !e662 !e669 !e670 possible creation of out-of-bounds pointer*/ + arb_discard_packet(packet); + packet_len+= (LENGTH_HC_VJ - type_len); + pos += (LENGTH_HC_VJ - type_len); + packet = temp_desc; + + error_found = TRUE; + } + else if(ppp_data->ncp.r_hc NEQ PPP_HC_VJ) + { + error_found = TRUE; + } + else if(type_len > LENGTH_HC_VJ) + { + error_found = TRUE; + } + if(error_found EQ TRUE) + { + packet->buffer[copy_pos] = TYPE_HC;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = LENGTH_HC_VJ;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PROTOCOL_VJ_MSB;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PROTOCOL_VJ_LSB;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = ppp_data->ncp.req_msid;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PPP_CSID_YES;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + } + pos+= type_len; + break; + } + code_ret = CODE_CONF_REJ; + copy_pos = 4; + /* fall through */ + case CODE_CONF_REJ: + if(((analyzed & (1UL << MASK_TYPE_HC)) EQ 0) && + (ppp_data->ncp.req_hc NEQ PPP_HC_DEFAULT) && + (ppp_data->ncp.s_hc EQ PPP_HC_VJ) && + ((ppp_data->ncp.s_rejected & (1UL << MASK_TYPE_HC)) EQ 0) && + ((protocol_hc NEQ DTI_PID_CTCP) || + (type_len NEQ LENGTH_HC_VJ) || + ((ppp_data->ncp.r_msid >= ppp_data->ncp.s_msid) && + (csid EQ PPP_CSID_YES)))) + { + analyzed|= (1UL << MASK_TYPE_HC); + pos+= type_len; + break; + } + /* + * set s_hc to default because we reject this configuration option + */ + ppp_data->ncp.s_hc = PPP_HC_DEFAULT; + while(type_len > 0) + { + packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + pos++; + type_len--; + } + break; + default: + TRACE_ERROR("Packet return code invalid"); + break; + } + break; + case TYPE_IP: + ip = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = (ip << 8); + ip+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + switch(code_ret) + { + case CODE_CONF_ACK: + if(((analyzed & (1UL << MASK_TYPE_IP)) EQ 0) && + (type_len EQ LENGTH_IP)) + { + if((ppp_data->mode EQ PPP_SERVER) && + (((ip EQ ppp_data->ncp.req_ip) && + (ppp_data->ncp.req_ip NEQ PPP_IP_DEFAULT)) || + ((ip NEQ PPP_IP_DEFAULT) && + (ppp_data->ncp.req_ip EQ PPP_IP_DEFAULT)))) + { + analyzed|=(1UL << MASK_TYPE_IP); + ppp_data->ncp.n_ip = ip; + pos+=LENGTH_IP; + break; + } + else if((ppp_data->mode EQ PPP_CLIENT) && + (ip NEQ PPP_IP_DEFAULT)) + { + /* + * accept Gateway address + */ + analyzed|=(1UL << MASK_TYPE_IP); + ppp_data->ncp.n_gateway = ip; + pos+=LENGTH_IP; + break; + } + } + code_ret=CODE_CONF_NAK; + /* fall through */ + case CODE_CONF_NAK: + /* + * this option will be rejected in following cases: + * - occurence more than once + * - in client mode if received IP is dynamic + * - in server mode if received and requested IP are dynamic + */ + if(((analyzed & (1UL << MASK_TYPE_IP)) EQ 0) && + (((ppp_data->mode EQ PPP_SERVER) && + ((ip NEQ ppp_data->ncp.req_ip) || + (ppp_data->ncp.req_ip NEQ PPP_IP_DEFAULT))) || + ((ppp_data->mode EQ PPP_CLIENT) && + (ip NEQ PPP_IP_DEFAULT)))) + { + analyzed|=(1UL << MASK_TYPE_IP); + + error_found=FALSE; + if(type_len < LENGTH_IP) + { + T_desc2* temp_desc; + + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + packet_len + + LENGTH_IP + - type_len)); + temp_desc->next = packet->next; + temp_desc->len = packet_len + LENGTH_IP - type_len; + memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 Possible data overrun*/ + memcpy(&temp_desc->buffer[pos + LENGTH_IP - type_len], + &packet->buffer[pos], + packet_len - pos);/*lint !e662 !e669 !e670 possible creation of out-of-bounds pointer*/ + arb_discard_packet(packet); + packet_len += (LENGTH_IP - type_len); + pos += (LENGTH_IP - type_len); + packet = temp_desc; + error_found = TRUE; + } + else if((ip NEQ ppp_data->ncp.req_ip) && + (ppp_data->ncp.req_ip NEQ PPP_IP_DEFAULT) && + (ppp_data->mode EQ PPP_SERVER)) + { + error_found=TRUE; + } + else if(type_len > LENGTH_IP) + { + error_found=TRUE; + } + if(error_found EQ TRUE) + { + packet->buffer[copy_pos]=TYPE_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=LENGTH_IP;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_ip >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_ip >> 16) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_ip >> 8) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_ip + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + } + pos+= type_len; + break; + } + code_ret = CODE_CONF_REJ; + copy_pos = 4; + /* fall through */ + case CODE_CONF_REJ: + if(((analyzed & (1UL << MASK_TYPE_IP)) EQ 0) && + (((ppp_data->mode EQ PPP_SERVER) && + ((ip NEQ ppp_data->ncp.req_ip) || + (ppp_data->ncp.req_ip NEQ PPP_IP_DEFAULT))) || + ((ppp_data->mode EQ PPP_CLIENT) && + (ip NEQ PPP_IP_DEFAULT)))) + { + analyzed|=(1UL << MASK_TYPE_IP); + pos+=type_len; + break; + } + while(type_len > 0) + { + packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + pos++; + type_len--; + } + break; + default: + TRACE_ERROR("Packet return code invalid"); + break; + } + break; + case TYPE_PDNS: /* only in server mode allowed */ + pdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = (pdns << 8); + pdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + switch(code_ret) + { + case CODE_CONF_ACK: + if(((analyzed & (1UL << MASK_TYPE_PDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + (type_len EQ LENGTH_PDNS) && + (((pdns EQ ppp_data->ncp.req_pdns) && + (ppp_data->ncp.req_pdns NEQ PPP_PDNS_DEFAULT)) || + ((pdns NEQ PPP_PDNS_DEFAULT) && + (ppp_data->ncp.req_pdns EQ PPP_PDNS_DEFAULT)))) + { + analyzed|=(1UL << MASK_TYPE_PDNS); + ppp_data->ncp.n_pdns = pdns; + pos+= LENGTH_PDNS; + break; + } + code_ret=CODE_CONF_NAK; + /* fall through */ + case CODE_CONF_NAK: + /* + * this option will be rejected in following cases: + * - occurence more than once + * - client mode + * - received and requested PDNS are dynamic + */ + if(((analyzed & (1UL << MASK_TYPE_PDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + ((pdns NEQ ppp_data->ncp.req_pdns) || + (ppp_data->ncp.req_pdns NEQ PPP_PDNS_DEFAULT))) + { + analyzed|=(1UL << MASK_TYPE_PDNS); + + error_found=FALSE; + if(type_len < LENGTH_PDNS) + { + T_desc2* temp_desc; + + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + packet_len + + LENGTH_PDNS + - type_len)); + temp_desc->next = packet->next; + temp_desc->len = packet_len + LENGTH_PDNS - type_len; + memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 Possible data overrun*/ + memcpy(&temp_desc->buffer[pos + LENGTH_PDNS - type_len], + &packet->buffer[pos], + packet_len - pos);/*lint !e662 !e669 !e670 possible creation of out-of-bounds pointer*/ + arb_discard_packet(packet); + packet_len += (LENGTH_PDNS - type_len); + pos += (LENGTH_PDNS - type_len); + packet = temp_desc; + error_found = TRUE; + } + else if((pdns NEQ ppp_data->ncp.req_pdns) && + (ppp_data->ncp.req_pdns NEQ PPP_PDNS_DEFAULT)) + { + error_found=TRUE; + } + else if(type_len > LENGTH_PDNS) + { + error_found=TRUE; + } + if(error_found EQ TRUE) + { + packet->buffer[copy_pos]=TYPE_PDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=LENGTH_PDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_pdns >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_pdns >> 16) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_pdns >> 8) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_pdns + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + } + pos+= type_len; + break; + } + code_ret = CODE_CONF_REJ; + copy_pos = 4; + /* fall through */ + case CODE_CONF_REJ: + if(((analyzed & (1UL << MASK_TYPE_PDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + ((pdns NEQ ppp_data->ncp.req_pdns) || + (ppp_data->ncp.req_pdns NEQ PPP_PDNS_DEFAULT))) + { + analyzed|=(1UL << MASK_TYPE_PDNS); + pos+=type_len; + break; + } + while(type_len > 0) + { + packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + pos++; + type_len--; + } + break; + default: + TRACE_ERROR("Packet return code invalid"); + break; + } + break; + case TYPE_SDNS: /* only in server mode allowed */ + sdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = (sdns << 8); + sdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + switch(code_ret) + { + case CODE_CONF_ACK: + if(((analyzed & (1UL << MASK_TYPE_SDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + (type_len EQ LENGTH_SDNS) && + (((sdns EQ ppp_data->ncp.req_sdns) && + (ppp_data->ncp.req_sdns NEQ PPP_SDNS_DEFAULT)) || + ((sdns NEQ PPP_SDNS_DEFAULT) && + (ppp_data->ncp.req_sdns EQ PPP_SDNS_DEFAULT)))) + { + analyzed|=(1UL << MASK_TYPE_SDNS); + ppp_data->ncp.n_sdns = sdns; + pos+= LENGTH_SDNS; + break; + } + code_ret=CODE_CONF_NAK; + /* fall through */ + case CODE_CONF_NAK: + /* + * this option will be rejected in following cases: + * - occurence more than once + * - client mode + * - received and requested SDNS are dynamic + */ + if(((analyzed & (1UL << MASK_TYPE_SDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + ((sdns NEQ ppp_data->ncp.req_sdns) || + (ppp_data->ncp.req_sdns NEQ PPP_SDNS_DEFAULT))) + { + analyzed|=(1UL << MASK_TYPE_SDNS); + + error_found=FALSE; + if(type_len < LENGTH_SDNS) + { + T_desc2* temp_desc; + + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + packet_len + + LENGTH_SDNS + - type_len)); + temp_desc->next = packet->next; + temp_desc->len = packet_len + LENGTH_SDNS - type_len; + memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 Possible data overrun*/ + memcpy(&temp_desc->buffer[pos + LENGTH_SDNS - type_len], + &packet->buffer[pos], + packet_len - pos);/*lint !e662 !e669 !e670 possible creation of out-of-bounds pointer*/ + arb_discard_packet(packet); + packet_len += (LENGTH_SDNS - type_len); + pos += (LENGTH_SDNS - type_len); + packet = temp_desc; + error_found = TRUE; + } + else if((sdns NEQ ppp_data->ncp.req_sdns) && + (ppp_data->ncp.req_sdns NEQ PPP_SDNS_DEFAULT)) + { + error_found=TRUE; + } + else if(type_len > LENGTH_SDNS) + { + error_found=TRUE; + } + if(error_found EQ TRUE) + { + packet->buffer[copy_pos]=TYPE_SDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=LENGTH_SDNS;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_sdns >> 24);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_sdns >> 16) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)((ppp_data->ncp.req_sdns >> 8) + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos]=(UBYTE)(ppp_data->ncp.req_sdns + & 0x000000ff);/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + } + pos+= type_len; + break; + } + code_ret = CODE_CONF_REJ; + copy_pos = 4; + /* fall through */ + case CODE_CONF_REJ: + if(((analyzed & (1UL << MASK_TYPE_SDNS)) EQ 0) && + (ppp_data->mode EQ PPP_SERVER) && + ((sdns NEQ ppp_data->ncp.req_sdns) || + (ppp_data->ncp.req_sdns NEQ PPP_SDNS_DEFAULT))) + { + analyzed|=(1UL << MASK_TYPE_SDNS); + pos+=type_len; + break; + } + while(type_len > 0) + { + packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + pos++; + type_len--; + } + break; + default: + TRACE_ERROR("Packet return code invalid"); + break; + } + break; + default: + switch(code_ret) + { + case CODE_CONF_ACK: + case CODE_CONF_NAK: + code_ret=CODE_CONF_REJ; + copy_pos=4; + /* fall through */ + default: + while(type_len > 0) + { + packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + pos++; + type_len--; + } + break; + } + } + } + if(((analyzed & (1UL << MASK_TYPE_HC)) EQ 0) && + (ppp_data->ncp.s_hc EQ PPP_HC_VJ) && + (ppp_data->ncp.req_hc EQ PPP_HC_VJ) && + (code_ret NEQ CODE_CONF_REJ)) + { + T_desc2* temp_desc; + /* + * add header compression to the configure Nak packet + */ + code_ret = CODE_CONF_NAK; + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + + packet_len + + LENGTH_HC_VJ)); + temp_desc->next = packet->next; + temp_desc->len = packet_len + LENGTH_HC_VJ; + memcpy(temp_desc->buffer, packet->buffer, copy_pos);/*lint !e669 !e670 Possible data overrun*/ + arb_discard_packet(packet); + packet_len+= LENGTH_HC_VJ; + packet = temp_desc; + /* + * insert header compression option + */ + packet->buffer[copy_pos] = TYPE_HC;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = LENGTH_HC_VJ;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PROTOCOL_VJ_MSB;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PROTOCOL_VJ_LSB;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = ppp_data->ncp.req_msid;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + packet->buffer[copy_pos] = PPP_CSID_YES;/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + copy_pos++; + } + /* + * set new Code field in return packet + */ + packet->buffer[0]=code_ret; + *ptr_packet=packet; + + if(copy_pos > 4) + { + /* + * some configuration options are not acceptable + */ + *forward=FORWARD_RCRN; + /* + * set new Length field + */ + packet->len=copy_pos; + packet->buffer[2]=(UBYTE)(copy_pos >> 8);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet->buffer[3]=(UBYTE)(copy_pos & 0x00ff);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + return; + } + /* + * all configuration options are acceptable + */ + *forward=FORWARD_RCRP; +} /* ncp_rcr() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rca ++------------------------------------------------------------------------------ +| Description : The function ncp_rca() checks whether the given +| Configure Ack packet is valid and if so it returns +| FORWARD_RCA. Otherwise it returns FORWARD_DISCARD. +| +| Parameters : packet - Configure Ack packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rca (T_desc2* packet, UBYTE* forward) +{ + USHORT packet_len; + + TRACE_FUNCTION( "ncp_rca" ); + + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len < 4) || + (packet_len > packet->len) || + (ppp_data->ncp.scr EQ FALSE) || + (packet->buffer[1] NEQ ppp_data->ncp.nscri))/*lint !e415 access of out-of-bounds pointer */ + { + /* + * invalid packet + */ + *forward=FORWARD_DISCARD; + return; + } + /* + * acceptable packet + */ + arb_discard_packet(packet); + ppp_data->ncp.nscri++; + *forward=FORWARD_RCA; +} /* ncp_rca() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rcn ++------------------------------------------------------------------------------ +| Description : The function ncp_rcn() analyze the given +| Configure Nak packet, changes some requested values and returns +| FORWARD_RCN +| The packet pointer points to an appropriate response packet. +| +| Parameters : ptr_packet - Configure Nak packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rcn (T_desc2** ptr_packet, UBYTE* forward) +{ + T_desc2* packet; + USHORT packet_len; + UBYTE type_len; + USHORT pos; + USHORT protocol_hc; + ULONG ip; + ULONG pdns; + ULONG sdns; + + TRACE_FUNCTION( "ncp_rcn" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len > packet->len) || + (packet_len < 4) || + (ppp_data->ncp.scr EQ FALSE) || + (packet->buffer[1] NEQ ppp_data->ncp.nscri))/*lint !e415 access of out-of-bounds pointer */ + { + /* + * invalid packet + */ + *forward=FORWARD_DISCARD; + return; + } + /* + * check consistence of length of packet and length of configuration options + */ + pos=5; + while(pos < packet_len) + { + if(packet->buffer[pos] < 2)/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + *forward=FORWARD_DISCARD; + return; + } + pos+= packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + } + if((pos - 1) NEQ packet_len) + { + *forward=FORWARD_DISCARD; + return; + } + /* + * analyze configuration options + */ + pos=4; + while(pos < packet_len) + { + type_len=packet->buffer[pos + 1];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + switch(packet->buffer[pos])/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + /* + * yet supported configuration options + */ + case TYPE_HC: + protocol_hc = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + protocol_hc <<= 8; + protocol_hc+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + if((protocol_hc EQ DTI_PID_CTCP) && + (ppp_data->ncp.req_hc EQ PPP_HC_VJ) && + (type_len EQ LENGTH_HC_VJ)) + { + ppp_data->ncp.s_rejected &= ~(1UL << MASK_TYPE_HC); + ppp_data->ncp.s_hc = PPP_HC_VJ; + ppp_data->ncp.s_msid = ppp_data->ncp.req_msid; + } + break; + case TYPE_IP: + ip = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = ip << 8; + ip+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = ip << 8; + ip+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + ip = ip << 8; + ip+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + if(type_len EQ LENGTH_IP) + { + ppp_data->ncp.s_rejected &= ~(1UL << MASK_TYPE_IP); + if(ppp_data->mode EQ PPP_CLIENT) + ppp_data->ncp.n_ip = ip; + else if(ppp_data->ncp.req_gateway EQ PPP_GATEWAY_DEFAULT) + ppp_data->ncp.n_gateway = ip; + } + break; + case TYPE_PDNS: + pdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = pdns << 8; + pdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = pdns << 8; + pdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + pdns = pdns << 8; + pdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + if((type_len EQ LENGTH_PDNS) && + (ppp_data->mode EQ PPP_CLIENT)) + { + ppp_data->ncp.s_rejected &= ~(1UL << MASK_TYPE_PDNS); + ppp_data->ncp.n_pdns = pdns; + } + break; + case TYPE_SDNS: + sdns = packet->buffer[pos + 2];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = sdns << 8; + sdns+= packet->buffer[pos + 3];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = sdns << 8; + sdns+= packet->buffer[pos + 4];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + sdns = sdns << 8; + sdns+= packet->buffer[pos + 5];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + + if((type_len EQ LENGTH_SDNS) && + (ppp_data->mode EQ PPP_CLIENT)) + { + ppp_data->ncp.s_rejected &= ~(1UL << MASK_TYPE_SDNS); + ppp_data->ncp.n_sdns = sdns; + } + break; + default: + /* + * ignore unknown configuration options + */ + break; + } + pos+= type_len; + } + /* + * free this packet and create a new with changed configuration options + */ + arb_discard_packet(packet); + *forward=FORWARD_RCN; + ppp_data->ncp.nscri++; + ncp_get_scr(&packet); + *ptr_packet=packet; +} /* ncp_rcn() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rcj ++------------------------------------------------------------------------------ +| Description : The function ncp_rcj() analyze the given +| Configure Reject packet, marks some values as rejected and +| returns FORWARD_RCJ +| The packet pointer points to an appropriate response packet. +| +| Parameters : ptr_packet - pointer to a Configure Reject packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rcj (T_desc2** ptr_packet, UBYTE* forward) +{ + T_desc2* packet; + USHORT packet_len; + UBYTE type_len; + USHORT pos; + + TRACE_FUNCTION( "ncp_rcj" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len > packet->len) || + (packet_len < 4) || + (ppp_data->ncp.scr EQ FALSE) || + (packet->buffer[1] NEQ ppp_data->ncp.nscri))/*lint !e415 access of out-of-bounds pointer */ + { + /* + * invalid packet + */ + *forward=FORWARD_DISCARD; + return; + } + /* + * check consistence of length of packet and length of configuration options + */ + pos=5; + while(pos < packet_len) + { + if(packet->buffer[pos] < 2)/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + *forward=FORWARD_DISCARD; + return; + } + pos+= packet->buffer[pos];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + } + if((pos - 1) NEQ packet_len) + { + *forward=FORWARD_DISCARD; + return; + } + /* + * analyze configuration options + */ + pos=4; + while(pos < packet_len) + { + type_len=packet->buffer[pos + 1];/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + switch(packet->buffer[pos])/*lint !e662 !e661 possible creation and access of out-of-bounds pointer*/ + { + /* + * yet supported configuration options + */ + case TYPE_HC: + ppp_data->ncp.s_rejected|= (1UL << MASK_TYPE_HC); + ppp_data->ncp.s_hc = PPP_HC_DEFAULT; + break; + case TYPE_IP: + if (ppp_data->mode EQ PPP_CLIENT) + { /* error: server has to support valid IP address */ + *forward=FORWARD_DISCARD; + return; + } + ppp_data->ncp.s_rejected |= (1UL << MASK_TYPE_IP); + break; + case TYPE_PDNS: + ppp_data->ncp.s_rejected |= (1UL << MASK_TYPE_PDNS); + break; + case TYPE_SDNS: + ppp_data->ncp.s_rejected |= (1UL << MASK_TYPE_SDNS); + break; + default: + /* + * ignore unknown configuration options + */ + break; + } + pos+= type_len; + } + /* + * free this packet and create a new with changed configuration options + */ + arb_discard_packet(packet); + *forward=FORWARD_RCN; + ppp_data->ncp.nscri++; + ncp_get_scr(&packet); + *ptr_packet=packet; +} /* ncp_rcj() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rtr ++------------------------------------------------------------------------------ +| Description : The function ncp_rtr() checks whether the given +| Terminate Request packet is valid and if so it returns +| FORWARD_RCA. Otherwise it returns FORWARD_DISCARD. +| +| Parameters : ptr_packet - pointer to a Terminate Request packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rtr (T_desc2** ptr_packet, UBYTE* forward) +{ + T_desc2* packet; + USHORT packet_len; + + TRACE_FUNCTION( "ncp_rtr" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len < 4) || (packet_len > packet->len)) + { + *forward=FORWARD_DISCARD; + return; + } + + /* + * change code field + */ + packet->buffer[0]=CODE_TERM_ACK; + + *forward=FORWARD_RTR; +} /* ncp_rtr() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rta ++------------------------------------------------------------------------------ +| Description : The function ncp_rta() checks whether the given +| Terminate Ack packet is valid and if so it returns +| FORWARD_RTA. Otherwise it returns FORWARD_DISCARD. +| +| Parameters : packet - Terminate Ack packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rta (T_desc2* packet, UBYTE* forward) +{ + USHORT packet_len; + + TRACE_FUNCTION( "ncp_rta" ); + + /* + * check for correct length field + */ + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len < 4) || (packet_len > packet->len)) + { + *forward=FORWARD_DISCARD; + return; + } + + if((ppp_data->ncp.str EQ TRUE) && + (packet->buffer[1] NEQ ppp_data->ncp.nstri))/*lint !e415 access of out-of-bounds pointer */ + { + /* + * invalid packet + */ + *forward=FORWARD_DISCARD; + return; + } + /* + * acceptable packet + */ + arb_discard_packet(packet); + ppp_data->ncp.nstri++; + *forward=FORWARD_RTA; +} /* ncp_rta() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_rxj ++------------------------------------------------------------------------------ +| Description : The function ncp_rxj() analyzes whether the given Code Reject +| is acceptable. If not it returns FORWARD_RXJN. +| +| Parameters : ptr_packet - Pointer to a Code Reject packet +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_rxj (T_desc2** ptr_packet, UBYTE* forward) +{ + USHORT packet_len; + T_desc2* packet; + + TRACE_FUNCTION( "ncp_rxj" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet_len < 5) || (packet_len > packet->len)) + { + *forward=FORWARD_DISCARD; + return; + } + + switch(packet->buffer[4])/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + { + case CODE_CONF_REQ: + case CODE_CONF_REJ: + case CODE_CONF_NAK: + case CODE_CONF_ACK: + case CODE_TERM_REQ: + case CODE_TERM_ACK: + case CODE_CODE_REJ: + arb_discard_packet(packet); + ncp_get_str(&packet); + *ptr_packet = packet; + *forward = FORWARD_RXJN; + break; + default: + *forward=FORWARD_DISCARD; + break; + } +} /* ncp_rxj() */ + + + +/* ++------------------------------------------------------------------------------ +| Function : ncp_ruc ++------------------------------------------------------------------------------ +| Description : The function ncp_ruc() creates a Code Reject packet and returns +| FORWARD_RUC. +| +| Parameters : ptr_packet - packet with unknown code +| forward - returns result of analysis +| ++------------------------------------------------------------------------------ +*/ +GLOBAL void ncp_ruc (T_desc2** ptr_packet, UBYTE* forward) +{ + T_desc2* packet; + T_desc2* temp_desc; + USHORT packet_len; + + TRACE_FUNCTION( "ncp_ruc" ); + + /* + * check for correct length field + */ + packet = *ptr_packet; + packet_len = packet->buffer[2];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet_len <<= 8; + packet_len+= packet->buffer[3];/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + if((packet->len < packet_len) || (packet_len < 4)) + { + *forward=FORWARD_DISCARD; + return; + } + + /* + * create a new larger packet and copy the content + * of the old packet into the new + */ + packet_len+=4; + if(packet_len > PPP_MRU_MIN) + packet_len = PPP_MRU_MIN; + MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + packet_len)); + + temp_desc->next = packet->next; + temp_desc->len = packet_len; + memcpy(&temp_desc->buffer[4], packet->buffer, packet_len - 4);/*lint !e416 !e669 !e670 creation of out-of-bounds pointer */ + arb_discard_packet(packet); + packet = temp_desc; + + /* + * fill the first bytes to create a Code Reject + */ + packet->buffer[0] = CODE_CODE_REJ; + ppp_data->ncp.nscji++; + packet->buffer[1] = ppp_data->ncp.nscji;/*lint !e415 access of out-of-bounds pointer */ + packet->buffer[2] = (UBYTE)(packet_len >> 8);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + packet->buffer[3] = (UBYTE)(packet_len & 0x00ff);/*lint !e415 !e416 creation and access of out-of-bounds pointer */ + + /* + * set return values + */ + *ptr_packet=packet; + *forward=FORWARD_RUC; + +} /* ncp_ruc() */