Files
m241Neelima/components/ip_net2-6.9/iprohc/include/iprohc_format.h
T
2026-07-30 11:19:44 +05:30

437 lines
14 KiB
C

/* iprohc_format.h - ROHC formatting 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
--------------------
01i,20mar12,ggz Fix WIND00340441
01h,25aug11,ggz Fix WIND00290718
01g,09apr10,ggz Fix 64bit compiler warnings
01f,20apr09,tlu Fix Linux build warnings for mips64 gcc (cav_ebt5800)
01e,26sep08,tlu Initialize buff[4] in IPv4 dynamic format macro to 0
01d,03jul08,tlu Add to handle IP extension headers
01c,21may08,tlu Use encoded SN to format base header
01b,20may08,tlu Add large CID encoding macro
01a,25mar08,tlu Created.
*/
#ifndef IPROHC_FORMAT_H
#define IPROHC_FORMAT_H
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#include <ipcom_type.h>
#include <ipcom_clib.h>
#include <ipcom_inet.h>
#include <ipcom_cstyle.h>
#include "iprohc_constant.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* DEFINES
****************************************************************************
*/
/*
*===========================================================================
* IPROHC_FMT_LIST_ET0
*===========================================================================
* Add the compressed list encoding type 0
*
* 5.8.6.1 Encoding Type 0 (generic scheme)
*
* ---------------------------------
* | ET=0 |GP|PS| CC = m |
* ---------------------------------
* : gen_id : 1 octet, if GP = 1
* ---------------------------------
* | XI 1, ..., XI m | m octets, or m * 4 bits
* / -----------------/
* | : Padding : if PS = 0 and m is odd
* ---------------------------------
* / item1, ..., item n / variable
* ---------------------------------
*
*/
#define IPROHC_FMT_LIST_ET0(iprohc_header, edata) \
{ \
int i; \
Iprohc_ref_list *ext_hdr, *n_ext_hdr; \
Ip_u8 *ebuff = (Ip_u8 *)edata; \
\
ebuff[0] = iprohc_header->ref_num; \
ebuff[1] = iprohc_header->gen_id; \
\
if (iprohc_header->ref_num < 8) \
{ \
ebuff[0] |= 0x20; \
for (i = 1; i <= iprohc_header->ref_num/2; i++) \
{ \
ebuff[i+1] = (Ip_u8)(0x88 | (i<<4)); \
ebuff[i+1] |= (Ip_u8)(i+1); \
} \
if (iprohc_header->ref_num % 2) \
{ \
ebuff[i+1] = (Ip_u8)(0x80 | (i<<4)); \
i++; /* point to next byte to be formatted */ \
} \
} \
else \
{ \
ebuff[0] |= 0x30; \
for (i=1; i <= iprohc_header->ref_num; i++) \
ebuff[i+1] = (Ip_u8)(0x80 | i); \
} \
\
for (ext_hdr = IPCOM_LIST_FIRST(&iprohc_header->ref_head); \
ext_hdr; \
ext_hdr = n_ext_hdr) \
{ \
n_ext_hdr = IPCOM_LIST_NEXT(&ext_hdr->ref_list); \
ipcom_memcpy(&ebuff[i+1], ext_hdr->data, ext_hdr->length); \
i += ext_hdr->length; \
} \
}
/*
*===========================================================================
* IPROHC_FMT_IPV4_STATIC
*===========================================================================
* Add an IPv4 static part to Static chain in a IR packet
*
* 5.7.7.4 IPv4 header static part format
*
* ---------------------------------
* | version = 4 | 0 |
* ---------------------------------
* | Protocol |
* ---------------------------------
* / Source Address / 4 octets
* ---------------------------------
* / Destination Address / 4 octets
* ---------------------------------
*
*/
#ifdef IPCOM_USE_INET
#define IPROHC_FMT_IPV4_STATIC(iprohc_header, data) \
{ \
Ipcom_ip_header *ip4_header = &(iprohc_header->header.ip4); \
Ip_u8 *buff = (Ip_u8 *)data; \
\
buff[0] = 0x40; \
buff[1] = ip4_header->protocol; \
ipcom_memcpy(&buff[2], &ip4_header->src, 4); \
ipcom_memcpy(&buff[6], &ip4_header->dst, 4); \
}
#else
#define IPROHC_FMT_IPV4_STATIC(iprohc_header, data) IP_NOOP
#endif
/*
*===========================================================================
* IPROHC_FMT_IPV6_STATIC
*===========================================================================
* Add an IPv6 static part to Static chain in a IR packet
*
* 5.7.7.3 IPv6 header static part format
*
* ---------------------------------
* | version = 6 |Flow Label (msb) | 1 octet
* ---------------------------------
* | Flow Label (lsb) | 2 octets
* ---------------------------------
* | Next Header | 1 octet
* ---------------------------------
* / Source Address / 16 octets
* ---------------------------------
* / Destination Address / 16 octets
* ---------------------------------
*
*/
#ifdef IPCOM_USE_INET6
#define IPROHC_FMT_IPV6_STATIC(iprohc_header, data) \
{ \
Ipcom_ip6_header *ip6_header = &(iprohc_header->header.ip6); \
Ip_u32 flow; \
Ip_u16 flow_lsb; \
Ip_u8 *buff = (Ip_u8 *)data; \
\
buff[0] = 0x60; \
flow = IP_GET_NTOHL(&ip6_header->ver_class_flow) & 0xfffff; \
flow_lsb = (Ip_u16)(flow & 0xffff); \
buff[0] = (Ip_u8)(buff[0] | ((flow >> 16) & 0x0f)); \
flow_lsb = ip_htons(flow_lsb); \
ipcom_memcpy(&buff[1], &flow_lsb, 2); \
buff[3] = ip6_header->nxt; \
ipcom_memcpy(&buff[4], &ip6_header->src, 16); \
ipcom_memcpy(&buff[20], &ip6_header->dst, 16); \
}
#else
#define IPROHC_FMT_IPV6_STATIC(iprohc_header, data) IP_NOOP
#endif
/*
*===========================================================================
* IPROHC_FMT_IPV4_DYNAMIC
*===========================================================================
* Add an IPv4 dynamic part to Dynamic chain in a IR/IR-DYN packet
*
* 5.7.7.4 IPv4 header dynamic part format
*
* ---------------------------------
* | Type of Service |
* ---------------------------------
* | Time to Live |
* ---------------------------------
* / Identification / 2 octets
* ---------------------------------
* | DF|RND|NBO|SID| 0 |
* ---------------------------------
* / Generic extension Header list / (not supported)
* ---------------------------------
*
*/
#ifdef IPCOM_USE_INET
#define IPROHC_FMT_IPV4_DYNAMIC(iprohc_header, data) \
{ \
Ipcom_ip_header *ip4_header = &(iprohc_header->header.ip4); \
Ip_u8 *buff = (Ip_u8 *)data; \
\
buff[0] = ip4_header->tos; \
buff[1] = ip4_header->ttl; \
ipcom_memcpy(&buff[2], &(ip4_header->id), 2); \
buff[4] = 0x00; \
if (ip4_header->frag & IPCOM_IPFRAG_DF) buff[4] = 0x80; \
if (iprohc_header->rnd) buff[4] |= 0x40; \
if (iprohc_header->nbo) buff[4] |= 0x20; \
if (iprohc_header->sid) buff[4] |= 0x10; \
if (iprohc_header->has_exten) \
IPROHC_FMT_LIST_ET0(iprohc_header, &buff[5]); \
}
#else
#define IPROHC_FMT_IPV4_DYNAMIC(iprohc_header, data) IP_NOOP
#endif
/*
*===========================================================================
* IPROHC_FMT_IPV6_DYNAMIC
*===========================================================================
* Add an IPv6 dynamic part to Dynamic chain in a IR/IR-DYN packet
*
* 5.7.7.3 IPv6 header dynamic part format
*
* ---------------------------------
* | Traffic Class | 1 octet
* ---------------------------------
* | Hop Limit | 1 octet
* ---------------------------------
* / Generic extension Header list / (not supported)
* ---------------------------------
*
*/
#ifdef IPCOM_USE_INET6
#define IPROHC_FMT_IPV6_DYNAMIC(iprohc_header, data) \
{ \
Ipcom_ip6_header *ip6_header; \
Ip_u8 *buff = (Ip_u8 *)data; \
\
ip6_header = (Ipcom_ip6_header *)&(iprohc_header->header.ip6); \
buff[0] = (Ip_u8)((IP_GET_NTOHL(&ip6_header->ver_class_flow)>>20)&0xff); \
buff[1] = ip6_header->hlim; \
if (iprohc_header->has_exten) \
IPROHC_FMT_LIST_ET0(iprohc_header, &buff[2]); \
}
#else
#define IPROHC_FMT_IPV6_DYNAMIC(iprohc_header, data) IP_NOOP
#endif
/*
*===========================================================================
* IPROHC_FMT_IP_STATIC
*===========================================================================
* Fomat Static chain in a IR packet
*/
#define IPROHC_FMT_IP_STATIC(ip_context, pointer, pkt) \
{ \
Iprohc_ip_header *ip_header, *p_ip_header; \
\
for (ip_header = IPCOM_LIST_LAST(&ip_context->ip_head); ip_header; \
ip_header = p_ip_header) \
{ \
p_ip_header = IPCOM_LIST_PREV(&ip_header->ip_list); \
\
if (ip_header->packet_type == ROHC_PKT_IPV4) \
{ \
/* Move pointer back for one IPv4 static part */ \
pointer -= 10; \
\
/* Add an IPv4 static part to Static chain */ \
IPROHC_FMT_IPV4_STATIC(ip_header, &pkt->data[pointer]); \
} \
else \
{ \
/* Move pointer back for one IPv6 static part */ \
pointer -= 36; \
\
/* Add an IPv6 static part to static chain */ \
IPROHC_FMT_IPV6_STATIC(ip_header, &pkt->data[pointer]); \
} \
} \
}
/*
*===========================================================================
* IPROHC_FMT_IP_DYNAMIC
*===========================================================================
* Fomat Dynamic chain in a IR/IR-DYN packet
*/
#define IPROHC_FMT_IP_DYNAMC(ip_context, pointer, pkt, has_dynamic, num_h) \
{ \
Iprohc_ip_header *ip_header, *p_ip_header; \
Ip_u8 et0_len; \
\
for (ip_header = IPCOM_LIST_LAST(&ip_context->ip_head); \
(ip_header && num_h); \
ip_header = p_ip_header, num_h--) \
{ \
p_ip_header = IPCOM_LIST_PREV(&ip_header->ip_list); \
has_dynamic = IP_TRUE; \
et0_len = 0; \
\
/* Calculate compressed list ET0 header length */ \
if (ip_header->ref_num != 0) \
{ \
if (ip_header->ref_num < 8) \
et0_len = (Ip_u8)(2 + (ip_header->ref_num/2) + (ip_header->ref_num%2)); \
else \
et0_len = (Ip_u8)(2 + ip_header->ref_num); \
} \
\
if (ip_header->packet_type == ROHC_PKT_IPV4) \
{ \
/* Move pointer back for one IPv4 dynamic part */ \
/* and IP extension length */ \
pointer -= (5 + ip_header->ref_len + et0_len); \
\
/* Add an IPv4 dynamic part to Dynamic chain */ \
IPROHC_FMT_IPV4_DYNAMIC(ip_header, &pkt->data[pointer]); \
} \
else \
{ \
/* Move pointer back for one IPv6 dynamic part */ \
pointer -= (2 + ip_header->ref_len + et0_len); \
\
/* Add an IPv6 dynamic part to Dynamic chain */ \
IPROHC_FMT_IPV6_DYNAMIC(ip_header, &pkt->data[pointer]); \
} \
} \
}
/*
*===========================================================================
* IPROHC_ENCODE_LARGE_CID
*===========================================================================
* Encode large CID according to RFC 3095, section 4.5.6.
* RFC 3095, section 5.2.2: If the first bit is 0, the CID uses
* one octet. If the first bit is 1, the CID uses two octets.
*/
#define IPROHC_ENCODE_LARGE_CID(data, pointer, cid, cid_size) \
{ \
if (cid < 128) \
{ \
/* 0 < cid < 128 (0x80) */ \
data[pointer] = (Ip_u8)cid; \
cid_size = 1; \
} \
else \
{ \
/* 127 (0x7F) < cid < 16384 (0x4000): set the first bit to 1 */ \
cid |= 0x8000; \
cid = ip_htons(cid); \
ipcom_memcpy(&(data[pointer]), &cid, 2); \
cid_size = 2; \
} \
}
/*
****************************************************************************
* Public TYPES
****************************************************************************
*/
/*
****************************************************************************
* LOCAL TYPES
****************************************************************************
*/
/*
****************************************************************************
* GLOBAL FUNCTIONS
****************************************************************************
*/
IP_PUBLIC Ip_err iprohc_fmt_extension(Ipcom_pkt *pkt, int *pointer,
Iprohc_extension ext_type,
void *ip_header1, void *ip_header2,
Ip_u16 sn, Iprohc_mode mode,
Ip_u8 flags1, Ip_u8 flags2);
IP_PUBLIC Ip_u8 iprohc_fmt_base_header(Ip_u8 *base_header,
Iprohc_c_context *context, void *header1,
Ip_u8 sn, Ip_u8 crc);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef IPROHC_FORMAT_H */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/