FreeCalypso > hg > fc-magnetite
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; + } + } +} + +/*-------------------------------------------------------------------------*/ +