Exemple #1
0
void IPCP_recv
   (
      PCB_PTR     pcb,
            /* [IN] received packet */
      pointer     handle
            /* [IN] IPCP configuration */
   )
{ /* Body */
   IP_IF_PTR            if_ptr = handle;
   RTCSPCB_PTR          packet;
   uint_32              error;

   IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_TOTAL++);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_OCTETS += pcb->FRAG[0].LENGTH);
   IF_IPIF_STATS_ENABLED(if_ptr->STATS.ST_RX_UNICAST++);

   packet = RTCSPCB_alloc_recv(pcb);
   if (packet == NULL) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      PCB_free(pcb);
      return;
   } /* Endif */

   //RTCSLOG_PCB_ALLOC(packet);

   error = RTCSPCB_next(packet, 2);
   if (error) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_ERRORS++);
      IF_IPIF_STATS_ENABLED(RTCS_seterror(&if_ptr->STATS.ERR_RX, error, (uint_32)packet));
      RTCSLOG_PCB_FREE(packet, error);
      RTCSPCB_free(packet);
      return;
   } /* Endif */

   RTCSLOG_PCB_READ(packet, RTCS_LOGCTRL_IFTYPE(IPIFTYPE_PPP), 0);

   packet->TYPE = RTCSPCB_TYPE_ONLYCAST;
   packet->IFSRC = if_ptr;

   if (!RTCSCMD_service(packet, IP_service)) {
      IF_IPIF_STATS_ENABLED(if_ptr->STATS.COMMON.ST_RX_MISSED++);
      RTCSLOG_PCB_FREE(packet, RTCS_OK);
      RTCSPCB_free(packet);
   } /* Endif */

} /* Endbody */
static RTCSPCB_PTR IPREASM_reasm_dgram
   (
      IP_DGRAM_PTR   dgram    /* [IN] the dgram descriptor */
   )
{ /* Body */
   RTCSPCB_PTR outpcb;
   PCB_PTR     bpcb;
   PCB_FRAGMENT      *pcb_frag_ptr;
   unsigned char   *data;
   uint32_t     iphlen  = (mqx_ntohc(dgram->header.IP4.IPH.VERSLEN) & 0xF) << 2;
   uint32_t     ip_totlen = iphlen + dgram->TOTLEN;

   bpcb = RTCS_mem_alloc_system(sizeof(PCB) + sizeof(PCB_FRAGMENT) + ip_totlen);
   if (!bpcb) {
      return NULL;
   } /* Endif */

   data = (unsigned char *)bpcb + sizeof(PCB) + sizeof(PCB_FRAGMENT);
   bpcb->FREE    = (void(_CODE_PTR_)(PCB_PTR))_mem_free;
   bpcb->PRIVATE = NULL;
 
   pcb_frag_ptr = bpcb->FRAG;
   pcb_frag_ptr->LENGTH   = ip_totlen;
   pcb_frag_ptr->FRAGMENT = data;
   pcb_frag_ptr++;
   pcb_frag_ptr->LENGTH   = 0;
   pcb_frag_ptr->FRAGMENT = NULL;

   /* Copy the IP header with options */
   mqx_htons(dgram->header.IP4.IPH.FRAGMENT, 0);
   _mem_copy(&dgram->header.IP4.IPH, data, iphlen);
   data += iphlen;

   /*
   ** At this point, we really should update the LENGTH
   ** and CHECKSUM fields in the new IP header, but we
   ** don't actually need to, because this datagram is
   ** going straight to IPLOCAL_service, which doesn't
   ** check these things.
   */

   /* Copy the stored data in the new packet */
   IPREASM_blk_read_all(dgram, data, dgram->TOTLEN);

   /* Put it in an RTCSPCB */
   outpcb = RTCSPCB_alloc_recv(bpcb);
   if (outpcb == NULL) {
      PCB_free(bpcb);
      return NULL;
   } /* Endif */
   //RTCSLOG_PCB_ALLOC(bpcb);
   outpcb->IFSRC           = dgram->IFSRC;
   outpcb->TYPE            = dgram->TYPE;
   outpcb->LINK_OPTIONS.RX = dgram->LINKOPT;
   RTCSPCB_DATA_NETWORK(outpcb) = RTCSPCB_DATA(outpcb);
   RTCSPCB_SET_TRANS_PROTL(outpcb, dgram->header.IP4.PROTO);
   RTCSPCB_SET_TRANS_DELTA(outpcb, iphlen);

   /* Delete the local structure */
   IPREASM_del_dgram(dgram);

   return outpcb;

} /* Endbody */