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 c_generic.h 00019 * @brief ROHC generic compression context for IP-only, UDP and UDP Lite 00020 * profiles. 00021 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00022 * @author The hackers from ROHC for Linux 00023 */ 00024 00025 #ifndef C_GENERIC_H 00026 #define C_GENERIC_H 00027 00028 #include "rohc_comp_internals.h" 00029 #include "rohc_packets.h" 00030 #include "comp_list.h" 00031 #include "ip.h" 00032 00033 #include <stdlib.h> 00034 #include <netinet/ip.h> 00035 00036 00037 /** 00038 * @brief The maximal delta accepted between two consecutive IPv4 ID so that it 00039 * can be considered as coded in Network Byte Order (NBO) 00040 */ 00041 #define IPID_MAX_DELTA 20 00042 00043 /// The number of compression list items 00044 #define MAX_ITEM 15 00045 00046 /// The number of compressed list to send to make the reference list 00047 /// L is the name specified in the RFC 00048 #define L 5 00049 00050 /** 00051 * @brief Store information about an IPv4 header between the different 00052 * compressions of IP packets. 00053 * 00054 * Defines an object that contains counters, flags and structures related to an 00055 * IPv4 header and that need to be saved between the different compressions of 00056 * packets. A compression context owns objects like this for the two first 00057 * IPv4 headers. 00058 */ 00059 struct ipv4_header_info 00060 { 00061 /// A window to store the IP-ID 00062 struct c_wlsb *ip_id_window; 00063 00064 /// The previous IP header 00065 struct iphdr old_ip; 00066 00067 /// The number of times the DF field was added to the compressed header 00068 int df_count; 00069 /// @brief The number of times the IP-ID is specified as random in the 00070 /// compressed header 00071 int rnd_count; 00072 /// @brief The number of times the IP-ID is specified as coded in Network 00073 /// Byte Order (NBO) in the compressed header 00074 int nbo_count; 00075 00076 /// Whether the IP-ID is considered as random or not 00077 int rnd; 00078 /// Whether the IP-ID is considered as coded in NBO or not 00079 int nbo; 00080 /// @brief Whether the IP-ID of the previous IP header was considered as 00081 /// random or not 00082 int old_rnd; 00083 /// @brief Whether the IP-ID of the previous IP header was considered as 00084 /// coded in NBO or not 00085 int old_nbo; 00086 00087 /// The delta between the IP-ID and the current Sequence Number (SN) 00088 /// (overflow over 16 bits is expected when SN > IP-ID) 00089 uint16_t id_delta; 00090 }; 00091 00092 00093 /** 00094 * @brief Store information about an IPv6 header between the different 00095 * compressions of IP packets. 00096 * 00097 * Defines an object that contains counters, flags and structures related to an 00098 * IPv6 header and that need to be saved between the different compressions of 00099 * packets. A compression context owns objects like this for the two first 00100 * IPv6 headers. 00101 */ 00102 struct ipv6_header_info 00103 { 00104 /// The previous IPv6 header 00105 struct ip6_hdr old_ip; 00106 /// The extension compressor 00107 struct list_comp *ext_comp; 00108 }; 00109 00110 00111 /** 00112 * @brief Store information about an IP (IPv4 or IPv6) header between the 00113 * different compressions of IP packets. 00114 */ 00115 struct ip_header_info 00116 { 00117 ip_version version; ///< The version of the IP header 00118 00119 /// The number of times the TOS/TC field was added to the compressed header 00120 int tos_count; 00121 /// The number of times the TTL/HL field was added to the compressed header 00122 int ttl_count; 00123 /// @brief The number of times the Protocol/Next Header field was added to 00124 /// the compressed header 00125 int protocol_count; 00126 00127 union 00128 { 00129 struct ipv4_header_info v4; ///< The IPv4-specific header info 00130 struct ipv6_header_info v6; ///< The IPv6-specific header info 00131 } info; ///< The version specific header info 00132 }; 00133 00134 00135 /** 00136 * @brief Structure that contains variables that are used during one single 00137 * compression of packet. 00138 * 00139 * Structure that contains variables that are temporary, i.e. variables that 00140 * will only be used for the compression of the current packet. These variables 00141 * must be reinitialized every time a new packet arrive. 00142 * 00143 * @see c_init_tmp_variables 00144 */ 00145 struct generic_tmp_vars 00146 { 00147 /// The number of IP headers in the packet to compress (1 or 2 only) 00148 int nr_of_ip_hdr; 00149 00150 /// The number of fields that changed in the outer IP header 00151 unsigned short changed_fields; 00152 /// The number of fields that changed in the inner IP header 00153 unsigned short changed_fields2; 00154 /// The number of static fields that changed in the two IP headers 00155 int send_static; 00156 /// The number of dynamic fields that changed in the two IP headers 00157 int send_dynamic; 00158 00159 /// The number of bits needed to encode the Sequence Number (SN) 00160 size_t nr_sn_bits; 00161 /// The number of bits needed to encode the IP-ID of the outer IP header 00162 size_t nr_ip_id_bits; 00163 /// The number of bits needed to encode the IP-ID of the inner IP header 00164 size_t nr_ip_id_bits2; 00165 00166 /// The type of packet the compressor must send: IR, IR-DYN, UO* 00167 rohc_packet_t packet_type; 00168 00169 /// The maximal size of the compressed packet 00170 int max_size; 00171 }; 00172 00173 00174 /** 00175 * @brief The generic compression context 00176 * 00177 * The object defines the generic context that manages IP(/nextheader) and 00178 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00179 * part of the context. 00180 */ 00181 struct c_generic_context 00182 { 00183 /// The Sequence Number (SN) 00184 unsigned int sn; 00185 /// A window used to encode the SN 00186 struct c_wlsb *sn_window; 00187 00188 /// The number of packets sent while in Initialization & Refresh (IR) state 00189 int ir_count; 00190 /// The number of packets sent while in First Order (FO) state 00191 int fo_count; 00192 /// The number of packets sent while in Second Order (SO) state 00193 int so_count; 00194 00195 /// @brief The number of packet sent while in SO state, used for the periodic 00196 /// refreshes of the context 00197 /// @see periodic_down_transition 00198 int go_back_fo_count; 00199 /// @brief The number of packet sent while in FO or SO state, used for the 00200 /// periodic refreshes of the context 00201 /// @see periodic_down_transition 00202 int go_back_ir_count; 00203 /// @brief The minimal number of IR-DYN packets the compressor must sent 00204 /// before sending UO* packets 00205 int ir_dyn_count; 00206 00207 /// Information about the outer IP header 00208 struct ip_header_info ip_flags; 00209 /// Information about the inner IP header 00210 struct ip_header_info ip2_flags; 00211 /// Whether the ip2_flags object is initialized or not 00212 int is_ip2_initialized; 00213 00214 /// Temporary variables that are used during one single compression of packet 00215 struct generic_tmp_vars tmp; 00216 00217 /* below are some information and handlers to manage the next header 00218 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00219 00220 /// The protocol number registered by IANA for the next header protocol 00221 unsigned int next_header_proto; 00222 /// The length of the next header 00223 unsigned int next_header_len; 00224 00225 /// @brief The handler used to decide the state that should be used for the 00226 /// next packet 00227 void (*decide_state)(struct c_context *const context); 00228 00229 /// The handler used to initialize some data just before the IR packet build 00230 void (*init_at_IR)(const struct c_context *context, 00231 const unsigned char *next_header); 00232 00233 /// @brief The handler used to add the static part of the next header to the 00234 /// ROHC packet 00235 int (*code_static_part)(const struct c_context *context, 00236 const unsigned char *next_header, 00237 unsigned char *const dest, 00238 int counter); 00239 00240 /// @brief The handler used to add the dynamic part of the next header to the 00241 /// ROHC pachet 00242 int (*code_dynamic_part)(const struct c_context *context, 00243 const unsigned char *next_header, 00244 unsigned char *const dest, 00245 int counter); 00246 00247 /// @brief The handler used to add an additional header in the head of the 00248 /// UO-0, UO-1 and UO-2 packets 00249 int (*code_UO_packet_head)(const struct c_context *context, 00250 const unsigned char *next_header, 00251 unsigned char *const dest, 00252 int counter, 00253 int *const first_position); 00254 00255 /// @brief The handler used to add an additional header in the tail of the 00256 /// UO-0, UO-1 and UO-2 packets 00257 int (*code_UO_packet_tail)(const struct c_context *context, 00258 const unsigned char *next_header, 00259 unsigned char *const dest, 00260 int counter); 00261 00262 /// @brief The handler used to compute the CRC-STATIC value 00263 unsigned int (*compute_crc_static)(const unsigned char *const ip, 00264 const unsigned char *const ip2, 00265 const unsigned char *const next_header, 00266 const unsigned int crc_type, 00267 const unsigned int init_val, 00268 const unsigned char *const crc_table); 00269 00270 /// @brief The handler used to compute the CRC-DYNAMIC value 00271 unsigned int (*compute_crc_dynamic)(const unsigned char *const ip, 00272 const unsigned char *const ip2, 00273 const unsigned char *const next_header, 00274 const unsigned int crc_type, 00275 const unsigned int init_val, 00276 const unsigned char *const crc_table); 00277 00278 /// Profile-specific data 00279 void *specific; 00280 }; 00281 00282 00283 /** 00284 * @brief The list compressor 00285 */ 00286 struct list_comp 00287 { 00288 /// The reference list 00289 struct c_list *ref_list; 00290 /// The current list 00291 struct c_list *curr_list; 00292 /// counter which indicates if ref_list is reference list 00293 int counter; 00294 /// The compression based table 00295 struct rohc_list_item based_table[MAX_ITEM]; 00296 /// The translation table 00297 struct c_translation trans_table[MAX_ITEM]; 00298 /// Boolean which equals to 1 if the update is done, 0 else 00299 int update_done; 00300 /// Boolean which equals to 1 if the list change 00301 int list_compress; 00302 /// Boolean which equals to 1 if there is a list, 0 else 00303 int islist; 00304 00305 /// @brief the handler used to get the extension in the IP packet 00306 unsigned char * (*get_extension)(const struct ip_packet *ip, 00307 const int index); 00308 00309 /// @brief the handler used to get the index in based table for the corresponding item 00310 int (*get_index_table)(const struct ip_packet *ip, const int index); 00311 00312 /// @brief the handler used to get the size of an extension 00313 unsigned short (*get_size)(const unsigned char *ext); 00314 00315 /// @brief the handler used to compare two extension of the same type 00316 int (*compare)(const unsigned char *ext, 00317 const struct list_comp *comp, 00318 const int size, 00319 const int index_table); 00320 00321 /// @brief the handler used to create the item with the corresponding 00322 /// type of the extension 00323 void (*create_item)(struct list_comp *const comp, 00324 const unsigned int index_table, 00325 const unsigned char *ext_data, 00326 const size_t ext_size); 00327 00328 /// @brief the handler used to free the based table element 00329 void (*free_table)(struct list_comp *const comp); 00330 }; 00331 00332 00333 /* 00334 * Function prototypes. 00335 */ 00336 00337 int c_generic_create(struct c_context *const context, 00338 const struct ip_packet *ip); 00339 void c_generic_destroy(struct c_context *const context); 00340 00341 void change_mode(struct c_context *const context, const rohc_mode new_mode); 00342 void change_state(struct c_context *const context, const rohc_c_state new_state); 00343 00344 void ip6_c_init_table(struct list_comp *const comp); 00345 00346 int rohc_list_decide_ipv6_compression(struct list_comp *const comp, 00347 const struct ip_packet *const ip); 00348 00349 int c_create_current_list(const int index, 00350 struct list_comp *const comp, 00351 const unsigned char *ext, 00352 const int index_table); 00353 int rohc_list_decide_type(struct list_comp *const comp); 00354 int rohc_list_encode(struct list_comp *const comp, 00355 unsigned char *const dest, 00356 int counter, 00357 const int ps, 00358 const int size); 00359 int rohc_list_encode_type_0(struct list_comp *const comp, 00360 unsigned char *const dest, 00361 int counter, 00362 const int ps); 00363 int rohc_list_encode_type_1(struct list_comp *const comp, 00364 unsigned char *const dest, 00365 int counter, 00366 const int ps); 00367 int rohc_list_encode_type_2(struct list_comp *const comp, 00368 unsigned char *const dest, 00369 int counter, 00370 const int ps); 00371 int rohc_list_encode_type_3(struct list_comp *const comp, 00372 unsigned char *const dest, 00373 int counter, 00374 const int ps); 00375 00376 int c_generic_encode(struct c_context *const context, 00377 const struct ip_packet *ip, 00378 const int packet_size, 00379 unsigned char *const dest, 00380 const int dest_size, 00381 rohc_packet_t *const packet_type, 00382 int *const payload_offset); 00383 00384 void c_generic_feedback(struct c_context *const context, 00385 const struct c_feedback *feedback); 00386 00387 void decide_state(struct c_context *const context); 00388 00389 00390 #endif 00391