/* iprohc_ip.h - ROHC IP profile head file */ /* * Copyright (c) 2008 Wind River Systems, Inc. * * The right to copy, distribute or otherwise make use of this software * may be licensed only pursuant to the terms of an applicable Wind River * license agreement. No license to Wind River intellectual property rights * is granted herein. All rights not licensed by Wind River are reserved * by Wind River. */ /* modification history -------------------- 01j,25aug11,ggz Fix WIND00289753. IP ext list assert failure 01l,10jun10,ggz Declare some functions public for use in ESP_IP and UDP_IP profiles 01h,20apr09,tlu Fix Linux build warnings for mips64 gcc (cav_ebt5800) 01g,02jul08,tlu Add to handle IP extension headers 01f,27may08,tlu Add compile condition to include WLSB/LSB 01e,21may08,tlu Add macro to update IP-ID offset from SN 01d,20may08,tlu Add SN WLSB encoding/decoding 01c,07may08,tlu Add debug functions to print a context 01b,29apr08,tlu Change type for payload_offset 01a,12mar08,tlu Created. */ #ifndef IPROHC_IP_H #define IPROHC_IP_H /* **************************************************************************** * INCLUDE FILES **************************************************************************** */ #include #include #include #include "iprohc_config.h" #include "iprohc_constant.h" #ifdef IPROHC_WLSB_LSB #include "iprohc_coding_util.h" #endif /* **************************************************************************** * DEFINES **************************************************************************** */ #define IPROHC_ENABLE_REENTRANT #ifdef __cplusplus extern "C" { #endif /* *=========================================================================== * IPROHC_PROC_EXT *=========================================================================== * Check whether Next Header (IPv6)/Protocol (IPv4) is a to-be-processed * IP extension header. */ #define IPROHC_PROC_EXT(nxt) \ ((nxt == IP_IPPROTO_ROUTING) || \ (nxt == IP_IPPROTO_DSTOPTS) || \ (nxt == IP_IPPROTO_HOPOPTS) || \ (nxt == IP_IPPROTO_MOBILE)) /* *=========================================================================== * IPROHC_IP6_EXT *=========================================================================== * Check whether it is a to-be-processed IPv6 extension header. */ #define IPROHC_IP6_EXT(type) \ ((type == IP_IPPROTO_ROUTING) || \ (type == IP_IPPROTO_DSTOPTS) || \ (type == IP_IPPROTO_HOPOPTS)) /* *=========================================================================== * IPROHC_FREE_REF_LIST *=========================================================================== * Free the compression list which contains the IP extension headers. */ #define IPROHC_FREE_REF_LIST(ip_head) \ { \ Iprohc_ref_list *ext_hdr, *n_ext_hdr; \ \ ip_head->has_exten = IP_FALSE; \ ip_head->ref_num = 0; \ ip_head->ref_len = 0; \ ip_head->gen_id = 0; \ for (ext_hdr = IPCOM_LIST_FIRST(&ip_head->ref_head); \ ext_hdr; \ ext_hdr = n_ext_hdr) \ { \ n_ext_hdr = IPCOM_LIST_NEXT(&ext_hdr->ref_list); \ ipcom_list_remove(&ext_hdr->ref_list); \ \ if (ext_hdr->data) \ ipcom_free(ext_hdr->data); \ \ ipcom_free(ext_hdr); \ } \ } /* *=========================================================================== * IPROHC_COPY_REF_LIST *=========================================================================== * Copy the IP extension headers from the list structure from_ip_head to * the list structure to_ip_head. */ #define IPROHC_COPY_REF_LIST(to_ip_head, from_ip_head) \ { \ Iprohc_ref_list *ext_hdr, *n_ext_hdr; \ \ ipcom_list_init(&to_ip_head->ref_head); \ to_ip_head->has_exten = from_ip_head->has_exten; \ to_ip_head->ref_num = from_ip_head->ref_num; \ to_ip_head->ref_len = from_ip_head->ref_len; \ to_ip_head->gen_id = from_ip_head->gen_id; \ for (ext_hdr = IPCOM_LIST_FIRST(&from_ip_head->ref_head); \ ext_hdr; \ ext_hdr = n_ext_hdr) \ { \ n_ext_hdr = IPCOM_LIST_NEXT(&ext_hdr->ref_list); \ \ ipcom_list_remove(&ext_hdr->ref_list); \ /* Add the ref list structure to to_ref_head */ \ ipcom_list_insert_last(&to_ip_head->ref_head, &ext_hdr->ref_list); \ } \ } /* *=========================================================================== * IPROHC_GET_REF_LIST *=========================================================================== * Parse the packet to get the reference list for to-be-processed IP * extension headers. */ #define IPROHC_GET_REF_LIST(ip_header, ptype, pkt, pointer) \ { \ Iprohc_ref_list *ref_list; \ Ip_u8 index_v = 1; \ \ ip_header->has_exten = IP_TRUE; \ ip_header->ref_len = 0; \ ip_header->ref_num = 0; \ \ do { \ /* Record the reference list */ \ ref_list = (Iprohc_ref_list *)ipcom_malloc(sizeof(Iprohc_ref_list)); \ if (ref_list == IP_NULL) \ { \ IPCOM_LOG0(ERR, "IPROHC_GET_REF_LIST, out of memory(ref_list)"); \ goto errout; \ } \ \ ipcom_memset(ref_list, 0, sizeof(Iprohc_ref_list)); \ \ /* Add the ref list structure to ROHC IP header structure */ \ ipcom_list_insert_last(&ip_header->ref_head, &ref_list->ref_list); \ ip_header->ref_num++; \ \ /* Record the IP extension header */ \ ref_list->type = ptype; \ ref_list->index = index_v; \ index_v++; \ if (IPROHC_IP6_EXT(ptype)) \ /* \ * IPv6 ext header, Hdr-ext-len (second octet of the ext header) \ * is the length of the extension header in 8-octet units, not \ * including the first 8 octets. \ */ \ ref_list->length = (Ip_u8)(8 * (pkt->data[*pointer+1] + 1)); \ else \ { \ /* minimal encapsulation header */ \ if (pkt->data[*pointer+1] & 0x80) \ ref_list->length = 12; \ else \ ref_list->length = 8; \ } \ \ ip_header->ref_len = (Ip_u16)(ip_header->ref_len + ref_list->length); \ ref_list->data = ipcom_malloc(ref_list->length); \ if (ref_list->data == IP_NULL) \ { \ IPCOM_LOG0(ERR, "IPROHC_GET_REF_LIST, out of memory(ref->data)"); \ goto errout; \ } \ \ /* Make a copy of the ext header */ \ ipcom_memcpy(ref_list->data, &(pkt->data[*pointer]), ref_list->length); \ \ /* Get type of next header and move the pointer to next ext header */ \ ptype = pkt->data[*pointer]; \ (*pointer) += ref_list->length; \ } while (IPROHC_PROC_EXT(ptype) && (ip_header->ref_num <= IPROHC_MAX_LIST_ITEMS)); \ } /* *=========================================================================== * IPROHC_UPD_IPID_OFFSET *=========================================================================== * Loop through IP headers and update ip_id offset: ip_id - sn for each * IPv4 header. */ #ifdef IPCOM_USE_INET #define IPROHC_UPD_IPID_OFFSET(ip_context) \ { \ Iprohc_ip_header *ip_header; \ \ /* Calcualte IP-ID offset for each IPv4 header : IP-ID - SN */ \ for (ip_header = IPCOM_LIST_FIRST(&ip_context->ip_head); \ ip_header; \ ip_header = IPCOM_LIST_NEXT(&ip_header->ip_list)) \ { \ if (ip_header->packet_type == ROHC_PKT_IPV4) \ { \ /* An IPv4 packet */ \ ip_header->offset = ip_header->header.ip4.id - \ ip_htons(ip_context->sn); \ } \ } \ } #else #define IPROHC_UPD_IPID_OFFSET(ip_context) IP_NOOP #endif /* #ifdef IPCOM_USE_INET */ /* **************************************************************************** * Public TYPES **************************************************************************** */ /* **************************************************************************** * LOCAL TYPES **************************************************************************** */ /* *=========================================================================== * Iprohc_ip_header *=========================================================================== * The ROHC IP header structure */ typedef struct Iprohc_ip_header_struct { Ipcom_list ip_list; /* an IPv4 or IPv6 packet */ Ip_u8 packet_type; #ifdef IPCOM_USE_INET Ip_bool nbo; /* IP-ID in IPv4 header is in network byte order */ Ip_bool rnd; /* IP-ID in IPv4 header is a pseudo-random number */ Ip_bool sid; /* IP-ID in IPv4 header is a static value */ Ip_s32 offset; /* offset = IP-ID - SN */ #endif /* IPCOM_USE_INET */ /* * Header flags according to the RFC 3095, section 5.7.5. * Only for compressor side. * Format: * --------------------------------------------- * | TOS | TTL | DF | PR | IPX | NBO | RND | X | * --------------------------------------------- * * If X is set, means NBO flag is changed; * RND bit represents pseudo-randomness of IP-ID; * For all other bits, if set, means the corresponding field is changed. */ Ip_u8 header_flags; union ip_header { #ifdef IPCOM_USE_INET /* IPv4 headers */ Ipcom_ip_header ip4; #endif /* IPCOM_USE_INET */ #ifdef IPCOM_USE_INET6 /* IPv6 headers */ Ipcom_ip6_header ip6; #endif /* IPCOM_USE_INET6 */ } header; /* IP extension headers */ Ip_bool has_exten; /* whether has to-be-processed IP extension */ Ip_u8 ref_num; /* number of IP extension headers */ Ip_u16 ref_len; /* total length of IP extension headers */ Ip_u8 gen_id; /* generation ID */ Ipcom_list ref_head; } Iprohc_ip_header; /* *=========================================================================== * Iprohc_c_ip_context *=========================================================================== * The ROHC compression IP profile specific context structure */ typedef struct Iprohc_c_ip_context_struct { /* Seqence number, increments in network order by 1 */ Ip_u16 sn; #ifdef IPROHC_WLSB_LSB /* WLSB for encoding SN */ iprohc_create_cmp_wlsb_struct(sn_wlsb, 16); #endif /* IPROHC_WLSB_LSB */ /* Whether to add list of dynamic chains for additional IP headers */ /* in a non IR/IR-DYN packet */ Ip_bool add_dynamic_chain; /* Payload offset in Ipcom_pkt structure */ int payload_offset; Ip_u8 ip_num; /* number of IP headers */ Ipcom_list ip_head; } Iprohc_c_ip_context; /* *=========================================================================== * Iprohc_d_ip_context *=========================================================================== * The ROHC decompression IP profile specific context structure */ typedef struct Iprohc_d_ip_context_struct { /* Seqence number for the context, increments in network order by 1 */ Ip_u16 sn; #ifdef IPROHC_WLSB_LSB /* LSB for decoding SN */ iprohc_create_dmp_lsb_struct(sn_lsb); #endif /* IPROHC_WLSB_LSB */ /* Payload offset in a received compressed Ipcom_pkt structure */ int payload_offset; Ip_u8 ip_num; /* number of IP headers */ Ipcom_list ip_head; } Iprohc_d_ip_context; /* **************************************************************************** * GLOBAL FUNCTIONS **************************************************************************** */ /* Profile registration/de-registration functions */ IP_PUBLIC Ip_err iprohc_profile_ip_register(void); IP_PUBLIC Ip_err iprohc_ip_deregister(void); /* Profile specific compression functions */ IP_PUBLIC Ip_err iprohc_ip_c_find_context(Iprohc_compressor *comp, Ipcom_pkt *pkt, Iprohc_c_context **c_context); IP_PUBLIC Iprohc_c_context * iprohc_ip_c_create_context(Iprohc_compressor *comp, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_ip_c_del_context(Iprohc_c_context *context); IP_PUBLIC Ip_err iprohc_ip_c_process_feedback(Iprohc_c_context *context, Ip_u8 *feedback, Ip_u8 size); IP_PUBLIC Ip_err iprohc_ip_c_compress(Iprohc_c_context *context, Ipcom_pkt *pkt); IP_PUBLIC void iprohc_ip_c_print_context(Iprohc_c_context *context); /* Profile specific decompression functions */ IP_PUBLIC Iprohc_d_context * iprohc_ip_d_find_context(Iprohc_decompressor *decomp, Ipcom_pkt *pkt); IP_PUBLIC Iprohc_d_context * iprohc_ip_d_create_context(Iprohc_decompressor *decomp, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_ip_d_del_context(Iprohc_d_context *context); IP_PUBLIC void iprohc_ip_d_print_context(Iprohc_d_context *context); IP_PUBLIC Ip_err iprohc_ip_d_decompress(Iprohc_d_context *context, Ipcom_pkt *pkt); /* IP profile routines used in other sprofiles */ IP_PUBLIC Ip_err iprohc_del_ip_context(void *context, Ip_bool is_comp); IP_PUBLIC Ip_err iprohc_d_copy_ip_context(Iprohc_d_ip_context **to_context, Iprohc_d_ip_context *from_context); IP_PUBLIC Ip_err iprohc_c_update_ip_hdrs(Iprohc_c_ip_context *context, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_c_update_ip_context(Iprohc_c_context *context, Ipcom_pkt *pkt); IP_PUBLIC Ip_err iprohc_c_update_ip_ext(Iprohc_ip_header *ip_header, Ip_u8 type, Ipcom_pkt *pkt, int *pointer, Ip_bool *updated); #ifdef __cplusplus } #endif #endif /* #ifndef IPROHC_IP_H */ /* **************************************************************************** * END OF FILE **************************************************************************** */