ROHC compression/decompression library
|
00001 /* 00002 * Copyright 2010,2011,2012,2013,2014 Didier Barvaux 00003 * Copyright 2007,2008 Thales Alenia Space 00004 * Copyright 2007,2008,2009,2010,2012,2013 Viveris Technologies 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /** 00022 * @file d_generic.h 00023 * @brief ROHC generic decompression context for IP-only, UDP and UDP Lite 00024 * profiles. 00025 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00026 * @author Didier Barvaux <didier@barvaux.org> 00027 * @author David Moreau from TAS 00028 */ 00029 00030 #ifndef ROHC_DECOMP_GENERIC_H 00031 #define ROHC_DECOMP_GENERIC_H 00032 00033 #include "rohc_decomp.h" 00034 #include "rohc_decomp_internals.h" 00035 #include "rohc_packets.h" 00036 #include "comp_list.h" 00037 #include "schemes/wlsb.h" 00038 #include "schemes/ip_id_offset.h" 00039 #include "schemes/list.h" 00040 #include "ip.h" 00041 #include "crc.h" 00042 00043 #include <stddef.h> 00044 #ifdef __KERNEL__ 00045 # include <linux/types.h> 00046 #else 00047 # include <stdbool.h> 00048 #endif 00049 00050 00051 /** The outer or inner IP bits extracted from ROHC headers */ 00052 struct rohc_extr_ip_bits 00053 { 00054 uint8_t version:4; /**< The version bits found in static chain of IR 00055 header */ 00056 00057 uint8_t tos; /**< The TOS/TC bits found in dynamic chain of IR/IR-DYN 00058 header or in extension header */ 00059 size_t tos_nr; /**< The number of TOS/TC bits found */ 00060 00061 uint16_t id; /**< The IP-ID bits found in dynamic chain of IR/IR-DYN 00062 header, in UO* base header, in extension header and 00063 in remainder of UO* header */ 00064 size_t id_nr; /**< The number of IP-ID bits found */ 00065 bool is_id_enc; /**< Whether value(IP-ID) is encoded or not */ 00066 00067 uint8_t df:1; /**< The DF bits found in dynamic chain of IR/IR-DYN 00068 header or in extension header */ 00069 size_t df_nr; /**< The number of DF bits found */ 00070 00071 uint8_t ttl; /**< The TTL/HL bits found in dynamic chain of IR/IR-DYN 00072 header or in extension header */ 00073 size_t ttl_nr; /**< The number of TTL/HL bits found */ 00074 00075 uint8_t proto; /**< The protocol/next header bits found static chain 00076 of IR header or in extension header */ 00077 size_t proto_nr; /**< The number of protocol/next header bits */ 00078 00079 uint8_t nbo:1; /**< The NBO bits found in dynamic chain of IR/IR-DYN 00080 header or in extension header */ 00081 size_t nbo_nr; /**< The number of NBO bits found */ 00082 00083 uint8_t rnd:1; /**< The RND bits found in dynamic chain of IR/IR-DYN 00084 header or in extension header */ 00085 size_t rnd_nr; /**< The number of RND bits found */ 00086 00087 uint8_t sid:1; /**< The SID bits found in dynamic chain of IR/IR-DYN 00088 header or in extension header */ 00089 size_t sid_nr; /**< The number of SID bits found */ 00090 00091 uint32_t flowid:20; /**< The IPv6 flow ID bits found in static chain of 00092 IR header */ 00093 size_t flowid_nr; /**< The number of flow label bits */ 00094 00095 uint8_t saddr[16]; /**< The source address bits found in static chain of 00096 IR header */ 00097 size_t saddr_nr; /**< The number of source address bits */ 00098 00099 uint8_t daddr[16]; /**< The destination address bits found in static 00100 chain of IR header */ 00101 size_t daddr_nr; /**< The number of source address bits */ 00102 }; 00103 00104 00105 /** 00106 * @brief The bits extracted from ROHC UO* base headers 00107 * 00108 * @see parse_uo0 00109 * @see parse_uo1 00110 * @see parse_uor2 00111 */ 00112 struct rohc_extr_bits 00113 { 00114 bool is_context_reused; /**< Whether the context is re-used or not */ 00115 00116 /* SN */ 00117 uint32_t sn; /**< The SN bits found in ROHC header */ 00118 size_t sn_nr; /**< The number of SN bits found in ROHC header */ 00119 bool is_sn_enc; /**< Whether value(SN) is encoded with W-LSB or not */ 00120 rohc_lsb_ref_t sn_ref_type; /**< The SN reference to use for LSB decoding 00121 (used for context repair after CRC failure) */ 00122 bool sn_ref_offset; /**< Optional offset to add to the reference SN 00123 (used for context repair after CRC failure) */ 00124 00125 /** bits related to outer IP header */ 00126 struct rohc_extr_ip_bits outer_ip; 00127 00128 /** bits related to inner IP header */ 00129 struct rohc_extr_ip_bits inner_ip; 00130 00131 /* CRC */ 00132 rohc_crc_type_t crc_type; /**< The type of CRC that protect the ROHC header */ 00133 uint8_t crc; /**< The CRC bits found in ROHC header */ 00134 size_t crc_nr; /**< The number of CRC bits found in ROHC header */ 00135 00136 /* X (extension) flag */ 00137 uint8_t ext_flag:1; /**< X (extension) flag */ 00138 00139 /* Mode bits */ 00140 uint8_t mode:2; /**< The Mode bits found in ROHC header */ 00141 size_t mode_nr; /**< The number of Mode bits found in ROHC header */ 00142 00143 00144 /* bits below are for UDP-based profiles only 00145 @todo TODO should be moved in d_udp.c */ 00146 00147 uint16_t udp_src; /**< The UDP source port bits found in static chain 00148 of IR header */ 00149 size_t udp_src_nr; /**< The number of UDP source port bits */ 00150 00151 uint16_t udp_dst; /**< The UDP destination port bits in static chain 00152 of IR header */ 00153 size_t udp_dst_nr; /**< The number of UDP destination port bits */ 00154 00155 uint16_t udp_check; /**< The UDP checksum bits found in dynamic chain 00156 of IR/IR-DYN header or in remainder of UO* 00157 header */ 00158 size_t udp_check_nr; /**< The number of UDP checksum bits */ 00159 00160 00161 /* bits below are for UDP-Lite-based profiles only 00162 @todo TODO should be moved in d_udp_lite.c */ 00163 00164 uint16_t udp_lite_cc; /**< The UDP-Lite CC bits found in dynamic 00165 chain of IR/IR-DYN header or in remainder 00166 of UO* header */ 00167 size_t udp_lite_cc_nr; /**< The number of UDP-Lite CC bits */ 00168 00169 00170 /* bits below are for RTP profile only 00171 @todo TODO should be moved in d_rtp.c */ 00172 00173 /* RTP version */ 00174 uint8_t rtp_version:2; /**< The RTP version bits found in dynamic chain 00175 of IR/IR-DYN header */ 00176 size_t rtp_version_nr; /**< The number of RTP version bits */ 00177 00178 /* RTP Padding (R-P) flag */ 00179 uint8_t rtp_p:1; /**< The RTP Padding bits found in dynamic chain 00180 of IR/IR-DYN header or in extension header */ 00181 size_t rtp_p_nr; /**< The number of RTP Padding bits */ 00182 00183 /* RTP eXtension (R-X) flag */ 00184 uint8_t rtp_x:1; /**< The RTP eXtension (R-X) bits found in 00185 extension header */ 00186 size_t rtp_x_nr; /**< The number of RTP X bits */ 00187 00188 /* RTP CSRC Count (CC) */ 00189 uint8_t rtp_cc:4; /**< The RTP CSRC Count bits found in dynamic 00190 chain of IR/IR-DYN header */ 00191 size_t rtp_cc_nr; /**< The number of the RTP CSRC Count bits */ 00192 00193 /* RTP Marker (M) flag */ 00194 uint8_t rtp_m:1; /**< The RTP Marker (M) bits found in dynamic chain 00195 of IR/IR-DYN header, UO* base header and 00196 extension header */ 00197 size_t rtp_m_nr; /**< The number of the RTP Marker (M) bits */ 00198 00199 /* RTP Payload Type (RTP-PT) */ 00200 uint8_t rtp_pt:7; /**< The RTP Payload Type (PT) bits found in 00201 dynamic chain of IR/IR-DYN header or in 00202 extension header */ 00203 size_t rtp_pt_nr; /**< The number of RTP PT bits found in header */ 00204 00205 /* RTP TimeStamp (TS) */ 00206 uint32_t ts; /**< The TS bits found in dynamic chain of 00207 IR/IR-DYN header, in UO* base header or in 00208 extension header */ 00209 size_t ts_nr; /**< The number of TS bits found in ROHC header */ 00210 bool is_ts_scaled; /**< Whether TS is transmitted scaled or not */ 00211 00212 /* RTP Synchronization SouRCe (SSRC) identifier */ 00213 uint32_t rtp_ssrc; /**< The SSRC bits found in static chain of 00214 IR header */ 00215 size_t rtp_ssrc_nr; /**< The number of SSRC bits found in header */ 00216 00217 00218 /* bits below are for ESP profile only 00219 @todo TODO should be moved in d_esp.c */ 00220 00221 /* ESP Security Parameters Index (SPI) */ 00222 uint32_t esp_spi; /**< The SPI bits found in static chain of 00223 IR header */ 00224 size_t esp_spi_nr; /**< The number of SPI bits found in header */ 00225 }; 00226 00227 00228 /** The outer or inner IP values decoded from the extracted ROHC bits */ 00229 struct rohc_decoded_ip_values 00230 { 00231 uint8_t version:4; /**< The decoded version field */ 00232 uint8_t tos; /**< The decoded TOS/TC field */ 00233 uint16_t id; /**< The decoded IP-ID field (IPv4 only) */ 00234 uint8_t df:1; /**< The decoded DF field (IPv4 only) */ 00235 uint8_t ttl; /**< The decoded TTL/HL field */ 00236 uint8_t proto; /**< The decoded protocol/NH field */ 00237 uint8_t nbo:1; /**< The decoded NBO field (IPv4 only) */ 00238 uint8_t rnd:1; /**< The decoded RND field (IPv4 only) */ 00239 uint8_t sid:1; /**< The decoded SID field (IPv4 only) */ 00240 uint32_t flowid:20; /**< The decoded flow ID field (IPv6 only) */ 00241 uint8_t saddr[16]; /**< The decoded source address field */ 00242 uint8_t daddr[16]; /**< The decoded destination address field */ 00243 }; 00244 00245 00246 /** 00247 * @brief The values decoded from the bits extracted from ROHC header 00248 * 00249 * @see decode_uo0 00250 * @see decode_uo1 00251 * @see decode_uor2 00252 * @see decode_values_from_bits 00253 * @see rtp_decode_values_from_bits 00254 */ 00255 struct rohc_decoded_values 00256 { 00257 uint32_t sn; /**< The decoded SN value */ 00258 00259 /** The decoded values for the outer IP header */ 00260 struct rohc_decoded_ip_values outer_ip; 00261 /** The decoded values for the inner IP header */ 00262 struct rohc_decoded_ip_values inner_ip; 00263 00264 /* bits below are for UDP-based profile only 00265 @todo TODO should be moved in d_udp.c */ 00266 uint16_t udp_src; /**< The decoded UDP source port */ 00267 uint16_t udp_dst; /**< The decoded UDP destination port bits */ 00268 uint16_t udp_check; /**< The decoded UDP checksum */ 00269 00270 /* bits below are for UDP-Lite-based profile only 00271 @todo TODO should be moved in d_udp_lite.c */ 00272 uint16_t udp_lite_cc; /**< The decoded UDP-Lite CC */ 00273 00274 /* bits below are for RTP profile only 00275 @todo TODO should be moved in d_rtp.c */ 00276 uint8_t rtp_version:2; /**< The decoded RTP version */ 00277 uint8_t rtp_p:1; /**< The decoded RTP Padding (R-P) flag */ 00278 uint8_t rtp_x:1; /**< The decoded RTP eXtension (R-X) flag */ 00279 uint8_t rtp_cc:4; /**< The decoded RTP CSRC Count */ 00280 uint8_t rtp_m:1; /**< The decoded RTP Marker (M) flag */ 00281 uint8_t rtp_pt:7; /**< The decoded RTP Payload Type (RTP-PT) */ 00282 uint32_t ts; /**< The decoded RTP TimeStamp (TS) value */ 00283 uint32_t rtp_ssrc; /**< The decoded SSRC value */ 00284 00285 /* bits below are for ESP profile only 00286 @todo TODO should be moved in d_esp.c */ 00287 uint32_t esp_spi; /**< The decoded ESP SPI */ 00288 }; 00289 00290 00291 /** 00292 * @brief Store information about an IP header between the different 00293 * decompressions of IP packets. 00294 * 00295 * Defines an object that contains flags and structures related to an IP header 00296 * and that need to be saved between the different decompressions of packets. A 00297 * decompression context owns objects like this for the two first IP headers. 00298 */ 00299 struct d_generic_changes 00300 { 00301 /// The IP header 00302 struct ip_packet ip; 00303 00304 /// Whether the IP-ID is considered as random or not (IPv4 only) 00305 int rnd; 00306 /// Whether the IP-ID is considered as coded in NBO or not (IPv4 only) 00307 int nbo; 00308 /// Whether the IP-ID is considered as static or not (IPv4 only) 00309 int sid; 00310 00311 /// The next header located after the IP header(s) 00312 void *next_header; 00313 /// The length of the next header 00314 unsigned int next_header_len; 00315 }; 00316 00317 00318 /** 00319 * @brief The different correction algorithms available in case of CRC failure 00320 */ 00321 typedef enum 00322 { 00323 ROHC_DECOMP_CRC_CORR_SN_NONE = 0, /**< No correction */ 00324 ROHC_DECOMP_CRC_CORR_SN_WRAP = 1, /**< Correction of SN wraparound */ 00325 ROHC_DECOMP_CRC_CORR_SN_UPDATES = 2, /**< Correction of incorrect SN updates */ 00326 00327 } rohc_decomp_crc_corr_t; 00328 00329 00330 /** 00331 * @brief The generic decompression context 00332 * 00333 * The object defines the generic context that manages IP(/nextheader) and 00334 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00335 * part of the context. 00336 */ 00337 struct d_generic_context 00338 { 00339 /// Information about the outer IP header 00340 struct d_generic_changes *outer_ip_changes; 00341 /// Information about the inner IP header 00342 struct d_generic_changes *inner_ip_changes; 00343 00344 /// The LSB decoding context for the Sequence Number (SN) 00345 struct rohc_lsb_decode *sn_lsb_ctxt; 00346 /// The IP-ID of the outer IP header 00347 struct ip_id_offset_decode *outer_ip_id_offset_ctxt; 00348 /// The IP-ID of the inner IP header 00349 struct ip_id_offset_decode *inner_ip_id_offset_ctxt; 00350 00351 /// The list decompressor of the outer IP header 00352 struct list_decomp list_decomp1; 00353 /// The list decompressor of the inner IP header 00354 struct list_decomp list_decomp2; 00355 00356 /// Whether the decompressed packet contains a 2nd IP header 00357 int multiple_ip; 00358 00359 /* below are some information and handlers to manage the next header 00360 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00361 00362 /// The IP protocol ID of the protocol the context is able to decompress 00363 unsigned short next_header_proto; 00364 00365 /// The length of the next header 00366 unsigned int next_header_len; 00367 00368 /// @brief The handler used to parse the static part of the next header 00369 /// in the ROHC packet 00370 int (*parse_static_next_hdr)(const struct rohc_decomp_ctxt *const context, 00371 const unsigned char *packet, 00372 size_t length, 00373 struct rohc_extr_bits *const bits); 00374 00375 /// @brief The handler used to parse the dynamic part of the next header 00376 /// in the ROHC packet 00377 int (*parse_dyn_next_hdr)(const struct rohc_decomp_ctxt *const context, 00378 const uint8_t *packet, 00379 const size_t length, 00380 struct rohc_extr_bits *const bits); 00381 00382 /** 00383 * @brief The handler used to parse the extension 3 of the UO* ROHC packet 00384 * 00385 * @param context The decompression context 00386 * @param rohc_data The ROHC data to parse 00387 * @param rohc_data_len The length of the ROHC data to parse 00388 * @param packet_type The type of ROHC packet to parse 00389 * @param bits IN: the bits already found in base header 00390 * OUT: the bits found in the extension header 3 00391 * @return The data length read from the ROHC packet, 00392 * -2 in case packet must be reparsed, 00393 * -1 in case of error 00394 */ 00395 int (*parse_ext3)(const struct rohc_decomp_ctxt *const context, 00396 const unsigned char *const rohc_data, 00397 const size_t rohc_data_len, 00398 const rohc_packet_t packet_type, 00399 struct rohc_extr_bits *const bits) 00400 __attribute__((warn_unused_result, nonnull(1, 2, 5))); 00401 00402 /// The handler used to parse the tail of the UO* ROHC packet 00403 int (*parse_uo_remainder)(const struct rohc_decomp_ctxt *const context, 00404 const unsigned char *packet, 00405 unsigned int length, 00406 struct rohc_extr_bits *const bits); 00407 00408 /** The handler used to decode extracted for next header */ 00409 bool (*decode_values_from_bits)(const struct rohc_decomp_ctxt *context, 00410 const struct rohc_extr_bits bits, 00411 struct rohc_decoded_values *const decoded); 00412 00413 /** The handler used to build the uncompressed next header */ 00414 int (*build_next_header)(const struct rohc_decomp_ctxt *const context, 00415 const struct rohc_decoded_values decoded, 00416 unsigned char *dest, 00417 const unsigned int payload_len); 00418 00419 /// @brief The handler used to compute the CRC-STATIC value 00420 uint8_t (*compute_crc_static)(const uint8_t *const ip, 00421 const uint8_t *const ip2, 00422 const uint8_t *const next_header, 00423 const rohc_crc_type_t crc_type, 00424 const uint8_t init_val, 00425 const uint8_t *const crc_table); 00426 00427 /// @brief The handler used to compute the CRC-DYNAMIC value 00428 uint8_t (*compute_crc_dynamic)(const uint8_t *const ip, 00429 const uint8_t *const ip2, 00430 const uint8_t *const next_header, 00431 const rohc_crc_type_t crc_type, 00432 const uint8_t init_val, 00433 const uint8_t *const crc_table); 00434 00435 /** The handler used to update context with decoded next header fields */ 00436 void (*update_context)(const struct rohc_decomp_ctxt *context, 00437 const struct rohc_decoded_values decoded); 00438 00439 /// Profile-specific data 00440 void *specific; 00441 00442 00443 /* 00444 * for correction upon CRC failure 00445 */ 00446 00447 /** The algorithm being used for correction CRC failure */ 00448 rohc_decomp_crc_corr_t crc_corr; 00449 /** Correction counter (see e and f in 5.3.2.2.4 of the RFC 3095) */ 00450 size_t correction_counter; 00451 /** The number of last packets to record arrival times for */ 00452 #define ROHC_MAX_ARRIVAL_TIMES 10U 00453 /** The arrival times for the last packets */ 00454 struct rohc_ts arrival_times[ROHC_MAX_ARRIVAL_TIMES]; 00455 /** The number of arrival times in arrival_times */ 00456 size_t arrival_times_nr; 00457 /** The index for the arrival time of the next packet */ 00458 size_t arrival_times_index; 00459 /** The arrival time of the current packet */ 00460 struct rohc_ts cur_arrival_time; 00461 }; 00462 00463 00464 /* 00465 * Public function prototypes. 00466 */ 00467 00468 void * d_generic_create(const struct rohc_decomp_ctxt *const context, 00469 #if !defined(ROHC_ENABLE_DEPRECATED_API) || ROHC_ENABLE_DEPRECATED_API == 1 00470 rohc_trace_callback_t trace_cb, 00471 #endif 00472 rohc_trace_callback2_t trace_cb2, 00473 void *const trace_cb_priv, 00474 const int profile_id) 00475 __attribute__((nonnull(1), warn_unused_result)); 00476 00477 void d_generic_destroy(void *const context) 00478 __attribute__((nonnull(1))); 00479 00480 rohc_status_t d_generic_decode(struct rohc_decomp *const decomp, 00481 struct rohc_decomp_ctxt *const context, 00482 const struct rohc_buf rohc_packet, 00483 const size_t add_cid_len, 00484 const size_t large_cid_len, 00485 struct rohc_buf *const uncomp_packet, 00486 rohc_packet_t *const packet_type) 00487 __attribute__((warn_unused_result, nonnull(1, 2, 6, 7))); 00488 00489 uint32_t d_generic_get_sn(const struct rohc_decomp_ctxt *const context); 00490 00491 00492 00493 /* 00494 * Helper functions 00495 */ 00496 00497 00498 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits bits) 00499 __attribute__((warn_unused_result, const)); 00500 00501 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits bits) 00502 __attribute__((warn_unused_result, const)); 00503 00504 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits bits) 00505 __attribute__((warn_unused_result, const)); 00506 00507 00508 /** 00509 * @brief Is the given IP header IPV4 wrt packet? 00510 * 00511 * @param bits The bits extracted from packet 00512 * @return true if IPv4, false if IPv6 00513 */ 00514 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits bits) 00515 { 00516 return (bits.version == IPV4); 00517 } 00518 00519 00520 /** 00521 * @brief Is the given IP header IPv4 and its IP-ID random wrt packet? 00522 * 00523 * @param bits The bits extracted from packet 00524 * @return true if IPv4 and random, false otherwise 00525 */ 00526 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits bits) 00527 { 00528 return (is_ipv4_pkt(bits) && bits.rnd == 1); 00529 } 00530 00531 00532 /** 00533 * @brief Is the given IP header IPv4 and its IP-ID non-random wrt packet? 00534 * 00535 * @param bits The bits extracted from packet 00536 * @return true if IPv4 and non-random, false otherwise 00537 */ 00538 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits bits) 00539 { 00540 return (is_ipv4_pkt(bits) && bits.rnd == 0); 00541 } 00542 00543 00544 #endif 00545