FreeCalypso > hg > fc-selenite
view src/g23m-fad/ppp/ppp_lcpf.c @ 196:5f3544fc0308
AT@SPENH brought over from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 24 May 2020 19:46:18 +0000 |
parents | d393cd9bb723 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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 (LCP-statemachine) +----------------------------------------------------------------------------- */ #ifndef PPP_LCPF_C #define PPP_LCPF_C #endif /* !PPP_LCPF_C */ #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 "cnf_ppp.h" /* to get cnf-definitions */ #include "mon_ppp.h" /* to get mon-definitions */ #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 */ #include "ppp_capf.h" #ifdef _SIMULATION_ #include <stdio.h> /* to get sprintf */ #endif /* _SIMULATION_ */ /*==== CONST ================================================================*/ #define TYPE_MRU 1 #define TYPE_ACCM 2 #define TYPE_AP 3 #define TYPE_QP 4 #define TYPE_MAGIC 5 #define TYPE_PFC 7 #define TYPE_ACFC 8 #define TYPE_FCS 9 #define LENGTH_MRU 4 #define LENGTH_ACCM 6 #define LENGTH_AP_PAP 4 #define LENGTH_AP_CHAP 5 #define LENGTH_AP_MIN 4 #define LENGTH_AP_MAX LENGTH_AP_CHAP #define LENGTH_MAGIC 6 #define LENGTH_PFC 2 #define LENGTH_ACFC 2 #define LENGTH_FCS 3 /* * all other configuration options not yet supported */ #define LCP_CONF_REQ_LENGTH_MAX (4 + \ LENGTH_MRU + \ LENGTH_ACCM + \ LENGTH_AP_MAX + \ LENGTH_PFC + \ LENGTH_ACFC) #define LCP_TERM_REQ_LENGTH 6 #define ALGORITHM_MD5 5 /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : lcp_init +------------------------------------------------------------------------------ | Description : The function lcp_init() initialize Link Control Protocol (LCP) | | Parameters : no parameters | +------------------------------------------------------------------------------ */ GLOBAL void lcp_init () { TRACE_FUNCTION( "lcp_init" ); /* * initialize values */ ppp_data->lcp.req_mru=PPP_MRU_DEFAULT; ppp_data->lcp.req_ap=PPP_AP_DEFAULT; ppp_data->lcp.req_accm=PPP_ACCM_DEFAULT; ppp_data->lcp.r_mru=PPP_MRU_DEFAULT; ppp_data->lcp.r_accm=PPP_ACCM_DEFAULT; ppp_data->lcp.r_pfc=PPP_PFC_DEFAULT; ppp_data->lcp.r_acfc=PPP_ACFC_DEFAULT; ppp_data->lcp.s_mru=PPP_MRU_DEFAULT; ppp_data->lcp.s_accm=PPP_ACCM_DEFAULT; ppp_data->lcp.s_pfc=PPP_PFC_DEFAULT; ppp_data->lcp.s_acfc=PPP_ACFC_DEFAULT; ppp_data->lcp.n_ap=PPP_AP_DEFAULT; ppp_data->lcp.s_rejected=0; ppp_data->lcp.nscri=0; ppp_data->lcp.nstri=0; ppp_data->lcp.nscji=0; ppp_data->lcp.scr=FALSE; ppp_data->lcp.str=FALSE; INIT_STATE( PPP_SERVICE_LCP , LCP_STATE ); } /* lcp_init() */ /* +------------------------------------------------------------------------------ | Function : lcp_get_values +------------------------------------------------------------------------------ | Description : The function lcp_get_values() returns negotiated values | | Parameters : ptr_ap - returns Authentication Protocol | ptr_mru - returns Maximum Receive Unit | ptr_accm - returns Async Control Character Map | ptr_pfc - returns Protocol Field Compression | ptr_acfc - returns Address and Control Field Compression | +------------------------------------------------------------------------------ */ GLOBAL void lcp_get_values (UBYTE* ptr_ap, USHORT* ptr_mru, ULONG* ptr_accm, UBYTE* ptr_pfc, UBYTE* ptr_acfc) { TRACE_FUNCTION( "lcp_get_values" ); *ptr_mru = ppp_data->lcp.r_mru; *ptr_accm = ppp_data->lcp.r_accm | ppp_data->lcp.s_accm; *ptr_ap = ppp_data->lcp.n_ap; *ptr_pfc = ppp_data->lcp.r_pfc; *ptr_acfc = ppp_data->lcp.r_acfc; } /* lcp_get_values() */ /* +------------------------------------------------------------------------------ | Function : lcp_fill_out_packet +------------------------------------------------------------------------------ | Description : The function lcp_fill_out_packet() puts a LCP packet into | the protocol configuration list | | Parameters : pco_buf - pco list buffer | ptr_pos - position where to write the LCP packet, this value | must get back to the calling funtion | +------------------------------------------------------------------------------ */ GLOBAL void lcp_fill_out_packet (UBYTE pco_buf[], USHORT* ptr_pos) { USHORT pos; USHORT len_pos1, len_pos2; USHORT mru; TRACE_FUNCTION( "lcp_fill_out_packet" ); if((ppp_data->pco_mask & PPP_PCO_MASK_LCP_MRU) || (ppp_data->pco_mask & PPP_PCO_MASK_LCP_AP) || (ppp_data->pco_mask & PPP_PCO_MASK_LCP_TWO)) { pos = *ptr_pos; #ifdef _SIMULATION_ TRACE_EVENT_P3("parameters: pco_buf[]=%08x, ptr_pos=%08x, pos=%d", pco_buf, ptr_pos, (int)pos); #endif /* _SIMULATION_ */ /* * create Configure-Request packet */ /* * Protocol ID */ pco_buf[pos] = PROTOCOL_LCP_MSB; pos++; pco_buf[pos] = PROTOCOL_LCP_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_LCP_MRU) { /* * Maximum Receive Unit */ /* * if PPP_PCO_MASK_LCP_TWO is set use always s_mru * if PPP_PCO_MASK_LCP_TWO is not set * use the smaller one of s_mru and r_mru */ if((ppp_data->pco_mask & PPP_PCO_MASK_LCP_TWO) || (ppp_data->lcp.s_mru < ppp_data->lcp.r_mru)) mru = ppp_data->lcp.s_mru; else mru = ppp_data->lcp.r_mru; pco_buf[pos]=TYPE_MRU; pos++; pco_buf[pos]=LENGTH_MRU; pos++; pco_buf[pos]=(UBYTE)(mru >> 8); pos++; pco_buf[pos]=(UBYTE)(mru & 0x00ff); pos++; } if(ppp_data->pco_mask & PPP_PCO_MASK_LCP_AP) { /* * Authentication Protocol */ switch(ppp_data->lcp.n_ap) { case PPP_AP_PAP: pco_buf[pos]=TYPE_AP; pos++; pco_buf[pos]=LENGTH_AP_PAP; pos++; pco_buf[pos]=PROTOCOL_PAP_MSB; pos++; pco_buf[pos]=PROTOCOL_PAP_LSB; pos++; break; case PPP_AP_CHAP: pco_buf[pos]=TYPE_AP; pos++; pco_buf[pos]=LENGTH_AP_CHAP; pos++; pco_buf[pos]=PROTOCOL_CHAP_MSB; pos++; pco_buf[pos]=PROTOCOL_CHAP_LSB; pos++; pco_buf[pos]=ALGORITHM_MD5; pos++; break; } } /* * insert packet length */ #ifdef _SIMULATION_ TRACE_EVENT_P3("len_pos1=%d, len_pos2=%d, pos=%d", (int)len_pos1, (int)len_pos2, (int)pos); #endif /* _SIMULATION_ */ 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]; if(ppp_data->pco_mask & PPP_PCO_MASK_LCP_TWO) { /* * create client Configure-Request packet */ /* * Protocol ID */ pco_buf[pos] = PROTOCOL_LCP_MSB; pos++; pco_buf[pos] = PROTOCOL_LCP_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_LCP_MRU) { /* * Maximum Receive Unit */ mru = ppp_data->lcp.r_mru; pco_buf[pos]=TYPE_MRU; pos++; pco_buf[pos]=LENGTH_MRU; pos++; pco_buf[pos]=(UBYTE)(mru >> 8); pos++; pco_buf[pos]=(UBYTE)(mru & 0x00ff); pos++; } /* * insert packet length */ #ifdef _SIMULATION_ TRACE_EVENT_P3("len_pos1=%d, len_pos2=%d, pos=%d", (int)len_pos1, (int)len_pos2, (int)pos); #endif /* _SIMULATION_ */ 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]; } #ifdef _SIMULATION_ TRACE_EVENT_P6("pco_buf[%d]=%02x, pco_buf[%d]=%02x, pco_buf[%d]=%02x", (int)(len_pos1), pco_buf[len_pos1], (int)(len_pos2 - 1), pco_buf[len_pos2 - 1], (int)len_pos2, pco_buf[len_pos2]); #endif /* _SIMULATION_ */ /* * return new position */ *ptr_pos=pos; } } /* lcp_fill_out_packet() */ /* +------------------------------------------------------------------------------ | Function : lcp_get_scr +------------------------------------------------------------------------------ | Description : The function lcp_get_scr() returns a LCP | Configure Request packet | | Parameters : ptr_packet - returns the Configure Request packet | THE MEMORY FOR THE PACKET WILL ALLOCATED BY | THIS FUNCTION | +------------------------------------------------------------------------------ */ GLOBAL void lcp_get_scr (T_desc2** ptr_packet) { T_desc2* ret_desc; USHORT len_pos; USHORT pos; TRACE_FUNCTION( "lcp_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 + LCP_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->lcp.nscri;/*lint !e415 (Warning -- access of out-of-bounds pointer) */ pos++; /* * Length field (store the position) */ len_pos=pos; pos++; pos++; /* * Maximum Receive Unit */ if(((ppp_data->lcp.s_rejected & (1UL << TYPE_MRU)) EQ 0) && (ppp_data->lcp.s_mru NEQ PPP_MRU_DEFAULT)) { ret_desc->buffer[pos]=TYPE_MRU;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_MRU;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)(ppp_data->lcp.s_mru >> 8);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)(ppp_data->lcp.s_mru & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; } /* * Async Control Character Map */ if(((ppp_data->lcp.s_rejected & (1UL << TYPE_ACCM)) EQ 0) && (ppp_data->lcp.s_accm NEQ PPP_ACCM_DEFAULT)) { ret_desc->buffer[pos]=TYPE_ACCM;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_ACCM;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)(ppp_data->lcp.s_accm >> 24);/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)((ppp_data->lcp.s_accm >> 16) & 0x000000ff);/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)((ppp_data->lcp.s_accm >> 8) & 0x000000ff);/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=(UBYTE)(ppp_data->lcp.s_accm & 0x000000ff);/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; } /* * Authentication Protocol * (only in server mode) */ if(((ppp_data->lcp.s_rejected & (1UL << TYPE_AP)) EQ 0) && (ppp_data->mode EQ PPP_SERVER) && (ppp_data->lcp.n_ap NEQ PPP_AP_DEFAULT)) if(ppp_data->lcp.n_ap EQ PPP_AP_PAP) { ret_desc->buffer[pos]=TYPE_AP;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_AP_PAP;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=PROTOCOL_PAP_MSB;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=PROTOCOL_PAP_LSB;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; } else { ret_desc->buffer[pos]=TYPE_AP;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_AP_CHAP;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=PROTOCOL_CHAP_MSB;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=PROTOCOL_CHAP_LSB;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=ALGORITHM_MD5;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; } /* * Protocol Field Compression */ if(((ppp_data->lcp.s_rejected & (1UL << TYPE_PFC)) EQ 0) && (ppp_data->lcp.s_pfc NEQ PPP_PFC_DEFAULT)) { ret_desc->buffer[pos]=TYPE_PFC;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_PFC;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; } /* * Address and Control Field Compression */ if(((ppp_data->lcp.s_rejected & (1UL << TYPE_ACFC)) EQ 0) && (ppp_data->lcp.s_acfc NEQ PPP_ACFC_DEFAULT)) { ret_desc->buffer[pos]=TYPE_ACFC;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos]=LENGTH_ACFC;/*lint !e661 !e662 (Warning -- Likely access/creation of out-of-bounds pointer) */ pos++; } /* * insert packet length */ ret_desc->len=pos; ret_desc->buffer[len_pos]=(UBYTE)(pos >> 8);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ len_pos++; ret_desc->buffer[len_pos]=(UBYTE)(pos & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ /* * return the created packet */ ppp_data->lcp.scr=TRUE; *ptr_packet=ret_desc; } /* lcp_get_scr() */ /* +------------------------------------------------------------------------------ | Function : lcp_get_str +------------------------------------------------------------------------------ | Description : The function lcp_get_str() returns a LCP | Terminate Request packet | | Parameters : ptr_packet - returns the Terminate Request packet | THE MEMORY FOR THE PACKET WILL ALLOCATED BY | THIS FUNCTION | +------------------------------------------------------------------------------ */ GLOBAL void lcp_get_str (T_desc2** ptr_packet) { T_desc2* ret_desc; USHORT pos; TRACE_FUNCTION( "lcp_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 + LCP_TERM_REQ_LENGTH)); /* * fill the packet */ ret_desc->next = (ULONG)NULL; ret_desc->len = LCP_TERM_REQ_LENGTH; pos = 0; /* * Code field */ ret_desc->buffer[pos] = CODE_TERM_REQ; pos++; /* * Identifier field */ ret_desc->buffer[pos] = ppp_data->lcp.nstri;/*lint !e415 (Warning -- access of out-of-bounds pointer) */ pos++; /* * Length field */ ret_desc->buffer[pos] = 0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos] = LCP_TERM_REQ_LENGTH;/*lint !e415 !e416 (Warning -- access/creation 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 (Warning -- access/creation of out-of-bounds pointer) */ pos++; ret_desc->buffer[pos] = (U8)((ppp_data->ppp_cause) & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ pos++; /* * return the created packet */ ppp_data->lcp.str = TRUE; *ptr_packet = ret_desc; } /* lcp_get_str() */ /* +------------------------------------------------------------------------------ | Function : lcp_rcr +------------------------------------------------------------------------------ | Description : The function lcp_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 lcp_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; USHORT ap_id; UBYTE error_found; TRACE_FUNCTION( "lcp_rcr" ); /* * check for correct length field */ packet=*ptr_packet; packet_len=packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len=packet_len << 8; packet_len+=packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation 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) { *forward=FORWARD_DISCARD; return; } pos += packet->buffer[pos]; } if((pos - 1) NEQ packet_len) { *forward=FORWARD_DISCARD; return; } /* * check whether it is a new identifier */ *isnew=TRUE; if((ppp_data->lcp.rcr) && (ppp_data->lcp.lrcri EQ packet->buffer[1]))/*lint !e415 (Warning -- access of out-of-bounds pointer) */ *isnew=FALSE; ppp_data->lcp.lrcri=packet->buffer[1];/*lint !e415 (Warning -- access of out-of-bounds pointer) */ ppp_data->lcp.rcr=TRUE; /* * analyze configuration options */ ppp_data->lcp.r_mru = PPP_MRU_DEFAULT; ppp_data->lcp.r_accm = PPP_ACCM_DEFAULT; ppp_data->lcp.r_pfc = PPP_PFC_DEFAULT; ppp_data->lcp.r_acfc = PPP_ACFC_DEFAULT; if(ppp_data->mode EQ PPP_CLIENT) ppp_data->lcp.n_ap=PPP_AP_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 !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(packet->buffer[pos])/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ { /* * yet supported configuration options */ case TYPE_MRU: ppp_data->lcp.r_mru = packet->buffer[pos + 2];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ ppp_data->lcp.r_mru = (ppp_data->lcp.r_mru << 8); ppp_data->lcp.r_mru+= packet->buffer[pos + 3];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(code_ret) { case CODE_CONF_ACK: if(((analyzed & (1UL << TYPE_MRU)) EQ 0) && (type_len EQ LENGTH_MRU) && (ppp_data->lcp.r_mru >= PPP_MRU_MIN)) { analyzed|=(1UL << TYPE_MRU); pos+=LENGTH_MRU; break; } code_ret=CODE_CONF_NAK; case CODE_CONF_NAK: if((analyzed & (1UL << TYPE_MRU)) EQ 0) { analyzed|=(1UL << TYPE_MRU); error_found=FALSE; if(type_len < LENGTH_MRU) { 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_MRU - type_len)); temp_desc->next=packet->next; temp_desc->len=packet_len + LENGTH_MRU - type_len; memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 (Warning -- Possible data overrun, Possible access beyond array ) */ memcpy(&temp_desc->buffer[pos + LENGTH_MRU - type_len], &packet->buffer[pos], packet_len - pos);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ arb_discard_packet(packet); packet_len += (LENGTH_MRU - type_len); pos += (LENGTH_MRU - type_len); packet=temp_desc; error_found=TRUE; ppp_data->lcp.r_mru=PPP_MRU_MIN; } else if(ppp_data->lcp.r_mru < PPP_MRU_MIN) { error_found=TRUE; ppp_data->lcp.r_mru=PPP_MRU_MIN; } else if(type_len > LENGTH_MRU) { error_found=TRUE; } if(error_found EQ TRUE) { packet->buffer[copy_pos]=TYPE_MRU;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=LENGTH_MRU;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=(UBYTE)(ppp_data->lcp.r_mru >> 8);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=(UBYTE)(ppp_data->lcp.r_mru & 0x00ff);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; } pos+= type_len; break; } code_ret = CODE_CONF_REJ; copy_pos = 4; case CODE_CONF_REJ: if((analyzed & (1UL << TYPE_MRU)) EQ 0) { analyzed|=(1UL << TYPE_MRU); pos+= type_len; break; } while(type_len > 0) { packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } break; } break; case TYPE_ACCM: ppp_data->lcp.r_accm=packet->buffer[pos + 2];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ ppp_data->lcp.r_accm=(ppp_data->lcp.r_accm << 8); ppp_data->lcp.r_accm+=packet->buffer[pos + 3];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ ppp_data->lcp.r_accm=(ppp_data->lcp.r_accm << 8); ppp_data->lcp.r_accm+=packet->buffer[pos + 4];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ ppp_data->lcp.r_accm=(ppp_data->lcp.r_accm << 8); ppp_data->lcp.r_accm+=packet->buffer[pos + 5];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(code_ret) { case CODE_CONF_ACK: if(((analyzed & (1UL << TYPE_ACCM)) EQ 0) && (type_len EQ LENGTH_ACCM)) { analyzed|=(1UL << TYPE_ACCM); pos+=LENGTH_ACCM; break; } code_ret=CODE_CONF_NAK; case CODE_CONF_NAK: if((analyzed & (1UL << TYPE_ACCM)) EQ 0) { analyzed|=(1UL << TYPE_ACCM); error_found=FALSE; if(type_len < LENGTH_ACCM) { 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_ACCM - type_len)); temp_desc->next=packet->next; temp_desc->len=packet_len + LENGTH_ACCM - type_len; memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 (Warning -- Possible data overrun, Possible access beyond array ) */ memcpy(&temp_desc->buffer[pos + LENGTH_ACCM - type_len], &packet->buffer[pos], packet_len - pos);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ arb_discard_packet(packet); packet_len += (LENGTH_ACCM - type_len); pos += (LENGTH_ACCM - type_len); packet=temp_desc; error_found=TRUE; } else if(type_len > LENGTH_ACCM) { error_found=TRUE; } if(error_found EQ TRUE) { memmove(&packet->buffer[copy_pos], &packet->buffer[pos], LENGTH_ACCM);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ packet->buffer[copy_pos + 1]=LENGTH_ACCM;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos+=LENGTH_ACCM; } pos+=type_len; break; } code_ret = CODE_CONF_REJ; copy_pos = 4; case CODE_CONF_REJ: if((analyzed & (1UL << TYPE_ACCM)) EQ 0) { analyzed|=(1UL << TYPE_ACCM); pos+=type_len; break; } while(type_len > 0) { packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } break; } break; case TYPE_AP: ap_id = (packet->buffer[pos + 2]) << 8;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ ap_id |= packet->buffer[pos + 3];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(code_ret) { case CODE_CONF_ACK: if(((analyzed & (1UL << TYPE_AP)) EQ 0) && (ppp_data->mode EQ PPP_CLIENT)) { if((ap_id EQ DTI_PID_PAP) && (type_len EQ LENGTH_AP_PAP) && (ppp_data->lcp.req_ap EQ PPP_AP_PAP)) { analyzed|=(1UL << TYPE_AP); pos+=type_len; ppp_data->lcp.n_ap = PPP_AP_PAP; break; } if((ap_id EQ DTI_PID_PAP) && (type_len EQ LENGTH_AP_PAP) && (ppp_data->lcp.req_ap EQ PPP_AP_AUTO)) { analyzed|=(1UL << TYPE_AP); pos+=type_len; ppp_data->lcp.n_ap = PPP_AP_PAP; break; } if((ap_id EQ DTI_PID_CHAP) && (type_len EQ LENGTH_AP_CHAP) && (ppp_data->lcp.req_ap EQ PPP_AP_CHAP)) { analyzed|=(1UL << TYPE_AP); pos+=type_len; ppp_data->lcp.n_ap = PPP_AP_CHAP; break; } if((ap_id EQ DTI_PID_CHAP) && (type_len EQ LENGTH_AP_CHAP) && (ppp_data->lcp.req_ap EQ PPP_AP_AUTO)) { analyzed|=(1UL << TYPE_AP); pos+=type_len; ppp_data->lcp.n_ap = PPP_AP_CHAP; break; } } code_ret=CODE_CONF_NAK; case CODE_CONF_NAK: if(((analyzed & (1UL << TYPE_AP)) EQ 0) && (ppp_data->mode EQ PPP_CLIENT) && (ppp_data->lcp.req_ap NEQ PPP_AP_NO)) { analyzed|=(1UL << TYPE_AP); error_found=FALSE; if(((ppp_data->lcp.req_ap EQ PPP_AP_PAP) && (type_len < LENGTH_AP_PAP)) || ((ppp_data->lcp.req_ap EQ PPP_AP_CHAP) && (type_len < LENGTH_AP_CHAP))) { T_desc2* temp_desc; /* * create a new larger packet and copy the content * of the old packet into the new */ if(ppp_data->lcp.req_ap EQ PPP_AP_PAP) { MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + packet_len + LENGTH_AP_PAP - type_len)); temp_desc->len=packet_len + LENGTH_AP_PAP - type_len; memcpy(&temp_desc->buffer[pos + LENGTH_AP_PAP - type_len], &packet->buffer[pos], packet_len - pos);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ packet_len += (LENGTH_AP_PAP - type_len); pos += (LENGTH_AP_PAP - type_len); } else { MALLOC (temp_desc, (USHORT)(sizeof(T_desc2) - 1 + packet_len + LENGTH_AP_CHAP - type_len)); temp_desc->len=packet_len + LENGTH_AP_CHAP - type_len; memcpy(&temp_desc->buffer[pos + LENGTH_AP_CHAP - type_len], &packet->buffer[pos], packet_len - pos);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ packet_len += (LENGTH_AP_CHAP - type_len); pos += (LENGTH_AP_CHAP - type_len); } temp_desc->next=packet->next; memcpy(temp_desc->buffer, packet->buffer, pos);/*lint !e669 !e670 (Warning -- Possible data overrun, Possible access beyond array ) */ arb_discard_packet(packet); packet=temp_desc; error_found=TRUE; } else if(((ppp_data->lcp.req_ap EQ PPP_AP_PAP) && (ap_id NEQ DTI_PID_PAP)) || ((ppp_data->lcp.req_ap EQ PPP_AP_CHAP) && (ap_id NEQ DTI_PID_CHAP))) { error_found=TRUE; } else if(((ppp_data->lcp.req_ap EQ PPP_AP_PAP) && (type_len > LENGTH_AP_PAP)) || ((ppp_data->lcp.req_ap EQ PPP_AP_CHAP) && (type_len > LENGTH_AP_CHAP))) { error_found=TRUE; } if(error_found EQ TRUE) { packet->buffer[copy_pos]=TYPE_AP;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; if(ppp_data->lcp.req_ap EQ PPP_AP_PAP) { packet->buffer[copy_pos]=LENGTH_AP_PAP;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=PROTOCOL_PAP_MSB;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=PROTOCOL_PAP_LSB;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; } else { packet->buffer[copy_pos]=LENGTH_AP_CHAP;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=PROTOCOL_CHAP_MSB;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=PROTOCOL_CHAP_LSB;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; packet->buffer[copy_pos]=ALGORITHM_MD5;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; } } pos+=type_len; break; } code_ret=CODE_CONF_REJ; copy_pos=4; case CODE_CONF_REJ: if(((analyzed & (1UL << TYPE_AP)) EQ 0) && (ppp_data->mode EQ PPP_CLIENT) && (ppp_data->lcp.req_ap NEQ PPP_AP_NO)) { analyzed|=(1UL << TYPE_AP); pos+=type_len; break; } while(type_len > 0) { packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } break; } break; case TYPE_PFC: ppp_data->lcp.r_pfc=TRUE; switch(code_ret) { case CODE_CONF_ACK: if(((analyzed & (1UL << TYPE_PFC)) EQ 0) && (type_len EQ LENGTH_PFC)) { analyzed|=(1UL << TYPE_PFC); pos+=LENGTH_PFC; break; } code_ret=CODE_CONF_NAK; case CODE_CONF_NAK: if((analyzed & (1UL << TYPE_PFC)) EQ 0) { analyzed|=(1UL << TYPE_PFC); if(type_len > LENGTH_PFC) { memmove(&packet->buffer[copy_pos], &packet->buffer[pos], LENGTH_PFC);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ packet->buffer[copy_pos + 1]=LENGTH_PFC;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos+=LENGTH_PFC; } pos+=type_len; break; } code_ret=CODE_CONF_REJ; copy_pos=4; case CODE_CONF_REJ: if((analyzed & (1UL << TYPE_PFC)) EQ 0) { analyzed|=(1UL << TYPE_PFC); pos+=type_len; break; } while(type_len > 0) { packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } break; } break; case TYPE_ACFC: ppp_data->lcp.r_acfc=TRUE; switch(code_ret) { case CODE_CONF_ACK: if(((analyzed & (1UL << TYPE_ACFC)) EQ 0) && (type_len EQ LENGTH_ACFC)) { analyzed|=(1UL << TYPE_ACFC); pos+=LENGTH_ACFC; break; } code_ret=CODE_CONF_NAK; case CODE_CONF_NAK: if((analyzed & (1UL << TYPE_ACFC)) EQ 0) { analyzed|=(1UL << TYPE_ACFC); if(type_len > LENGTH_ACFC) { memmove(&packet->buffer[copy_pos], &packet->buffer[pos], LENGTH_ACFC);/*lint !e669 !e670 !e662 (Warning -- Possible data overrun, Possible access beyond array ) */ packet->buffer[copy_pos + 1]=LENGTH_ACFC;/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos+=LENGTH_ACFC; } pos+=type_len; break; } code_ret=CODE_CONF_REJ; copy_pos=4; case CODE_CONF_REJ: if((analyzed & (1UL << TYPE_ACFC)) EQ 0) { analyzed|=(1UL << TYPE_ACFC); pos+=type_len; break; } while(type_len > 0) { packet->buffer[copy_pos]=packet->buffer[pos];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } 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 !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ copy_pos++; pos++; type_len--; } break; } } } /* * 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 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[3]=(UBYTE)(copy_pos & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ return; } #ifdef _SIMULATION_ ppp_trace_desc(packet); #endif /* * all configuration options are acceptable */ *forward=FORWARD_RCRP; } /* lcp_rcr() */ /* +------------------------------------------------------------------------------ | Function : lcp_rca +------------------------------------------------------------------------------ | Description : The function lcp_rca() checks whether the given | Configure Ack packet is valid and if so it returns | FORWARD_RCA. | | Parameters : packet - Configure Ack packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rca (T_desc2* packet, UBYTE* forward) { USHORT packet_len; TRACE_FUNCTION( "lcp_rca" ); packet_len=packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len=packet_len << 8; packet_len+=packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 4) || (packet_len > packet->len)) { *forward=FORWARD_DISCARD; return; } if((ppp_data->lcp.scr EQ FALSE) || (packet->buffer[1] NEQ ppp_data->lcp.nscri))/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ { /* * invalid packet */ *forward=FORWARD_DISCARD; return; } /* * acceptable packet */ arb_discard_packet(packet); ppp_data->lcp.nscri++; *forward=FORWARD_RCA; } /* lcp_rca() */ /* +------------------------------------------------------------------------------ | Function : lcp_rcn +------------------------------------------------------------------------------ | Description : The function lcp_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 lcp_rcn (T_desc2** ptr_packet, UBYTE* forward) { T_desc2* packet; USHORT packet_len; UBYTE type_len; USHORT pos; USHORT mru; ULONG accm; TRACE_FUNCTION( "lcp_rcn" ); /* * check for correct length field */ packet = *ptr_packet; packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len > packet->len) || (packet_len < 4)) { *forward=FORWARD_DISCARD; return; } if((ppp_data->lcp.scr EQ FALSE) || (packet->buffer[1] NEQ ppp_data->lcp.nscri))/*lint !e415 (Warning -- 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) { *forward=FORWARD_DISCARD; return; } pos += packet->buffer[pos]; } 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 !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(packet->buffer[pos])/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ { /* * yet supported configuration options */ case TYPE_MRU: mru = packet->buffer[pos + 2];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ mru = mru << 8; mru+= packet->buffer[pos + 3];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ if((type_len EQ LENGTH_MRU) && (mru >= PPP_MRU_MIN) && (mru <= ppp_data->lcp.req_mru)) { /* * clear reject flag and set new mru value */ ppp_data->lcp.s_rejected &= ~(1UL << TYPE_MRU); ppp_data->lcp.s_mru=mru; } break; case TYPE_ACCM: if(type_len EQ LENGTH_ACCM) { accm=packet->buffer[pos + 2];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ accm=accm << 8; accm+=packet->buffer[pos + 3];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ accm=accm << 8; accm+=packet->buffer[pos + 4];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ accm=accm << 8; accm+=packet->buffer[pos + 5];/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ /* * clear reject flag and set new accm value */ ppp_data->lcp.s_rejected &= ~(1UL << TYPE_ACCM); ppp_data->lcp.s_accm |= accm; } break; case TYPE_AP: if(ppp_data->lcp.n_ap EQ PPP_AP_CHAP) { TRACE_EVENT("LCP: CHAP rejected by client"); } else if(ppp_data->lcp.n_ap EQ PPP_AP_PAP) { TRACE_EVENT("LCP: PAP rejected by client"); } if((ppp_data->lcp.req_ap EQ PPP_AP_AUTO) && (ppp_data->mode EQ PPP_SERVER)) { /* * clear reject flag ans set new authentication protocol value */ ppp_data->lcp.s_rejected &= ~(1UL << TYPE_AP); if((packet->buffer[pos + 2] EQ PROTOCOL_CHAP_MSB) && (packet->buffer[pos + 3] EQ PROTOCOL_CHAP_LSB))/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ { ppp_data->lcp.n_ap=PPP_AP_CHAP; } else if((packet->buffer[pos + 2] EQ PROTOCOL_PAP_MSB) && (packet->buffer[pos + 3] EQ PROTOCOL_PAP_LSB))/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ { ppp_data->lcp.n_ap=PPP_AP_PAP; } else { ppp_data->lcp.n_ap=PPP_AP_NO; } } break; case TYPE_PFC: if(type_len EQ LENGTH_PFC) { /* * clear reject flag ans set new pfc value */ ppp_data->lcp.s_rejected &= ~(1UL << TYPE_PFC); ppp_data->lcp.s_pfc=TRUE; } break; case TYPE_ACFC: if(type_len EQ LENGTH_ACFC) { /* * clear reject flag ans set new acfc value */ ppp_data->lcp.s_rejected &= ~(1UL << TYPE_ACFC); ppp_data->lcp.s_acfc=TRUE; } break; } pos+=type_len; } /* * free this packet and create a new with changed configuration options */ arb_discard_packet(packet); *forward=FORWARD_RCN; ppp_data->lcp.nscri++; lcp_get_scr(&packet); *ptr_packet=packet; } /* lcp_rcn() */ /* +------------------------------------------------------------------------------ | Function : lcp_rcj +------------------------------------------------------------------------------ | Description : The function lcp_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 lcp_rcj (T_desc2** ptr_packet, UBYTE* forward) { T_desc2* packet; USHORT packet_len; UBYTE type_len; USHORT pos; TRACE_FUNCTION( "lcp_rcj" ); /* * check for correct length field */ packet=*ptr_packet; packet_len=packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len=packet_len << 8; packet_len+=packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len > packet->len) || (packet_len < 4)) { *forward=FORWARD_DISCARD; return; } if((ppp_data->lcp.scr EQ FALSE) || (packet->buffer[1] NEQ ppp_data->lcp.nscri))/*lint !e415 !e416 (Warning -- access/creation 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) { *forward=FORWARD_DISCARD; return; } pos += packet->buffer[pos]; } 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 !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ switch(packet->buffer[pos])/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */ { /* * yet supported configuration options */ case TYPE_MRU: ppp_data->lcp.s_rejected |= (1UL << TYPE_MRU); break; case TYPE_ACCM: ppp_data->lcp.s_rejected |= (1UL << TYPE_ACCM); break; case TYPE_PFC: ppp_data->lcp.s_rejected |= (1UL << TYPE_PFC); break; case TYPE_ACFC: ppp_data->lcp.s_rejected |= (1UL << TYPE_ACFC); break; case TYPE_AP: if(ppp_data->lcp.n_ap EQ PPP_AP_CHAP) { TRACE_EVENT("LCP: CHAP rejected by client"); } else if(ppp_data->lcp.n_ap EQ PPP_AP_PAP) { TRACE_EVENT("LCP: PAP rejected by client"); } if((ppp_data->lcp.req_ap EQ PPP_AP_AUTO) && (ppp_data->mode EQ PPP_SERVER)) { ppp_data->lcp.s_rejected |= (1UL << TYPE_AP); } break; } pos+=type_len; } /* * free this packet and create a new with changed configuration options */ arb_discard_packet(packet); *forward=FORWARD_RCN; ppp_data->lcp.nscri++; lcp_get_scr(&packet); *ptr_packet=packet; } /* lcp_rcj() */ /* +------------------------------------------------------------------------------ | Function : lcp_rtr +------------------------------------------------------------------------------ | Description : The function lcp_rtr() creates a Terminate Ack packet. | | Parameters : ptr_packet - pointer to a Terminate Request packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rtr (T_desc2** ptr_packet, UBYTE* forward) { T_desc2* packet; USHORT packet_len; TRACE_FUNCTION( "lcp_rtr" ); /* * check for correct length field */ packet = *ptr_packet; packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation 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; } /* lcp_rtr() */ /* +------------------------------------------------------------------------------ | Function : lcp_rta +------------------------------------------------------------------------------ | Description : The function lcp_rta() checks whether the given | Terminate Ack packet is valid and if so it returns | FORWARD_RTA | | Parameters : packet - Terminate Ack packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rta (T_desc2* packet, UBYTE* forward) { USHORT packet_len; TRACE_FUNCTION( "lcp_rta" ); /* * check for correct length field */ packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 4) || (packet_len > packet->len)) { *forward=FORWARD_DISCARD; return; } if((ppp_data->lcp.str EQ FALSE) || (packet->buffer[1] NEQ ppp_data->lcp.nstri))/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ { /* * invalid packet */ *forward=FORWARD_DISCARD; return; } /* * acceptable packet */ arb_discard_packet(packet); ppp_data->lcp.nstri++; *forward=FORWARD_RTA; } /* lcp_rta() */ /* +------------------------------------------------------------------------------ | Function : lcp_rxj +------------------------------------------------------------------------------ | Description : The function lcp_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 lcp_rxj (T_desc2** ptr_packet, UBYTE* forward) { USHORT packet_len; T_desc2* packet; TRACE_FUNCTION( "lcp_rxj" ); /* * check for correct length field */ packet = *ptr_packet; packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 5) || (packet_len > packet->len)) { *forward=FORWARD_DISCARD; return; } switch(packet->buffer[4])/*lint !e415 !e416 (Warning -- access/creation 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: case CODE_PROT_REJ: arb_discard_packet(packet); ppp_data->lcp.nstri++; lcp_get_str(&packet); *ptr_packet=packet; *forward=FORWARD_RXJN; break; default: *forward=FORWARD_DISCARD; break; } } /* lcp_rxj() */ /* +------------------------------------------------------------------------------ | Function : lcp_rpj +------------------------------------------------------------------------------ | Description : The function lcp_rpj() analyzes which protocol is rejected. | | Parameters : packet - Protocol Reject packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rpj (T_desc2* packet, UBYTE* forward) { USHORT packet_len; USHORT rej_protocol; TRACE_FUNCTION( "lcp_rpj" ); /* * check for correct length field */ packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 6) || (packet_len > packet->len)) { *forward=FORWARD_DISCARD; return; } /* * get rejected protocol */ rej_protocol=packet->buffer[4];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ rej_protocol=rej_protocol << 8; rej_protocol+=packet->buffer[5];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ /* * analyze rejected protocol */ switch(rej_protocol) { case DTI_PID_LCP: arb_discard_packet(packet); *forward=FORWARD_RPJ_LCP; break; case DTI_PID_PAP: arb_discard_packet(packet); *forward=FORWARD_RPJ_PAP; break; case DTI_PID_CHAP: arb_discard_packet(packet); *forward=FORWARD_RPJ_CHAP; break; case DTI_PID_IPCP: arb_discard_packet(packet); *forward=FORWARD_RPJ_IPCP; break; case DTI_PID_IP: arb_discard_packet(packet); *forward=FORWARD_RPJ_IP; break; case DTI_PID_CTCP: arb_discard_packet(packet); *forward=FORWARD_RPJ_CTCP; break; case DTI_PID_UTCP: arb_discard_packet(packet); *forward=FORWARD_RPJ_UTCP; break; default: *forward=FORWARD_DISCARD; break; } } /* lcp_rpj() */ /* +------------------------------------------------------------------------------ | Function : lcp_rer +------------------------------------------------------------------------------ | Description : The function lcp_rer() creates an Echo Reply | | Parameters : ptr_packet - Echo Request packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rer (T_desc2** ptr_packet, UBYTE* forward) { T_desc2* packet; USHORT packet_len; TRACE_FUNCTION( "lcp_rer" ); /* * check for correct length field */ packet = *ptr_packet; packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 8) || (packet_len > packet->len)) { *forward=FORWARD_DISCARD; return; } /* * insert zero for magic number because we not yet support magic number * negotiation */ packet->buffer[4]=0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[5]=0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[6]=0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[7]=0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ /* * change Code field */ packet->buffer[0]=CODE_ECHO_REP; /* * set return value */ *forward=FORWARD_RER; } /* lcp_rer() */ /* +------------------------------------------------------------------------------ | Function : lcp_rep_rdr +------------------------------------------------------------------------------ | Description : The function lcp_rep_rdr() just analyzes the given | Magic Number. | | Parameters : packet - Echo Reply packet | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_rep_rdr (T_desc2* packet, UBYTE* forward) { TRACE_FUNCTION( "lcp_rep_rdr" ); *forward=FORWARD_DISCARD; } /* lcp_rep_rdr() */ /* +------------------------------------------------------------------------------ | Function : lcp_ruc +------------------------------------------------------------------------------ | Description : The function lcp_ruc() creates a Code Reject packet and returns | FORWARD_RUC. | | Parameters : ptr_packet - packet with unknown code | forward - returns result of analysis | +------------------------------------------------------------------------------ */ GLOBAL void lcp_ruc (T_desc2** ptr_packet, UBYTE* forward) { T_desc2* packet; T_desc2* temp_desc; USHORT packet_len; TRACE_FUNCTION( "lcp_ruc" ); /* * check for correct length field */ packet = *ptr_packet; packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet_len = packet_len << 8; packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ if((packet_len < 4) || (packet_len > packet->len)) { *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 !e669 !e670 !e416 (Warning -- Possible data overrun, Possible access beyond array ) */ arb_discard_packet(packet); packet = temp_desc; /* * fill the first bytes to create a Code Reject */ packet->buffer[0] = CODE_CODE_REJ; ppp_data->lcp.nscji++; packet->buffer[1] = ppp_data->lcp.nscji;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[2] = (UBYTE)(packet_len >> 8);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ packet->buffer[3] = (UBYTE)(packet_len & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */ /* * set return values */ *ptr_packet = packet; *forward = FORWARD_RUC; } /* lcp_ruc() */