diff src/g23m-fad/ppp/ppp_lcpf.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_lcpf.c	Fri Oct 16 06:25:50 2020 +0000
@@ -0,0 +1,1913 @@
+/* 
++----------------------------------------------------------------------------- 
+|  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() */