ROHC compression/decompression library
d_generic.h
Go to the documentation of this file.
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