450 lines
14 KiB
C
450 lines
14 KiB
C
/* 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 <ipcom_tags.h>
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_list.h>
|
|
|
|
|
|
#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
|
|
****************************************************************************
|
|
*/
|
|
|