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 RFC6846 §7.1 and §7.2 */
43 #define ROHC_PACKET_TYPE_IR 0xFD
44 #define ROHC_PACKET_TYPE_IR_CR 0xfc
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 2U
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 5U
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 /**
158  * @brief The different chains used by the TCP profile
159  */
160 typedef enum
161 {
162  ROHC_TCP_CHAIN_STATIC = 0, /**< The TCP static chain */
163  ROHC_TCP_CHAIN_DYNAMIC = 1, /**< The TCP dynamic chain */
164  ROHC_TCP_CHAIN_REPLICATE = 2, /**< The TCP replicate chain */
165  ROHC_TCP_CHAIN_IRREGULAR = 3, /**< The TCP irregular chain */
166  ROHC_TCP_CHAIN_CO = 4, /**< Not a chain, but in CO packet */
167 
169 
170 
171 /** The different TCP options */
172 typedef enum
173 {
174  TCP_OPT_EOL = 0U, /**< The End of Option List (EOL) TCP option */
175  TCP_OPT_NOP = 1U, /**< The No OPeration (NOP) TCP option */
176  TCP_OPT_MSS = 2U, /**< The Maximum Segment Size (MSS) TCP option */
177 #define TCP_OLEN_MSS 4U
178  TCP_OPT_WS = 3U, /**< The Window Scale (WS) TCP option */
179 #define TCP_OLEN_WS 3U
180  TCP_OPT_SACK_PERM = 4U, /**< The SACK Permitted TCP option */
181 #define TCP_OLEN_SACK_PERM 2U
182  TCP_OPT_SACK = 5U, /**< The Selective ACKnowledgement (SACK) TCP option */
183  TCP_OPT_TS = 8U, /**< The TimeStamp (TS) TCP option */
184 #define TCP_OLEN_TS 10U
185  TCP_OPT_MAX = 255U /**< The maximum TCP option */
186 
188 
189 
190 #define TCP_INDEX_NOP 0U
191 #define TCP_INDEX_EOL 1U
192 #define TCP_INDEX_MSS 2U
193 #define TCP_INDEX_WS 3U
194 #define TCP_INDEX_TS 4U
195 #define TCP_INDEX_SACK_PERM 5U
196 #define TCP_INDEX_SACK 6U
197 #define TCP_INDEX_GENERIC7 7U
198 #define TCP_INDEX_GENERIC8 8U
199 #define TCP_INDEX_GENERIC9 9U
200 #define TCP_INDEX_GENERIC10 10U
201 #define TCP_INDEX_GENERIC11 11U
202 #define TCP_INDEX_GENERIC12 12U
203 #define TCP_INDEX_GENERIC13 13U
204 #define TCP_INDEX_GENERIC14 14U
205 #define TCP_INDEX_GENERIC15 15U
206 
207 
208 /**
209  * @brief The Selective Acknowlegment TCP option
210  *
211  * See RFC2018 for TCP Selective Acknowledgement Options
212  * See RFC4996 page 66
213  */
214 typedef struct
215 {
216  uint32_t block_start;
217  uint32_t block_end;
218 } __attribute__((packed)) sack_block_t;
219 
220 
221 /** The maximum number of SACK blocks in the TCP SACK option */
222 #define TCP_SACK_BLOCKS_MAX_NR 4U
223 
224 
225 /** The Timestamp option of the TCP header */
227 {
228  uint32_t ts; /**< The timestamp value */
229  uint32_t ts_reply; /**< The timestamp echo reply value */
230 } __attribute__((packed));
231 
232 
233 
234 /************************************************************************
235  * Compressed IPv4 header *
236  ************************************************************************/
237 
238 /**
239  * @brief The IPv4 static part
240  *
241  * See RFC4996 page 62
242  */
243 typedef struct
244 {
245 #if WORDS_BIGENDIAN == 1
246  uint8_t version_flag:1;
247  uint8_t reserved:7;
248 #else
249  uint8_t reserved:7;
250  uint8_t version_flag:1;
251 #endif
252  uint8_t protocol;
253  uint32_t src_addr;
254  uint32_t dst_addr;
255 } __attribute__((packed)) ipv4_static_t;
256 
257 
258 /** The different IP-ID behaviors */
259 typedef enum
260 {
261  IP_ID_BEHAVIOR_SEQ = 0, /**< IP-ID increases */
262  IP_ID_BEHAVIOR_SEQ_SWAP = 1, /**< IP-ID increases in little endian */
263  IP_ID_BEHAVIOR_RAND = 2, /**< IP-ID is random */
264  IP_ID_BEHAVIOR_ZERO = 3, /**< IP-ID is constant zero */
266 
267 
268 /**
269  * @brief The IPv4 dynamic part without IP-ID field
270  *
271  * See RFC4996 page 62
272  */
273 typedef struct
274 {
275 #if WORDS_BIGENDIAN == 1
276  uint8_t reserved:5;
277  uint8_t df:1;
278  uint8_t ip_id_behavior:2;
279  uint8_t dscp:6;
280  uint8_t ip_ecn_flags:2;
281 #else
282  uint8_t ip_id_behavior:2;
283  uint8_t df:1;
284  uint8_t reserved:5;
285  uint8_t ip_ecn_flags:2;
286  uint8_t dscp:6;
287 #endif
288  uint8_t ttl_hopl;
289 } __attribute__((packed)) ipv4_dynamic1_t;
290 
291 
292 /**
293  * @brief The IPv4 dynamic part with IP-ID field
294  *
295  * See RFC4996 page 62
296  */
297 typedef struct
298 {
299 #if WORDS_BIGENDIAN == 1
300  uint8_t reserved:5;
301  uint8_t df:1;
302  uint8_t ip_id_behavior:2;
303  uint8_t dscp:6;
304  uint8_t ip_ecn_flags:2;
305 #else
306  uint8_t ip_id_behavior:2;
307  uint8_t df:1;
308  uint8_t reserved:5;
309  uint8_t ip_ecn_flags:2;
310  uint8_t dscp:6;
311 #endif
312  uint8_t ttl_hopl;
313  uint16_t ip_id;
314 } __attribute__((packed)) ipv4_dynamic2_t;
315 
316 
317 /**
318  * @brief The IPv4 replicate part
319  *
320  * See RFC6846 page 64
321  */
322 typedef struct
323 {
324 #if WORDS_BIGENDIAN == 1
325  uint8_t reserved:4; /* reserved =:= '0000' [ 4 ]; */
326  uint8_t ip_id_behavior:2; /* ip_id_behavior_innermost =:= irregular(2) [ 2 ]; */
327  uint8_t ttl_flag:1; /* ttl_flag =:= irregular(1) [ 1 ]; */
328  uint8_t df:1; /* df =:= irregular(1) [ 1 ]; */
329  uint8_t dscp:6; /* dscp =:= irregular(6) [ 6 ]; */
330  uint8_t ip_ecn_flags:2; /* ip_ecn_flags =:= irregular(2) [ 2 ]; */
331 #else
332  uint8_t df:1;
333  uint8_t ttl_flag:1;
334  uint8_t ip_id_behavior:2;
335  uint8_t reserved:4;
336  uint8_t ip_ecn_flags:2;
337  uint8_t dscp:6;
338 #endif
339  /* ip_id =:= ip_id_enc_dyn(ip_id_behavior_innermost.UVALUE) [ 0, 16 ]; */
340  /* ttl_hopl =:= static_or_irreg(ttl_flag.UVALUE, 8) [ 0, 8 ]; */
341 } __attribute__((packed)) ipv4_replicate_t;
342 
343 
344 
345 /************************************************************************
346  * Compressed IPv6 base header and its extension headers *
347  ************************************************************************/
348 
349 /** The static part of IPv6 option header */
350 typedef struct
351 {
352  uint8_t next_header;
353  uint8_t length;
354 } __attribute__((packed)) ip_opt_static_t;
355 
356 
357 /** The static part of IPv6 Destination option header */
358 typedef struct
359 {
360  uint8_t next_header;
361  uint8_t length;
362 } __attribute__((packed)) ip_dest_opt_static_t;
363 
364 
365 /** The static part of IPv6 Hop-by-Hop option header */
366 typedef struct
367 {
368  uint8_t next_header;
369  uint8_t length;
370 } __attribute__((packed)) ip_hop_opt_static_t;
371 
372 
373 /** The static part of IPv6 Routing option header */
374 typedef struct
375 {
376  uint8_t next_header;
377  uint8_t length;
378  uint8_t value[1];
379 } __attribute__((packed)) ip_rout_opt_static_t;
380 
381 
382 /**
383  * @brief The IPv6 static part, null flow_label encoded with 1 bit
384  *
385  * See RFC4996 page 58
386  */
387 typedef struct
388 {
389 #if WORDS_BIGENDIAN == 1
390  uint8_t version_flag:1;
391  uint8_t reserved1:2;
392  uint8_t flow_label_enc_discriminator:1;
393  uint8_t reserved2:4;
394 #else
395  uint8_t reserved2:4;
397  uint8_t reserved1:2;
398  uint8_t version_flag:1;
399 #endif
400  uint8_t next_header;
401  uint32_t src_addr[4];
402  uint32_t dst_addr[4];
403 } __attribute__((packed)) ipv6_static1_t;
404 
405 
406 /**
407  * @brief The IPv6 static part, flow_label encoded with 1+20 bits
408  *
409  * See RFC4996 page 59
410  */
411 typedef struct
412 {
413 #if WORDS_BIGENDIAN == 1
414  uint8_t version_flag:1;
415  uint8_t reserved:2;
416  uint8_t flow_label_enc_discriminator:1;
417  uint8_t flow_label1:4;
418 #else
419  uint8_t flow_label1:4;
421  uint8_t reserved:2;
422  uint8_t version_flag:1;
423 #endif
424  uint16_t flow_label2;
425  uint8_t next_header;
426  uint32_t src_addr[4];
427  uint32_t dst_addr[4];
428 } __attribute__((packed)) ipv6_static2_t;
429 
430 
431 /**
432  * @brief The IPv6 dynamic part
433  *
434  * See RFC4996 page 59
435  */
436 typedef struct
437 {
438 #if WORDS_BIGENDIAN == 1
439  uint8_t dscp:6;
440  uint8_t ip_ecn_flags:2;
441 #else
442  uint8_t ip_ecn_flags:2;
443  uint8_t dscp:6;
444 #endif
445  uint8_t ttl_hopl;
446 } __attribute__((packed)) ipv6_dynamic_t;
447 
448 
449 /**
450  * @brief The IPv6 replicate part with short Flow Label
451  *
452  * See RFC6846 page 60
453  */
454 typedef struct
455 {
456 #if WORDS_BIGENDIAN == 1
457  uint8_t dscp:6; /* dscp =:= irregular(6) [ 6 ]; */
458  uint8_t ip_ecn_flags:2; /* ip_ecn_flags =:= irregular(2) [ 2 ]; */
459  uint8_t reserved1:3; /* reserved =:= '000' [ 3 ]; */
460  uint8_t fl_enc_flag:1; /* flow_label =:= fl_enc [ 1 ]; */
461  uint8_t reserved2:4; /* reserved =:= '0000' [ 4 ]; */
462 #else
463  uint8_t ip_ecn_flags:2;
464  uint8_t dscp:6;
465  uint8_t reserved2:4;
466  uint8_t fl_enc_flag:1;
467  uint8_t reserved1:3;
468 #endif
469 } __attribute__((packed)) ipv6_replicate1_t;
470 
471 
472 /**
473  * @brief The IPv6 replicate part with long Flow Label
474  *
475  * See RFC6846 page 60
476  */
477 typedef struct
478 {
479 #if WORDS_BIGENDIAN == 1
480  uint8_t dscp:6; /* dscp =:= irregular(6) [ 6 ]; */
481  uint8_t ip_ecn_flags:2; /* ip_ecn_flags =:= irregular(2) [ 2 ]; */
482  uint8_t reserved:3; /* reserved =:= '000' [ 3 ]; */
483  uint8_t fl_enc_flag:1; /* flow_label =:= fl_enc [ 21 ]; */
484  uint8_t flow_label1:4;
485 #else
486  uint8_t ip_ecn_flags:2;
487  uint8_t dscp:6;
488  uint8_t flow_label1:4;
489  uint8_t fl_enc_flag:1;
490  uint8_t reserved:3;
491 #endif
492  uint16_t flow_label2;
493 } __attribute__((packed)) ipv6_replicate2_t;
494 
495 
496 
497 /************************************************************************
498  * Compressed TCP header and its options *
499  ************************************************************************/
500 
501 /**
502  * @brief The TCP static part
503  *
504  * See RFC4996 page 73/74
505  */
506 typedef struct
507 {
508  uint16_t src_port; /**< irregular(16) [ 16 ] */
509  uint16_t dst_port; /**< irregular(16) [ 16 ] */
510 } __attribute__((packed)) tcp_static_t;
511 
512 
513 /**
514  * @brief The TCP dynamic part
515  *
516  * See RFC4996 page 73/74
517  */
518 typedef struct
519 {
520 #if WORDS_BIGENDIAN == 1
521  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
522  uint8_t ack_stride_flag:1; /**< irregular(1) [ 1 ] */
523  uint8_t ack_zero:1; /**< irregular(1) [ 1 ] */
524  uint8_t urp_zero:1; /**< irregular(1) [ 1 ] */
525  uint8_t tcp_res_flags:4; /**< irregular(4) [ 4 ] */
526 
527  uint8_t tcp_ecn_flags:2; /**< irregular(2) [ 2 ] */
528  uint8_t urg_flag:1; /**< irregular(1) [ 1 ] */
529  uint8_t ack_flag:1; /**< irregular(1) [ 1 ] */
530  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
531  uint8_t rsf_flags:3; /**< irregular(3) [ 3 ] */
532 #else
533  uint8_t tcp_res_flags:4;
534  uint8_t urp_zero:1;
535  uint8_t ack_zero:1;
536  uint8_t ack_stride_flag:1;
537  uint8_t ecn_used:1;
538 
539  uint8_t rsf_flags:3;
540  uint8_t psh_flag:1;
541  uint8_t ack_flag:1;
542  uint8_t urg_flag:1;
543  uint8_t tcp_ecn_flags:2;
544 #endif
545  uint16_t msn; /**< irregular(16) [ 16 ] */
546  uint32_t seq_num; /**< irregular(32) [ 32 ] */
547 
548  /* variable fields:
549  * zero_or_irreg(ack_zero.CVALUE, 32) [ 0, 32 ]
550  * irregular(16) [ 16 ]
551  * irregular(16) [ 16 ]
552  * zero_or_irreg(urp_zero.CVALUE, 16) [ 0, 16 ]
553  * static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ]
554  * list_tcp_options [ VARIABLE ]
555  */
556 
557 } __attribute__((packed)) tcp_dynamic_t;
558 
559 
560 /**
561  * @brief The different presence flags for port_replicate() encoding scheme
562  */
563 enum
564 {
565  ROHC_TCP_PORT_STATIC = 0, /**< port is static, so it is not transmitted */
566  ROHC_TCP_PORT_LSB8 = 1, /**< port is not static and it is compressible */
567  ROHC_TCP_PORT_IRREGULAR = 2, /**< port is not static and it is not compressible */
568  ROHC_TCP_PORT_RESERVED = 3, /**< reserved value */
569 };
570 
571 /**
572  * @brief The TCP replicate part
573  *
574  * See RFC6846 pages 75-76
575  */
576 typedef struct
577 {
578 #if WORDS_BIGENDIAN == 1
579  uint8_t reserved:1; /**< reserved '0' [ 1 ] */
580  uint8_t window_presence:1; /**< irregular(1) [ 1 ] */
581  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
582  uint8_t src_port_presence:2; /**< irregular(2) [ 2 ] */
583  uint8_t dst_port_presence:2; /**< irregular(2) [ 2 ] */
584  uint8_t ack_stride_flag:1; /**< irregular(1) [ 1 ] */
585 
586  uint8_t ack_presence:1; /**< irregular(1) [ 1 ] */
587  uint8_t urp_presence:1; /**< irregular(1) [ 1 ] */
588  uint8_t urg_flag:1; /**< irregular(1) [ 1 ] */
589  uint8_t ack_flag:1; /**< irregular(1) [ 1 ] */
590  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
591  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
592  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
593 #else
594  uint8_t ack_stride_flag:1;
595  uint8_t dst_port_presence:2;
596  uint8_t src_port_presence:2;
597  uint8_t list_present:1;
598  uint8_t window_presence:1;
599  uint8_t reserved:1;
600 
601  uint8_t ecn_used:1;
602  uint8_t rsf_flags:2;
603  uint8_t psh_flag:1;
604  uint8_t ack_flag:1;
605  uint8_t urg_flag:1;
606  uint8_t urp_presence:1;
607  uint8_t ack_presence:1;
608 #endif
609  uint16_t msn; /**< irregular(16) [ 16 ] */
610  uint32_t seq_num; /**< irregular(32) [ 32 ] */
611 
612  /* variable fields:
613  * src_port =:= port_replicate(src_port_presence) [ 0, 8, 16 ]
614  * dst_port =:= port_replicate(dst_port_presence) [ 0, 8, 16 ]
615  * window =:= static_or_irreg(window_presence, 16) [ 0, 16 ]
616  * urg_point =:= static_or_irreg(urp_presence, 16) [ 0, 16 ]
617  * ack_number =:= static_or_irreg(ack_presence, 32) [ 0, 32 ]
618  * ecn_padding =:= optional_2bit_padding(ecn_used.CVALUE) [ 0, 2 ]
619  * tcp_res_flags =:= static_or_irreg(ecn_used.CVALUE, 4) [ 0, 4 ]
620  * tcp_ecn_flags =:= static_or_irreg(ecn_used.CVALUE, 2) [ 0, 2 ]
621  * checksum =:= irregular(16) [ 16 ]
622  * ack_stride =:= static_or_irreg(ack_stride_flag.CVALUE, 16) [ 0, 16 ]
623  * options =:= tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]
624  */
625 
626 } __attribute__((packed)) tcp_replicate_t;
627 
628 
629 /**
630  * @brief The Common compressed packet format
631  *
632  * See RFC4996 page 80/81
633  */
634 typedef struct
635 {
636 #if WORDS_BIGENDIAN == 1
637 
638  uint8_t discriminator:7; /**< '1111101' [ 7 ] */
639  uint8_t ttl_hopl_outer_flag:1; /**< compressed_value(1,
640  ttl_irregular_chain_flag) [ 1 ] */
641 
642  uint8_t ack_flag:1; /**< irregular(1) [ 1 ] */
643  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
644  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
645  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
646 
647  uint8_t seq_indicator:2; /**< irregular(2) [ 2 ] */
648  uint8_t ack_indicator:2; /**< irregular(2) [ 2 ] */
649  uint8_t ack_stride_indicator:1; /**< irregular(1) [ 1 ] */
650  uint8_t window_indicator:1; /**< irregular(1) [ 1 ] */
651  uint8_t ip_id_indicator:1; /**< irregular(1) [ 1 ] */
652  uint8_t urg_ptr_present:1; /**< irregular(1) [ 1 ] */
653 
654  uint8_t reserved:1; /**< compressed_value(1, 0) [ 1 ] */
655  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
656  uint8_t dscp_present:1; /**< irregular(1) [ 1 ] */
657  uint8_t ttl_hopl_present:1; /**< irregular(1) [ 1 ] */
658  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
659  uint8_t ip_id_behavior:2; /**< ip_id_behavior_choice(true) [ 2 ] */
660  uint8_t urg_flag:1; /**< irregular(1) [ 1 ] */
661 
662  uint8_t df:1; /**< dont_fragment(version.UVALUE) [ 1 ] */
663  uint8_t header_crc:7; /**< crc7(THIS.UVALUE,THIS.ULENGTH) [ 7 ] */
664 
665 #else
666 
668  uint8_t discriminator:7;
669 
670  uint8_t msn:4;
671  uint8_t rsf_flags:2;
672  uint8_t psh_flag:1;
673  uint8_t ack_flag:1;
674 
675  uint8_t urg_ptr_present:1;
676  uint8_t ip_id_indicator:1;
677  uint8_t window_indicator:1;
679  uint8_t ack_indicator:2;
680  uint8_t seq_indicator:2;
681 
682  uint8_t urg_flag:1;
683  uint8_t ip_id_behavior:2;
684  uint8_t list_present:1;
685  uint8_t ttl_hopl_present:1;
686  uint8_t dscp_present:1;
687  uint8_t ecn_used:1;
688  uint8_t reserved:1;
689 
690  uint8_t header_crc:7;
691  uint8_t df:1;
692 
693 #endif
694 
695  /* variable fields:
696  * variable_length_32_enc(seq_indicator.CVALUE) [ 0, 8, 16, 32 ]
697  * variable_length_32_enc(ack_indicator.CVALUE) [ 0, 8, 16, 32 ]
698  * static_or_irreg(ack_stride_indicator.CVALUE, 16) [ 0, 16 ]
699  * static_or_irreg(window_indicator.CVALUE, 16) [ 0, 16 ]
700  * optional_ip_id_lsb(ip_id_behavior.UVALUE,ip_id_indicator.CVALUE) [ 0, 8, 16 ]
701  * static_or_irreg(urg_ptr_present.CVALUE, 16) [ 0, 16 ]
702  * dscp_enc-dscp_present.CVALUE) [ 0, 8 ]
703  * static_or_irreg(ttl_hopl_present.CVALUE, 8) [ 0, 8 ]
704  * tcp_list_presence_enc(list_present.CVALUE) [ VARIABLE ]
705  * irregular chain [ VARIABLE ]
706  */
707 
708 } __attribute__((packed)) co_common_t;
709 
710 
711 /**
712  * @brief The rnd_1 compressed packet format
713  *
714  * Send LSBs of sequence number
715  * See RFC4996 page 81
716  */
717 typedef struct
718 {
719 #if WORDS_BIGENDIAN == 1
720  uint8_t discriminator:6; /**< '101110' [ 6 ] */
721  uint8_t seq_num1:2; /**< lsb(18, 65535) [ 18 ] */
722  uint16_t seq_num2; /**< sequel of \e seq_num1 [ - ] */
723  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
724  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
725  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
726 #else
727  uint8_t seq_num1:2;
728  uint8_t discriminator:6;
729  uint16_t seq_num2;
730  uint8_t header_crc:3;
731  uint8_t psh_flag:1;
732  uint8_t msn:4;
733 #endif
734  /* irregular chain [ VARIABLE ] */
735 } __attribute__((packed)) rnd_1_t;
736 
737 
738 /**
739  * @brief The rnd_2 compressed packet format
740  *
741  * Send scaled sequence number LSBs
742  * See RFC4996 page 81
743  */
744 typedef struct
745 {
746 #if WORDS_BIGENDIAN == 1
747  uint8_t discriminator:4; /**< '1100' [ 4 ] */
748  uint8_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
749  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
750  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
751  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
752 #else
753  uint8_t seq_num_scaled:4;
754  uint8_t discriminator:4;
755  uint8_t header_crc:3;
756  uint8_t psh_flag:1;
757  uint8_t msn:4;
758 #endif
759  /* irregular chain [ VARIABLE ] */
760 } __attribute__((packed)) rnd_2_t;
761 
762 
763 /**
764  * @brief The rnd_3 compressed packet format
765  *
766  * Send acknowledgment number LSBs
767  * See RFC4996 page 81
768  */
769 typedef struct
770 {
771 #if WORDS_BIGENDIAN == 1
772  uint8_t discriminator:1; /**< '0' [ 1 ] */
773  uint8_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
774  uint8_t ack_num2; /**< sequel of \e ack_num1 [ - ] */
775  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
776  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
777  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
778 #else
779  uint8_t ack_num1:7;
780  uint8_t discriminator:1;
781  uint8_t ack_num2:8;
782  uint8_t header_crc:3;
783  uint8_t psh_flag:1;
784  uint8_t msn:4;
785 #endif
786  /* irregular chain [ VARIABLE ] */
787 } __attribute__((packed)) rnd_3_t;
788 
789 
790 /**
791  * @brief The rnd_4 compressed packet format
792  *
793  * Send acknowlegment number scaled
794  * See RFC4996 page 81
795  */
796 typedef struct
797 {
798 #if WORDS_BIGENDIAN == 1
799  uint8_t discriminator:4; /**< '1101' [ 4 ] */
800  uint8_t ack_num_scaled:4; /**< lsb(4, 3) [ 4 ] */
801  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
802  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
803  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
804 #else
805  uint8_t ack_num_scaled:4;
806  uint8_t discriminator:4;
807  uint8_t header_crc:3;
808  uint8_t psh_flag:1;
809  uint8_t msn:4;
810 #endif
811  /* irregular chain [ VARIABLE ] */
812 } __attribute__((packed)) rnd_4_t;
813 
814 
815 /**
816  * @brief The rnd_5 compressed packet format
817  *
818  * Send ACK and sequence number
819  * See RFC4996 page 82
820  */
821 typedef struct
822 {
823 #if WORDS_BIGENDIAN == 1
824  uint8_t discriminator:3; /**< '100' [ 3 ] */
825  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
826  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
827  uint32_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
828  uint32_t seq_num1:5; /**< lsb(14, 8191) [ 14 ] */
829  uint32_t seq_num2:8; /**< sequel of \e seq_num1 [ - ] */
830  uint32_t seq_num3:1; /**< sequel of \e seq_num1 and \e seq_num2 [ - ] */
831  uint32_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
832  uint32_t ack_num2:8; /**< sequel of \e ack_num1 [ - ] */
833 #else
834  uint8_t msn:4;
835  uint8_t psh_flag:1;
836  uint8_t discriminator:3;
837  uint8_t seq_num1:5;
838  uint8_t header_crc:3;
839  uint8_t seq_num2;
840  uint8_t ack_num1:7;
841  uint8_t seq_num3:1;
842  uint8_t ack_num2;
843 #endif
844  /* irregular chain [ VARIABLE ] */
845 } __attribute__((packed)) rnd_5_t;
846 
847 
848 /**
849  * @brief The rnd_6 compressed packet format
850  *
851  * Send both ACK and scaled sequence number LSBs
852  * See RFC4996 page 82
853  */
854 typedef struct
855 {
856 #if WORDS_BIGENDIAN == 1
857  uint8_t discriminator:4; /**< '1010' [ 4 ] */
858  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
859  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
860 #else
861  uint8_t psh_flag:1;
862  uint8_t header_crc:3;
863  uint8_t discriminator:4;
864 #endif
865  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
866 #if WORDS_BIGENDIAN == 1
867  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
868  uint8_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
869 #else
870  uint8_t seq_num_scaled:4;
871  uint8_t msn:4;
872 #endif
873  /* irregular chain [ VARIABLE ] */
874 } __attribute__((packed)) rnd_6_t;
875 
876 
877 /**
878  * @brief The rnd_7 compressed packet format
879  *
880  * Send ACK and window
881  * See RFC4996 page 82
882  */
883 typedef struct
884 {
885 #if WORDS_BIGENDIAN == 1
886  uint8_t discriminator:6; /**< '101111' [ 6 ] */
887  uint8_t ack_num1:2; /**< lsb(18, 65535) [ 18 ] */
888  uint16_t ack_num2; /**< sequel of \e ack_num1 [ - ]*/
889 #else
890  uint8_t ack_num1:2;
891  uint8_t discriminator:6;
892  uint16_t ack_num2;
893 #endif
894  uint16_t window; /**< irregular(16) [ 16 ] */
895 #if WORDS_BIGENDIAN == 1
896  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
897  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
898  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
899 #else
900  uint8_t header_crc:3;
901  uint8_t psh_flag:1;
902  uint8_t msn:4;
903 #endif
904  /* irregular chain [ VARIABLE ] */
905 } __attribute__((packed)) rnd_7_t;
906 
907 
908 /**
909  * @brief The rnd_8 compressed packet format
910  *
911  * Can send LSBs of TTL, RSF flags, change ECN behavior and options list
912  * See RFC4996 page 82
913  */
914 typedef struct
915 {
916 #if WORDS_BIGENDIAN == 1
917  uint8_t discriminator:5; /**< '10110' [ 5 ] */
918  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
919  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
920  uint16_t header_crc:7; /**< crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ] */
921  uint16_t msn1:1; /**< lsb(4, 4) [ 4 ] */
922  uint16_t msn2:3; /**< sequel of \e msn1 [ - ] */
923  uint16_t psh_flag:1; /**< irregular(1) [ 1 ] */
924  uint16_t ttl_hopl:3; /**< lsb(3, 3) [ 3 ] */
925  uint16_t ecn_used:1; /**< one_bit_choice [ 1 ] */
926 #else
927  uint8_t list_present:1;
928  uint8_t rsf_flags:2;
929  uint8_t discriminator:5;
930  uint8_t msn1:1;
931  uint8_t header_crc:7;
932  uint8_t ecn_used:1;
933  uint8_t ttl_hopl:3;
934  uint8_t psh_flag:1;
935  uint8_t msn2:3;
936 #endif
937  uint16_t seq_num; /**< lsb(16, 65535) [ 16 ] */
938  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
939  uint8_t options[0]; /**< tcp_list_presence_enc(list_present.CVALUE)
940  [ VARIABLE ] */
941  /* irregular chain [ VARIABLE ] */
942 } __attribute__((packed)) rnd_8_t;
943 
944 
945 /**
946  * @brief The seq_1 compressed packet format
947  *
948  * Send LSBs of sequence number
949  * See RFC4996 page 83
950  */
951 typedef struct
952 {
953 #if WORDS_BIGENDIAN == 1
954  uint8_t discriminator:4; /**< '1010' [ 4 ] */
955  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
956 #else
957  uint8_t ip_id:4;
958  uint8_t discriminator:4;
959 #endif
960  uint16_t seq_num; /**< lsb(16, 32767) [ 16 ] */
961 #if WORDS_BIGENDIAN == 1
962  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
963  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
964  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
965 #else
966  uint8_t header_crc:3;
967  uint8_t psh_flag:1;
968  uint8_t msn:4;
969 #endif
970  /* irregular chain [ VARIABLE ] */
971 } __attribute__((packed)) seq_1_t;
972 
973 
974 /**
975  * @brief The seq_2 compressed packet format
976  *
977  * Send scaled sequence number LSBs
978  * See RFC4996 page 83
979  */
980 typedef struct
981 {
982 #if WORDS_BIGENDIAN == 1
983  uint16_t discriminator:5; /**< '11010' [ 5 ] */
984  uint16_t ip_id1:3; /**< ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ] */
985  uint16_t ip_id2:4; /**< sequel of ip_id1 [ - ] */
986  uint16_t seq_num_scaled:4; /**< lsb(4, 7) [ 4 ] */
987  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
988  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
989  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
990 #else
991  uint8_t ip_id1:3;
992  uint8_t discriminator:5;
993  uint8_t seq_num_scaled:4;
994  uint8_t ip_id2:4;
995  uint8_t header_crc:3;
996  uint8_t psh_flag:1;
997  uint8_t msn:4;
998 #endif
999  /* irregular chain [ VARIABLE ] */
1000 } __attribute__((packed)) seq_2_t;
1001 
1002 
1003 /**
1004  * @brief The seq_3 compressed packet format
1005  *
1006  * Send acknowledgment number LSBs
1007  * See RFC4996 page 83
1008  */
1009 typedef struct
1010 {
1011 #if WORDS_BIGENDIAN == 1
1012  uint8_t discriminator:4; /**< '1001' [ 4 ] */
1013  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
1014 #else
1015  uint8_t ip_id:4;
1016  uint8_t discriminator:4;
1017 #endif
1018  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
1019 #if WORDS_BIGENDIAN == 1
1020  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1021  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1022  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
1023 #else
1024  uint8_t header_crc:3;
1025  uint8_t psh_flag:1;
1026  uint8_t msn:4;
1027 #endif
1028  /* irregular chain [ VARIABLE ] */
1029 } __attribute__((packed)) seq_3_t;
1030 
1031 
1032 /**
1033  * @brief The seq_4 compressed packet format
1034  *
1035  * Send scaled acknowledgment number scaled
1036  * See RFC4996 page 84
1037  */
1038 typedef struct
1039 {
1040 #if WORDS_BIGENDIAN == 1
1041  uint8_t discriminator:1; /**< '0' [ 1 ] */
1042  uint8_t ack_num_scaled:4; /**< lsb(4, 3) [ 4 ] */
1043  uint8_t ip_id:3; /**< ip_id_lsb(ip_id_behavior.UVALUE, 3, 1) [ 3 ] */
1044  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1045  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1046  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
1047 #else
1048  uint8_t ip_id:3;
1049  uint8_t ack_num_scaled:4;
1050  uint8_t discriminator:1;
1051  uint8_t header_crc:3;
1052  uint8_t psh_flag:1;
1053  uint8_t msn:4;
1054 #endif
1055  /* irregular chain [ VARIABLE ] */
1056 } __attribute__((packed)) seq_4_t;
1057 
1058 
1059 /**
1060  * @brief The seq_5 compressed packet format
1061  *
1062  * Send ACK and sequence number
1063  * See RFC4996 page 84
1064  */
1065 typedef struct
1066 {
1067 #if WORDS_BIGENDIAN == 1
1068  uint8_t discriminator:4; /**< '1000' [ 4 ] */
1069  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
1070 #else
1071  uint8_t ip_id:4;
1072  uint8_t discriminator:4;
1073 #endif
1074  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
1075  uint16_t seq_num; /**< lsb(16, 32767) [ 16 ] */
1076 #if WORDS_BIGENDIAN == 1
1077  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1078  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1079  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
1080 #else
1081  uint8_t header_crc:3;
1082  uint8_t psh_flag:1;
1083  uint8_t msn:4;
1084 #endif
1085  /* irregular chain [ VARIABLE ] */
1086 } __attribute__((packed)) seq_5_t;
1087 
1088 
1089 /**
1090  * @brief The seq_6 compressed packet format
1091  *
1092  * Send both ACK and scaled sequence number LSBs
1093  * See RFC4996 page 84
1094  */
1095 typedef struct
1096 {
1097 #if WORDS_BIGENDIAN == 1
1098  uint16_t discriminator:5; /**< '11011' [ 5 ] */
1099  uint16_t seq_num_scaled1:3; /**< lsb(4, 7) [ 4 ] */
1100  uint16_t seq_num_scaled2:1; /**< sequel of \e seq_num_scaled1 [ 4 ] */
1101  uint16_t ip_id:7; /**< ip_id_lsb(ip_id_behavior.UVALUE, 7, 3) [ 7 ] */
1102 #else
1103  uint8_t seq_num_scaled1:3;
1104  uint8_t discriminator:5;
1105  uint8_t ip_id:7;
1106  uint8_t seq_num_scaled2:1;
1107 #endif
1108  uint16_t ack_num; /**< lsb(16, 16383) [ 16 ] */
1109 #if WORDS_BIGENDIAN == 1
1110  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1111  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1112  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
1113 #else
1114  uint8_t header_crc:3;
1115  uint8_t psh_flag:1;
1116  uint8_t msn:4;
1117 #endif
1118  /* irregular chain [ VARIABLE ] */
1119 } __attribute__((packed)) seq_6_t;
1120 
1121 
1122 /**
1123  * @brief The seq_7 compressed packet format
1124  *
1125  * Send ACK and window
1126  * See RFC4996 page 85
1127  */
1128 typedef struct
1129 {
1130 #if WORDS_BIGENDIAN == 1
1131  uint8_t discriminator:4; /**< '1100' [ 4 ] */
1132  uint8_t window1:4; /**< lsb(15, 16383) [ 15 ] */
1133  uint8_t window2; /**< sequel of \e window1 [ - ] */
1134  uint8_t window3:3; /**< sequel of \e window1 and \e window2 [ - ] */
1135  uint8_t ip_id:5; /**< ip_id_lsb(ip_id_behavior.UVALUE, 5, 3) [ 5 ] */
1136  uint16_t ack_num; /**< lsb(16, 32767) [ 16 ] */
1137  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1138  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1139  uint8_t header_crc:3; /**< crc3(THIS.UVALUE, THIS.ULENGTH) [ 3 ] */
1140 #else
1141  uint8_t window1:4;
1142  uint8_t discriminator:4;
1143  uint8_t window2;
1144  uint8_t ip_id:5;
1145  uint8_t window3:3;
1146  uint16_t ack_num;
1147  uint8_t header_crc:3;
1148  uint8_t psh_flag:1;
1149  uint8_t msn:4;
1150 #endif
1151  /* irregular chain [ VARIABLE ] */
1152 } __attribute__((packed)) seq_7_t;
1153 
1154 
1155 /**
1156  * @brief The seq_8 compressed packet format
1157  *
1158  * Can send LSBs of TTL, RSF flags, change ECN behavior, and options list
1159  * See RFC4996 page 85
1160  */
1161 typedef struct
1162 {
1163 #if WORDS_BIGENDIAN == 1
1164  uint8_t discriminator:4; /**< '1011' [ 4 ] */
1165  uint8_t ip_id:4; /**< ip_id_lsb(ip_id_behavior.UVALUE, 4, 3) [ 4 ] */
1166  uint8_t list_present:1; /**< irregular(1) [ 1 ] */
1167  uint8_t header_crc:7; /**< crc7(THIS.UVALUE, THIS.ULENGTH) [ 7 ] */
1168  uint8_t msn:4; /**< lsb(4, 4) [ 4 ] */
1169  uint8_t psh_flag:1; /**< irregular(1) [ 1 ] */
1170  uint8_t ttl_hopl:3; /**< lsb(3, 3) [ 3 ] */
1171  uint8_t ecn_used:1; /**< one_bit_choice [ 1 ] */
1172  uint8_t ack_num1:7; /**< lsb(15, 8191) [ 15 ] */
1173  uint8_t ack_num2; /**< sequel of \e ack_num1 [ - ] */
1174  uint8_t rsf_flags:2; /**< rsf_index_enc [ 2 ] */
1175  uint8_t seq_num1:6; /**< lsb(14, 8191) [ 14 ] */
1176  uint8_t seq_num2; /**< sequel of \e seq_num1 [ - ] */
1177 #else
1178  uint8_t ip_id:4;
1179  uint8_t discriminator:4;
1180  uint8_t header_crc:7;
1181  uint8_t list_present:1;
1182  uint8_t ttl_hopl:3;
1183  uint8_t psh_flag:1;
1184  uint8_t msn:4;
1185  uint8_t ack_num1:7;
1186  uint8_t ecn_used:1;
1187  uint8_t ack_num2;
1188  uint8_t seq_num1:6;
1189  uint8_t rsf_flags:2;
1190  uint8_t seq_num2:8;
1191 #endif
1192  uint8_t options[0]; /**< tcp_list_presence_enc(list_present.CVALUE)
1193  [ VARIABLE ] */
1194  /* irregular chain [ VARIABLE ] */
1195 } __attribute__((packed)) seq_8_t;
1196 
1197 
1198 
1199 /************************************************************************
1200  * Helper functions *
1201  ************************************************************************/
1202 
1203 static inline char * tcp_ip_id_behavior_get_descr(const tcp_ip_id_behavior_t ip_id_behavior)
1204  __attribute__((warn_unused_result, const));
1205 
1206 static inline char * tcp_opt_get_descr(const uint8_t opt_type)
1207  __attribute__((warn_unused_result, const));
1208 
1209 
1210 /**
1211  * @brief Get a string that describes the given IP-ID behavior
1212  *
1213  * @param behavior The type of the option to get a description for
1214  * @return The description of the option
1215  */
1216 static inline char * tcp_ip_id_behavior_get_descr(const tcp_ip_id_behavior_t behavior)
1217 {
1218  switch(behavior)
1219  {
1220  case IP_ID_BEHAVIOR_SEQ:
1221  return "sequential";
1223  return "sequential swapped";
1224  case IP_ID_BEHAVIOR_RAND:
1225  return "random";
1226  case IP_ID_BEHAVIOR_ZERO:
1227  return "constant zero";
1228  default:
1229  return "unknown IP-ID behavior";
1230  }
1231 }
1232 
1233 
1234 /**
1235  * @brief Get a string that describes the given option type
1236  *
1237  * @param opt_type The type of the option to get a description for
1238  * @return The description of the option
1239  */
1240 static inline char * tcp_opt_get_descr(const uint8_t opt_type)
1241 {
1242  switch(opt_type)
1243  {
1244  case TCP_OPT_EOL:
1245  return "EOL";
1246  case TCP_OPT_NOP:
1247  return "NOP";
1248  case TCP_OPT_MSS:
1249  return "MSS";
1250  case TCP_OPT_WS:
1251  return "Window Scale";
1252  case TCP_OPT_SACK_PERM:
1253  return "SACK permitted";
1254  case TCP_OPT_SACK:
1255  return "SACK";
1256  case TCP_OPT_TS:
1257  return "Timestamp";
1258  default:
1259  return "generic";
1260  }
1261 }
1262 
1263 
1264 #endif /* ROHC_PROTOCOLS_TCP_H */
1265 
uint8_t ecn_flags
Definition: tcp.h:136
uint8_t rsf_flags
Definition: tcp.h:602
uint32_t ts
Definition: tcp.h:228
uint8_t ack_num1
Definition: tcp.h:1185
uint8_t psh_flag
Definition: tcp.h:835
uint8_t discriminator
Definition: tcp.h:1104
uint8_t ttl_hopl_present
Definition: tcp.h:685
uint16_t window
Definition: tcp.h:138
Definition: tcp.h:567
The rnd_1 compressed packet format.
Definition: tcp.h:717
The TCP replicate part.
Definition: tcp.h:576
uint8_t flow_label_enc_discriminator
Definition: tcp.h:396
uint8_t rsf_flags
Definition: tcp.h:928
uint8_t ack_presence
Definition: tcp.h:607
uint8_t ip_ecn_flags
Definition: tcp.h:463
uint8_t list_present
Definition: tcp.h:927
The rnd_6 compressed packet format.
Definition: tcp.h:854
uint8_t ip_id_behavior
Definition: tcp.h:306
uint8_t version_flag
Definition: tcp.h:250
uint8_t ack_num1
Definition: tcp.h:779
uint8_t psh_flag
Definition: tcp.h:731
uint16_t flow_label2
Definition: tcp.h:492
The Selective Acknowlegment TCP option.
Definition: tcp.h:214
uint8_t ack_num2
Definition: tcp.h:781
uint8_t ip_ecn_flags
Definition: tcp.h:309
uint8_t ip_id
Definition: tcp.h:1105
uint8_t reserved2
Definition: tcp.h:465
uint8_t protocol
Definition: tcp.h:252
uint8_t urp_presence
Definition: tcp.h:606
Definition: tcp.h:358
uint8_t discriminator
Definition: tcp.h:806
uint8_t ecn_used
Definition: tcp.h:932
uint8_t version_flag
Definition: tcp.h:398
uint8_t discriminator
Definition: tcp.h:863
uint8_t ip_id_behavior
Definition: tcp.h:683
Definition: tcp.h:174
uint8_t df
Definition: tcp.h:691
The rnd_2 compressed packet format.
Definition: tcp.h:744
Definition: tcp.h:568
uint8_t reserved
Definition: tcp.h:249
uint32_t block_end
Definition: tcp.h:217
uint8_t msn
Definition: tcp.h:834
uint16_t msn
Definition: tcp.h:609
uint8_t discriminator
Definition: tcp.h:1179
uint8_t msn
Definition: tcp.h:902
uint8_t next_header
Definition: tcp.h:376
uint8_t ack_zero
Definition: tcp.h:535
uint8_t ip_id_indicator
Definition: tcp.h:676
The rnd_8 compressed packet format.
Definition: tcp.h:914
Definition: tcp.h:163
uint8_t flow_label_enc_discriminator
Definition: tcp.h:420
uint8_t reserved
Definition: tcp.h:490
Definition: tcp.h:176
uint8_t ip_id
Definition: tcp.h:957
uint16_t dst_port
Definition: tcp.h:118
uint8_t psh_flag
Definition: tcp.h:1052
uint8_t header_crc
Definition: tcp.h:755
uint16_t ack_num
Definition: tcp.h:1018
uint8_t version_flag
Definition: tcp.h:422
uint8_t urg_flag
Definition: tcp.h:682
uint8_t list_present
Definition: tcp.h:1181
uint8_t msn
Definition: tcp.h:997
uint8_t seq_num_scaled
Definition: tcp.h:870
uint8_t psh_flag
Definition: tcp.h:603
uint8_t ack_flag
Definition: tcp.h:541
uint16_t seq_num
Definition: tcp.h:1075
The IPv6 static part, flow_label encoded with 1+20 bits.
Definition: tcp.h:411
uint8_t discriminator
Definition: tcp.h:992
uint16_t ack_num
Definition: tcp.h:865
uint8_t psh_flag
Definition: tcp.h:1115
uint16_t msn
Definition: tcp.h:545
Definition: tcp.h:374
uint8_t seq_num1
Definition: tcp.h:837
uint8_t window1
Definition: tcp.h:1141
The rnd_7 compressed packet format.
Definition: tcp.h:883
uint8_t psh_flag
Definition: tcp.h:783
uint8_t ack_num1
Definition: tcp.h:840
uint8_t window2
Definition: tcp.h:1143
uint8_t rsf_flags
Definition: tcp.h:1189
uint8_t dscp
Definition: tcp.h:443
The rnd_4 compressed packet format.
Definition: tcp.h:796
uint8_t ttl_hopl
Definition: tcp.h:1182
uint8_t ttl_hopl
Definition: tcp.h:288
Definition: tcp.h:162
uint8_t discriminator
Definition: tcp.h:1050
uint8_t discriminator
Definition: tcp.h:958
Definition: tcp.h:366
Definition: tcp.h:350
uint8_t reserved1
Definition: tcp.h:467
The TCP static part.
Definition: tcp.h:506
uint8_t df
Definition: tcp.h:307
uint8_t ip_id
Definition: tcp.h:1178
The rnd_5 compressed packet format.
Definition: tcp.h:821
uint8_t ack_stride_flag
Definition: tcp.h:536
The IPv6 dynamic part.
Definition: tcp.h:436
uint8_t ttl_flag
Definition: tcp.h:333
uint8_t src_port_presence
Definition: tcp.h:596
uint8_t ack_stride_flag
Definition: tcp.h:594
uint8_t psh_flag
Definition: tcp.h:861
uint8_t length
Definition: tcp.h:369
uint8_t ecn_used
Definition: tcp.h:601
uint8_t window_indicator
Definition: tcp.h:677
uint32_t seq_num
Definition: tcp.h:546
uint8_t ecn_used
Definition: tcp.h:1186
uint8_t flow_label1
Definition: tcp.h:488
uint8_t msn
Definition: tcp.h:809
uint8_t psh_flag
Definition: tcp.h:1183
The rnd_3 compressed packet format.
Definition: tcp.h:769
uint8_t ip_ecn_flags
Definition: tcp.h:336
uint8_t flow_label1
Definition: tcp.h:419
uint16_t ip_id
Definition: tcp.h:313
uint8_t window3
Definition: tcp.h:1145
uint8_t urg_flag
Definition: tcp.h:135
uint8_t ecn_used
Definition: tcp.h:687
uint8_t reserved
Definition: tcp.h:335
uint8_t ack_num1
Definition: tcp.h:890
The seq_1 compressed packet format.
Definition: tcp.h:951
uint8_t reserved
Definition: tcp.h:688
uint8_t ip_id1
Definition: tcp.h:991
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:1216
uint8_t header_crc
Definition: tcp.h:1147
uint8_t ip_id
Definition: tcp.h:1015
uint8_t reserved
Definition: tcp.h:599
The IPv4 dynamic part without IP-ID field.
Definition: tcp.h:273
uint8_t fl_enc_flag
Definition: tcp.h:489
The seq_6 compressed packet format.
Definition: tcp.h:1095
Definition: tcp.h:165
uint8_t fl_enc_flag
Definition: tcp.h:466
uint8_t ip_id_behavior
Definition: tcp.h:334
uint16_t ack_num
Definition: tcp.h:938
uint16_t ack_num
Definition: tcp.h:1146
uint8_t ttl_hopl
Definition: tcp.h:312
uint8_t psh_flag
Definition: tcp.h:756
uint8_t msn1
Definition: tcp.h:930
uint8_t discriminator
Definition: tcp.h:1016
uint8_t discriminator
Definition: tcp.h:1072
uint16_t src_port
Definition: tcp.h:508
uint8_t seq_num_scaled
Definition: tcp.h:753
uint16_t urg_ptr
Definition: tcp.h:140
uint8_t ip_ecn_flags
Definition: tcp.h:442
uint8_t list_present
Definition: tcp.h:684
uint8_t header_crc
Definition: tcp.h:1114
uint8_t rsf_flags
Definition: tcp.h:539
uint8_t discriminator
Definition: tcp.h:754
rohc_tcp_option_type_t
Definition: tcp.h:172
uint16_t checksum
Definition: tcp.h:139
uint32_t block_start
Definition: tcp.h:216
uint16_t seq_num2
Definition: tcp.h:729
uint8_t ttl_hopl
Definition: tcp.h:445
uint8_t urg_flag
Definition: tcp.h:542
uint8_t psh_flag
Definition: tcp.h:934
uint8_t urg_flag
Definition: tcp.h:605
The TCP dynamic part.
Definition: tcp.h:518
The seq_2 compressed packet format.
Definition: tcp.h:980
The IPv6 static part, null flow_label encoded with 1 bit.
Definition: tcp.h:387
uint8_t ecn_used
Definition: tcp.h:537
uint8_t dst_port_presence
Definition: tcp.h:595
uint8_t ack_num2
Definition: tcp.h:842
The IPv6 replicate part with short Flow Label.
Definition: tcp.h:454
uint8_t options[0]
Definition: tcp.h:141
The IPv4 dynamic part with IP-ID field.
Definition: tcp.h:297
uint8_t tcp_res_flags
Definition: tcp.h:533
uint8_t header_crc
Definition: tcp.h:900
static char * tcp_opt_get_descr(const uint8_t opt_type)
Get a string that describes the given option type.
Definition: tcp.h:1240
uint8_t header_crc
Definition: tcp.h:1081
The seq_8 compressed packet format.
Definition: tcp.h:1161
uint8_t res_flags
Definition: tcp.h:130
uint8_t next_header
Definition: tcp.h:425
uint8_t data_offset
Definition: tcp.h:131
The TCP base header without options.
Definition: tcp.h:115
uint8_t psh_flag
Definition: tcp.h:996
Definition: tcp.h:565
uint8_t psh_flag
Definition: tcp.h:901
uint8_t seq_num_scaled2
Definition: tcp.h:1106
uint16_t seq_num
Definition: tcp.h:937
The IPv4 static part.
Definition: tcp.h:243
uint8_t header_crc
Definition: tcp.h:807
uint8_t dscp
Definition: tcp.h:337
uint8_t header_crc
Definition: tcp.h:782
The IPv6 replicate part with long Flow Label.
Definition: tcp.h:477
uint16_t dst_port
Definition: tcp.h:509
uint8_t ttl_hopl
Definition: tcp.h:933
uint16_t flow_label2
Definition: tcp.h:424
uint32_t ack_num
Definition: tcp.h:120
uint8_t msn
Definition: tcp.h:1026
uint8_t psh_flag
Definition: tcp.h:1148
uint8_t ack_stride_indicator
Definition: tcp.h:678
uint8_t next_header
Definition: tcp.h:400
The seq_7 compressed packet format.
Definition: tcp.h:1128
uint8_t tcp_ecn_flags
Definition: tcp.h:543
uint8_t length
Definition: tcp.h:353
uint8_t discriminator
Definition: tcp.h:1142
uint32_t seq_num
Definition: tcp.h:119
uint8_t psh_flag
Definition: tcp.h:672
uint16_t ack_num
Definition: tcp.h:1108
uint16_t window
Definition: tcp.h:894
Definition: tcp.h:183
uint8_t seq_num2
Definition: tcp.h:839
Definition: tcp.h:264
uint8_t rsf_flags
Definition: tcp.h:132
uint8_t msn
Definition: tcp.h:1116
uint8_t msn
Definition: tcp.h:968
uint8_t msn
Definition: tcp.h:757
The seq_4 compressed packet format.
Definition: tcp.h:1038
uint8_t header_crc
Definition: tcp.h:1180
uint8_t msn
Definition: tcp.h:670
uint8_t ip_id
Definition: tcp.h:1144
uint8_t header_crc
Definition: tcp.h:838
uint8_t ip_ecn_flags
Definition: tcp.h:285
uint8_t reserved
Definition: tcp.h:308
uint8_t psh_flag
Definition: tcp.h:540
Definition: tcp.h:261
uint8_t seq_num2
Definition: tcp.h:1190
uint8_t urg_ptr_present
Definition: tcp.h:675
uint8_t discriminator
Definition: tcp.h:891
uint8_t ttl_hopl_outer_flag
Definition: tcp.h:667
uint8_t psh_flag
Definition: tcp.h:967
uint8_t discriminator
Definition: tcp.h:836
The seq_5 compressed packet format.
Definition: tcp.h:1065
uint8_t length
Definition: tcp.h:377
uint8_t msn
Definition: tcp.h:1053
uint8_t rsf_flags
Definition: tcp.h:671
uint8_t dscp
Definition: tcp.h:487
Definition: tcp.h:185
uint32_t dst_addr
Definition: tcp.h:254
uint16_t seq_num
Definition: tcp.h:960
uint8_t ip_id_behavior
Definition: tcp.h:282
The IPv4 replicate part.
Definition: tcp.h:322
Definition: tcp.h:182
The seq_3 compressed packet format.
Definition: tcp.h:1009
uint8_t next_header
Definition: tcp.h:368
uint8_t header_crc
Definition: tcp.h:1024
uint8_t seq_num1
Definition: tcp.h:1188
uint32_t src_addr
Definition: tcp.h:253
uint8_t ack_num2
Definition: tcp.h:1187
Definition: tcp.h:175
uint8_t psh_flag
Definition: tcp.h:808
uint8_t dscp
Definition: tcp.h:310
uint8_t header_crc
Definition: tcp.h:862
uint8_t ip_id2
Definition: tcp.h:994
uint8_t dscp_present
Definition: tcp.h:686
uint8_t df
Definition: tcp.h:332
uint8_t reserved
Definition: tcp.h:284
uint8_t discriminator
Definition: tcp.h:780
uint8_t ip_id
Definition: tcp.h:1048
uint8_t next_header
Definition: tcp.h:360
uint8_t msn
Definition: tcp.h:784
uint16_t ack_num
Definition: tcp.h:1074
Definition: tcp.h:263
uint8_t discriminator
Definition: tcp.h:929
rohc_tcp_chain_t
The different chains used by the TCP profile.
Definition: tcp.h:160
uint8_t reserved2
Definition: tcp.h:395
Definition: tcp.h:566
uint8_t ack_flag
Definition: tcp.h:673
uint8_t next_header
Definition: tcp.h:352
uint8_t psh_flag
Definition: tcp.h:133
uint8_t length
Definition: tcp.h:361
uint8_t seq_indicator
Definition: tcp.h:680
uint8_t msn
Definition: tcp.h:1184
uint8_t window_presence
Definition: tcp.h:598
Definition: tcp.h:262
uint32_t seq_num
Definition: tcp.h:610
uint8_t ack_flag
Definition: tcp.h:604
uint8_t msn
Definition: tcp.h:732
uint8_t msn2
Definition: tcp.h:935
uint8_t header_crc
Definition: tcp.h:1051
uint8_t psh_flag
Definition: tcp.h:1025
tcp_ip_id_behavior_t
Definition: tcp.h:259
uint8_t dscp
Definition: tcp.h:286
uint8_t seq_num1
Definition: tcp.h:727
uint8_t ack_num_scaled
Definition: tcp.h:1049
uint8_t msn
Definition: tcp.h:1083
uint8_t urp_zero
Definition: tcp.h:534
The Common compressed packet format.
Definition: tcp.h:634
Definition: tcp.h:166
uint8_t reserved
Definition: tcp.h:421
Definition: tcp.h:178
Definition: tcp.h:226
uint8_t ack_num_scaled
Definition: tcp.h:805
uint8_t seq_num3
Definition: tcp.h:841
uint8_t header_crc
Definition: tcp.h:931
Definition: tcp.h:164
uint8_t msn
Definition: tcp.h:1149
uint8_t psh_flag
Definition: tcp.h:1082
uint8_t ip_ecn_flags
Definition: tcp.h:486
uint8_t header_crc
Definition: tcp.h:730
uint8_t list_present
Definition: tcp.h:597
uint8_t header_crc
Definition: tcp.h:995
uint8_t df
Definition: tcp.h:283
uint8_t ack_indicator
Definition: tcp.h:679
uint8_t header_crc
Definition: tcp.h:690
uint8_t ack_flag
Definition: tcp.h:134
uint8_t msn
Definition: tcp.h:871
uint8_t reserved1
Definition: tcp.h:397
uint32_t ts_reply
Definition: tcp.h:229
uint8_t ip_id
Definition: tcp.h:1071
uint8_t discriminator
Definition: tcp.h:668
uint8_t seq_num_scaled
Definition: tcp.h:993
uint16_t ack_num2
Definition: tcp.h:892
uint8_t seq_num_scaled1
Definition: tcp.h:1103
Definition: tcp.h:180
uint8_t header_crc
Definition: tcp.h:966
uint8_t dscp
Definition: tcp.h:464
uint8_t discriminator
Definition: tcp.h:728