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_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