ROHC compression/decompression library
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * This program is distributed in the hope that it will be useful, 00008 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 * GNU General Public License for more details. 00011 * 00012 * You should have received a copy of the GNU General Public License 00013 * along with this program; if not, write to the Free Software 00014 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00015 */ 00016 00017 /** 00018 * @file d_generic.h 00019 * @brief ROHC generic decompression context for IP-only, UDP and UDP Lite 00020 * profiles. 00021 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00022 * @author Didier Barvaux <didier@barvaux.org> 00023 * @author The hackers from ROHC for Linux 00024 * @author David Moreau from TAS 00025 */ 00026 00027 #ifndef D_GENERIC_H 00028 #define D_GENERIC_H 00029 00030 #include "rohc_decomp.h" 00031 #include "rohc_decomp_internals.h" 00032 #include "rohc_packets.h" 00033 #include "comp_list.h" 00034 #include "lsb_decode.h" 00035 #include "ip_id_offset_decode.h" 00036 #include "ip.h" 00037 #include "crc.h" 00038 00039 #include <stddef.h> 00040 #ifdef __KERNEL__ 00041 # include <linux/types.h> 00042 #else 00043 # include <stdbool.h> 00044 #endif 00045 00046 00047 #define MAX_ITEM 15 00048 #if MAX_ITEM <= 7 00049 #error "translation table must be larger enough for indexes stored on 3 bits" 00050 #endif 00051 00052 #define LIST_COMP_WINDOW 100 00053 00054 #define L 5 00055 00056 00057 /** The outer or inner IP bits extracted from ROHC headers */ 00058 struct rohc_extr_ip_bits 00059 { 00060 uint8_t version:4; /**< The version bits found in static chain of IR 00061 header */ 00062 00063 uint8_t tos; /**< The TOS/TC bits found in dynamic chain of IR/IR-DYN 00064 header or in extension header */ 00065 size_t tos_nr; /**< The number of TOS/TC bits found */ 00066 00067 uint16_t id; /**< The IP-ID bits found in dynamic chain of IR/IR-DYN 00068 header, in UO* base header, in extension header and 00069 in remainder of UO* header */ 00070 size_t id_nr; /**< The number of IP-ID bits found */ 00071 00072 uint8_t df:1; /**< The DF bits found in dynamic chain of IR/IR-DYN 00073 header or in extension header */ 00074 size_t df_nr; /**< The number of DF bits found */ 00075 00076 uint8_t ttl; /**< The TTL/HL bits found in dynamic chain of IR/IR-DYN 00077 header or in extension header */ 00078 size_t ttl_nr; /**< The number of TTL/HL bits found */ 00079 00080 uint8_t proto; /**< The protocol/next header bits found static chain 00081 of IR header or in extension header */ 00082 size_t proto_nr; /**< The number of protocol/next header bits */ 00083 00084 uint8_t nbo:1; /**< The NBO bits found in dynamic chain of IR/IR-DYN 00085 header or in extension header */ 00086 size_t nbo_nr; /**< The number of NBO bits found */ 00087 00088 uint8_t rnd:1; /**< The RND bits found in dynamic chain of IR/IR-DYN 00089 header or in extension header */ 00090 size_t rnd_nr; /**< The number of RND bits found */ 00091 00092 uint8_t sid:1; /**< The SID bits found in dynamic chain of IR/IR-DYN 00093 header or in extension header */ 00094 size_t sid_nr; /**< The number of SID bits found */ 00095 00096 uint32_t flowid:20; /**< The IPv6 flow ID bits found in static chain of 00097 IR header */ 00098 size_t flowid_nr; /**< The number of flow label bits */ 00099 00100 uint8_t saddr[16]; /**< The source address bits found in static chain of 00101 IR header */ 00102 size_t saddr_nr; /**< The number of source address bits */ 00103 00104 uint8_t daddr[16]; /**< The destination address bits found in static 00105 chain of IR header */ 00106 size_t daddr_nr; /**< The number of source address bits */ 00107 }; 00108 00109 00110 /** 00111 * @brief The bits extracted from ROHC UO* base headers 00112 * 00113 * @see parse_uo0 00114 * @see parse_uo1 00115 * @see parse_uor2 00116 */ 00117 struct rohc_extr_bits 00118 { 00119 bool is_context_reused; /**< Whether the context is re-used or not */ 00120 00121 /* SN */ 00122 uint32_t sn; /**< The SN bits found in ROHC header */ 00123 size_t sn_nr; /**< The number of SN bits found in ROHC header */ 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 uint8_t crc; /**< The CRC bits found in ROHC header */ 00133 size_t crc_nr; /**< The number of CRC bits found in ROHC header */ 00134 00135 /* X (extension) flag */ 00136 uint8_t ext_flag:1; /**< X (extension) flag */ 00137 00138 00139 /* bits below are for UDP-based profiles only 00140 @todo TODO should be moved in d_udp.c */ 00141 00142 uint16_t udp_src; /**< The UDP source port bits found in static chain 00143 of IR header */ 00144 size_t udp_src_nr; /**< The number of UDP source port bits */ 00145 00146 uint16_t udp_dst; /**< The UDP destination port bits in static chain 00147 of IR header */ 00148 size_t udp_dst_nr; /**< The number of UDP destination port bits */ 00149 00150 uint16_t udp_check; /**< The UDP checksum bits found in dynamic chain 00151 of IR/IR-DYN header or in remainder of UO* 00152 header */ 00153 size_t udp_check_nr; /**< The number of UDP checksum bits */ 00154 00155 00156 /* bits below are for UDP-Lite-based profiles only 00157 @todo TODO should be moved in d_udp_lite.c */ 00158 00159 uint16_t udp_lite_cc; /**< The UDP-Lite CC bits found in dynamic 00160 chain of IR/IR-DYN header or in remainder 00161 of UO* header */ 00162 size_t udp_lite_cc_nr; /**< The number of UDP-Lite CC bits */ 00163 00164 00165 /* bits below are for RTP profile only 00166 @todo TODO should be moved in d_rtp.c */ 00167 00168 /* RTP version */ 00169 uint8_t rtp_version:2; /**< The RTP version bits found in dynamic chain 00170 of IR/IR-DYN header */ 00171 size_t rtp_version_nr; /**< The number of RTP version bits */ 00172 00173 /* RTP Padding (R-P) flag */ 00174 uint8_t rtp_p:1; /**< The RTP Padding bits found in dynamic chain 00175 of IR/IR-DYN header or in extension header */ 00176 size_t rtp_p_nr; /**< The number of RTP Padding bits */ 00177 00178 /* RTP eXtension (R-X) flag */ 00179 uint8_t rtp_x:1; /**< The RTP eXtension (R-X) bits found in 00180 extension header */ 00181 size_t rtp_x_nr; /**< The number of RTP X bits */ 00182 00183 /* RTP CSRC Count (CC) */ 00184 uint8_t rtp_cc:4; /**< The RTP CSRC Count bits found in dynamic 00185 chain of IR/IR-DYN header */ 00186 size_t rtp_cc_nr; /**< The number of the RTP CSRC Count bits */ 00187 00188 /* RTP Marker (M) flag */ 00189 uint8_t rtp_m:1; /**< The RTP Marker (M) bits found in dynamic chain 00190 of IR/IR-DYN header, UO* base header and 00191 extension header */ 00192 size_t rtp_m_nr; /**< The number of the RTP Marker (M) bits */ 00193 00194 /* RTP Payload Type (RTP-PT) */ 00195 uint8_t rtp_pt:7; /**< The RTP Payload Type (PT) bits found in 00196 dynamic chain of IR/IR-DYN header or in 00197 extension header */ 00198 size_t rtp_pt_nr; /**< The number of RTP PT bits found in header */ 00199 00200 /* RTP TimeStamp (TS) */ 00201 uint32_t ts; /**< The TS bits found in dynamic chain of 00202 IR/IR-DYN header, in UO* base header or in 00203 extension header */ 00204 size_t ts_nr; /**< The number of TS bits found in ROHC header */ 00205 bool is_ts_scaled; /**< Whether TS is transmitted scaled or not */ 00206 00207 /* RTP Synchronization SouRCe (SSRC) identifier */ 00208 uint32_t rtp_ssrc; /**< The SSRC bits found in static chain of 00209 IR header */ 00210 size_t rtp_ssrc_nr; /**< The number of SSRC bits found in header */ 00211 00212 00213 /* bits below are for ESP profile only 00214 @todo TODO should be moved in d_esp.c */ 00215 00216 /* ESP Security Parameters Index (SPI) */ 00217 uint32_t esp_spi; /**< The SPI bits found in static chain of 00218 IR header */ 00219 size_t esp_spi_nr; /**< The number of SPI bits found in header */ 00220 }; 00221 00222 00223 /** The outer or inner IP values decoded from the extracted ROHC bits */ 00224 struct rohc_decoded_ip_values 00225 { 00226 uint8_t version:4; /**< The decoded version field */ 00227 uint8_t tos; /**< The decoded TOS/TC field */ 00228 uint16_t id; /**< The decoded IP-ID field (IPv4 only) */ 00229 uint8_t df:1; /**< The decoded DF field (IPv4 only) */ 00230 uint8_t ttl; /**< The decoded TTL/HL field */ 00231 uint8_t proto; /**< The decoded protocol/NH field */ 00232 uint8_t nbo:1; /**< The decoded NBO field (IPv4 only) */ 00233 uint8_t rnd:1; /**< The decoded RND field (IPv4 only) */ 00234 uint8_t sid:1; /**< The decoded SID field (IPv4 only) */ 00235 uint32_t flowid:20; /**< The decoded flow ID field (IPv6 only) */ 00236 uint8_t saddr[16]; /**< The decoded source address field */ 00237 uint8_t daddr[16]; /**< The decoded destination address field */ 00238 }; 00239 00240 00241 /** 00242 * @brief The values decoded from the bits extracted from ROHC header 00243 * 00244 * @see decode_uo0 00245 * @see decode_uo1 00246 * @see decode_uor2 00247 * @see decode_values_from_bits 00248 * @see rtp_decode_values_from_bits 00249 */ 00250 struct rohc_decoded_values 00251 { 00252 uint32_t sn; /**< The decoded SN value */ 00253 00254 /** The decoded values for the outer IP header */ 00255 struct rohc_decoded_ip_values outer_ip; 00256 /** The decoded values for the inner IP header */ 00257 struct rohc_decoded_ip_values inner_ip; 00258 00259 /* bits below are for UDP-based profile only 00260 @todo TODO should be moved in d_udp.c */ 00261 uint16_t udp_src; /**< The decoded UDP source port */ 00262 uint16_t udp_dst; /**< The decoded UDP destination port bits */ 00263 uint16_t udp_check; /**< The decoded UDP checksum */ 00264 00265 /* bits below are for UDP-Lite-based profile only 00266 @todo TODO should be moved in d_udp_lite.c */ 00267 uint16_t udp_lite_cc; /**< The decoded UDP-Lite CC */ 00268 00269 /* bits below are for RTP profile only 00270 @todo TODO should be moved in d_rtp.c */ 00271 uint8_t rtp_version:2; /**< The decoded RTP version */ 00272 uint8_t rtp_p:1; /**< The decoded RTP Padding (R-P) flag */ 00273 uint8_t rtp_x:1; /**< The decoded RTP eXtension (R-X) flag */ 00274 uint8_t rtp_cc:4; /**< The decoded RTP CSRC Count */ 00275 uint8_t rtp_m:1; /**< The decoded RTP Marker (M) flag */ 00276 uint8_t rtp_pt:7; /**< The decoded RTP Payload Type (RTP-PT) */ 00277 uint32_t ts; /**< The decoded RTP TimeStamp (TS) value */ 00278 uint32_t rtp_ssrc; /**< The decoded SSRC value */ 00279 00280 /* bits below are for ESP profile only 00281 @todo TODO should be moved in d_esp.c */ 00282 uint32_t esp_spi; /**< The decoded ESP SPI */ 00283 }; 00284 00285 00286 /** 00287 * @brief Store information about an IP header between the different 00288 * decompressions of IP packets. 00289 * 00290 * Defines an object that contains flags and structures related to an IP header 00291 * and that need to be saved between the different decompressions of packets. A 00292 * decompression context owns objects like this for the two first IP headers. 00293 */ 00294 struct d_generic_changes 00295 { 00296 /// The IP header 00297 struct ip_packet ip; 00298 00299 /// Whether the IP-ID is considered as random or not (IPv4 only) 00300 int rnd; 00301 /// Whether the IP-ID is considered as coded in NBO or not (IPv4 only) 00302 int nbo; 00303 /// Whether the IP-ID is considered as static or not (IPv4 only) 00304 int sid; 00305 00306 /// The next header located after the IP header(s) 00307 unsigned char *next_header; 00308 /// The length of the next header 00309 unsigned int next_header_len; 00310 }; 00311 00312 00313 /** 00314 * @brief The generic decompression context 00315 * 00316 * The object defines the generic context that manages IP(/nextheader) and 00317 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00318 * part of the context. 00319 */ 00320 struct d_generic_context 00321 { 00322 /// Information about the outer IP header 00323 struct d_generic_changes *outer_ip_changes; 00324 /// Information about the inner IP header 00325 struct d_generic_changes *inner_ip_changes; 00326 00327 /// The LSB decoding context for the Sequence Number (SN) 00328 struct rohc_lsb_decode *sn_lsb_ctxt; 00329 /// The IP-ID of the outer IP header 00330 struct ip_id_offset_decode *outer_ip_id_offset_ctxt; 00331 /// The IP-ID of the inner IP header 00332 struct ip_id_offset_decode *inner_ip_id_offset_ctxt; 00333 00334 /// The list decompressor of the outer IP header 00335 struct list_decomp *list_decomp1; 00336 /// The list decompressor of the inner IP header 00337 struct list_decomp *list_decomp2; 00338 00339 /// Whether the decompressed packet contains a 2nd IP header 00340 int multiple_ip; 00341 00342 /// The type of packet the decompressor may receive: IR, IR-DYN, UO* 00343 rohc_packet_t packet_type; 00344 00345 /* below are some information and handlers to manage the next header 00346 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00347 00348 /// The IP protocol ID of the protocol the context is able to decompress 00349 unsigned short next_header_proto; 00350 00351 /// The length of the next header 00352 unsigned int next_header_len; 00353 00354 /** The handler used to detect the packet type */ 00355 rohc_packet_t (*detect_packet_type)(struct rohc_decomp *decomp, 00356 struct d_context *context, 00357 const unsigned char *packet, 00358 const size_t rohc_length, 00359 const size_t large_cid_len); 00360 00361 /// @brief The handler used to parse the static part of the next header 00362 /// in the ROHC packet 00363 int (*parse_static_next_hdr)(const struct d_context *const context, 00364 const unsigned char *packet, 00365 unsigned int length, 00366 struct rohc_extr_bits *const bits); 00367 00368 /// @brief The handler used to parse the dynamic part of the next header 00369 /// in the ROHC packet 00370 int (*parse_dyn_next_hdr)(const struct d_context *const context, 00371 const unsigned char *packet, 00372 unsigned int length, 00373 struct rohc_extr_bits *const bits); 00374 00375 /// The handler used to parse the tail of the UO* ROHC packet 00376 int (*parse_uo_remainder)(const struct d_context *const context, 00377 const unsigned char *packet, 00378 unsigned int length, 00379 struct rohc_extr_bits *const bits); 00380 00381 /** The handler used to decode extracted for next header */ 00382 bool (*decode_values_from_bits)(const struct d_context *context, 00383 const struct rohc_extr_bits bits, 00384 struct rohc_decoded_values *const decoded); 00385 00386 /** The handler used to build the uncompressed next header */ 00387 int (*build_next_header)(const struct d_context *const context, 00388 const struct rohc_decoded_values decoded, 00389 unsigned char *dest, 00390 const unsigned int payload_len); 00391 00392 /// @brief The handler used to compute the CRC-STATIC value 00393 unsigned int (*compute_crc_static)(const unsigned char *const ip, 00394 const unsigned char *const ip2, 00395 const unsigned char *const next_header, 00396 const rohc_crc_type_t crc_type, 00397 const unsigned int init_val, 00398 const unsigned char *const crc_table); 00399 00400 /// @brief The handler used to compute the CRC-DYNAMIC value 00401 unsigned int (*compute_crc_dynamic)(const unsigned char *const ip, 00402 const unsigned char *const ip2, 00403 const unsigned char *const next_header, 00404 const rohc_crc_type_t crc_type, 00405 const unsigned int init_val, 00406 const unsigned char *const crc_table); 00407 00408 /** The handler used to update context with decoded next header fields */ 00409 void (*update_context)(const struct d_context *context, 00410 const struct rohc_decoded_values decoded); 00411 00412 /// Profile-specific data 00413 void *specific; 00414 00415 /// Correction counter (see e and f in 5.3.2.2.4 of the RFC 3095) 00416 unsigned int correction_counter; 00417 }; 00418 00419 00420 /** 00421 * @brief The list decompressor 00422 */ 00423 struct list_decomp 00424 { 00425 /// The reference list 00426 struct c_list *ref_list; 00427 /// The table of lists 00428 struct c_list *list_table[LIST_COMP_WINDOW]; 00429 /// The compression based table 00430 struct rohc_list_item based_table[MAX_ITEM]; 00431 /// The translation table 00432 struct d_translation trans_table[MAX_ITEM]; 00433 /// counter in list table 00434 int counter_list; 00435 /// counter which indicates if the list is reference list 00436 int counter; 00437 /// boolean which indicates if there is a list to decompress 00438 bool is_present; 00439 /// boolean which indicates if the ref list must be decompressed 00440 int ref_ok; 00441 00442 00443 /* Functions for handling the data to decompress */ 00444 00445 /// The handler used to free the based table 00446 void (*free_table)(struct list_decomp *decomp); 00447 /// The handler used to add the extension to IP packet 00448 int (*encode_extension)(struct list_decomp *const decomp, 00449 const uint8_t ip_nh_type, 00450 unsigned char *dest); 00451 /// The handler used to check if the index 00452 /// corresponds to an existing item 00453 int (*check_index)(struct list_decomp *decomp, int index); 00454 /// The handler used to create the item at 00455 /// the corresponding index of the based table 00456 bool (*create_item)(const unsigned char *data, 00457 int length, 00458 int index, 00459 struct list_decomp *decomp); 00460 /// The handler used to get the size of an extension 00461 int (*get_ext_size)(const unsigned char *data, const size_t data_len); 00462 00463 00464 /* Traces */ 00465 00466 /** The callback function used to manage traces */ 00467 rohc_trace_callback_t trace_callback; 00468 /** The profile ID the decompression list was created for */ 00469 int profile_id; 00470 }; 00471 00472 00473 /* 00474 * Public function prototypes. 00475 */ 00476 00477 void * d_generic_create(const struct d_context *const context, 00478 rohc_trace_callback_t trace_callback, 00479 const int profile_id) 00480 __attribute__((nonnull(1, 2), warn_unused_result)); 00481 00482 void d_generic_destroy(void *const context) 00483 __attribute__((nonnull(1))); 00484 00485 int d_generic_decode(struct rohc_decomp *decomp, 00486 struct d_context *context, 00487 const unsigned char *const rohc_packet, 00488 const unsigned int rohc_length, 00489 const size_t add_cid_len, 00490 const size_t large_cid_len, 00491 unsigned char *dest); 00492 00493 int d_generic_get_sn(struct d_context *context); 00494 00495 #endif 00496