ROHC compression/decompression library
|
00001 /* 00002 * Copyright 2012,2013,2014 Didier Barvaux 00003 * Copyright 2013 Viveris Technologies 00004 * Copyright 2012 WBX 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 tcp.h 00023 * @brief TCP header description. 00024 * @author FWX <rohc_team@dialine.fr> 00025 * @author Didier Barvaux <didier@barvaux.org> 00026 * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com> 00027 */ 00028 00029 #ifndef ROHC_PROTOCOLS_TCP_H 00030 #define ROHC_PROTOCOLS_TCP_H 00031 00032 #include <stdint.h> 00033 00034 #ifdef __KERNEL__ 00035 # include <endian.h> 00036 #else 00037 # include "config.h" /* for WORDS_BIGENDIAN */ 00038 #endif 00039 00040 00041 /* See RFC4996 page 37-40 */ 00042 00043 #define ROHC_PACKET_TYPE_IR 0xFD 00044 #define ROHC_PACKET_TYPE_IR_DYN 0xF8 00045 00046 /** 00047 * @brief Define the IPv6 option header. 00048 * 00049 */ 00050 00051 typedef struct __attribute__((packed)) ipv6_opt 00052 { 00053 uint8_t next_header; 00054 uint8_t length; 00055 uint8_t value[1]; 00056 } ipv6_opt_t; 00057 00058 /** 00059 * @brief Define the static part of IPv6 option header. 00060 * 00061 */ 00062 00063 typedef struct __attribute__((packed)) ip_opt_static 00064 { 00065 uint8_t next_header; 00066 uint8_t length; 00067 } ip_opt_static_t; 00068 00069 /** 00070 * @brief Define the dynamic part of IPv6 option header. 00071 * 00072 */ 00073 00074 typedef struct __attribute__((packed)) ip_opt_dynamic 00075 { 00076 uint8_t value[1]; 00077 } ip_opt_dynamic_t; 00078 00079 /** 00080 * @brief Define the IPv6 Destination options header 00081 * 00082 */ 00083 00084 typedef struct __attribute__((packed)) ip_dest_opt 00085 { 00086 uint8_t next_header; 00087 uint8_t length; 00088 uint8_t value[1]; 00089 } ip_dest_opt_t; 00090 00091 /** 00092 * @brief Define the static part of IPv6 Destination option header. 00093 * 00094 */ 00095 00096 typedef struct __attribute__((packed)) ip_dest_opt_static 00097 { 00098 uint8_t next_header; 00099 uint8_t length; 00100 } ip_dest_opt_static_t; 00101 00102 /** 00103 * @brief Define the dynamic part of IPv6 Destination option header. 00104 * 00105 */ 00106 00107 typedef struct __attribute__((packed)) ip_dest_opt_dynamic 00108 { 00109 uint8_t value[1]; 00110 } ip_dest_opt_dynamic_t; 00111 00112 /** 00113 * @brief Define the IPv6 Hop-by-Hop option header. 00114 * 00115 */ 00116 00117 typedef struct __attribute__((packed)) ip_hop_opt 00118 { 00119 uint8_t next_header; 00120 uint8_t length; 00121 uint8_t value[1]; 00122 } ip_hop_opt_t; 00123 00124 /** 00125 * @brief Define the static part of IPv6 Hop-by-Hop option header. 00126 * 00127 */ 00128 00129 typedef struct __attribute__((packed)) ip_hop_opt_static 00130 { 00131 uint8_t next_header; 00132 uint8_t length; 00133 } ip_hop_opt_static_t; 00134 00135 /** 00136 * @brief Define the dynamic part of IPv6 Hop-by-Hop option header. 00137 * 00138 */ 00139 00140 typedef struct __attribute__((packed)) ip_hop_opt_dynamic 00141 { 00142 uint8_t value[1]; 00143 } ip_hop_opt_dynamic_t; 00144 00145 /** 00146 * @brief Define the IPv6 Routing option header. 00147 * 00148 */ 00149 00150 typedef struct __attribute__((packed)) ip_rout_opt 00151 { 00152 uint8_t next_header; 00153 uint8_t length; 00154 uint8_t value[1]; 00155 } ip_rout_opt_t; 00156 00157 /** 00158 * @brief Define the static part of IPv6 Routing option header. 00159 * 00160 */ 00161 00162 typedef struct __attribute__((packed)) ip_rout_opt_static 00163 { 00164 uint8_t next_header; 00165 uint8_t length; 00166 uint8_t value[1]; 00167 } ip_rout_opt_static_t; 00168 00169 /** 00170 * @brief Define the IPv6 GRE option header. 00171 * 00172 * See RFC5225 page 55 00173 */ 00174 00175 typedef struct __attribute__((packed)) ip_gre_opt 00176 { 00177 #if WORDS_BIGENDIAN != 1 00178 uint8_t reserved2 : 4; 00179 uint8_t s_flag : 1; 00180 uint8_t k_flag : 1; 00181 uint8_t r_flag : 1; 00182 uint8_t c_flag : 1; 00183 00184 uint8_t version : 3; 00185 uint8_t reserved1 : 5; 00186 #else 00187 uint16_t c_flag : 1; 00188 uint16_t r_flag : 1; 00189 uint16_t k_flag : 1; 00190 uint16_t s_flag : 1; 00191 uint16_t reserved0 : 9; 00192 uint16_t version : 3; 00193 #endif 00194 uint16_t protocol; 00195 uint32_t datas[1]; 00196 } ip_gre_opt_t; 00197 00198 /** 00199 * @brief Define the static part of IPv6 GRE option header. 00200 * 00201 */ 00202 00203 typedef struct __attribute__((packed)) ip_gre_opt_static 00204 { 00205 #if WORDS_BIGENDIAN != 1 00206 uint8_t padding : 4; 00207 uint8_t s_flag : 1; 00208 uint8_t k_flag : 1; 00209 uint8_t c_flag : 1; 00210 uint8_t protocol : 1; 00211 #else 00212 uint8_t protocol : 1; 00213 uint8_t c_flag : 1; 00214 uint8_t k_flag : 1; 00215 uint8_t s_flag : 1; 00216 uint8_t padding : 4; 00217 #endif 00218 uint8_t options[0]; // if k_flag 00219 } ip_gre_opt_static_t; 00220 00221 /** 00222 * @brief Define the IPv6 MIME option header. 00223 * 00224 */ 00225 00226 typedef struct __attribute__((packed)) ip_mime_opt 00227 { 00228 uint8_t next_header; 00229 #if WORDS_BIGENDIAN != 1 00230 uint8_t res_bits : 7; 00231 uint8_t s_bit : 1; 00232 #else 00233 uint8_t s_bit : 1; 00234 uint8_t res_bits : 7; 00235 #endif 00236 uint16_t checksum; 00237 uint32_t orig_dest; 00238 uint32_t orig_src; // if s_bit set 00239 } ip_mime_opt_t; 00240 00241 /** 00242 * @brief Define the static part of IPv6 MIME option header. 00243 * 00244 */ 00245 00246 typedef struct __attribute__((packed)) ip_mime_opt_static 00247 { 00248 uint8_t next_header; 00249 #if WORDS_BIGENDIAN != 1 00250 uint8_t res_bits : 7; 00251 uint8_t s_bit : 1; 00252 #else 00253 uint8_t s_bit : 1; 00254 uint8_t res_bits : 7; 00255 #endif 00256 uint32_t orig_dest; 00257 uint32_t orig_src; // if s_bit set 00258 } ip_mime_opt_static_t; 00259 00260 /** 00261 * @brief Define the IPv6 Authentication option header. 00262 * 00263 */ 00264 00265 typedef struct __attribute__((packed)) ip_ah_opt 00266 { 00267 uint8_t next_header; 00268 uint8_t length; 00269 uint16_t res_bits; 00270 uint32_t spi; 00271 uint32_t sequence_number; 00272 uint32_t auth_data[1]; 00273 } ip_ah_opt_t; 00274 00275 /** 00276 * @brief Define the static part of IPv6 Authentication option header. 00277 * 00278 */ 00279 00280 typedef struct __attribute__((packed)) ip_ah_opt_static 00281 { 00282 uint8_t next_header; 00283 uint8_t length; 00284 uint32_t spi; 00285 } ip_ah_opt_static_t; 00286 00287 /** 00288 * @brief Define the dynamic part of IPv6 Authentication option header. 00289 * 00290 */ 00291 00292 typedef struct __attribute__((packed)) ip_ah_opt_dynamic 00293 { 00294 uint32_t sequence_number; 00295 uint32_t auth_data[0]; 00296 } ip_ah_opt_dynamic_t; 00297 00298 /** 00299 * @brief Define the common IP v4/v6 header. 00300 * 00301 */ 00302 00303 typedef struct __attribute__((packed)) base_header_ip_vx 00304 { 00305 #if WORDS_BIGENDIAN != 1 00306 uint8_t reserved : 4; 00307 uint8_t version : 4; 00308 #else 00309 uint8_t version : 4; 00310 uint8_t reserved : 4; 00311 #endif 00312 } base_header_ip_vx_t; 00313 00314 /** 00315 * @brief Define the IPv4 header. 00316 * 00317 * See RFC4996 page 77 00318 */ 00319 00320 typedef struct __attribute__((packed)) base_header_ip_v4 00321 { 00322 #if WORDS_BIGENDIAN != 1 00323 uint8_t header_length : 4; 00324 uint8_t version : 4; 00325 uint8_t ip_ecn_flags : 2; 00326 uint8_t dscp : 6; 00327 #else 00328 uint8_t version : 4; 00329 uint8_t header_length : 4; 00330 uint8_t dscp : 6; 00331 uint8_t ip_ecn_flags : 2; 00332 #endif 00333 uint16_t length; 00334 uint16_t ip_id; 00335 #if WORDS_BIGENDIAN != 1 00336 uint8_t frag_offset1 : 5; 00337 uint8_t mf : 1; 00338 uint8_t df : 1; 00339 uint8_t rf : 1; 00340 uint8_t frag_offset2; 00341 #else 00342 uint16_t rf : 1; 00343 uint16_t df : 1; 00344 uint16_t mf : 1; 00345 uint16_t frag_offset : 13; 00346 #endif 00347 uint8_t ttl_hopl; 00348 uint8_t protocol; 00349 uint16_t checksum; 00350 uint32_t src_addr; 00351 uint32_t dest_addr; 00352 // extension_headers 00353 } base_header_ip_v4_t; 00354 00355 /** 00356 * @brief Define the IP v6 header. 00357 * 00358 * See RFC4996 page 78 00359 */ 00360 00361 typedef struct __attribute__((packed)) base_header_ip_v6 00362 { 00363 #if WORDS_BIGENDIAN != 1 00364 uint8_t dscp1 : 4; 00365 uint8_t version : 4; 00366 uint8_t flow_label1 : 4; 00367 uint8_t ip_ecn_flags : 2; 00368 uint8_t dscp2 : 2; 00369 #else 00370 uint16_t version : 4; 00371 uint16_t dscp1:4; 00372 uint16_t dscp2:2; 00373 uint16_t ip_ecn_flags : 2; 00374 uint16_t flow_label1 : 4; 00375 #endif 00376 uint16_t flow_label2; 00377 uint16_t payload_length; 00378 uint8_t next_header; 00379 uint8_t ttl_hopl; 00380 uint32_t src_addr[4]; 00381 uint32_t dest_addr[4]; 00382 // extension_headers 00383 } base_header_ip_v6_t; 00384 00385 #define DSCP_V6(ptr) (((ptr)->dscp1 << 2) | (ptr)->dscp2) 00386 #define FLOW_LABEL_V6(ptr) (((ptr->flow_label1) << 16) | ptr->flow_label2) 00387 00388 /** 00389 * @brief Define the IP v4 static part. 00390 * 00391 * See RFC4996 page 62 00392 */ 00393 00394 typedef struct __attribute__((packed)) ipv4_static 00395 { 00396 #if WORDS_BIGENDIAN != 1 00397 uint8_t reserved : 7; 00398 uint8_t version_flag : 1; 00399 #else 00400 uint8_t version_flag : 1; 00401 uint8_t reserved : 7; 00402 #endif 00403 uint8_t protocol; 00404 uint32_t src_addr; 00405 uint32_t dst_addr; 00406 } ipv4_static_t; 00407 00408 00409 /** The different IP-ID behaviors */ 00410 typedef enum 00411 { 00412 IP_ID_BEHAVIOR_SEQ = 0, /**< IP-ID increases */ 00413 IP_ID_BEHAVIOR_SEQ_SWAP = 1, /**< IP-ID increases in little endian */ 00414 IP_ID_BEHAVIOR_RAND = 2, /**< IP-ID is random */ 00415 IP_ID_BEHAVIOR_ZERO = 3, /**< IP-ID is constant zero */ 00416 } tcp_ip_id_behavior_t; 00417 00418 00419 /** 00420 * @brief Define the IP v4 dynamic part without ip_id. 00421 * 00422 * See RFC4996 page 62 00423 */ 00424 00425 typedef struct __attribute__((packed)) ipv4_dynamic1 00426 { 00427 #if WORDS_BIGENDIAN != 1 00428 uint8_t ip_id_behavior : 2; 00429 uint8_t df : 1; 00430 uint8_t reserved : 5; 00431 uint8_t ip_ecn_flags : 2; 00432 uint8_t dscp : 6; 00433 #else 00434 uint8_t reserved : 5; 00435 uint8_t df : 1; 00436 uint8_t ip_id_behavior : 2; 00437 uint8_t dscp : 6; 00438 uint8_t ip_ecn_flags : 2; 00439 #endif 00440 uint8_t ttl_hopl; 00441 } ipv4_dynamic1_t; 00442 00443 /** 00444 * @brief Define the IP v4 dynamic part with ip_id field. 00445 * 00446 * See RFC4996 page 62 00447 */ 00448 00449 typedef struct __attribute__((packed)) ipv4_dynamic2 00450 { 00451 #if WORDS_BIGENDIAN != 1 00452 uint8_t ip_id_behavior : 2; 00453 uint8_t df : 1; 00454 uint8_t reserved : 5; 00455 uint8_t ip_ecn_flags : 2; 00456 uint8_t dscp : 6; 00457 #else 00458 uint8_t reserved : 5; 00459 uint8_t df : 1; 00460 uint8_t ip_id_behavior : 2; 00461 uint8_t dscp : 6; 00462 uint8_t ip_ecn_flags : 2; 00463 #endif 00464 uint8_t ttl_hopl; 00465 uint16_t ip_id; 00466 } ipv4_dynamic2_t; 00467 00468 /** 00469 * @brief Define the IP v4 replicate part. 00470 * 00471 * See RFC4996 page 63 00472 */ 00473 00474 typedef struct __attribute__((packed)) ipv4_replicate 00475 { 00476 #if WORDS_BIGENDIAN != 1 00477 uint8_t df : 1; 00478 uint8_t ttl_flag : 1; 00479 uint8_t ip_id_behavior : 2; 00480 uint8_t reserved : 4; 00481 uint8_t ip_ecn_flags : 2; 00482 uint8_t dscp : 6; 00483 #else 00484 uint8_t reserved : 4; 00485 uint8_t ip_id_behavior : 2; 00486 uint8_t ttl_flag : 1; 00487 uint8_t df : 1; 00488 uint8_t dscp : 6; 00489 uint8_t ip_ecn_flags : 2; 00490 #endif 00491 // uint16_t ip_id; 00492 // uint8_t ttl_hopl; 00493 } ipv4_replicate_t; 00494 00495 /** 00496 * @brief Define the IP v6 static part, null flow_label encoded with 1 bit 00497 * 00498 * See RFC4996 page 58 00499 */ 00500 00501 typedef struct __attribute__((packed)) ipv6_static1 00502 { 00503 #if WORDS_BIGENDIAN != 1 00504 uint8_t reserved2 : 4; 00505 uint8_t flow_label_enc_discriminator : 1; 00506 uint8_t reserved1 : 2; 00507 uint8_t version_flag : 1; 00508 #else 00509 uint8_t version_flag : 1; 00510 uint8_t reserved1 : 2; 00511 uint8_t flow_label_enc_discriminator : 1; 00512 uint8_t reserved2 : 4; 00513 #endif 00514 uint8_t next_header; 00515 uint32_t src_addr[4]; 00516 uint32_t dst_addr[4]; 00517 } ipv6_static1_t; 00518 00519 /** 00520 * @brief Define the IP v6 static part, flow_label encoded with 1+20 bits 00521 * 00522 * See RFC4996 page 59 00523 */ 00524 00525 typedef struct __attribute__((packed)) ipv6_static2 00526 { 00527 #if WORDS_BIGENDIAN != 1 00528 uint8_t flow_label1 : 4; 00529 uint8_t flow_label_enc_discriminator : 1; 00530 uint8_t reserved : 2; 00531 uint8_t version_flag : 1; 00532 #else 00533 uint8_t version_flag : 1; 00534 uint8_t reserved : 2; 00535 uint8_t flow_label_enc_discriminator : 1; 00536 uint8_t flow_label1 : 4; 00537 #endif 00538 uint16_t flow_label2; 00539 uint8_t next_header; 00540 uint32_t src_addr[4]; 00541 uint32_t dst_addr[4]; 00542 } ipv6_static2_t; 00543 00544 /** 00545 * @brief Define the IP v6 dynamic part. 00546 * 00547 * See RFC4996 page 59 00548 */ 00549 00550 typedef struct __attribute__((packed)) ipv6_dynamic 00551 { 00552 #if WORDS_BIGENDIAN != 1 00553 uint8_t ip_ecn_flags : 2; 00554 uint8_t dscp : 6; 00555 #else 00556 uint8_t dscp : 6; 00557 uint8_t ip_ecn_flags : 2; 00558 #endif 00559 uint8_t ttl_hopl; 00560 } ipv6_dynamic_t; 00561 00562 /** 00563 * @brief Define the IP v6 replicate part, flow_label encoded with 5 bits 00564 * 00565 * See RFC4996 page 59 00566 */ 00567 00568 typedef struct __attribute__((packed)) ipv6_replicate1 00569 { 00570 #if WORDS_BIGENDIAN != 1 00571 uint8_t ip_ecn_flags : 2; 00572 uint8_t dscp : 6; 00573 uint8_t flow_label : 5; 00574 uint8_t reserved : 3; 00575 #else 00576 uint8_t dscp : 6; 00577 uint8_t ip_ecn_flags : 2; 00578 uint8_t reserved : 3; 00579 uint8_t flow_label : 5; 00580 #endif 00581 } ipv6_replicate1_t; 00582 00583 /** 00584 * @brief Define the IP v6 replicate part, flow_label encoded with 21 bits 00585 * 00586 * See RFC4996 page 59 00587 */ 00588 00589 typedef struct __attribute__((packed)) ipv6_replicate2 00590 { 00591 #if WORDS_BIGENDIAN != 1 00592 uint8_t ip_ecn_flags : 2; 00593 uint8_t dscp : 6; 00594 uint8_t flow_label1 : 5; 00595 uint8_t reserved : 3; 00596 #else 00597 uint8_t dscp : 6; 00598 uint8_t ip_ecn_flags : 2; 00599 uint8_t reserved : 3; 00600 uint8_t flow_label1 : 5; 00601 #endif 00602 uint16_t flow_label2; 00603 } ipv6_replicate2_t; 00604 00605 /** 00606 * @brief Define the IP v6 extension 00607 * 00608 */ 00609 00610 /* The high-order 3 bits of the option type define the behavior 00611 * when processing an unknown option and whether or not the option 00612 * content changes in flight. 00613 */ 00614 00615 typedef struct __attribute__((packed)) ipv6_extension 00616 { 00617 uint8_t next_header; 00618 uint8_t extension_length; 00619 uint8_t datas[1]; 00620 } ipv6_extension_t; 00621 00622 /** 00623 * @brief Define the Selective Acknowlegment TCP option 00624 * 00625 * See RFC2018 for TCP Selective Acknowledgement Options 00626 * See RFC4996 page 66 00627 */ 00628 00629 typedef struct __attribute__((packed)) 00630 { 00631 uint32_t block_start; 00632 uint32_t block_end; 00633 } sack_block_t; 00634 00635 /** 00636 * @brief Define the TCP header 00637 * 00638 * See RFC4996 page 72/73 00639 */ 00640 00641 typedef struct __attribute__((packed)) tcphdr 00642 { 00643 uint16_t src_port; 00644 uint16_t dst_port; 00645 uint32_t seq_num; 00646 uint32_t ack_num; 00647 #if WORDS_BIGENDIAN != 1 00648 uint8_t res_flags : 4; 00649 uint8_t data_offset : 4; 00650 uint8_t rsf_flags : 3; 00651 uint8_t psh_flag : 1; 00652 uint8_t ack_flag : 1; 00653 uint8_t urg_flag : 1; 00654 uint8_t ecn_flags : 2; 00655 #else 00656 uint8_t data_offset : 4; 00657 uint8_t res_flags : 4; 00658 uint8_t ecn_flags : 2; 00659 uint8_t urg_flag : 1; 00660 uint8_t ack_flag : 1; 00661 uint8_t psh_flag : 1; 00662 uint8_t rsf_flags : 3; 00663 #endif 00664 uint16_t window; 00665 uint16_t checksum; 00666 uint16_t urg_ptr; 00667 uint8_t options[0]; /**< The beginning of the TCP options */ 00668 } tcphdr_t; 00669 00670 00671 /** The largest index that may be used to identify one TCP option */ 00672 #define MAX_TCP_OPTION_INDEX 15U 00673 00674 /** 00675 * @brief The maximum of TCP options 00676 * 00677 * One TCP header may contain up to 40 bytes of options, so it may contain 00678 * up 40 1-byte options, so the ROHC (de)compressors should expect such TCP 00679 * packets. However the m field in the compressed list of TCP options (see 00680 * RFC 6846, section 6.3.3 for more details) cannot be larger than 15, so 00681 * restrict the number of TCP options that value. One TCP packet with more 00682 * than 15 TCP options will be compressed with the IP-only profile. 00683 * */ 00684 #define ROHC_TCP_OPTS_MAX 15U 00685 00686 00687 /** The Timestamp option of the TCP header */ 00688 struct tcp_option_timestamp 00689 { 00690 uint32_t ts; /**< The timestamp value */ 00691 uint32_t ts_reply; /**< The timestamp echo reply value */ 00692 } __attribute__((packed)); 00693 00694 00695 /** 00696 * @brief Define the RSF flags 00697 * 00698 */ 00699 00700 #define RSF_RST_ONLY 0x04 00701 #define RSF_SYN_ONLY 0x02 00702 #define RSF_FIN_ONLY 0x01 00703 #define RSF_NONE 0x00 00704 00705 /** 00706 * @brief Define the TCP static part. 00707 * 00708 * See RFC4996 page 73/74 00709 */ 00710 00711 typedef struct __attribute__((packed)) tcp_static 00712 { 00713 uint16_t src_port; // =:= irregular(16) [ 16 ]; 00714 uint16_t dst_port; // =:= irregular(16) [ 16 ]; 00715 } tcp_static_t; 00716 00717 /** 00718 * @brief Define the TCP dynamic part. 00719 * 00720 * See RFC4996 page 73/74 00721 */ 00722 00723 typedef struct __attribute__((packed)) tcp_dynamic 00724 { 00725 #if WORDS_BIGENDIAN != 1 00726 uint8_t tcp_res_flags : 4; // =:= irregular(4) [ 4 ]; 00727 uint8_t urp_zero : 1; // =:= irregular(1) [ 1 ]; 00728 uint8_t ack_zero : 1; // =:= irregular(1) [ 1 ]; 00729 uint8_t ack_stride_flag : 1; // =:= irregular(1) [ 1 ]; 00730 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00731 00732 uint8_t rsf_flags : 3; // =:= irregular(3) [ 3 ]; 00733 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00734 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00735 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00736 uint8_t tcp_ecn_flags : 2; // =:= irregular(2) [ 2 ]; 00737 00738 #else 00739 00740 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00741 uint8_t ack_stride_flag : 1; // =:= irregular(1) [ 1 ]; 00742 uint8_t ack_zero : 1; // =:= irregular(1) [ 1 ]; 00743 uint8_t urp_zero : 1; // =:= irregular(1) [ 1 ]; 00744 uint8_t tcp_res_flags : 4; // =:= irregular(4) [ 4 ]; 00745 00746 uint8_t tcp_ecn_flags : 2; // =:= irregular(2) [ 2 ]; 00747 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00748 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00749 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00750 uint8_t rsf_flags : 3; // =:= irregular(3) [ 3 ]; 00751 00752 #endif 00753 00754 uint16_t msn; // =:= irregular(16) [ 16 ]; 00755 uint32_t seq_num; // =:= irregular(32) [ 32 ]; 00756 // uint32_t ack_num; // =:= zero_or_irreg(ack_zero.CVALUE, 32) [ 0, 32 ]; 00757 // uint16_t window; // =:= irregular(16) [ 16 ]; 00758 // uint16_t checksum; // =:= irregular(16) [ 16 ]; 00759 // uint16_t urg_ptr; // =:= zero_or_irreg(urp_zero.CVALUE, 16) [ 0, 16 ]; 00760 // uint16_t ack_stride; // =:= static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ]; 00761 // options // =:= list_tcp_options [ VARIABLE ]; 00762 } tcp_dynamic_t; 00763 00764 /** 00765 * @brief Define the TCP replicate part. 00766 * 00767 * See RFC4996 page 74/75 00768 */ 00769 00770 typedef struct __attribute__((packed)) tcp_replicate 00771 { 00772 #if WORDS_BIGENDIAN != 1 00773 00774 uint8_t dst_port_presence : 2; // =:= irregular(2) [ 2 ]; 00775 uint8_t src_port_presence : 2; // =:= irregular(2) [ 2 ]; 00776 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 00777 uint8_t window_presence : 1; // =:= irregular(1) [ 1 ]; 00778 uint8_t reserved : 1; // =:= irregular(1) [ 1 ]; 00779 00780 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00781 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 00782 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00783 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00784 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00785 uint8_t urp_presence : 1; // =:= irregular(1) [ 1 ]; 00786 uint8_t ack_presence : 1; // =:= irregular(1) [ 1 ]; 00787 uint8_t ack_stride_flag : 1; // =:= irregular(1) [ 1 ]; 00788 00789 #else 00790 00791 uint8_t reserved : 1; // =:= irregular(1) [ 1 ]; 00792 uint8_t window_presence : 1; // =:= irregular(1) [ 1 ]; 00793 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 00794 uint8_t src_port_presence : 2; // =:= irregular(2) [ 2 ]; 00795 uint8_t dst_port_presence : 2; // =:= irregular(2) [ 2 ]; 00796 00797 uint8_t ack_stride_flag : 1; // =:= irregular(1) [ 1 ]; 00798 uint8_t ack_presence : 1; // =:= irregular(1) [ 1 ]; 00799 uint8_t urp_presence : 1; // =:= irregular(1) [ 1 ]; 00800 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00801 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00802 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00803 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 00804 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00805 00806 #endif 00807 00808 uint16_t msn; // =:= irregular(16) [ 16 ]; 00809 uint32_t seq_num; // =:= irregular(32) [ 32 ]; 00810 // uint16_t src_port; // =:= port_replicate(src_port_presence) [ 0, 8, 16 ]; 00811 // uint16_t dst_port; // =:= port_replicate(dst_port_presence) [ 0, 8, 16 ]; 00812 // uint16_t window; // =:= static_or_irreg(window_presence, 16) [ 0, 16 ]; 00813 // uint16_t urg_point; // =:= static_or_irreg(urp_presence, 16) [ 0, 16 ]; 00814 // uint32_t ack_num; // =:= static_or_irreg(ack_presence, 32) [ 0, 32 ]; 00815 // uint8_t ecn_padding:2; // =:= optional_2bit_padding(ecn_used.CVALUE) [ 0, 2 ]; 00816 // uint8_t tcp_res_flags:4; // =:= static_or_irreg(ecn_used.CVALUE, 4) [ 0, 4 ]; 00817 // uint8_t tcp_ecn_flags:2; // =:= static_or_irreg(ecn_used.CVALUE, 2) [ 0, 2 ]; 00818 // uint16_t checksum; // =:= irregular(16) [ 16 ]; 00819 // uint16_t ack_stride; // =:= static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ]; 00820 // options // =:= tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]; 00821 00822 } tcp_replicate_t; 00823 00824 /** 00825 * @brief Define the TCP options. 00826 * 00827 */ 00828 00829 #define TCP_OPT_EOL 0 00830 #define TCP_OPT_NOP 1 00831 #define TCP_OPT_MAXSEG 2 00832 #define TCP_OLEN_MAXSEG 4 00833 #define TCP_OPT_WINDOW 3 00834 #define TCP_OLEN_WINDOW 3 00835 #define TCP_OPT_SACK_PERMITTED 4 /* Experimental */ 00836 #define TCP_OLEN_SACK_PERMITTED 2 00837 #define TCP_OPT_SACK 5 /* Experimental */ 00838 #define TCP_OPT_TIMESTAMP 8 00839 #define TCP_OLEN_TIMESTAMP 10 00840 #define TCP_OLEN_TSTAMP_APPA (TCP_OLEN_TIMESTAMP + 2) /* appendix A */ 00841 00842 #define TCP_OPT_TSTAMP_HDR \ 00843 (TCP_OPT_NOP << 24 | TCP_OPT_NOP << 16 | TCP_OPT_TIMESTAMP << 8 | TCP_OLEN_TIMESTAMP) 00844 00845 #define TCP_INDEX_NOP 0 00846 #define TCP_INDEX_EOL 1 00847 #define TCP_INDEX_MAXSEG 2 00848 #define TCP_INDEX_WINDOW 3 00849 #define TCP_INDEX_TIMESTAMP 4 00850 #define TCP_INDEX_SACK_PERMITTED 5 00851 #define TCP_INDEX_SACK 6 00852 00853 /** 00854 * @brief Define the Common compressed packet format 00855 * 00856 * See RFC4996 page 80/81 00857 */ 00858 00859 typedef struct __attribute__((packed)) co_common 00860 { 00861 #if WORDS_BIGENDIAN != 1 00862 00863 uint8_t ttl_hopl_outer_flag : 1; // =:= compressed_value(1, ttl_irregular_chain_flag) [ 1 ]; 00864 uint8_t discriminator : 7; // =:= '1111101' 00865 00866 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00867 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 00868 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00869 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00870 00871 uint8_t urg_ptr_present : 1; // =:= irregular(1) [ 1 ]; 00872 uint8_t ip_id_indicator : 1; // =:= irregular(1) [ 1 ]; 00873 uint8_t window_indicator : 1; // =:= irregular(1) [ 1 ]; 00874 uint8_t ack_stride_indicator : 1; // =:= irregular(1) [ 1 ]; 00875 uint8_t ack_indicator : 2; // =:= irregular(2) [ 2 ]; 00876 uint8_t seq_indicator : 2; // =:= irregular(2) [ 2Â ]; 00877 00878 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00879 uint8_t ip_id_behavior : 2; // =:= ip_id_behavior_choice(true) [ 2 ]; 00880 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 00881 uint8_t ttl_hopl_present : 1; // =:= irregular(1) [ 1 ]; 00882 uint8_t dscp_present : 1; // =:= irregular(1) [ 1 ]; 00883 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00884 uint8_t reserved : 1; // =:= compressed_value(1, 0) [ 1 ]; 00885 00886 uint8_t header_crc : 7; // =:= crc7(THIS.UVALUE,THIS.ULENGTH) [ 7 ]; 00887 uint8_t df : 1; // =:= dont_fragment(version.UVALUE) [ 1 ]; 00888 00889 #else 00890 00891 uint8_t discriminator : 7; // =:= '1111101' 00892 uint8_t ttl_hopl_outer_flag : 1; // =:= compressed_value(1, ttl_irregular_chain_flag) [ 1 ]; 00893 00894 uint8_t ack_flag : 1; // =:= irregular(1) [ 1 ]; 00895 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00896 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 00897 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00898 00899 uint8_t seq_indicator : 2; // =:= irregular(2) [ 2Â ]; 00900 uint8_t ack_indicator : 2; // =:= irregular(2) [ 2 ]; 00901 uint8_t ack_stride_indicator : 1; // =:= irregular(1) [ 1 ]; 00902 uint8_t window_indicator : 1; // =:= irregular(1) [ 1 ]; 00903 uint8_t ip_id_indicator : 1; // =:= irregular(1) [ 1 ]; 00904 uint8_t urg_ptr_present : 1; // =:= irregular(1) [ 1 ]; 00905 00906 uint8_t reserved : 1; // =:= compressed_value(1, 0) [ 1 ]; 00907 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 00908 uint8_t dscp_present : 1; // =:= irregular(1) [ 1 ]; 00909 uint8_t ttl_hopl_present : 1; // =:= irregular(1) [ 1 ]; 00910 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 00911 uint8_t ip_id_behavior : 2; // =:= ip_id_behavior_choice(true) [ 2 ]; 00912 uint8_t urg_flag : 1; // =:= irregular(1) [ 1 ]; 00913 00914 uint8_t df : 1; // =:= dont_fragment(version.UVALUE) [ 1 ]; 00915 uint8_t header_crc : 7; // =:= crc7(THIS.UVALUE,THIS.ULENGTH) [ 7 ]; 00916 00917 #endif 00918 00919 // u_intXX_t seq_num:X; // =:= variable_length_32_enc(seq_indicator.CVALUE) [ 0, 8, 16, 32 ]; 00920 // u_intXX_t ack_num:X; // =:= variable_length_32_enc(ack_indicator.CVALUE) [ 0, 8, 16, 32 ]; 00921 // u_intXX_t ack_stride:X; // =:= static_or_irreg(ack_stride_indicator.CVALUE, 16) [ 0, 16 ]; 00922 // u_intXX_t window:X; // =:= static_or_irreg(window_indicator.CVALUE, 16) [ 0, 16 ]; 00923 // u_intXX_t ip_id:X; // =:= optional_ip_id_lsb(ip_id_behavior.UVALUE,ip_id_indicator.CVALUE) [ 0, 8, 16 ]; 00924 // u_intXX_t urg_ptr:X; // =:= static_or_irreg(urg_ptr_present.CVALUE, 16) [ 0, 16 ]; 00925 // u_intXX_t dscp:X; // =:= dscp_enc-dscp_present.CVALUE) [ 0, 8 ]; 00926 // u_intXX_t ttl_hopl:X; // =:= static_or_irreg(ttl_hopl_present.CVALUE, 8) [ 0, 8 ]; 00927 // options // =:= tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]; 00928 00929 } co_common_t; 00930 00931 00932 /** 00933 * @brief Define the rnd_1 compressed packet format 00934 * 00935 * Send LSBs of sequence number 00936 * See RFC4996 page 81 00937 */ 00938 typedef struct __attribute__((packed)) rnd_1 00939 { 00940 #if WORDS_BIGENDIAN != 1 00941 uint8_t seq_num1:2; // =:= lsb(18, 65535) [ 18 ]; 00942 uint8_t discriminator : 6; // =:= '101110' [ 6 ]; 00943 uint16_t seq_num2; // =:= lsb(18, 65535) [ 18 ]; 00944 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 00945 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00946 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00947 #else 00948 uint8_t discriminator : 6; // =:= '101110' [ 6 ]; 00949 uint8_t seq_num1:2; // =:= lsb(18, 65535) [ 18 ]; 00950 uint16_t seq_num2; // =:= lsb(18, 65535) [ 18 ]; 00951 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00952 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00953 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 00954 #endif 00955 } rnd_1_t; 00956 00957 00958 /** 00959 * @brief Define the rnd_2 compressed packet format 00960 * 00961 * Send scaled sequence number LSBs 00962 * See RFC4996 page 81 00963 */ 00964 typedef struct __attribute__((packed)) rnd_2 00965 { 00966 #if WORDS_BIGENDIAN != 1 00967 uint8_t seq_num_scaled:4; // =:= lsb(4, 7) [ 4 ]; 00968 uint8_t discriminator : 4; // =:= '1100' [ 4 ]; 00969 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 00970 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00971 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00972 #else 00973 uint8_t discriminator : 4; // =:= '1100' [ 4 ]; 00974 uint8_t seq_num_scaled:4; // =:= lsb(4, 7) [ 4 ]; 00975 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00976 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00977 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 00978 #endif 00979 } rnd_2_t; 00980 00981 00982 /** 00983 * @brief Define the rnd_3 compressed packet format 00984 * 00985 * Send acknowlegment number LSBs 00986 * See RFC4996 page 81 00987 */ 00988 typedef struct __attribute__((packed)) rnd_3 00989 { 00990 #if WORDS_BIGENDIAN != 1 00991 uint8_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 00992 uint8_t discriminator : 1; // =:= '0' [ 4 ]; 00993 uint8_t ack_num2:8; // =:= lsb(15, 8191) [ 15 ]; 00994 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 00995 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 00996 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 00997 #else 00998 uint16_t discriminator : 1; // =:= '0' [ 4 ]; 00999 uint8_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 01000 uint8_t ack_num2; // =:= lsb(15, 8191) [ 15 ]; 01001 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01002 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01003 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01004 #endif 01005 } rnd_3_t; 01006 01007 01008 /** 01009 * @brief Define the rnd_4 compressed packet format 01010 * 01011 * Send acknowlegment number scaled 01012 * See RFC4996 page 81 01013 */ 01014 typedef struct __attribute__((packed)) rnd_4 01015 { 01016 #if WORDS_BIGENDIAN != 1 01017 uint8_t ack_num_scaled:4; // =:= lsb(4, 3) [ 4 ]; 01018 uint8_t discriminator : 4; // =:= '1101' [ 4 ]; 01019 01020 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01021 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01022 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01023 #else 01024 uint8_t discriminator : 4; // =:= '1101' [ 4 ]; 01025 uint8_t ack_num_scaled:4; // =:= lsb(4, 3) [ 4 ]; 01026 01027 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01028 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01029 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01030 #endif 01031 } rnd_4_t; 01032 01033 01034 /** 01035 * @brief Define the rnd_5 compressed packet format 01036 * 01037 * Send ACK and sequence number 01038 * See RFC4996 page 82 01039 */ 01040 typedef struct __attribute__((packed)) rnd_5 01041 { 01042 #if WORDS_BIGENDIAN != 1 01043 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01044 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01045 uint8_t discriminator : 3; // =:= '100' [ 3 ]; 01046 01047 uint8_t seq_num1:5; // =:= lsb(15, 8191) [ 15 ]; 01048 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01049 uint8_t seq_num2; // =:= lsb(15, 8191) [ 15 ]; 01050 uint8_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 01051 uint8_t seq_num3:1; // =:= lsb(15, 8191) [ 15 ]; 01052 uint8_t ack_num2; // =:= lsb(15, 8191) [ 15 ]; 01053 #else 01054 uint8_t discriminator : 3; // =:= '100' [ 3 ]; 01055 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01056 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01057 01058 uint32_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01059 uint32_t seq_num1:5; // =:= lsb(14, 8191) [ 14 ]; 01060 uint32_t seq_num2:8; // =:= lsb(14, 8191) [ 14 ]; 01061 uint32_t seq_num3:1; // =:= lsb(14, 8191) [ 14 ]; 01062 uint32_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 01063 uint32_t ack_num2:8; // =:= lsb(15, 8191) [ 15 ]; 01064 #endif 01065 } rnd_5_t; 01066 01067 01068 /** 01069 * @brief Define the rnd_6 compressed packet format 01070 * 01071 * Send both ACK and scaled sequence number LSBs 01072 * See RFC4996 page 82 01073 */ 01074 typedef struct __attribute__((packed)) rnd_6 01075 { 01076 #if WORDS_BIGENDIAN != 1 01077 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01078 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01079 uint8_t discriminator : 4; // =:= '1010' [ 4 ]; 01080 #else 01081 uint8_t discriminator : 4; // =:= '1010' [ 4 ]; 01082 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01083 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01084 #endif 01085 uint16_t ack_num; // =:= lsb(16, 16383) [ 16 ]; 01086 #if WORDS_BIGENDIAN != 1 01087 uint8_t seq_num_scaled:4; // =:= lsb(4, 7) [ 4 ]; 01088 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01089 #else 01090 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01091 uint8_t seq_num_scaled:4; // =:= lsb(4, 7) [ 4 ]; 01092 #endif 01093 } rnd_6_t; 01094 01095 01096 /** 01097 * @brief Define the rnd_7 compressed packet format 01098 * 01099 * Send ACK and window 01100 * See RFC4996 page 82 01101 */ 01102 typedef struct __attribute__((packed)) rnd_7 01103 { 01104 #if WORDS_BIGENDIAN != 1 01105 uint8_t ack_num1:2; // =:= lsb(18, 65535) [ 18 ]; 01106 uint8_t discriminator : 6; // =:= '101111' [ 6 ]; 01107 uint16_t ack_num2; // =:= lsb(18, 65535) [ 18 ]; 01108 #else 01109 uint8_t discriminator : 6; // =:= '101111' [ 6 ]; 01110 uint8_t ack_num1:2; // =:= lsb(18, 65535) [ 18 ]; 01111 uint16_t ack_num2; // =:= lsb(18, 65535) [ 18 ]; 01112 #endif 01113 uint16_t window; // =:= irregular(16) [ 16 ]; 01114 #if WORDS_BIGENDIAN != 1 01115 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01116 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01117 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01118 #else 01119 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01120 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01121 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01122 #endif 01123 } rnd_7_t; 01124 01125 01126 /** 01127 * @brief Define the rnd_8 compressed packet format 01128 * 01129 * Can send LSBs of TTL, RSF flags, change ECN behavior and options list 01130 * See RFC4996 page 82 01131 */ 01132 typedef struct __attribute__((packed)) rnd_8 01133 { 01134 #if WORDS_BIGENDIAN != 1 01135 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 01136 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 01137 uint8_t discriminator : 5; // =:= '10110' [ 5 ]; 01138 uint8_t msn1 : 1; // =:= lsb(4, 4) [ 4 ]; 01139 uint8_t header_crc : 7; // =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; 01140 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 01141 uint8_t ttl_hopl : 3; // =:= lsb(3, 3) [ 3 ]; 01142 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01143 uint8_t msn2 : 3; // =:= lsb(4, 4) [ 4 ]; 01144 #else 01145 uint8_t discriminator : 5; // =:= '10110' [ 5 ]; 01146 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 01147 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 01148 uint16_t header_crc : 7; // =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; 01149 uint16_t msn1 : 1; // =:= lsb(4, 4) [ 4 ]; 01150 uint16_t msn2 : 3; // =:= lsb(4, 4) [ 4 ]; 01151 uint16_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01152 uint16_t ttl_hopl : 3; // =:= lsb(3, 3) [ 3 ]; 01153 uint16_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 01154 #endif 01155 uint16_t seq_num; // =:= lsb(16, 65535) [ 16 ]; 01156 uint16_t ack_num; // =:= lsb(16, 16383) [ 16 ]; 01157 uint8_t options[0]; // =:= tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]; 01158 } rnd_8_t; 01159 01160 01161 /** 01162 * @brief Define the seq_1 compressed packet format 01163 * 01164 * Send LSBs of sequence number 01165 * See RFC4996 page 83 01166 */ 01167 typedef struct __attribute__((packed)) seq_1 01168 { 01169 #if WORDS_BIGENDIAN != 1 01170 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01171 uint8_t discriminator : 4; // =:= '1010' [ 4 ]; 01172 #else 01173 uint8_t discriminator : 4; // =:= '1010' [ 4 ]; 01174 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01175 #endif 01176 uint16_t seq_num; // =:= lsb(16, 32767) [ 16 ]; 01177 #if WORDS_BIGENDIAN != 1 01178 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01179 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01180 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01181 #else 01182 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01183 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01184 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01185 #endif 01186 } seq_1_t; 01187 01188 01189 /** 01190 * @brief Define the seq_2 compressed packet format 01191 * 01192 * Send scaled sequence number LSBs 01193 * See RFC4996 page 83 01194 */ 01195 typedef struct __attribute__((packed)) seq_2 01196 { 01197 #if WORDS_BIGENDIAN != 1 01198 uint8_t ip_id1 : 3; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 3 ]; 01199 uint8_t discriminator : 5; // =:= '11010' [ 5 ]; 01200 uint8_t seq_num_scaled:4; // =:= lsb(4, 7) [ 4 ]; 01201 uint8_t ip_id2 : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 4 ]; 01202 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01203 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01204 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01205 #else 01206 uint16_t discriminator : 5; // =:= '11010' [ 5 ]; 01207 uint16_t ip_id1 : 3; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ]; 01208 uint16_t ip_id2 : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ]; 01209 uint16_t seq_num_scaled : 4; // =:= lsb(4, 7) [ 4 ]; 01210 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01211 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01212 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01213 #endif 01214 } seq_2_t; 01215 01216 01217 /** 01218 * @brief Define the seq_3 compressed packet format 01219 * 01220 * Send acknowledgment number LSBs 01221 * See RFC4996 page 83 01222 */ 01223 typedef struct __attribute__((packed)) seq_3 01224 { 01225 #if WORDS_BIGENDIAN != 1 01226 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01227 uint8_t discriminator : 4; // =:= '1001' [ 4 ]; 01228 #else 01229 uint8_t discriminator : 4; // =:= '1001' [ 4 ]; 01230 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01231 #endif 01232 uint16_t ack_num; // =:= lsb(16, 16383) [ 16 ]; 01233 #if WORDS_BIGENDIAN != 1 01234 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01235 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01236 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01237 #else 01238 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01239 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01240 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01241 #endif 01242 } seq_3_t; 01243 01244 01245 /** 01246 * @brief Define the seq_4 compressed packet format 01247 * 01248 * Send scaled acknowledgment number scaled 01249 * See RFC4996 page 84 01250 */ 01251 typedef struct __attribute__((packed)) seq_4 01252 { 01253 #if WORDS_BIGENDIAN != 1 01254 uint8_t ip_id : 3; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 3, 1) [ 3 ]; 01255 uint8_t ack_num_scaled:4; // =:= lsb(4, 3) [ 4 ]; 01256 uint8_t discriminator : 1; // =:= '0' [ 1 ]; 01257 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01258 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01259 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01260 #else 01261 uint8_t discriminator : 1; // =:= '0' [ 1 ]; 01262 uint8_t ack_num_scaled:4; // =:= lsb(4, 3) [ 4 ]; 01263 uint8_t ip_id : 3; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 3, 1) [ 3 ]; 01264 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01265 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01266 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01267 #endif 01268 } seq_4_t; 01269 01270 01271 /** 01272 * @brief Define the seq_5 compressed packet format 01273 * 01274 * Send ACK and sequence number 01275 * See RFC4996 page 84 01276 */ 01277 typedef struct __attribute__((packed)) seq_5 01278 { 01279 #if WORDS_BIGENDIAN != 1 01280 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01281 uint8_t discriminator : 4; // =:= '1000' [ 4 ]; 01282 #else 01283 uint8_t discriminator : 4; // =:= '1000' [ 4 ]; 01284 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01285 #endif 01286 uint16_t ack_num; // =:= lsb(16, 16383) [ 16 ]; 01287 uint16_t seq_num; // =:= lsb(16, 32767) [ 16 ]; 01288 #if WORDS_BIGENDIAN != 1 01289 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01290 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01291 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01292 #else 01293 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01294 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01295 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01296 #endif 01297 } seq_5_t; 01298 01299 01300 /** 01301 * @brief Define the seq_6 compressed packet format 01302 * 01303 * Send both ACK and scaled sequence number LSBs 01304 * See RFC4996 page 84 01305 */ 01306 typedef struct __attribute__((packed)) seq_6 01307 { 01308 #if WORDS_BIGENDIAN != 1 01309 uint8_t seq_num_scaled1:3; // =:= lsb(4, 7) [ 3 ]; 01310 uint8_t discriminator : 5; // =:= '11011' [ 5 ]; 01311 uint8_t ip_id : 7; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ]; 01312 uint8_t seq_num_scaled2:1; // =:= lsb(4, 7) [ 1 ]; 01313 #else 01314 uint16_t discriminator : 5; // =:= '11011' [ 5 ]; 01315 uint16_t seq_num_scaled1:3; // =:= lsb(4, 7) [ 4 ]; 01316 uint16_t seq_num_scaled2:1; // =:= lsb(4, 7) [ 4 ]; 01317 uint16_t ip_id : 7; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ]; 01318 #endif 01319 uint16_t ack_num; // =:= lsb(16, 16383) [ 16 ]; 01320 #if WORDS_BIGENDIAN != 1 01321 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01322 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01323 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01324 #else 01325 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01326 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01327 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01328 #endif 01329 } seq_6_t; 01330 01331 01332 /** 01333 * @brief Define the seq_7 compressed packet format 01334 * 01335 * Send ACK and window 01336 * See RFC4996 page 85 01337 */ 01338 typedef struct __attribute__((packed)) seq_7 01339 { 01340 #if WORDS_BIGENDIAN != 1 01341 uint8_t window1 : 4; // =:= lsb(15, 16383) [ 15 ]; 01342 uint8_t discriminator : 4; // =:= '1100' [ 4 ]; 01343 01344 uint8_t window2; 01345 01346 uint8_t ip_id : 5; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ]; 01347 uint8_t window3 : 3; 01348 01349 uint16_t ack_num; // =:= lsb(16, 32767) [ 16 ]; 01350 01351 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01352 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01353 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01354 #else 01355 uint8_t discriminator : 4; // =:= '1100' [ 4 ]; 01356 uint8_t window1 : 4; // =:= lsb(15, 16383) [ 15 ]; 01357 01358 uint8_t window2; 01359 01360 uint8_t window3 : 3; 01361 uint8_t ip_id : 5; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ]; 01362 01363 uint16_t ack_num; // =:= lsb(16, 32767) [ 16 ]; 01364 01365 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01366 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01367 uint8_t header_crc : 3; // =:= crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ]; 01368 #endif 01369 } seq_7_t; 01370 01371 01372 /** 01373 * @brief Define the seq_8 compressed packet format 01374 * 01375 * Can send LSBs of TTL, RSF flags, change ECN behavior, and options list 01376 * See RFC4996 page 85 01377 */ 01378 typedef struct __attribute__((packed)) seq_8 01379 { 01380 #if WORDS_BIGENDIAN != 1 01381 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01382 uint8_t discriminator : 4; // =:= '1011' [ 4 ]; 01383 uint8_t header_crc : 7; // =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; 01384 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 01385 uint8_t ttl_hopl : 3; // =:= lsb(3, 3) [ 3 ]; 01386 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01387 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01388 uint8_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 01389 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 01390 uint8_t ack_num2; // =:= lsb(15, 8191) [ 15 ]; 01391 uint8_t seq_num1:6; // =:= lsb(14, 8191) [ 14 ]; 01392 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 01393 uint8_t seq_num2:8; // =:= lsb(14, 8191) [ 14 ]; 01394 #else 01395 uint8_t discriminator : 4; // =:= '1011' [ 4 ]; 01396 uint8_t ip_id : 4; // =:= ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ]; 01397 uint8_t list_present : 1; // =:= irregular(1) [ 1 ]; 01398 uint8_t header_crc : 7; // =:= crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ]; 01399 uint8_t msn : 4; // =:= lsb(4, 4) [ 4 ]; 01400 uint8_t psh_flag : 1; // =:= irregular(1) [ 1 ]; 01401 uint8_t ttl_hopl : 3; // =:= lsb(3, 3) [ 3 ]; 01402 uint8_t ecn_used : 1; // =:= one_bit_choice [ 1 ]; 01403 uint8_t ack_num1:7; // =:= lsb(15, 8191) [ 15 ]; 01404 uint8_t ack_num2; // =:= lsb(15, 8191) [ 15 ]; 01405 uint8_t rsf_flags : 2; // =:= rsf_index_enc [ 2 ]; 01406 uint8_t seq_num1 : 6; // =:= lsb(14, 8191) [ 14 ]; 01407 uint8_t seq_num2; // =:= lsb(14, 8191) [ 14 ]; 01408 #endif 01409 uint8_t options[0]; // =:= tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]; 01410 } seq_8_t; 01411 01412 01413 /** 01414 * @brief Define union of different header pointers 01415 */ 01416 typedef union 01417 { 01418 unsigned int uint; 01419 uint8_t *uint8; 01420 uint16_t *uint16; 01421 base_header_ip_vx_t *ipvx; 01422 base_header_ip_v4_t *ipv4; 01423 base_header_ip_v6_t *ipv6; 01424 ipv6_opt_t *ipv6_opt; 01425 ip_dest_opt_t *ip_dest_opt; 01426 ip_hop_opt_t *ip_hop_opt; 01427 ip_rout_opt_t *ip_rout_opt; 01428 ip_gre_opt_t *ip_gre_opt; 01429 ip_mime_opt_t *ip_mime_opt; 01430 ip_ah_opt_t *ip_ah_opt; 01431 tcphdr_t *tcphdr; 01432 } base_header_ip_t; 01433 01434 01435 #endif /* ROHC_PROTOCOLS_TCP_H */ 01436