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