00001 /* 00002 * Copyright 2010,2011,2012,2013,2014 Didier Barvaux 00003 * Copyright 2007,2008 Thales Alenia Space 00004 * Copyright 2007,2008,2009,2010,2012,2013 Viveris Technologies 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /** 00022 * @file rohc_decomp_rfc3095.c 00023 * @brief Generic framework for RFC3095-based decompression profiles such as 00024 * IP-only, UDP, UDP-Lite, ESP, and RTP profiles. 00025 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00026 * @author Didier Barvaux <didier@barvaux.org> 00027 * @author David Moreau from TAS 00028 */ 00029 00030 #ifndef ROHC_DECOMP_RFC3095_H 00031 #define ROHC_DECOMP_RFC3095_H 00032 00033 #include "rohc_decomp.h" 00034 #include "rohc_decomp_internals.h" 00035 #include "rohc_packets.h" 00036 #include "rohc_utils.h" 00037 #include "schemes/decomp_wlsb.h" 00038 #include "schemes/ip_id_offset.h" 00039 #include "schemes/decomp_list.h" 00040 #include "protocols/udp_lite.h" 00041 #include "ip.h" 00042 #include "crc.h" 00043 00044 #include <stddef.h> 00045 #ifdef __KERNEL__ 00046 # include <linux/types.h> 00047 #else 00048 # include <stdbool.h> 00049 #endif 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 bool is_id_enc; /**< Whether value(IP-ID) is encoded or not */ 00067 00068 uint8_t df:1; /**< The DF bits found in dynamic chain of IR/IR-DYN 00069 header or in extension header */ 00070 size_t df_nr; /**< The number of DF bits found */ 00071 00072 uint8_t ttl; /**< The TTL/HL bits found in dynamic chain of IR/IR-DYN 00073 header or in extension header */ 00074 size_t ttl_nr; /**< The number of TTL/HL bits found */ 00075 00076 uint8_t proto; /**< The protocol/next header bits found static chain 00077 of IR header or in extension header */ 00078 size_t proto_nr; /**< The number of protocol/next header bits */ 00079 00080 uint8_t nbo:1; /**< The NBO bits found in dynamic chain of IR/IR-DYN 00081 header or in extension header */ 00082 size_t nbo_nr; /**< The number of NBO bits found */ 00083 00084 uint8_t rnd:1; /**< The RND bits found in dynamic chain of IR/IR-DYN 00085 header or in extension header */ 00086 size_t rnd_nr; /**< The number of RND bits found */ 00087 00088 uint8_t sid:1; /**< The SID bits found in dynamic chain of IR/IR-DYN 00089 header or in extension header */ 00090 size_t sid_nr; /**< The number of SID bits found */ 00091 00092 uint32_t flowid:20; /**< The IPv6 flow ID bits found in static chain of 00093 IR header */ 00094 size_t flowid_nr; /**< The number of flow label bits */ 00095 00096 uint8_t saddr[16]; /**< The source address bits found in static chain of 00097 IR header */ 00098 size_t saddr_nr; /**< The number of source address bits */ 00099 00100 uint8_t daddr[16]; /**< The destination address bits found in static 00101 chain of IR header */ 00102 size_t daddr_nr; /**< The number of source address bits */ 00103 }; 00104 00105 00106 /** 00107 * @brief The bits extracted from ROHC UO* base headers 00108 * 00109 * @see parse_uo0 00110 * @see parse_uo1 00111 * @see parse_uor2 00112 */ 00113 struct rohc_extr_bits 00114 { 00115 bool is_context_reused; /**< Whether the context is re-used or not */ 00116 00117 /* SN */ 00118 uint32_t sn; /**< The SN bits found in ROHC header */ 00119 size_t sn_nr; /**< The number of SN bits found in ROHC header */ 00120 bool is_sn_enc; /**< Whether value(SN) is encoded with W-LSB or not */ 00121 rohc_lsb_ref_t lsb_ref_type; /**< The reference to use for LSB decoding 00122 (used for context repair after CRC failure) */ 00123 bool sn_ref_offset; /**< Optional offset to add to the reference SN 00124 (used for context repair after CRC failure) */ 00125 00126 /** Whether there are multiple IP headers or only one single IP header */ 00127 bool multiple_ip; 00128 00129 /** bits related to outer IP header */ 00130 struct rohc_extr_ip_bits outer_ip; 00131 00132 /** bits related to inner IP header */ 00133 struct rohc_extr_ip_bits inner_ip; 00134 00135 /* X (extension) flag */ 00136 uint8_t ext_flag:1; /**< X (extension) flag */ 00137 00138 /* Mode bits */ 00139 uint8_t mode:2; /**< The Mode bits found in ROHC header */ 00140 size_t mode_nr; /**< The number of Mode bits found in ROHC header */ 00141 00142 00143 /* bits below are for UDP-based profiles only 00144 @todo TODO should be moved in d_udp.c */ 00145 00146 uint16_t udp_src; /**< The UDP source port bits found in static chain 00147 of IR header */ 00148 size_t udp_src_nr; /**< The number of UDP source port bits */ 00149 00150 uint16_t udp_dst; /**< The UDP destination port bits in static chain 00151 of IR header */ 00152 size_t udp_dst_nr; /**< The number of UDP destination port bits */ 00153 00154 rohc_tristate_t udp_check_present; /**< Whether the UDP checksum field is 00155 encoded in the ROHC packet or not */ 00156 uint16_t udp_check; /**< The UDP checksum bits found in dynamic chain 00157 of IR/IR-DYN header or in remainder of UO* 00158 header */ 00159 size_t udp_check_nr; /**< The number of UDP checksum bits */ 00160 00161 00162 /* bits below are for UDP-Lite-based profiles only 00163 @todo TODO should be moved in d_udp_lite.c */ 00164 00165 rohc_packet_cce_t cce_pkt; /**< TODO */ 00166 rohc_tristate_t cfp; /**< TODO */ 00167 rohc_tristate_t cfi; /**< TODO */ 00168 uint16_t udp_lite_cc; /**< The UDP-Lite CC bits found in dynamic 00169 chain of IR/IR-DYN header or in remainder 00170 of UO* header */ 00171 size_t udp_lite_cc_nr; /**< The number of UDP-Lite CC bits */ 00172 00173 00174 /* bits below are for RTP profile only 00175 @todo TODO should be moved in d_rtp.c */ 00176 00177 /* RTP version */ 00178 uint8_t rtp_version:2; /**< The RTP version bits found in dynamic chain 00179 of IR/IR-DYN header */ 00180 size_t rtp_version_nr; /**< The number of RTP version bits */ 00181 00182 /* RTP Padding (R-P) flag */ 00183 uint8_t rtp_p:1; /**< The RTP Padding bits found in dynamic chain 00184 of IR/IR-DYN header or in extension header */ 00185 size_t rtp_p_nr; /**< The number of RTP Padding bits */ 00186 00187 /* RTP eXtension (R-X) flag */ 00188 uint8_t rtp_x:1; /**< The RTP eXtension (R-X) bits found in 00189 extension header */ 00190 size_t rtp_x_nr; /**< The number of RTP X bits */ 00191 00192 /* RTP CSRC Count (CC) */ 00193 uint8_t rtp_cc:4; /**< The RTP CSRC Count bits found in dynamic 00194 chain of IR/IR-DYN header */ 00195 size_t rtp_cc_nr; /**< The number of the RTP CSRC Count bits */ 00196 00197 /* RTP Marker (M) flag */ 00198 uint8_t rtp_m:1; /**< The RTP Marker (M) bits found in dynamic chain 00199 of IR/IR-DYN header, UO* base header and 00200 extension header */ 00201 size_t rtp_m_nr; /**< The number of the RTP Marker (M) bits */ 00202 00203 /* RTP Payload Type (RTP-PT) */ 00204 uint8_t rtp_pt:7; /**< The RTP Payload Type (PT) bits found in 00205 dynamic chain of IR/IR-DYN header or in 00206 extension header */ 00207 size_t rtp_pt_nr; /**< The number of RTP PT bits found in header */ 00208 00209 /* RTP TimeStamp (TS) */ 00210 uint32_t ts; /**< The TS bits found in dynamic chain of 00211 IR/IR-DYN header, in UO* base header or in 00212 extension header */ 00213 size_t ts_nr; /**< The number of TS bits found in ROHC header */ 00214 bool is_ts_scaled; /**< Whether TS is transmitted scaled or not */ 00215 00216 /* RTP Synchronization SouRCe (SSRC) identifier */ 00217 uint32_t rtp_ssrc; /**< The SSRC bits found in static chain of 00218 IR header */ 00219 size_t rtp_ssrc_nr; /**< The number of SSRC bits found in header */ 00220 00221 00222 /* bits below are for ESP profile only 00223 @todo TODO should be moved in d_esp.c */ 00224 00225 /* ESP Security Parameters Index (SPI) */ 00226 uint32_t esp_spi; /**< The SPI bits found in static chain of 00227 IR header */ 00228 size_t esp_spi_nr; /**< The number of SPI bits found in header */ 00229 }; 00230 00231 00232 /** The outer or inner IP values decoded from the extracted ROHC bits */ 00233 struct rohc_decoded_ip_values 00234 { 00235 uint8_t version:4; /**< The decoded version field */ 00236 uint8_t tos; /**< The decoded TOS/TC field */ 00237 uint16_t id; /**< The decoded IP-ID field (IPv4 only) */ 00238 uint8_t df:1; /**< The decoded DF field (IPv4 only) */ 00239 uint8_t ttl; /**< The decoded TTL/HL field */ 00240 uint8_t proto; /**< The decoded protocol/NH field */ 00241 uint8_t nbo:1; /**< The decoded NBO field (IPv4 only) */ 00242 uint8_t rnd:1; /**< The decoded RND field (IPv4 only) */ 00243 uint8_t sid:1; /**< The decoded SID field (IPv4 only) */ 00244 uint32_t flowid:20; /**< The decoded flow ID field (IPv6 only) */ 00245 uint8_t saddr[16]; /**< The decoded source address field */ 00246 uint8_t daddr[16]; /**< The decoded destination address field */ 00247 }; 00248 00249 00250 /** 00251 * @brief The values decoded from the bits extracted from ROHC header 00252 * 00253 * @see decode_values_from_bits 00254 * @see rtp_decode_values_from_bits 00255 */ 00256 struct rohc_decoded_values 00257 { 00258 bool is_context_reused; /**< Whether the context is re-used or not */ 00259 00260 uint32_t sn; /**< The decoded SN value */ 00261 00262 rohc_mode_t mode; /**< The operation mode asked by compressor */ 00263 00264 /** Whether there are multiple IP headers or only one single IP header */ 00265 bool multiple_ip; 00266 /** The decoded values for the outer IP header */ 00267 struct rohc_decoded_ip_values outer_ip; 00268 /** The decoded values for the inner IP header */ 00269 struct rohc_decoded_ip_values inner_ip; 00270 00271 /* bits below are for UDP-based profile only 00272 @todo TODO should be moved in d_udp.c */ 00273 uint16_t udp_src; /**< The decoded UDP source port */ 00274 uint16_t udp_dst; /**< The decoded UDP destination port bits */ 00275 uint16_t udp_check; /**< The decoded UDP checksum */ 00276 rohc_tristate_t udp_check_present; /**< Whether the UDP checksum field is 00277 encoded in the ROHC packet or not */ 00278 00279 /* bits below are for UDP-Lite-based profile only 00280 @todo TODO should be moved in d_udp_lite.c */ 00281 rohc_packet_cce_t cce_pkt; /**< TODO */ 00282 rohc_tristate_t cfp; /**< TODO */ 00283 rohc_tristate_t cfi; /**< TODO */ 00284 uint16_t udp_lite_cc; /**< The decoded UDP-Lite CC */ 00285 00286 /* bits below are for RTP profile only 00287 @todo TODO should be moved in d_rtp.c */ 00288 uint8_t rtp_version:2; /**< The decoded RTP version */ 00289 uint8_t rtp_p:1; /**< The decoded RTP Padding (R-P) flag */ 00290 uint8_t rtp_x:1; /**< The decoded RTP eXtension (R-X) flag */ 00291 uint8_t rtp_cc:4; /**< The decoded RTP CSRC Count */ 00292 uint8_t rtp_m:1; /**< The decoded RTP Marker (M) flag */ 00293 uint8_t rtp_pt:7; /**< The decoded RTP Payload Type (RTP-PT) */ 00294 uint32_t ts; /**< The decoded RTP TimeStamp (TS) value */ 00295 uint32_t rtp_ssrc; /**< The decoded SSRC value */ 00296 00297 /* bits below are for ESP profile only 00298 @todo TODO should be moved in d_esp.c */ 00299 uint32_t esp_spi; /**< The decoded ESP SPI */ 00300 }; 00301 00302 00303 /** 00304 * @brief Store information about an IP header between the different 00305 * decompressions of IP packets. 00306 * 00307 * Defines an object that contains flags and structures related to an IP header 00308 * and that need to be saved between the different decompressions of packets. A 00309 * decompression context owns objects like this for the two first IP headers. 00310 */ 00311 struct rohc_decomp_rfc3095_changes 00312 { 00313 /// The IP header 00314 struct ip_packet ip; 00315 00316 /// Whether the IP-ID is considered as random or not (IPv4 only) 00317 int rnd; 00318 /// Whether the IP-ID is considered as coded in NBO or not (IPv4 only) 00319 int nbo; 00320 /// Whether the IP-ID is considered as static or not (IPv4 only) 00321 int sid; 00322 00323 /// The next header located after the IP header(s) 00324 void *next_header; 00325 /// The length of the next header 00326 unsigned int next_header_len; 00327 }; 00328 00329 00330 /** 00331 * @brief The generic decompression context for RFC3095-based profiles 00332 * 00333 * The object defines the generic context that manages IP(/nextheader) and 00334 * IP/IP(/nextheader) packets. nextheader is managed by the profile-specific 00335 * part of the context. 00336 */ 00337 struct rohc_decomp_rfc3095_ctxt 00338 { 00339 /// Information about the outer IP header 00340 struct rohc_decomp_rfc3095_changes *outer_ip_changes; 00341 /// Information about the inner IP header 00342 struct rohc_decomp_rfc3095_changes *inner_ip_changes; 00343 00344 /** The LSB shift parameter for the Sequence Number (SN) */ 00345 rohc_lsb_shift_t sn_lsb_p; 00346 /// The LSB decoding context for the Sequence Number (SN) 00347 struct rohc_lsb_decode *sn_lsb_ctxt; 00348 /// The IP-ID of the outer IP header 00349 struct ip_id_offset_decode *outer_ip_id_offset_ctxt; 00350 /// The IP-ID of the inner IP header 00351 struct ip_id_offset_decode *inner_ip_id_offset_ctxt; 00352 00353 /// The list decompressor of the outer IP header 00354 struct list_decomp list_decomp1; 00355 /// The list decompressor of the inner IP header 00356 struct list_decomp list_decomp2; 00357 00358 /// Whether the decompressed packet contains a 2nd IP header 00359 int multiple_ip; 00360 00361 /* below are some information and handlers to manage the next header 00362 * (if any) located just after the IP headers (1 or 2 IP headers) */ 00363 00364 /// The IP protocol ID of the protocol the context is able to decompress 00365 unsigned short next_header_proto; 00366 00367 /// The length of the next header 00368 unsigned int next_header_len; 00369 00370 /// @brief The handler used to parse the static part of the next header 00371 /// in the ROHC packet 00372 int (*parse_static_next_hdr)(const struct rohc_decomp_ctxt *const context, 00373 const uint8_t *packet, 00374 size_t length, 00375 struct rohc_extr_bits *const bits); 00376 00377 /// @brief The handler used to parse the dynamic part of the next header 00378 /// in the ROHC packet 00379 int (*parse_dyn_next_hdr)(const struct rohc_decomp_ctxt *const context, 00380 const uint8_t *packet, 00381 const size_t length, 00382 struct rohc_extr_bits *const bits); 00383 00384 /** 00385 * @brief The handler used to parse the extension 3 of the UO* ROHC packet 00386 * 00387 * @param context The decompression context 00388 * @param rohc_data The ROHC data to parse 00389 * @param rohc_data_len The length of the ROHC data to parse 00390 * @param packet_type The type of ROHC packet to parse 00391 * @param bits IN: the bits already found in base header 00392 * OUT: the bits found in the extension header 3 00393 * @return The data length read from the ROHC packet, 00394 * -2 in case packet must be reparsed, 00395 * -1 in case of error 00396 */ 00397 int (*parse_ext3)(const struct rohc_decomp_ctxt *const context, 00398 const uint8_t *const rohc_data, 00399 const size_t rohc_data_len, 00400 const rohc_packet_t packet_type, 00401 struct rohc_extr_bits *const bits) 00402 __attribute__((warn_unused_result, nonnull(1, 2, 5))); 00403 00404 /// The handler used to parse the tail of the UO* ROHC packet 00405 int (*parse_uo_remainder)(const struct rohc_decomp_ctxt *const context, 00406 const uint8_t *packet, 00407 unsigned int length, 00408 struct rohc_extr_bits *const bits); 00409 00410 /** The handler used to decode extracted for next header */ 00411 bool (*decode_values_from_bits)(const struct rohc_decomp_ctxt *context, 00412 const struct rohc_extr_bits *const bits, 00413 struct rohc_decoded_values *const decoded) 00414 __attribute__((warn_unused_result, nonnull(1, 2, 3))); 00415 00416 /** The handler used to build the uncompressed next header */ 00417 int (*build_next_header)(const struct rohc_decomp_ctxt *const context, 00418 const struct rohc_decoded_values *const decoded, 00419 uint8_t *const dest, 00420 const unsigned int payload_len); 00421 00422 /// @brief The handler used to compute the CRC-STATIC value 00423 uint8_t (*compute_crc_static)(const uint8_t *const ip, 00424 const uint8_t *const ip2, 00425 const uint8_t *const next_header, 00426 const rohc_crc_type_t crc_type, 00427 const uint8_t init_val, 00428 const uint8_t *const crc_table); 00429 00430 /// @brief The handler used to compute the CRC-DYNAMIC value 00431 uint8_t (*compute_crc_dynamic)(const uint8_t *const ip, 00432 const uint8_t *const ip2, 00433 const uint8_t *const next_header, 00434 const rohc_crc_type_t crc_type, 00435 const uint8_t init_val, 00436 const uint8_t *const crc_table); 00437 00438 /** The handler used to update context with decoded next header fields */ 00439 void (*update_context)(struct rohc_decomp_ctxt *const context, 00440 const struct rohc_decoded_values *const decoded) 00441 __attribute__((nonnull(1, 2))); 00442 00443 /// Profile-specific data 00444 void *specific; 00445 }; 00446 00447 00448 /* 00449 * Public function prototypes. 00450 */ 00451 00452 bool rohc_decomp_rfc3095_create(const struct rohc_decomp_ctxt *const context, 00453 struct rohc_decomp_rfc3095_ctxt **const persist_ctxt, 00454 struct rohc_decomp_volat_ctxt *const volat_ctxt, 00455 rohc_trace_callback2_t trace_cb, 00456 void *const trace_cb_priv, 00457 const int profile_id) 00458 __attribute__((warn_unused_result, nonnull(1, 2, 3))); 00459 00460 void rohc_decomp_rfc3095_destroy(struct rohc_decomp_rfc3095_ctxt *const rfc3095_ctxt, 00461 const struct rohc_decomp_volat_ctxt *const volat_ctxt) 00462 __attribute__((nonnull(1, 2))); 00463 00464 bool rfc3095_decomp_parse_pkt(const struct rohc_decomp_ctxt *const context, 00465 const struct rohc_buf rohc_packet, 00466 const size_t large_cid_len, 00467 rohc_packet_t *const packet_type, 00468 struct rohc_decomp_crc *const extr_crc, 00469 struct rohc_extr_bits *const bits, 00470 size_t *const rohc_hdr_len) 00471 __attribute__((warn_unused_result, nonnull(1, 4, 5, 6, 7))); 00472 00473 rohc_status_t rfc3095_decomp_build_hdrs(const struct rohc_decomp *const decomp, 00474 const struct rohc_decomp_ctxt *const context, 00475 const rohc_packet_t packet_type, 00476 const struct rohc_decomp_crc *const extr_crc, 00477 const struct rohc_decoded_values *const decoded, 00478 const size_t payload_len, 00479 struct rohc_buf *const uncomp_hdrs, 00480 size_t *const uncomp_hdrs_len) 00481 __attribute__((warn_unused_result, nonnull(1, 2, 4, 5, 7, 8))); 00482 00483 bool rfc3095_decomp_decode_bits(const struct rohc_decomp_ctxt *const context, 00484 const struct rohc_extr_bits *const bits, 00485 const size_t payload_len __attribute__((unused)), 00486 struct rohc_decoded_values *const decoded) 00487 __attribute__((warn_unused_result, nonnull(1, 2, 4))); 00488 00489 void rfc3095_decomp_update_ctxt(struct rohc_decomp_ctxt *const context, 00490 const struct rohc_decoded_values *const decoded, 00491 const size_t payload_len, 00492 bool *const do_change_mode) 00493 __attribute__((nonnull(1, 2, 4))); 00494 00495 bool rfc3095_decomp_attempt_repair(const struct rohc_decomp *const decomp, 00496 const struct rohc_decomp_ctxt *const context, 00497 const struct rohc_ts pkt_arrival_time, 00498 struct rohc_decomp_crc_corr_ctxt *const crc_corr, 00499 struct rohc_extr_bits *const extr_bits) 00500 __attribute__((warn_unused_result, nonnull(1, 2, 4, 5))); 00501 00502 uint32_t rohc_decomp_rfc3095_get_sn(const struct rohc_decomp_ctxt *const context) 00503 __attribute__((warn_unused_result, nonnull(1))); 00504 00505 00506 00507 /* 00508 * Helper functions 00509 */ 00510 00511 00512 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits *const bits) 00513 __attribute__((warn_unused_result, pure, always_inline)); 00514 00515 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits *const bits) 00516 __attribute__((warn_unused_result, pure, always_inline)); 00517 00518 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits *const bits) 00519 __attribute__((warn_unused_result, pure, always_inline)); 00520 00521 00522 /** 00523 * @brief Is the given IP header IPV4 wrt packet? 00524 * 00525 * @param bits The bits extracted from packet 00526 * @return true if IPv4, false if IPv6 00527 */ 00528 static inline bool is_ipv4_pkt(const struct rohc_extr_ip_bits *const bits) 00529 { 00530 return (bits->version == IPV4); 00531 } 00532 00533 00534 /** 00535 * @brief Is the given IP header IPv4 and its IP-ID random wrt packet? 00536 * 00537 * @param bits The bits extracted from packet 00538 * @return true if IPv4 and random, false otherwise 00539 */ 00540 static inline bool is_ipv4_rnd_pkt(const struct rohc_extr_ip_bits *const bits) 00541 { 00542 return (is_ipv4_pkt(bits) && bits->rnd == 1); 00543 } 00544 00545 00546 /** 00547 * @brief Is the given IP header IPv4 and its IP-ID non-random wrt packet? 00548 * 00549 * @param bits The bits extracted from packet 00550 * @return true if IPv4 and non-random, false otherwise 00551 */ 00552 static inline bool is_ipv4_non_rnd_pkt(const struct rohc_extr_ip_bits *const bits) 00553 { 00554 return (is_ipv4_pkt(bits) && bits->rnd == 0); 00555 } 00556 00557 00558 #endif 00559
1.6.1