diff src/g23m-fad/udp/udp_kerf.c @ 174:90eb61ecd093

src/g23m-fad: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 12 Oct 2016 05:40:46 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-fad/udp/udp_kerf.c	Wed Oct 12 05:40:46 2016 +0000
@@ -0,0 +1,300 @@
+/*
++----------------------------------------------------------------------------
+|  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 defines the functions for processing
+|             of incomming primitives for the component
+|             Internet Protocol of the mobile station
++----------------------------------------------------------------------------
+*/
+
+#define ENTITY_UDP
+
+#include <string.h>
+#include "typedefs.h"
+#include "pcm.h"
+#include "pconst.cdg"
+#include "mconst.cdg"
+#include "message.h"
+#include "ccdapi.h"
+#include "vsi.h"
+#include "macdef.h" /* to get PFREE_DESC2 */
+#include "custom.h"
+#include "gsm.h"
+#include "prim.h"
+#include "cus_udp.h"
+#include "cnf_udp.h"
+#include "mon_udp.h"
+#include "pei.h"
+#include "tok.h"
+#include "dti.h" /* to get dti lib */
+#include "udp.h"
+#include "ip_udp.h"
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : WAP                                 MODULE  : udp_kerf.c |
+| STATE   : code                                ROUTINE : init_udp   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Init the global variables of UDP
+*/
+
+void init_udp (void)
+{
+  T_HILA * p_ul;
+  T_LOLA * p_dl;
+  T_KER * p_ker = & udp_data->ker;
+
+  /* Set global variables for every entity */
+
+  INIT_STATE (HILA, DOWN);
+  INIT_STATE (LOLA, DOWN);
+
+  p_ul = & udp_data->hila;
+  *p_ul->entity_name = 0;
+  p_ul->dti_state    = DTI_CLOSED;
+  p_ul->dti_data_req = NULL;
+
+  p_dl = & udp_data->lola;
+  *p_dl->entity_name = 0;
+  p_dl->dti_state    = DTI_CLOSED;
+  p_dl->dti_data_ind = NULL;
+  p_dl->drop_packet  = FALSE;
+  p_dl->state_err    = STATE_DL_NO_ERROR;
+  p_dl->src_addr     = NO_ADDR;
+  p_dl->dst_addr     = NO_ADDR;
+  p_dl->dst_port     = NO_PORT;
+  p_dl->src_port     = NO_PORT;
+
+  /* Downlink and uplink for one entity */
+
+  p_ker->send_icmp         = FALSE;
+  p_ker->port_state        = PORT_DOWN;
+  p_ker->dti_data_req_icmp = NULL;
+
+  p_ker->dst_addr = NO_ADDR;
+  p_ker->src_addr = NO_ADDR;
+  p_ker->src_port = NO_PORT;
+  p_ker->dst_port = NO_PORT;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : WAP                           MODULE  : udp_kerf.c       |
+| STATE   : code                          ROUTINE : udp_build_packet |
++--------------------------------------------------------------------+
+
+  PURPOSE : Build UDP and ICMP packets to send
+*/
+
+void udp_build_packet (BOOL hila, UBYTE to_do)
+{
+  T_KER * p_ker = & udp_data->ker;
+
+  if (hila) /* Build the packets for higher layer */
+  {
+    switch (to_do)
+    {
+    case B_NORMAL_PACKET:
+      {
+        T_desc_list2 * desc_list = & udp_data->hila.dti_data_req->desc_list2;
+        T_desc2 * desc = (T_desc2 *) desc_list->first;
+        USHORT udp_payload_len = desc_list->list_len;
+
+        if (desc == NULL)
+        {
+          TRACE_ERROR ("Hila's desc == NULL in udp_build_packet().");
+          return;
+        }
+        else
+        {
+          /* Make a new desc for the IP and UDP packet header */
+
+          USHORT headroom = LEN_IP_HEADER_B + LEN_UDP_HEADER_B;
+          UBYTE * ip_header;
+          T_desc2 * desc_new = M_ALLOC (offsetof (T_desc2, buffer) + headroom);
+
+          if (desc_new == NULL)
+          {
+            TRACE_ERROR ("Not enough memory in udp_build_packet().");
+            return;
+          }
+          desc_new->next = (ULONG) desc;
+          desc_new->offset = 0;
+          desc_new->len = headroom;
+          desc_new->size = headroom;
+          ip_header = desc_new->buffer;
+          {
+            register unsigned i;
+            for (i=0; i < headroom; i++)
+              ip_header[i] = '\0';/*lint !e661 !e662 (Warning -- access/creation of out-of-bounds pointer) */
+          }
+
+          /* Put the desc at the first place of the descs and
+           * build the UDP header */
+
+          desc_list->first = (ULONG) desc_new;
+          desc_list->list_len = (USHORT) (desc_new->len + desc_list->list_len);
+
+          /* Fill in IP header information */
+
+          SET_IP_VERSION (ip_header, IP_VERSION);
+          SET_IP_HEADER_LEN (ip_header, MIN_HEADER_LEN);
+          /*lint -e{661, 662} (Warning -- access/creation of out-of-bounds pointer) */
+         {
+          SET_IP_TOTAL_LEN (ip_header, desc_list->list_len);
+          SET_IP_PROT (ip_header, UDP_PROT);
+          SET_IP_SOURCE_ADDR (ip_header, p_ker->src_addr);
+          SET_IP_DEST_ADDR (ip_header, p_ker->dst_addr);
+
+          SET_UDP_SRC_PORT (ip_header, p_ker->src_port);
+          SET_UDP_DST_PORT (ip_header, p_ker->dst_port);
+          SET_UDP_LEN (ip_header, udp_payload_len + LEN_UDP_HEADER_B);
+          }
+          {
+            UBYTE pseudo_header [LEN_PSEUDO_HEADER_B];
+            ULONG overlay;
+            USHORT chksum;
+
+            /* Build the pseudoheader for to calculate the chksum */
+
+            SET_UDP_PSEUDO_H_SRC_ADDR (pseudo_header, p_ker->src_addr);
+            SET_UDP_PSEUDO_H_DEST_ADDR (pseudo_header, p_ker->dst_addr);
+            SET_UDP_PSEUDO_H_ZERO (pseudo_header, 0);
+            SET_UDP_PSEUDO_H_PROT (pseudo_header, UDP_PROT);
+            SET_UDP_PSEUDO_H_LEN (pseudo_header, udp_payload_len + LEN_UDP_HEADER_B);
+
+            /* Calculate the checksum for the pseudoheader */
+            overlay = partial_checksum (pseudo_header, LEN_PSEUDO_HEADER_B);
+
+            /* Calculate for the UDP header and the data */
+            RESET_UDP_CHKSUM (ip_header, LEN_IP_HEADER_B);/*lint !e661 !e662 (Warning -- access/creation of out-of-bounds pointer) */
+            chksum = desc_checksum (desc_list, LEN_IP_HEADER_B, overlay);
+            SET_UDP_CHKSUM (ip_header, LEN_IP_HEADER_B, chksum);/*lint !e661 !e662 (Warning -- access/creation of out-of-bounds pointer) */
+          }
+        }
+      }
+      break;
+
+    default:
+      break;
+    }
+  }
+  else /* Build the packets for lower layer */
+  {
+    T_LOLA * p_dl = & udp_data->lola;
+    T_desc_list2 * desc_list = & p_dl->dti_data_ind->desc_list2;
+    T_desc2 * desc = (T_desc2 *) desc_list->first;
+
+    if (desc == NULL)
+    {
+      TRACE_ERROR ("Lola's desc == NULL in udp_build_packet().");
+      return;
+    }
+    if (desc->len < LEN_IP_HEADER_B)
+    {
+      TRACE_ERROR (
+        "Lola's desc->len < LEN_IP_HEADER_B "
+        "in udp_build_packet()."
+      );
+      return;
+    }
+    if (GET_IP_HEADER_LEN_B (desc->buffer + desc->offset) < LEN_IP_HEADER_B)
+    {
+      TRACE_ERROR (
+        "Lola's GET_IP_HEADER_LEN_B() < LEN_IP_HEADER_B "
+        "in udp_build_packet()."
+      );
+      return;
+    }
+
+    switch (to_do)
+    {
+    case B_NORMAL_PACKET:
+      {
+        /* Build a new desc for IP addresses and port numbers */
+
+        T_desc2 * addr = M_ALLOC (
+          offsetof (T_desc2, buffer) + sizeof (T_SRC_DES)
+        );
+        if (addr == NULL) {
+          TRACE_ERROR ("Not enough memory in udp_build_packet().");
+          return;
+        }
+
+        addr->next = (ULONG) desc;
+        addr->offset = 0;
+        addr->len = sizeof (T_SRC_DES);
+        addr->size = sizeof (T_SRC_DES);
+
+        memcpy (((T_SRC_DES *) addr->buffer)->src_ip, & p_dl->src_addr, 4);
+        memcpy (((T_SRC_DES *) addr->buffer)->des_ip, & p_dl->dst_addr, 4);
+        memcpy (((T_SRC_DES *) addr->buffer)->src_port, & p_dl->src_port, 2);
+        memcpy (((T_SRC_DES *) addr->buffer)->des_port, & p_dl->dst_port, 2);
+
+        desc_list->first = (ULONG) addr;
+        desc_list->list_len = (USHORT) (addr->len + desc_list->list_len);
+
+        /* Filter out the given IP and UDP header */
+        {
+          register unsigned headroom =
+            GET_IP_HEADER_LEN_B (desc->buffer + desc->offset) + LEN_UDP_HEADER_B;
+          if (desc->len < headroom)
+          {
+            TRACE_ERROR ("Lola's IP packet is short in udp_build_packet().");
+            return;
+          }
+          memmove (
+            desc->buffer + desc->offset,
+            desc->buffer + desc->offset + headroom,
+            desc->len - headroom
+          );
+          desc->len = (USHORT) (desc->len - headroom);
+          desc_list->list_len = (USHORT) (desc_list->list_len - headroom);
+        }
+      }
+      break;
+
+    case B_NO_DEST_PORT:
+      {
+        /* We build the whole ICMP packet */
+
+        PPASS (p_dl->dti_data_ind, data_req, DTI2_DATA_REQ);
+
+        desc_list = & data_req->desc_list2;
+        desc = (T_desc2 *) desc_list->first;
+
+        build_icmp_with_payload (
+          data_req,
+          IDENTITY_0,
+          STANDARD_TTL,
+          GET_IP_DEST_ADDR (desc->buffer + desc->offset),
+          ICMP_TYP_DEST_URECHBL,
+          ICMP_CODE_NO_PORT
+        );
+
+        p_ker->dti_data_req_icmp = data_req;
+      }
+      break;
+
+    default:
+      break;
+    }
+  }
+}
+
+/*-------------------------------------------------------------------------*/
+