ROHC compression/decompression library
tcp.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012,2013,2014 Didier Barvaux
3  * Copyright 2013 Viveris Technologies
4  * Copyright 2012 WBX
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file tcp.h
23  * @brief TCP header description.
24  * @author FWX <rohc_team@dialine.fr>
25  * @author Didier Barvaux <didier@barvaux.org>
26  * @author Didier Barvaux <didier.barvaux@toulouse.viveris.com>
27  */
28 
29 #ifndef ROHC_PROTOCOLS_TCP_H
30 #define ROHC_PROTOCOLS_TCP_H
31 
32 #include <stdint.h>
33 #include <assert.h>
34 
35 #ifdef __KERNEL__
36 # include <endian.h>
37 #else
38 # include "config.h" /* for WORDS_BIGENDIAN */
39 #endif
40 
41 
42 /* See RFC4996 page 37-40 */
43 
44 #define ROHC_PACKET_TYPE_IR 0xFD
45 #define ROHC_PACKET_TYPE_IR_DYN 0xF8
46 
47 
48 /************************************************************************
49  * Limits *
50  ************************************************************************/
51 
52 /**
53  * @brief The maximum number of IP headers supported by the TCP profile
54  *
55  * The limit value was chosen arbitrarily. It should handle most real-life case
56  * without hurting performances nor memory footprint.
57  */
58 #define ROHC_TCP_MAX_IP_HDRS 10U
59 
60 
61 /**
62  * @brief The maximum number of IP extension header supported by the TCP profile
63  *
64  * The limit value was chosen arbitrarily. It should handle most real-life case
65  * without hurting performances nor memory footprint.
66  */
67 #define ROHC_TCP_MAX_IP_EXT_HDRS 20U
68 
69 
70 /**
71  * @brief The largest index that may be used to identify one TCP option
72  *
73  * The ROHC standard defines that one TCP option is identified by an index. It
74  * also defines that index is in range [0 ; 15].
75  */
76 #define MAX_TCP_OPTION_INDEX 15U
77 
78 
79 /**
80  * @brief The maximum of TCP options supported by the TCP protocol
81  *
82  * One TCP header may contain up to 40 bytes of options, so it may contain
83  * up 40 1-byte options.
84  *
85  * @see ROHC_TCP_OPTS_MAX
86  */
87 #define ROHC_TCP_OPTS_MAX_PROTO 40U
88 
89 
90 /**
91  * @brief The maximum of TCP options supported by the TCP profile
92  *
93  * One TCP header may contain up to 40 bytes of options, so it may contain
94  * up 40 1-byte options, so the ROHC (de)compressors should expect such TCP
95  * packets. However the m field in the compressed list of TCP options (see
96  * RFC 6846, section 6.3.3 for more details) cannot be larger than 15, so
97  * restrict the number of TCP options that value. One TCP packet with more
98  * than 15 TCP options will be compressed with the IP-only profile.
99  *
100  * @see ROHC_TCP_OPTS_MAX_PROTO
101  */
102 #define ROHC_TCP_OPTS_MAX 15U
103 
104 
105 
106 /************************************************************************
107  * Uncompressed TCP base header *
108  ************************************************************************/
109 
110 /**
111  * @brief The TCP base header without options
112  *
113  * See RFC4996 page 72/73
114  */
115 struct tcphdr
116 {
117  uint16_t src_port;
118  uint16_t dst_port;
119  uint32_t seq_num;
120  uint32_t ack_num;
121 #if WORDS_BIGENDIAN == 1
122  uint8_t data_offset:4;
123  uint8_t res_flags:4;
124  uint8_t ecn_flags:2;
125  uint8_t urg_flag:1;
126  uint8_t ack_flag:1;
127  uint8_t psh_flag:1;
128  uint8_t rsf_flags:3;
129 #else
130  uint8_t res_flags:4;
131  uint8_t data_offset:4;
132  uint8_t rsf_flags:3;
133  uint8_t psh_flag:1;
134  uint8_t ack_flag:1;
135  uint8_t urg_flag:1;
136  uint8_t ecn_flags:2;
137 #endif
138  uint16_t window;
139  uint16_t checksum;
140  uint16_t urg_ptr;
141  uint8_t options[0]; /**< The beginning of the TCP options */
142 } __attribute__((packed));
143 
144 
145 /* The RSF flags */
146 #define RSF_RST_ONLY 0x04
147 #define RSF_SYN_ONLY 0x02
148 #define RSF_FIN_ONLY 0x01
149 #define RSF_NONE 0x00
150 
151 
152 
153 /************************************************************************
154  * Uncompressed TCP options *
155  ************************************************************************/
156 
157 /** The different TCP options */
158 typedef enum
159 {
160  TCP_OPT_EOL = 0U, /**< The End of Option List (EOL) TCP option */
161  TCP_OPT_NOP = 1U, /**< The No OPeration (NOP) TCP option */
162  TCP_OPT_MSS = 2U, /**< The Maximum Segment Size (MSS) TCP option */
163 #define TCP_OLEN_MSS 4U
164  TCP_OPT_WS = 3U, /**< The Window Scale (WS) TCP option */
165 #define TCP_OLEN_WS 3U
166  TCP_OPT_SACK_PERM = 4U, /**< The SACK Permitted TCP option */
167 #define TCP_OLEN_SACK_PERM 2U
168  TCP_OPT_SACK = 5U, /**< The Selective ACKnowledgement (SACK) TCP option */
169  TCP_OPT_TS = 8U, /**< The TimeStamp (TS) TCP option */
170 #define TCP_OLEN_TS 10U
171  TCP_OPT_MAX = 255U /**< The maximum TCP option */
172 
174 
175 
176 #define TCP_INDEX_NOP 0U
177 #define TCP_INDEX_EOL 1U
178 #define TCP_INDEX_MSS 2U
179 #define TCP_INDEX_WS 3U
180 #define TCP_INDEX_TS 4U
181 #define TCP_INDEX_SACK_PERM 5U
182 #define TCP_INDEX_SACK 6U
183 #define TCP_INDEX_GENERIC7 7U
184 #define TCP_INDEX_GENERIC8 8U
185 #define TCP_INDEX_GENERIC9 9U
186 #define TCP_INDEX_GENERIC10 10U
187 #define TCP_INDEX_GENERIC11 11U
188 #define TCP_INDEX_GENERIC12 12U
189 #define TCP_INDEX_GENERIC13 13U
190 #define TCP_INDEX_GENERIC14 14U
191 #define TCP_INDEX_GENERIC15 15U
192 
193 
194 /**
195  * @brief The Selective Acknowlegment TCP option
196  *
197  * See RFC2018 for TCP Selective Acknowledgement Options
198  * See RFC4996 page 66
199  */
200 typedef struct
201 {
202  uint32_t block_start;
203  uint32_t block_end;
204 } __attribute__((packed)) sack_block_t;
205 
206 
207 /** The maximum number of SACK blocks in the TCP SACK option */
208 #define TCP_SACK_BLOCKS_MAX_NR 4U
209 
210 
211 /** The Timestamp option of the TCP header */
213 {
214  uint32_t ts; /**< The timestamp value */
215  uint32_t ts_reply; /**< The timestamp echo reply value */
216 } __attribute__((packed));
217 
218 
219 
220 /************************************************************************
221  * Compressed IPv4 header *
222  ************************************************************************/
223 
224 /**
225  * @brief The IPv4 static part
226  *
227  * See RFC4996 page 62
228  */
229 typedef struct
230 {
231 #if WORDS_BIGENDIAN == 1
232  uint8_t version_flag:1;
233  uint8_t reserved:7;
234 #else
235  uint8_t reserved:7;
236  uint8_t version_flag:1;
237 #endif
238  uint8_t protocol;
239  uint32_t src_addr;
240  uint32_t dst_addr;
241 } __attribute__((packed)) ipv4_static_t;
242 
243 
244 /** The different IP-ID behaviors */
245 typedef enum
246 {
247  IP_ID_BEHAVIOR_SEQ = 0, /**< IP-ID increases */
248  IP_ID_BEHAVIOR_SEQ_SWAP = 1, /**< IP-ID increases in little endian */
249  IP_ID_BEHAVIOR_RAND = 2, /**< IP-ID is random */
250  IP_ID_BEHAVIOR_ZERO = 3, /**< IP-ID is constant zero */
252 
253 
254 /**
255  * @brief The IPv4 dynamic part without IP-ID field
256  *
257  * See RFC4996 page 62
258  */
259 typedef struct
260 {
261 #if WORDS_BIGENDIAN == 1
262  uint8_t reserved:5;
263  uint8_t df:1;
264  uint8_t ip_id_behavior:2;
265  uint8_t dscp:6;
266  uint8_t ip_ecn_flags:2;
267 #else
268  uint8_t ip_id_behavior:2;
269  uint8_t df:1;
270  uint8_t reserved:5;
271  uint8_t ip_ecn_flags:2;
272  uint8_t dscp:6;
273 #endif
274  uint8_t ttl_hopl;
275 } __attribute__((packed)) ipv4_dynamic1_t;
276 
277 
278 /**
279  * @brief The IPv4 dynamic part with IP-ID field
280  *
281  * See RFC4996 page 62
282  */
283 typedef struct
284 {
285 #if WORDS_BIGENDIAN == 1
286  uint8_t reserved:5;
287  uint8_t df:1;
288  uint8_t ip_id_behavior:2;
289  uint8_t dscp:6;
290  uint8_t ip_ecn_flags:2;
291 #else
292  uint8_t ip_id_behavior:2;
293  uint8_t df:1;
294  uint8_t reserved:5;
295  uint8_t ip_ecn_flags:2;
296  uint8_t dscp:6;
297 #endif
298  uint8_t ttl_hopl;
299  uint16_t ip_id;
300 } __attribute__((packed)) ipv4_dynamic2_t;
301 
302 
303 
304 /************************************************************************
305  * Compressed IPv6 base header and its extension headers *
306  ************************************************************************/
307 
308 /** The static part of IPv6 option header */
309 typedef struct
310 {
311  uint8_t next_header;
312  uint8_t length;
313 } __attribute__((packed)) ip_opt_static_t;
314 
315 
316 /** The static part of IPv6 Destination option header */
317 typedef struct
318 {
319  uint8_t next_header;
320  uint8_t length;
321 } __attribute__((packed)) ip_dest_opt_static_t;
322 
323 
324 /** The static part of IPv6 Hop-by-Hop option header */
325 typedef struct
326 {
327  uint8_t next_header;
328  uint8_t length;
329 } __attribute__((packed)) ip_hop_opt_static_t;
330 
331 
332 /** The static part of IPv6 Routing option header */
333 typedef struct
334 {
335  uint8_t next_header;
336  uint8_t length;
337  uint8_t value[1];
338 } __attribute__((packed)) ip_rout_opt_static_t;
339 
340 
341 /**
342  * @brief The IPv6 static part, null flow_label encoded with 1 bit
343  *
344  * See RFC4996 page 58
345  */
346 typedef struct
347 {
348 #if WORDS_BIGENDIAN == 1
349  uint8_t version_flag:1;
350  uint8_t reserved1:2;
351  uint8_t flow_label_enc_discriminator:1;
352  uint8_t reserved2:4;
353 #else
354  uint8_t reserved2:4;
355  uint8_t flow_label_enc_discriminator:1;
356  uint8_t reserved1:2;
357  uint8_t version_flag:1;
358 #endif
359  uint8_t next_header;
360  uint32_t src_addr[4];
361  uint32_t dst_addr[4];
362 } __attribute__((packed)) ipv6_static1_t;
363 
364 
365 /**
366  * @brief The IPv6 static part, flow_label encoded with 1+20 bits
367  *
368  * See RFC4996 page 59
369  */
370 typedef struct
371 {
372 #if WORDS_BIGENDIAN == 1
373  uint8_t version_flag:1;
374  uint8_t reserved:2;
375  uint8_t flow_label_enc_discriminator:1;
376  uint8_t flow_label1:4;
377 #else
378  uint8_t flow_label1:4;
379  uint8_t flow_label_enc_discriminator:1;
380  uint8_t reserved:2;
381  uint8_t version_flag:1;
382 #endif
383  uint16_t flow_label2;
384  uint8_t next_header;
385  uint32_t src_addr[4];
386  uint32_t dst_addr[4];
387 } __attribute__((packed)) ipv6_static2_t;
388 
389 
390 /**
391  * @brief The IPv6 dynamic part
392  *
393  * See RFC4996 page 59
394  */
395 typedef struct
396 {
397 #if WORDS_BIGENDIAN == 1
398  uint8_t dscp:6;
399  uint8_t ip_ecn_flags:2;
400 #else
401  uint8_t ip_ecn_flags:2;
402  uint8_t dscp:6;
403 #endif
404  uint8_t ttl_hopl;
405 } __attribute__((packed)) ipv6_dynamic_t;
406 
407 
408 
409 /************************************************************************
410  * Compressed TCP header and its options *
411  ************************************************************************/
412 
413 /**
414  * @brief The TCP static part
415  *
416  * See RFC4996 page 73/74
417  */
418 typedef struct
419 {
420  uint16_t src_port; /**< irregular(16) [ 16 ] */
421  uint16_t dst_port; /**< irregular(16) [ 16 ] */
422 } __attribute__((packed)) tcp_static_t;
423 
424 
425 /**
426  * @brief The TCP dynamic part
427  *
428  * See RFC4996 page 73/74
429  */
430 typedef struct
431 {
432 #if WORDS_BIGENDIAN == 1
433  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
434  uint8_t ack_stride_flag:1; /**< irregular(1) [ 1 ] */
435  uint8_t ack_zero:1; /**< irregular(1) [ 1 ] */
436  uint8_t urp_zero:1; /**< irregular(1) [ 1 ] */
437  uint8_t tcp_res_flags:4; /**< irregular(4) [ 4 ] */
438 
439  uint8_t tcp_ecn_flags:2; /**< irregular(2) [ 2 ] */
440  uint8_t urg_flag:1; /**< irregular(1) [ 1 ] */
441  uint8_t ack_flag:1; /**< irregular(1) [ 1 ] */
442  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
443  uint8_t rsf_flags:3; /**< irregular(3) [ 3 ] */
444 #else
445  uint8_t tcp_res_flags:4;
446  uint8_t urp_zero:1;
447  uint8_t ack_zero:1;
448  uint8_t ack_stride_flag:1;
449  uint8_t ecn_used:1;
450 
451  uint8_t rsf_flags:3;
452  uint8_t psh_flag:1;
453  uint8_t ack_flag:1;
454  uint8_t urg_flag:1;
455  uint8_t tcp_ecn_flags:2;
456 #endif
457  uint16_t msn; /**< irregular(16) [ 16 ] */
458  uint32_t seq_num; /**< irregular(32) [ 32 ] */
459 
460  /* variable fields:
461  * zero_or_irreg(ack_zero.CVALUE, 32) [ 0, 32 ]
462  * irregular(16) [ 16 ]
463  * irregular(16) [ 16 ]
464  * zero_or_irreg(urp_zero.CVALUE, 16) [ 0, 16 ]
465  * static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ]
466  * list_tcp_options [ VARIABLE ]
467  */
468 
469 } __attribute__((packed)) tcp_dynamic_t;
470 
471 
472 /**
473  * @brief The Common compressed packet format
474  *
475  * See RFC4996 page 80/81
476  */
477 typedef struct
478 {
479 #if WORDS_BIGENDIAN == 1
480 
481  uint8_t discriminator:7; /**< '1111101' [ 7 ] */
482  uint8_t ttl_hopl_outer_flag:1; /**< compressed_value(1,
483  ttl_irregular_chain_flag) [ 1 ] */
484 
485  uint8_t ack_flag:1; /**< irregular(1) [ 1 ] */
486  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
487  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
488  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
489 
490  uint8_t seq_indicator:2; /**< irregular(2) [ 2 ] */
491  uint8_t ack_indicator:2; /**< irregular(2) [ 2 ] */
492  uint8_t ack_stride_indicator:1; /**< irregular(1) [ 1 ] */
493  uint8_t window_indicator:1; /**< irregular(1) [ 1 ] */
494  uint8_t ip_id_indicator:1; /**< irregular(1) [ 1 ] */
495  uint8_t urg_ptr_present:1; /**< irregular(1) [ 1 ] */
496 
497  uint8_t reserved:1; /**< compressed_value(1, 0) [ 1 ] */
498  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
499  uint8_t dscp_present:1; /**< irregular(1) [ 1 ] */
500  uint8_t ttl_hopl_present:1; /**< irregular(1) [ 1 ] */
501  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
502  uint8_t ip_id_behavior:2; /**< ip_id_behavior_choice(true) [ 2 ] */
503  uint8_t urg_flag:1; /**< irregular(1) [ 1 ] */
504 
505  uint8_t df:1; /**< dont_fragment(version.UVALUE) [ 1 ] */
506  uint8_t header_crc:7; /**< crc7(THIS.UVALUE,THIS.ULENGTH) [ 7 ] */
507 
508 #else
509 
510  uint8_t ttl_hopl_outer_flag:1;
511  uint8_t discriminator:7;
512 
513  uint8_t msn:4;
514  uint8_t rsf_flags:2;
515  uint8_t psh_flag:1;
516  uint8_t ack_flag:1;
517 
518  uint8_t urg_ptr_present:1;
519  uint8_t ip_id_indicator:1;
520  uint8_t window_indicator:1;
521  uint8_t ack_stride_indicator:1;
522  uint8_t ack_indicator:2;
523  uint8_t seq_indicator:2;
524 
525  uint8_t urg_flag:1;
526  uint8_t ip_id_behavior:2;
527  uint8_t list_present:1;
528  uint8_t ttl_hopl_present:1;
529  uint8_t dscp_present:1;
530  uint8_t ecn_used:1;
531  uint8_t reserved:1;
532 
533  uint8_t header_crc:7;
534  uint8_t df:1;
535 
536 #endif
537 
538  /* variable fields:
539  * variable_length_32_enc(seq_indicator.CVALUE) [ 0, 8, 16, 32 ]
540  * variable_length_32_enc(ack_indicator.CVALUE) [ 0, 8, 16, 32 ]
541  * static_or_irreg(ack_stride_indicator.CVALUE, 16) [ 0, 16 ]
542  * static_or_irreg(window_indicator.CVALUE, 16) [ 0, 16 ]
543  * optional_ip_id_lsb(ip_id_behavior.UVALUE,ip_id_indicator.CVALUE) [ 0, 8, 16 ]
544  * static_or_irreg(urg_ptr_present.CVALUE, 16) [ 0, 16 ]
545  * dscp_enc-dscp_present.CVALUE) [ 0, 8 ]
546  * static_or_irreg(ttl_hopl_present.CVALUE, 8) [ 0, 8 ]
547  * tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]
548  * irregular chain [ VARIABLE ]
549  */
550 
551 } __attribute__((packed)) co_common_t;
552 
553 
554 /**
555  * @brief The rnd_1 compressed packet format
556  *
557  * Send LSBs of sequence number
558  * See RFC4996 page 81
559  */
560 typedef struct
561 {
562 #if WORDS_BIGENDIAN == 1
563  uint8_t discriminator:6; /**< '101110' [ 6 ] */
564  uint8_t seq_num1:2; /**< lsb(18, 65535) [ 18 ] */
565  uint16_t seq_num2; /**< sequel of \e seq_num1 [ - ] */
566  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
567  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
568  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
569 #else
570  uint8_t seq_num1:2;
571  uint8_t discriminator:6;
572  uint16_t seq_num2;
573  uint8_t header_crc:3;
574  uint8_t psh_flag:1;
575  uint8_t msn:4;
576 #endif
577  /* irregular chain [ VARIABLE ] */
578 } __attribute__((packed)) rnd_1_t;
579 
580 
581 /**
582  * @brief The rnd_2 compressed packet format
583  *
584  * Send scaled sequence number LSBs
585  * See RFC4996 page 81
586  */
587 typedef struct
588 {
589 #if WORDS_BIGENDIAN == 1
590  uint8_t discriminator:4; /**< '1100' [ 4 ] */
591  uint8_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
592  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
593  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
594  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
595 #else
596  uint8_t seq_num_scaled:4;
597  uint8_t discriminator:4;
598  uint8_t header_crc:3;
599  uint8_t psh_flag:1;
600  uint8_t msn:4;
601 #endif
602  /* irregular chain [ VARIABLE ] */
603 } __attribute__((packed)) rnd_2_t;
604 
605 
606 /**
607  * @brief The rnd_3 compressed packet format
608  *
609  * Send acknowledgment number LSBs
610  * See RFC4996 page 81
611  */
612 typedef struct
613 {
614 #if WORDS_BIGENDIAN == 1
615  uint16_t discriminator:1; /**< '0' [ 4 ] */
616  uint8_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
617  uint8_t ack_num2; /**< sequel of \e ack_num1 [ - ] */
618  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
619  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
620  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
621 #else
622  uint8_t ack_num1:7;
623  uint8_t discriminator:1;
624  uint8_t ack_num2:8;
625  uint8_t header_crc:3;
626  uint8_t psh_flag:1;
627  uint8_t msn:4;
628 #endif
629  /* irregular chain [ VARIABLE ] */
630 } __attribute__((packed)) rnd_3_t;
631 
632 
633 /**
634  * @brief The rnd_4 compressed packet format
635  *
636  * Send acknowlegment number scaled
637  * See RFC4996 page 81
638  */
639 typedef struct
640 {
641 #if WORDS_BIGENDIAN == 1
642  uint8_t discriminator:4; /**< '1101' [ 4 ] */
643  uint8_t ack_num_scaled:4; /**< lsb(4, 3) [ 4 ] */
644  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
645  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
646  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
647 #else
648  uint8_t ack_num_scaled:4;
649  uint8_t discriminator:4;
650  uint8_t header_crc:3;
651  uint8_t psh_flag:1;
652  uint8_t msn:4;
653 #endif
654  /* irregular chain [ VARIABLE ] */
655 } __attribute__((packed)) rnd_4_t;
656 
657 
658 /**
659  * @brief The rnd_5 compressed packet format
660  *
661  * Send ACK and sequence number
662  * See RFC4996 page 82
663  */
664 typedef struct
665 {
666 #if WORDS_BIGENDIAN == 1
667  uint8_t discriminator:3; /**< '100' [ 3 ] */
668  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
669  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
670  uint32_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
671  uint32_t seq_num1:5; /**< lsb(14, 8191) [ 14 ] */
672  uint32_t seq_num2:8; /**< sequel of \e seq_num1 [ - ] */
673  uint32_t seq_num3:1; /**< sequel of \e seq_num1 and \e seq_num2 [ - ] */
674  uint32_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
675  uint32_t ack_num2:8; /**< sequel of \e ack_num1 [ - ] */
676 #else
677  uint8_t msn:4;
678  uint8_t psh_flag:1;
679  uint8_t discriminator:3;
680  uint8_t seq_num1:5;
681  uint8_t header_crc:3;
682  uint8_t seq_num2;
683  uint8_t ack_num1:7;
684  uint8_t seq_num3:1;
685  uint8_t ack_num2;
686 #endif
687  /* irregular chain [ VARIABLE ] */
688 } __attribute__((packed)) rnd_5_t;
689 
690 
691 /**
692  * @brief The rnd_6 compressed packet format
693  *
694  * Send both ACK and scaled sequence number LSBs
695  * See RFC4996 page 82
696  */
697 typedef struct
698 {
699 #if WORDS_BIGENDIAN == 1
700  uint8_t discriminator:4; /**< '1010' [ 4 ] */
701  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
702  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
703 #else
704  uint8_t psh_flag:1;
705  uint8_t header_crc:3;
706  uint8_t discriminator:4;
707 #endif
708  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
709 #if WORDS_BIGENDIAN == 1
710  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
711  uint8_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
712 #else
713  uint8_t seq_num_scaled:4;
714  uint8_t msn:4;
715 #endif
716  /* irregular chain [ VARIABLE ] */
717 } __attribute__((packed)) rnd_6_t;
718 
719 
720 /**
721  * @brief The rnd_7 compressed packet format
722  *
723  * Send ACK and window
724  * See RFC4996 page 82
725  */
726 typedef struct
727 {
728 #if WORDS_BIGENDIAN == 1
729  uint8_t discriminator:6; /**< '101111' [ 6 ] */
730  uint8_t ack_num1:2; /**< lsb(18, 65535) [ 18 ] */
731  uint16_t ack_num2; /**< sequel of \e ack_num1 [ - ]*/
732 #else
733  uint8_t ack_num1:2;
734  uint8_t discriminator:6;
735  uint16_t ack_num2;
736 #endif
737  uint16_t window; /**< irregular(16) [ 16 ] */
738 #if WORDS_BIGENDIAN == 1
739  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
740  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
741  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
742 #else
743  uint8_t header_crc:3;
744  uint8_t psh_flag:1;
745  uint8_t msn:4;
746 #endif
747  /* irregular chain [ VARIABLE ] */
748 } __attribute__((packed)) rnd_7_t;
749 
750 
751 /**
752  * @brief The rnd_8 compressed packet format
753  *
754  * Can send LSBs of TTL, RSF flags, change ECN behavior and options list
755  * See RFC4996 page 82
756  */
757 typedef struct
758 {
759 #if WORDS_BIGENDIAN == 1
760  uint8_t discriminator:5; /**< '10110' [ 5 ] */
761  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
762  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
763  uint16_t header_crc:7; /**< crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ] */
764  uint16_t msn1:1; /**< lsb(4, 4) [ 4 ] */
765  uint16_t msn2:3; /**< sequel of \e msn1 [ - ] */
766  uint16_t psh_flag:1; /**< irregular(1) [ 1 ] */
767  uint16_t ttl_hopl:3; /**< lsb(3, 3) [ 3 ] */
768  uint16_t ecn_used:1; /**< one_bit_choice [ 1 ] */
769 #else
770  uint8_t list_present:1;
771  uint8_t rsf_flags:2;
772  uint8_t discriminator:5;
773  uint8_t msn1:1;
774  uint8_t header_crc:7;
775  uint8_t ecn_used:1;
776  uint8_t ttl_hopl:3;
777  uint8_t psh_flag:1;
778  uint8_t msn2:3;
779 #endif
780  uint16_t seq_num; /**< lsb(16, 65535) [ 16 ] */
781  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
782  uint8_t options[0]; /**< tcp_list_presence_enc(list_present.CVALUE)
783  [ VARIABLE ] */
784  /* irregular chain [ VARIABLE ] */
785 } __attribute__((packed)) rnd_8_t;
786 
787 
788 /**
789  * @brief The seq_1 compressed packet format
790  *
791  * Send LSBs of sequence number
792  * See RFC4996 page 83
793  */
794 typedef struct
795 {
796 #if WORDS_BIGENDIAN == 1
797  uint8_t discriminator:4; /**< '1010' [ 4 ] */
798  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
799 #else
800  uint8_t ip_id:4;
801  uint8_t discriminator:4;
802 #endif
803  uint16_t seq_num; /**< lsb(16, 32767) [ 16 ] */
804 #if WORDS_BIGENDIAN == 1
805  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
806  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
807  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
808 #else
809  uint8_t header_crc:3;
810  uint8_t psh_flag:1;
811  uint8_t msn:4;
812 #endif
813  /* irregular chain [ VARIABLE ] */
814 } __attribute__((packed)) seq_1_t;
815 
816 
817 /**
818  * @brief The seq_2 compressed packet format
819  *
820  * Send scaled sequence number LSBs
821  * See RFC4996 page 83
822  */
823 typedef struct
824 {
825 #if WORDS_BIGENDIAN == 1
826  uint16_t discriminator:5; /**< '11010' [ 5 ] */
827  uint16_t ip_id1:3; /**< ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ] */
828  uint16_t ip_id2:4; /**< sequel of ip_id1 [ - ] */
829  uint16_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
830  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
831  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
832  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
833 #else
834  uint8_t ip_id1:3;
835  uint8_t discriminator:5;
836  uint8_t seq_num_scaled:4;
837  uint8_t ip_id2:4;
838  uint8_t header_crc:3;
839  uint8_t psh_flag:1;
840  uint8_t msn:4;
841 #endif
842  /* irregular chain [ VARIABLE ] */
843 } __attribute__((packed)) seq_2_t;
844 
845 
846 /**
847  * @brief The seq_3 compressed packet format
848  *
849  * Send acknowledgment number LSBs
850  * See RFC4996 page 83
851  */
852 typedef struct
853 {
854 #if WORDS_BIGENDIAN == 1
855  uint8_t discriminator:4; /**< '1001' [ 4 ] */
856  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
857 #else
858  uint8_t ip_id:4;
859  uint8_t discriminator:4;
860 #endif
861  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
862 #if WORDS_BIGENDIAN == 1
863  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
864  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
865  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
866 #else
867  uint8_t header_crc:3;
868  uint8_t psh_flag:1;
869  uint8_t msn:4;
870 #endif
871  /* irregular chain [ VARIABLE ] */
872 } __attribute__((packed)) seq_3_t;
873 
874 
875 /**
876  * @brief The seq_4 compressed packet format
877  *
878  * Send scaled acknowledgment number scaled
879  * See RFC4996 page 84
880  */
881 typedef struct
882 {
883 #if WORDS_BIGENDIAN == 1
884  uint8_t discriminator:1; /**< '0' [ 1 ] */
885  uint8_t ack_num_scaled:4; /**< lsb(4, 3) [ 4 ] */
886  uint8_t ip_id:3; /**< ip_id_lsb(ip_id_behavior.UVALUE, 3, 1) [ 3 ] */
887  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
888  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
889  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
890 #else
891  uint8_t ip_id:3;
892  uint8_t ack_num_scaled:4;
893  uint8_t discriminator:1;
894  uint8_t header_crc:3;
895  uint8_t psh_flag:1;
896  uint8_t msn:4;
897 #endif
898  /* irregular chain [ VARIABLE ] */
899 } __attribute__((packed)) seq_4_t;
900 
901 
902 /**
903  * @brief The seq_5 compressed packet format
904  *
905  * Send ACK and sequence number
906  * See RFC4996 page 84
907  */
908 typedef struct
909 {
910 #if WORDS_BIGENDIAN == 1
911  uint8_t discriminator:4; /**< '1000' [ 4 ] */
912  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
913 #else
914  uint8_t ip_id:4;
915  uint8_t discriminator:4;
916 #endif
917  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
918  uint16_t seq_num; /**< lsb(16, 32767) [ 16 ] */
919 #if WORDS_BIGENDIAN == 1
920  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
921  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
922  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
923 #else
924  uint8_t header_crc:3;
925  uint8_t psh_flag:1;
926  uint8_t msn:4;
927 #endif
928  /* irregular chain [ VARIABLE ] */
929 } __attribute__((packed)) seq_5_t;
930 
931 
932 /**
933  * @brief The seq_6 compressed packet format
934  *
935  * Send both ACK and scaled sequence number LSBs
936  * See RFC4996 page 84
937  */
938 typedef struct
939 {
940 #if WORDS_BIGENDIAN == 1
941  uint16_t discriminator:5; /**< '11011' [ 5 ] */
942  uint16_t seq_num_scaled1:3; /**< lsb(4, 7) [ 4 ] */
943  uint16_t seq_num_scaled2:1; /**< sequel of \e seq_num_scaled1 [ 4 ] */
944  uint16_t ip_id:7; /**< ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ] */
945 #else
946  uint8_t seq_num_scaled1:3;
947  uint8_t discriminator:5;
948  uint8_t ip_id:7;
949  uint8_t seq_num_scaled2:1;
950 #endif
951  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
952 #if WORDS_BIGENDIAN == 1
953  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
954  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
955  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
956 #else
957  uint8_t header_crc:3;
958  uint8_t psh_flag:1;
959  uint8_t msn:4;
960 #endif
961  /* irregular chain [ VARIABLE ] */
962 } __attribute__((packed)) seq_6_t;
963 
964 
965 /**
966  * @brief The seq_7 compressed packet format
967  *
968  * Send ACK and window
969  * See RFC4996 page 85
970  */
971 typedef struct
972 {
973 #if WORDS_BIGENDIAN == 1
974  uint8_t discriminator:4; /**< '1100' [ 4 ] */
975  uint8_t window1:4; /**< lsb(15, 16383) [ 15 ] */
976  uint8_t window2; /**< sequel of \e window1 [ - ] */
977  uint8_t window3:3; /**< sequel of \e window1 and \e window2 [ - ] */
978  uint8_t ip_id:5; /**< ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ] */
979  uint16_t ack_num; /**< lsb(16, 32767) [ 16 ] */
980  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
981  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
982  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
983 #else
984  uint8_t window1:4;
985  uint8_t discriminator:4;
986  uint8_t window2;
987  uint8_t ip_id:5;
988  uint8_t window3:3;
989  uint16_t ack_num;
990  uint8_t header_crc:3;
991  uint8_t psh_flag:1;
992  uint8_t msn:4;
993 #endif
994  /* irregular chain [ VARIABLE ] */
995 } __attribute__((packed)) seq_7_t;
996 
997 
998 /**
999  * @brief The seq_8 compressed packet format
1000  *
1001  * Can send LSBs of TTL, RSF flags, change ECN behavior, and options list
1002  * See RFC4996 page 85
1003  */
1004 typedef struct
1005 {
1006 #if WORDS_BIGENDIAN == 1
1007  uint8_t discriminator:4; /**< '1011' [ 4 ] */
1008  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
1009  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
1010  uint8_t header_crc:7; /**< crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ] */
1011  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1012  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1013  uint8_t ttl_hopl:3; /**< lsb(3, 3) [ 3 ] */
1014  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
1015  uint8_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
1016  uint8_t ack_num2; /**< sequel of \e ack_num1 [ - ] */
1017  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
1018  uint8_t seq_num1:6; /**< lsb(14, 8191) [ 14 ] */
1019  uint8_t seq_num2; /**< sequel of \e seq_num1 [ - ] */
1020 #else
1021  uint8_t ip_id:4;
1022  uint8_t discriminator:4;
1023  uint8_t header_crc:7;
1024  uint8_t list_present:1;
1025  uint8_t ttl_hopl:3;
1026  uint8_t psh_flag:1;
1027  uint8_t msn:4;
1028  uint8_t ack_num1:7;
1029  uint8_t ecn_used:1;
1030  uint8_t ack_num2;
1031  uint8_t seq_num1:6;
1032  uint8_t rsf_flags:2;
1033  uint8_t seq_num2:8;
1034 #endif
1035  uint8_t options[0]; /**< tcp_list_presence_enc(list_present.CVALUE)
1036  [ VARIABLE ] */
1037  /* irregular chain [ VARIABLE ] */
1038 } __attribute__((packed)) seq_8_t;
1039 
1040 
1041 
1042 /************************************************************************
1043  * Helper functions *
1044  ************************************************************************/
1045 
1046 static inline char * tcp_ip_id_behavior_get_descr(const tcp_ip_id_behavior_t ip_id_behavior)
1047  __attribute__((warn_unused_result, const));
1048 
1049 static inline char * tcp_opt_get_descr(const uint8_t opt_type)
1050  __attribute__((warn_unused_result, const));
1051 
1052 
1053 /**
1054  * @brief Get a string that describes the given IP-ID behavior
1055  *
1056  * @param behavior The type of the option to get a description for
1057  * @return The description of the option
1058  */
1059 static inline char * tcp_ip_id_behavior_get_descr(const tcp_ip_id_behavior_t behavior)
1060 {
1061  switch(behavior)
1062  {
1063  case IP_ID_BEHAVIOR_SEQ:
1064  return "sequential";
1066  return "sequential swapped";
1067  case IP_ID_BEHAVIOR_RAND:
1068  return "random";
1069  case IP_ID_BEHAVIOR_ZERO:
1070  return "constant zero";
1071  default:
1072  return "unknown IP-ID behavior";
1073  }
1074 }
1075 
1076 
1077 /**
1078  * @brief Get a string that describes the given option type
1079  *
1080  * @param opt_type The type of the option to get a description for
1081  * @return The description of the option
1082  */
1083 static inline char * tcp_opt_get_descr(const uint8_t opt_type)
1084 {
1085  switch(opt_type)
1086  {
1087  case TCP_OPT_EOL:
1088  return "EOL";
1089  case TCP_OPT_NOP:
1090  return "NOP";
1091  case TCP_OPT_MSS:
1092  return "MSS";
1093  case TCP_OPT_WS:
1094  return "Window Scale";
1095  case TCP_OPT_SACK_PERM:
1096  return "SACK permitted";
1097  case TCP_OPT_SACK:
1098  return "SACK";
1099  case TCP_OPT_TS:
1100  return "Timestamp";
1101  default:
1102  return "generic";
1103  }
1104 }
1105 
1106 
1107 #endif /* ROHC_PROTOCOLS_TCP_H */
1108 
uint8_t ecn_flags
Definition: tcp.h:136
uint32_t ts
Definition: tcp.h:214
uint16_t window
Definition: tcp.h:138
The rnd_1 compressed packet format.
Definition: tcp.h:560
The rnd_6 compressed packet format.
Definition: tcp.h:697
The Selective Acknowlegment TCP option.
Definition: tcp.h:200
uint8_t protocol
Definition: tcp.h:238
Definition: tcp.h:317
Definition: tcp.h:160
The rnd_2 compressed packet format.
Definition: tcp.h:587
uint32_t block_end
Definition: tcp.h:203
uint8_t next_header
Definition: tcp.h:335
The rnd_8 compressed packet format.
Definition: tcp.h:757
Definition: tcp.h:162
uint16_t dst_port
Definition: tcp.h:118
uint16_t ack_num
Definition: tcp.h:861
uint16_t seq_num
Definition: tcp.h:918
The IPv6 static part, flow_label encoded with 1+20 bits.
Definition: tcp.h:370
uint16_t ack_num
Definition: tcp.h:708
uint16_t msn
Definition: tcp.h:457
Definition: tcp.h:333
The rnd_7 compressed packet format.
Definition: tcp.h:726
uint8_t window2
Definition: tcp.h:986
The rnd_4 compressed packet format.
Definition: tcp.h:639
uint8_t ttl_hopl
Definition: tcp.h:274
Definition: tcp.h:325
Definition: tcp.h:309
The TCP static part.
Definition: tcp.h:418
The rnd_5 compressed packet format.
Definition: tcp.h:664
The IPv6 dynamic part.
Definition: tcp.h:395
uint8_t length
Definition: tcp.h:328
uint32_t seq_num
Definition: tcp.h:458
The rnd_3 compressed packet format.
Definition: tcp.h:612
uint16_t ip_id
Definition: tcp.h:299
uint8_t urg_flag
Definition: tcp.h:135
The seq_1 compressed packet format.
Definition: tcp.h:794
uint16_t src_port
Definition: tcp.h:117
static char * tcp_ip_id_behavior_get_descr(const tcp_ip_id_behavior_t ip_id_behavior)
Get a string that describes the given IP-ID behavior.
Definition: tcp.h:1059
The IPv4 dynamic part without IP-ID field.
Definition: tcp.h:259
The seq_6 compressed packet format.
Definition: tcp.h:938
uint16_t ack_num
Definition: tcp.h:781
uint16_t ack_num
Definition: tcp.h:989
uint8_t ttl_hopl
Definition: tcp.h:298
uint16_t src_port
Definition: tcp.h:420
uint16_t urg_ptr
Definition: tcp.h:140
rohc_tcp_option_type_t
Definition: tcp.h:158
uint16_t checksum
Definition: tcp.h:139
uint32_t block_start
Definition: tcp.h:202
uint16_t seq_num2
Definition: tcp.h:572
uint8_t ttl_hopl
Definition: tcp.h:404
The TCP dynamic part.
Definition: tcp.h:430
The seq_2 compressed packet format.
Definition: tcp.h:823
The IPv6 static part, null flow_label encoded with 1 bit.
Definition: tcp.h:346
uint8_t ack_num2
Definition: tcp.h:685
uint8_t options[0]
Definition: tcp.h:141
The IPv4 dynamic part with IP-ID field.
Definition: tcp.h:283
static char * tcp_opt_get_descr(const uint8_t opt_type)
Get a string that describes the given option type.
Definition: tcp.h:1083
The seq_8 compressed packet format.
Definition: tcp.h:1004
uint8_t res_flags
Definition: tcp.h:130
uint8_t next_header
Definition: tcp.h:384
uint8_t data_offset
Definition: tcp.h:131
The TCP base header without options.
Definition: tcp.h:115
uint16_t seq_num
Definition: tcp.h:780
The IPv4 static part.
Definition: tcp.h:229
uint16_t dst_port
Definition: tcp.h:421
uint16_t flow_label2
Definition: tcp.h:383
uint32_t ack_num
Definition: tcp.h:120
uint8_t next_header
Definition: tcp.h:359
The seq_7 compressed packet format.
Definition: tcp.h:971
uint8_t length
Definition: tcp.h:312
uint32_t seq_num
Definition: tcp.h:119
uint16_t ack_num
Definition: tcp.h:951
uint16_t window
Definition: tcp.h:737
Definition: tcp.h:169
uint8_t seq_num2
Definition: tcp.h:682
Definition: tcp.h:250
uint8_t rsf_flags
Definition: tcp.h:132
The seq_4 compressed packet format.
Definition: tcp.h:881
Definition: tcp.h:247
The seq_5 compressed packet format.
Definition: tcp.h:908
uint8_t length
Definition: tcp.h:336
Definition: tcp.h:171
uint32_t dst_addr
Definition: tcp.h:240
uint16_t seq_num
Definition: tcp.h:803
Definition: tcp.h:168
The seq_3 compressed packet format.
Definition: tcp.h:852
uint8_t next_header
Definition: tcp.h:327
uint32_t src_addr
Definition: tcp.h:239
uint8_t ack_num2
Definition: tcp.h:1030
Definition: tcp.h:161
uint8_t next_header
Definition: tcp.h:319
uint16_t ack_num
Definition: tcp.h:917
Definition: tcp.h:249
uint8_t next_header
Definition: tcp.h:311
uint8_t psh_flag
Definition: tcp.h:133
uint8_t length
Definition: tcp.h:320
Definition: tcp.h:248
tcp_ip_id_behavior_t
Definition: tcp.h:245
The Common compressed packet format.
Definition: tcp.h:477
Definition: tcp.h:164
Definition: tcp.h:212
uint8_t ack_flag
Definition: tcp.h:134
uint32_t ts_reply
Definition: tcp.h:215
uint16_t ack_num2
Definition: tcp.h:735
Definition: tcp.h:166