1use arrayvec::ArrayVec;
2
3use crate::err::{ValueTooBigError, ValueType};
4
5use super::super::*;
6
7#[deprecated(since = "0.14.0", note = "Use `TcpHeader::MIN_LEN` instead")]
9pub const TCP_MINIMUM_HEADER_SIZE: usize = 5 * 4;
10
11#[deprecated(since = "0.14.0", note = "Use `TcpHeader::MIN_DATA_OFFSET` instead")]
13pub const TCP_MINIMUM_DATA_OFFSET: u8 = 5;
14
15#[deprecated(since = "0.14.0", note = "Use `TcpHeader::MAX_DATA_OFFSET` instead")]
17pub const TCP_MAXIMUM_DATA_OFFSET: u8 = 0xf;
18
19#[derive(Clone, Debug, Eq, PartialEq, Hash)]
23pub struct TcpHeader {
24 pub source_port: u16,
26 pub destination_port: u16,
28 pub sequence_number: u32,
34 pub acknowledgment_number: u32,
40 pub ns: bool,
42 pub fin: bool,
44 pub syn: bool,
46 pub rst: bool,
48 pub psh: bool,
50 pub ack: bool,
52 pub urg: bool,
54 pub ece: bool,
56 pub cwr: bool,
60 pub window_size: u16,
64 pub checksum: u16,
66 pub urgent_pointer: u16,
73
74 pub options: TcpOptions,
76}
77
78impl TcpHeader {
79 pub const MIN_LEN: usize = 5 * 4;
81
82 pub const MAX_LEN: usize = 0b1111 * 4;
89
90 pub const MIN_DATA_OFFSET: u8 = 5;
92
93 pub const MAX_DATA_OFFSET: u8 = 0xf;
95
96 pub fn new(
98 source_port: u16,
99 destination_port: u16,
100 sequence_number: u32,
101 window_size: u16,
102 ) -> TcpHeader {
103 TcpHeader {
104 source_port,
105 destination_port,
106 sequence_number,
107 acknowledgment_number: 0,
108 ns: false,
109 fin: false,
110 syn: false,
111 rst: false,
112 psh: false,
113 ack: false,
114 ece: false,
115 urg: false,
116 cwr: false,
117 window_size,
118 checksum: 0,
119 urgent_pointer: 0,
120 options: Default::default(),
121 }
122 }
123
124 #[inline]
156 pub fn data_offset(&self) -> u8 {
157 self.options.data_offset()
158 }
159
160 #[inline]
162 pub fn header_len(&self) -> usize {
163 20 + self.options.len()
164 }
165
166 #[inline]
168 pub fn header_len_u16(&self) -> u16 {
169 20 + u16::from(self.options.len_u8())
170 }
171
172 #[inline]
174 #[deprecated(since = "0.14.0", note = "Please use `options.len()` instead")]
175 pub fn options_len(&self) -> usize {
176 self.options.len()
177 }
178
179 #[inline]
181 #[deprecated(since = "0.14.0", note = "Please use `options.as_slice()` instead")]
182 pub fn options(&self) -> &[u8] {
183 self.options.as_slice()
184 }
185
186 pub fn set_options(
189 &mut self,
190 elements: &[TcpOptionElement],
191 ) -> Result<(), TcpOptionWriteError> {
192 self.options = TcpOptions::try_from_elements(elements)?;
193 Ok(())
194 }
195
196 pub fn set_options_raw(&mut self, data: &[u8]) -> Result<(), TcpOptionWriteError> {
198 self.options = TcpOptions::try_from_slice(data)?;
199 Ok(())
200 }
201
202 #[inline]
205 pub fn options_iterator(&self) -> TcpOptionsIterator {
206 self.options.elements_iter()
207 }
208
209 #[deprecated(since = "0.10.1", note = "Use TcpHeader::from_slice instead.")]
211 #[inline]
212 pub fn read_from_slice(slice: &[u8]) -> Result<(TcpHeader, &[u8]), err::tcp::HeaderSliceError> {
213 TcpHeader::from_slice(slice)
214 }
215
216 #[inline]
218 pub fn from_slice(slice: &[u8]) -> Result<(TcpHeader, &[u8]), err::tcp::HeaderSliceError> {
219 let h = TcpHeaderSlice::from_slice(slice)?;
220 Ok((h.to_header(), &slice[h.slice().len()..]))
221 }
222
223 #[cfg(feature = "std")]
225 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
226 pub fn read<T: std::io::Read + Sized>(
227 reader: &mut T,
228 ) -> Result<TcpHeader, err::tcp::HeaderReadError> {
229 use err::tcp::{HeaderError::*, HeaderReadError::*};
230
231 let raw = {
232 let mut raw: [u8; 20] = [0; 20];
233 reader.read_exact(&mut raw).map_err(Io)?;
234 raw
235 };
236 let source_port = u16::from_be_bytes([raw[0], raw[1]]);
237 let destination_port = u16::from_be_bytes([raw[2], raw[3]]);
238 let sequence_number = u32::from_be_bytes([raw[4], raw[5], raw[6], raw[7]]);
239 let acknowledgment_number = u32::from_be_bytes([raw[8], raw[9], raw[10], raw[11]]);
240 let (data_offset, ns) = {
241 let value = raw[12];
242 ((value & 0xf0) >> 4, 0 != value & 1)
243 };
244 let flags = raw[13];
245
246 Ok(TcpHeader {
247 source_port,
248 destination_port,
249 sequence_number,
250 acknowledgment_number,
251 ns,
252 fin: 0 != flags & 1,
253 syn: 0 != flags & 2,
254 rst: 0 != flags & 4,
255 psh: 0 != flags & 8,
256 ack: 0 != flags & 16,
257 urg: 0 != flags & 32,
258 ece: 0 != flags & 64,
259 cwr: 0 != flags & 128,
260 window_size: u16::from_be_bytes([raw[14], raw[15]]),
261 checksum: u16::from_be_bytes([raw[16], raw[17]]),
262 urgent_pointer: u16::from_be_bytes([raw[18], raw[19]]),
263 options: {
264 if data_offset < TcpHeader::MIN_DATA_OFFSET {
265 return Err(Content(DataOffsetTooSmall { data_offset }));
266 } else {
267 let mut options = TcpOptions {
268 len: (data_offset - TcpHeader::MIN_DATA_OFFSET) << 2,
269 buf: [0; 40],
270 };
271 if options.len > 0 {
273 reader
274 .read_exact(&mut options.buf[..options.len.into()])
275 .map_err(Io)?;
276 }
277 options
278 }
279 },
280 })
281 }
282
283 #[cfg(feature = "std")]
285 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
286 pub fn write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error> {
287 let src_be = self.source_port.to_be_bytes();
289 let dst_be = self.destination_port.to_be_bytes();
290 let seq_be = self.sequence_number.to_be_bytes();
291 let ack_be = self.acknowledgment_number.to_be_bytes();
292 let window_be = self.window_size.to_be_bytes();
293 let checksum_be = self.checksum.to_be_bytes();
294 let urg_ptr_be = self.urgent_pointer.to_be_bytes();
295 let data_offset = self.data_offset();
296 debug_assert!(TcpHeader::MIN_DATA_OFFSET <= data_offset);
297 debug_assert!(data_offset <= TcpHeader::MAX_DATA_OFFSET);
298
299 writer.write_all(&[
300 src_be[0],
301 src_be[1],
302 dst_be[0],
303 dst_be[1],
304 seq_be[0],
305 seq_be[1],
306 seq_be[2],
307 seq_be[3],
308 ack_be[0],
309 ack_be[1],
310 ack_be[2],
311 ack_be[3],
312 {
313 let value = (data_offset << 4) & 0xF0;
314 if self.ns {
315 value | 1
316 } else {
317 value
318 }
319 },
320 {
321 let mut value = 0;
322 if self.fin {
323 value |= 1;
324 }
325 if self.syn {
326 value |= 2;
327 }
328 if self.rst {
329 value |= 4;
330 }
331 if self.psh {
332 value |= 8;
333 }
334 if self.ack {
335 value |= 16;
336 }
337 if self.urg {
338 value |= 32;
339 }
340 if self.ece {
341 value |= 64;
342 }
343 if self.cwr {
344 value |= 128;
345 }
346 value
347 },
348 window_be[0],
349 window_be[1],
350 checksum_be[0],
351 checksum_be[1],
352 urg_ptr_be[0],
353 urg_ptr_be[1],
354 ])?;
355
356 let options = self.options.as_slice();
358 if false == options.is_empty() {
359 writer.write_all(options)?;
360 }
361 Ok(())
362 }
363
364 pub fn to_bytes(&self) -> ArrayVec<u8, { TcpHeader::MAX_LEN }> {
366 let src_be = self.source_port.to_be_bytes();
368 let dst_be = self.destination_port.to_be_bytes();
369 let seq_be = self.sequence_number.to_be_bytes();
370 let ack_be = self.acknowledgment_number.to_be_bytes();
371 let window_be = self.window_size.to_be_bytes();
372 let checksum_be = self.checksum.to_be_bytes();
373 let urg_ptr_be = self.urgent_pointer.to_be_bytes();
374
375 let mut result = ArrayVec::new();
376
377 result.extend([
379 src_be[0],
380 src_be[1],
381 dst_be[0],
382 dst_be[1],
383 seq_be[0],
384 seq_be[1],
385 seq_be[2],
386 seq_be[3],
387 ack_be[0],
388 ack_be[1],
389 ack_be[2],
390 ack_be[3],
391 {
392 let value = (self.data_offset() << 4) & 0xF0;
393 if self.ns {
394 value | 1
395 } else {
396 value
397 }
398 },
399 {
400 let mut value = 0;
401 if self.fin {
402 value |= 1;
403 }
404 if self.syn {
405 value |= 2;
406 }
407 if self.rst {
408 value |= 4;
409 }
410 if self.psh {
411 value |= 8;
412 }
413 if self.ack {
414 value |= 16;
415 }
416 if self.urg {
417 value |= 32;
418 }
419 if self.ece {
420 value |= 64;
421 }
422 if self.cwr {
423 value |= 128;
424 }
425 value
426 },
427 window_be[0],
428 window_be[1],
429 checksum_be[0],
430 checksum_be[1],
431 urg_ptr_be[0],
432 urg_ptr_be[1],
433 ]);
434
435 result.extend(self.options.buf);
437 unsafe {
440 result.set_len(self.header_len());
441 }
442
443 result
444 }
445
446 pub fn calc_checksum_ipv4(
448 &self,
449 ip_header: &Ipv4Header,
450 payload: &[u8],
451 ) -> Result<u16, ValueTooBigError<usize>> {
452 self.calc_checksum_ipv4_raw(ip_header.source, ip_header.destination, payload)
453 }
454
455 pub fn calc_checksum_ipv4_raw(
457 &self,
458 source_ip: [u8; 4],
459 destination_ip: [u8; 4],
460 payload: &[u8],
461 ) -> Result<u16, ValueTooBigError<usize>> {
462 let max_payload = usize::from(u16::MAX) - self.header_len();
464 if max_payload < payload.len() {
465 return Err(ValueTooBigError {
466 actual: payload.len(),
467 max_allowed: max_payload,
468 value_type: ValueType::TcpPayloadLengthIpv4,
469 });
470 }
471
472 let tcp_len = self.header_len_u16() + (payload.len() as u16);
474 Ok(self.calc_checksum_post_ip(
475 checksum::Sum16BitWords::new()
476 .add_4bytes(source_ip)
477 .add_4bytes(destination_ip)
478 .add_2bytes([0, ip_number::TCP.0])
479 .add_2bytes(tcp_len.to_be_bytes()),
480 payload,
481 ))
482 }
483
484 pub fn calc_checksum_ipv6(
486 &self,
487 ip_header: &Ipv6Header,
488 payload: &[u8],
489 ) -> Result<u16, ValueTooBigError<usize>> {
490 self.calc_checksum_ipv6_raw(ip_header.source, ip_header.destination, payload)
491 }
492
493 pub fn calc_checksum_ipv6_raw(
495 &self,
496 source: [u8; 16],
497 destination: [u8; 16],
498 payload: &[u8],
499 ) -> Result<u16, ValueTooBigError<usize>> {
500 let max_payload = (u32::MAX as usize) - self.header_len();
502 if max_payload < payload.len() {
503 return Err(ValueTooBigError {
504 actual: payload.len(),
505 max_allowed: max_payload,
506 value_type: ValueType::TcpPayloadLengthIpv6,
507 });
508 }
509
510 let tcp_len = u32::from(self.header_len_u16()) + (payload.len() as u32);
511 Ok(self.calc_checksum_post_ip(
512 checksum::Sum16BitWords::new()
513 .add_16bytes(source)
514 .add_16bytes(destination)
515 .add_4bytes(tcp_len.to_be_bytes())
516 .add_2bytes([0, ip_number::TCP.0]),
517 payload,
518 ))
519 }
520
521 fn calc_checksum_post_ip(
523 &self,
524 ip_pseudo_header_sum: checksum::Sum16BitWords,
525 payload: &[u8],
526 ) -> u16 {
527 ip_pseudo_header_sum
528 .add_2bytes(self.source_port.to_be_bytes())
529 .add_2bytes(self.destination_port.to_be_bytes())
530 .add_4bytes(self.sequence_number.to_be_bytes())
531 .add_4bytes(self.acknowledgment_number.to_be_bytes())
532 .add_2bytes([
533 {
534 let value = (self.data_offset() << 4) & 0xF0;
535 if self.ns {
536 value | 1
537 } else {
538 value
539 }
540 },
541 {
542 let mut value = 0;
543 if self.fin {
544 value |= 1;
545 }
546 if self.syn {
547 value |= 2;
548 }
549 if self.rst {
550 value |= 4;
551 }
552 if self.psh {
553 value |= 8;
554 }
555 if self.ack {
556 value |= 16;
557 }
558 if self.urg {
559 value |= 32;
560 }
561 if self.ece {
562 value |= 64;
563 }
564 if self.cwr {
565 value |= 128;
566 }
567 value
568 },
569 ])
570 .add_2bytes(self.window_size.to_be_bytes())
571 .add_2bytes(self.urgent_pointer.to_be_bytes())
572 .add_slice(self.options.as_slice())
573 .add_slice(payload)
574 .ones_complement()
575 .to_be()
576 }
577}
578
579impl Default for TcpHeader {
580 fn default() -> TcpHeader {
581 TcpHeader {
582 source_port: 0,
583 destination_port: 0,
584 sequence_number: 0,
585 acknowledgment_number: 0,
586 ns: false,
587 fin: false,
588 syn: false,
589 rst: false,
590 psh: false,
591 ack: false,
592 urg: false,
593 ece: false,
594 cwr: false,
595 window_size: 0,
596 checksum: 0,
597 urgent_pointer: 0,
598 options: TcpOptions {
599 len: 0,
600 buf: [0u8; 40],
601 },
602 }
603 }
604}
605
606#[cfg(test)]
607mod test {
608 use crate::{
609 err::{
610 tcp::{HeaderError::*, HeaderSliceError::*},
611 ValueTooBigError, ValueType,
612 },
613 tcp_option::*,
614 test_gens::*,
615 TcpOptionElement::*,
616 *,
617 };
618 use alloc::{format, vec::Vec};
619 use proptest::prelude::*;
620 use std::io::Cursor;
621
622 #[test]
623 fn default() {
624 let default: TcpHeader = Default::default();
625
626 assert_eq!(0, default.source_port);
627 assert_eq!(0, default.destination_port);
628 assert_eq!(0, default.sequence_number);
629 assert_eq!(0, default.acknowledgment_number);
630 assert_eq!(5, default.data_offset());
631 assert_eq!(false, default.ns);
632 assert_eq!(false, default.fin);
633 assert_eq!(false, default.syn);
634 assert_eq!(false, default.rst);
635 assert_eq!(false, default.psh);
636 assert_eq!(false, default.ack);
637 assert_eq!(false, default.ece);
638 assert_eq!(false, default.urg);
639 assert_eq!(false, default.cwr);
640 assert_eq!(0, default.window_size);
641 assert_eq!(0, default.checksum);
642 assert_eq!(0, default.urgent_pointer);
643 assert_eq!(0, default.options.as_slice().len());
644 }
645
646 proptest! {
647 #[test]
648 fn debug(header in tcp_any()) {
649
650 assert_eq!(
652 format!(
653 "TcpHeader {{ source_port: {}, destination_port: {}, sequence_number: {}, acknowledgment_number: {}, ns: {}, fin: {}, syn: {}, rst: {}, psh: {}, ack: {}, urg: {}, ece: {}, cwr: {}, window_size: {}, checksum: {}, urgent_pointer: {}, options: {:?} }}",
654 header.source_port,
655 header.destination_port,
656 header.sequence_number,
657 header.acknowledgment_number,
658 header.ns,
659 header.fin,
660 header.syn,
661 header.rst,
662 header.psh,
663 header.ack,
664 header.urg,
665 header.ece,
666 header.cwr,
667 header.window_size,
668 header.checksum,
669 header.urgent_pointer,
670 header.options_iterator()
671 ),
672 format!("{:?}", header)
673 );
674
675 {
677 let mut header = header.clone();
678 header.set_options(&[]).unwrap();
682 assert_eq!(
683 format!(
684 "TcpHeader {{
685 source_port: {},
686 destination_port: {},
687 sequence_number: {},
688 acknowledgment_number: {},
689 ns: {},
690 fin: {},
691 syn: {},
692 rst: {},
693 psh: {},
694 ack: {},
695 urg: {},
696 ece: {},
697 cwr: {},
698 window_size: {},
699 checksum: {},
700 urgent_pointer: {},
701 options: {:?},
702}}",
703 header.source_port,
704 header.destination_port,
705 header.sequence_number,
706 header.acknowledgment_number,
707 header.ns,
708 header.fin,
709 header.syn,
710 header.rst,
711 header.psh,
712 header.ack,
713 header.urg,
714 header.ece,
715 header.cwr,
716 header.window_size,
717 header.checksum,
718 header.urgent_pointer,
719 header.options_iterator()
720 ),
721 format!("{:#?}", header)
722 );
723 }
724 }
725 }
726
727 #[test]
728 fn eq() {
729 let options = [
730 TcpOptionElement::Timestamp(0x00102030, 0x01112131), TcpOptionElement::SelectiveAcknowledgement(
732 (0x02122232, 0x03132333),
733 [None, None, None],
734 ), TcpOptionElement::Timestamp(0x04142434, 0x05152535), TcpOptionElement::Timestamp(0x06162636, 0x07172737), ];
738
739 let base: TcpHeader = {
740 let mut base: TcpHeader = Default::default();
741 base.source_port = 1;
742 base.destination_port = 2;
743 base.sequence_number = 3;
744 base.acknowledgment_number = 4;
745 base.window_size = 6;
746 base.checksum = 7;
747 base.urgent_pointer = 8;
748 base.set_options(&options[..]).unwrap();
749
750 base
751 };
752
753 {
755 let other = base.clone();
756 assert_eq!(other, base);
757 }
758 {
761 let mut other = base.clone();
762 other.source_port = 10;
763 assert_ne!(other, base);
764 }
765 {
767 let mut other = base.clone();
768 other.destination_port = 10;
769 assert_ne!(other, base);
770 }
771 {
773 let mut other = base.clone();
774 other.sequence_number = 10;
775 assert_ne!(other, base);
776 }
777 {
779 let mut other = base.clone();
780 other.acknowledgment_number = 10;
781 assert_ne!(other, base);
782 }
783 {
785 let mut other = base.clone();
786 other
787 .set_options(&[TcpOptionElement::MaximumSegmentSize(16)])
788 .unwrap();
789 assert_ne!(other, base);
790 }
791 {
793 let mut other = base.clone();
794 other.ns = true;
795 assert_ne!(other, base);
796 }
797 {
799 let mut other = base.clone();
800 other.fin = true;
801 assert_ne!(other, base);
802 }
803 {
805 let mut other = base.clone();
806 other.syn = true;
807 assert_ne!(other, base);
808 }
809 {
811 let mut other = base.clone();
812 other.rst = true;
813 assert_ne!(other, base);
814 }
815 {
817 let mut other = base.clone();
818 other.psh = true;
819 assert_ne!(other, base);
820 }
821 {
823 let mut other = base.clone();
824 other.ack = true;
825 assert_ne!(other, base);
826 }
827 {
829 let mut other = base.clone();
830 other.ece = true;
831 assert_ne!(other, base);
832 }
833 {
835 let mut other = base.clone();
836 other.urg = true;
837 assert_ne!(other, base);
838 }
839 {
841 let mut other = base.clone();
842 other.cwr = true;
843 assert_ne!(other, base);
844 }
845 {
847 let mut other = base.clone();
848 other.window_size = 10;
849 assert_ne!(other, base);
850 }
851 {
853 let mut other = base.clone();
854 other.checksum = 10;
855 assert_ne!(other, base);
856 }
857 {
859 let mut other = base.clone();
860 other.urgent_pointer = 10;
861 assert_ne!(other, base);
862 }
863 {
865 let mut other = base.clone();
866 other
867 .set_options(&{
868 let mut other_options = options.clone();
869 other_options[0] = TcpOptionElement::Timestamp(0x00102039, 0x01112131);
870 other_options
871 })
872 .unwrap();
873
874 assert_ne!(other, base);
875 }
876 {
878 let mut other = base.clone();
879 other.set_options(&options).unwrap();
880
881 let mut other2 = base.clone();
882 other2
883 .set_options(&{
884 let mut options2 = options.clone();
885 options2[3] = TcpOptionElement::Timestamp(0x06162636, 0x97172737);
886 options2
887 })
888 .unwrap();
889
890 assert_ne!(other, other2);
891 }
892 {
894 let mut other = base.clone();
895 other.set_options(&options).unwrap();
896
897 let mut other2 = base.clone();
898 other2
899 .set_options(&{
900 let mut options2 = options.clone();
901 options2[3] = TcpOptionElement::Timestamp(0x06162636, 0x97172737);
902 options2
903 })
904 .unwrap();
905
906 let new_options = [TcpOptionElement::Timestamp(0x00102030, 0x01112131)];
908 other.set_options(&new_options).unwrap();
909 other2.set_options(&new_options).unwrap();
910
911 assert_eq!(other, other2);
912 }
913 }
914
915 proptest! {
916 #[test]
917 fn hash(header in tcp_any()) {
918 use std::collections::hash_map::DefaultHasher;
919 use core::hash::{Hash, Hasher};
920 let a = {
921 let mut hasher = DefaultHasher::new();
922 header.hash(&mut hasher);
923 hasher.finish()
924 };
925 let b = {
926 let mut hasher = DefaultHasher::new();
927 header.hash(&mut hasher);
928 hasher.finish()
929 };
930 assert_eq!(a, b);
931 }
932 }
933
934 proptest! {
935 #[test]
936 fn new(
937 source_port in any::<u16>(),
938 destination_port in any::<u16>(),
939 sequence_number in any::<u32>(),
940 window_size in any::<u16>()
941 ) {
942 let header = TcpHeader::new(
943 source_port,
944 destination_port,
945 sequence_number,
946 window_size
947 );
948 assert_eq!(header.source_port, source_port);
949 assert_eq!(header.destination_port, destination_port);
950 assert_eq!(header.sequence_number, sequence_number);
951 assert_eq!(header.acknowledgment_number, 0);
952 assert_eq!(header.ns, false);
953 assert_eq!(header.fin, false);
954 assert_eq!(header.syn, false);
955 assert_eq!(header.rst, false);
956 assert_eq!(header.psh, false);
957 assert_eq!(header.ack, false);
958 assert_eq!(header.urg, false);
959 assert_eq!(header.ece, false);
960 assert_eq!(header.cwr, false);
961 assert_eq!(header.window_size, window_size);
962 assert_eq!(header.checksum, 0);
963 assert_eq!(header.urgent_pointer, 0);
964 assert_eq!(header.options.as_slice(), &[]);
965 }
966 }
967
968 proptest! {
969 #[test]
970 fn data_offset(header in tcp_any()) {
971 assert_eq!(header.options.len()/4 + 5, header.data_offset().into());
972 }
973 }
974
975 proptest! {
976 #[test]
977 fn header_len(header in tcp_any()) {
978 assert_eq!(
979 header.header_len(),
980 (20 + header.options.len())
981 );
982 }
983 }
984
985 proptest! {
986 #[test]
987 fn header_len_u16(header in tcp_any()) {
988 assert_eq!(
989 header.header_len_u16(),
990 (20 + header.options.len()) as u16
991 );
992 }
993 }
994
995 proptest! {
996 #[test]
997 #[allow(deprecated)]
998 fn options_len(header in tcp_any()) {
999 assert_eq!(
1000 header.options_len(),
1001 header.to_bytes().len() - 20
1002 );
1003 }
1004 }
1005
1006 proptest! {
1007 #[test]
1008 #[allow(deprecated)]
1009 fn options(header in tcp_any()) {
1010 assert_eq!(
1011 header.options(),
1012 &header.to_bytes()[20..]
1013 );
1014 }
1015 }
1016
1017 proptest! {
1018 #[test]
1019 #[rustfmt::skip]
1020 fn set_options(
1021 header in tcp_any(),
1022 arg_u8 in any::<u8>(),
1023 arg_u16 in any::<u16>(),
1024 ack_args in proptest::collection::vec(any::<u32>(), 4*2),
1025 arg0_u32 in any::<u32>(),
1026 arg1_u32 in any::<u32>()
1027 ) {
1028 use crate::TcpOptionElement::*;
1029
1030 {
1032 let mut header = header.clone();
1033 header.set_options(
1034 &[Noop, Noop, MaximumSegmentSize(arg_u16), Noop]
1035 ).unwrap();
1036 assert_eq!(
1037 header.options.as_slice(),
1038 &{
1039 let arg_be = arg_u16.to_be_bytes();
1040 [
1041 KIND_NOOP, KIND_NOOP, KIND_MAXIMUM_SEGMENT_SIZE, 4,
1042 arg_be[0], arg_be[1], KIND_NOOP, KIND_END
1043 ]
1044 }
1045 );
1046 }
1047
1048 {
1050 let mut header = header.clone();
1051 header.set_options(
1052 &[Noop, Noop, WindowScale(arg_u8), Noop]
1053 ).unwrap();
1054 assert_eq!(
1055 header.options.as_slice(),
1056 &[
1057 KIND_NOOP, KIND_NOOP, KIND_WINDOW_SCALE, 3,
1058 arg_u8, KIND_NOOP, KIND_END, 0
1059 ]
1060 );
1061 }
1062
1063 {
1065 let mut header = header.clone();
1066 header.set_options(
1067 &[Noop, Noop, SelectiveAcknowledgementPermitted, Noop]
1068 ).unwrap();
1069 assert_eq!(
1070 header.options.as_slice(),
1071 &[
1072 KIND_NOOP, KIND_NOOP, KIND_SELECTIVE_ACK_PERMITTED, 2,
1073 KIND_NOOP, KIND_END, 0, 0
1074 ]
1075 );
1076 }
1077
1078 {
1080 let args_be : Vec<[u8;4]> = ack_args.iter().map(|v| v.to_be_bytes()).collect();
1081
1082 {
1084 let mut header = header.clone();
1085 header.set_options(
1086 &[Noop, Noop, SelectiveAcknowledgement((ack_args[0], ack_args[1]), [None, None, None]), Noop]
1087 ).unwrap();
1088 assert_eq!(
1089 header.options.as_slice(),
1090 &[
1091 KIND_NOOP, KIND_NOOP, KIND_SELECTIVE_ACK, 10,
1092 args_be[0][0], args_be[0][1], args_be[0][2], args_be[0][3],
1093 args_be[1][0], args_be[1][1], args_be[1][2], args_be[1][3],
1094 KIND_NOOP, KIND_END, 0, 0
1095 ]
1096 );
1097 }
1098
1099 {
1101 let mut header = header.clone();
1102 header.set_options(
1103 &[
1104 Noop,
1105 Noop,
1106 SelectiveAcknowledgement(
1107 (ack_args[0], ack_args[1]),
1108 [Some((ack_args[2], ack_args[3])), None, None]
1109 ),
1110 Noop
1111 ]
1112 ).unwrap();
1113 assert_eq!(
1114 header.options.as_slice(),
1115 [
1116 KIND_NOOP, KIND_NOOP, KIND_SELECTIVE_ACK, 18,
1117 args_be[0][0], args_be[0][1], args_be[0][2], args_be[0][3],
1118 args_be[1][0], args_be[1][1], args_be[1][2], args_be[1][3],
1119 args_be[2][0], args_be[2][1], args_be[2][2], args_be[2][3],
1120 args_be[3][0], args_be[3][1], args_be[3][2], args_be[3][3],
1121 KIND_NOOP, KIND_END, 0, 0
1122 ]
1123 );
1124 }
1125
1126 {
1128 let mut header = header.clone();
1129 header.set_options(
1130 &[
1131 Noop,
1132 Noop,
1133 SelectiveAcknowledgement(
1134 (ack_args[0], ack_args[1]),
1135 [
1136 Some((ack_args[2], ack_args[3])),
1137 Some((ack_args[4], ack_args[5])),
1138 None
1139 ]
1140 ),
1141 Noop
1142 ]
1143 ).unwrap();
1144 assert_eq!(
1145 header.options.as_slice(),
1146 &[
1147 KIND_NOOP, KIND_NOOP, KIND_SELECTIVE_ACK, 26,
1148 args_be[0][0], args_be[0][1], args_be[0][2], args_be[0][3],
1149 args_be[1][0], args_be[1][1], args_be[1][2], args_be[1][3],
1150 args_be[2][0], args_be[2][1], args_be[2][2], args_be[2][3],
1151 args_be[3][0], args_be[3][1], args_be[3][2], args_be[3][3],
1152 args_be[4][0], args_be[4][1], args_be[4][2], args_be[4][3],
1153 args_be[5][0], args_be[5][1], args_be[5][2], args_be[5][3],
1154 KIND_NOOP, KIND_END, 0, 0
1155 ]
1156 );
1157 }
1158
1159 {
1161 let mut header = header.clone();
1162 header.set_options(
1163 &[
1164 Noop,
1165 Noop,
1166 SelectiveAcknowledgement(
1167 (ack_args[0], ack_args[1]),
1168 [
1169 Some((ack_args[2], ack_args[3])),
1170 Some((ack_args[4], ack_args[5])),
1171 Some((ack_args[6], ack_args[7]))
1172 ]
1173 ),
1174 Noop
1175 ]
1176 ).unwrap();
1177 assert_eq!(
1178 header.options.as_slice(),
1179 &[
1180 KIND_NOOP, KIND_NOOP, KIND_SELECTIVE_ACK, 34,
1181 args_be[0][0], args_be[0][1], args_be[0][2], args_be[0][3],
1182 args_be[1][0], args_be[1][1], args_be[1][2], args_be[1][3],
1183 args_be[2][0], args_be[2][1], args_be[2][2], args_be[2][3],
1184 args_be[3][0], args_be[3][1], args_be[3][2], args_be[3][3],
1185 args_be[4][0], args_be[4][1], args_be[4][2], args_be[4][3],
1186 args_be[5][0], args_be[5][1], args_be[5][2], args_be[5][3],
1187 args_be[6][0], args_be[6][1], args_be[6][2], args_be[6][3],
1188 args_be[7][0], args_be[7][1], args_be[7][2], args_be[7][3],
1189 KIND_NOOP, KIND_END, 0, 0
1190 ]
1191 );
1192 }
1193 }
1194
1195 {
1197 let mut header = header.clone();
1198 header.set_options(
1199 &[Noop, Noop, Timestamp(arg0_u32, arg1_u32), Noop]
1200 ).unwrap();
1201 assert_eq!(
1202 header.options.as_slice(),
1203 &{
1204 let arg0_be = arg0_u32.to_be_bytes();
1205 let arg1_be = arg1_u32.to_be_bytes();
1206 [
1207 KIND_NOOP, KIND_NOOP, KIND_TIMESTAMP, 10,
1208 arg0_be[0], arg0_be[1], arg0_be[2], arg0_be[3],
1209 arg1_be[0], arg1_be[1], arg1_be[2], arg1_be[3],
1210 KIND_NOOP, KIND_END, 0, 0
1211 ]
1212 }
1213 );
1214 }
1215
1216 {
1218 let mut header = header.clone();
1219 header.set_options(&[
1220 MaximumSegmentSize(1400), SelectiveAcknowledgementPermitted, Timestamp(2661445915, 0), Noop, WindowScale(7), ]).unwrap(); assert_eq!(40, header.header_len());
1228 }
1229
1230 {
1232 let mut header = header.clone();
1233 assert_eq!(
1234 Err(TcpOptionWriteError::NotEnoughSpace(41)),
1235 header.set_options(&[
1236 MaximumSegmentSize(1), WindowScale(2), SelectiveAcknowledgementPermitted, SelectiveAcknowledgement((3, 4), [Some((5, 6)), None, None]), Timestamp(5, 6), Noop,
1242 Noop,
1243 Noop,
1244 Noop ])
1246 );
1247 assert_eq!(
1249 Err(TcpOptionWriteError::NotEnoughSpace(41)),
1250 header.set_options(&[
1251 Noop, SelectiveAcknowledgement((3, 4), [Some((5, 6)), Some((5, 6)), Some((5, 6))]), MaximumSegmentSize(1), Noop,
1255 Noop ])
1257 );
1258
1259 assert_eq!(
1261 Err(TcpOptionWriteError::NotEnoughSpace(41)),
1262 header.set_options(&[
1263 Noop, SelectiveAcknowledgement((3, 4), [None, None, None]), Timestamp(1, 2), Timestamp(1, 2), MaximumSegmentSize(1), Noop,
1269 Noop,
1270 Noop,
1271 Noop,
1272 Noop,
1273 Noop ])
1275 );
1276 }
1277 }
1278 }
1279
1280 proptest! {
1281 #[test]
1282 fn set_options_raw(header in tcp_any()) {
1283 let base: TcpHeader = Default::default();
1284
1285 let dummy = [
1286 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1287 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
1288 ];
1289
1290 for i in 0..40 {
1292 let mut header = header.clone();
1293 header.set_options_raw(&dummy[..i]).unwrap();
1295
1296 let mut options_length = i / 4;
1298 if i % 4 != 0 {
1299 options_length += 1;
1300 }
1301 options_length = options_length * 4;
1302
1303 let mut expected_options = [0; 40];
1305 expected_options[..i].copy_from_slice(&dummy[..i]);
1306
1307 assert_eq!(options_length, header.options.len());
1308 assert_eq!(
1309 (options_length / 4) as u8 + TcpHeader::MIN_DATA_OFFSET,
1310 header.data_offset()
1311 );
1312 assert_eq!(&expected_options[..options_length], header.options.as_slice());
1313 }
1314
1315 let mut header = base.clone();
1317 use crate::TcpOptionWriteError::*;
1318 assert_eq!(
1319 Err(NotEnoughSpace(dummy.len())),
1320 header.set_options_raw(&dummy[..])
1321 );
1322 }
1323 }
1324
1325 #[test]
1326 fn options_iterator() {
1327 let options = [
1328 TcpOptionElement::Timestamp(0x00102030, 0x01112131), TcpOptionElement::SelectiveAcknowledgement(
1330 (0x02122232, 0x03132333),
1331 [None, None, None],
1332 ), TcpOptionElement::Timestamp(0x04142434, 0x05152535), TcpOptionElement::Timestamp(0x06162636, 0x07172737), ];
1336
1337 let base: TcpHeader = {
1338 let mut base: TcpHeader = Default::default();
1339 base.set_options(&options[..]).unwrap();
1340 base
1341 };
1342
1343 assert_eq!(
1344 &options[..],
1345 &base
1346 .options_iterator()
1347 .map(|x| x.unwrap())
1348 .collect::<Vec<TcpOptionElement>>()[..]
1349 );
1350 }
1351
1352 proptest! {
1353 #[test]
1354 #[allow(deprecated)]
1355 fn read_from_slice(header in tcp_any()) {
1356 {
1358 let bytes = {
1359 let mut bytes = header.to_bytes();
1360 bytes.try_extend_from_slice(
1361 &([0u8;TcpHeader::MAX_LEN])[..bytes.remaining_capacity()]
1362 ).unwrap();
1363 bytes
1364 };
1365
1366 let (actual_header, actual_rest) = TcpHeader::read_from_slice(&bytes[..]).unwrap();
1367 assert_eq!(actual_header, header);
1368 assert_eq!(actual_rest, &bytes[header.header_len() as usize..]);
1369 }
1370
1371 for data_offset in 0..TcpHeader::MIN_DATA_OFFSET {
1373 let bytes = {
1374 let mut bytes = header.to_bytes();
1375 bytes[12] = (bytes[12] & 0xf) | ((data_offset << 4) & 0xf0);
1376 bytes
1377 };
1378 assert_eq!(
1379 TcpHeader::read_from_slice(&bytes[..]),
1380 Err(Content(DataOffsetTooSmall{ data_offset }))
1381 );
1382 }
1383
1384 {
1386 let bytes = header.to_bytes();
1387 for len in 0..(header.header_len() as usize) {
1388 assert_eq!(
1389 TcpHeader::read_from_slice(&bytes[..len])
1390 .unwrap_err(),
1391 Len(err::LenError {
1392 required_len: if len < TcpHeader::MIN_LEN {
1393 TcpHeader::MIN_LEN
1394 } else {
1395 header.header_len() as usize
1396 },
1397 len: len,
1398 len_source: LenSource::Slice,
1399 layer: err::Layer::TcpHeader,
1400 layer_start_offset: 0,
1401 })
1402 );
1403 }
1404 }
1405 }
1406 }
1407
1408 proptest! {
1409 #[test]
1410 fn from_slice(header in tcp_any()) {
1411 {
1413 let bytes = {
1414 let mut bytes = header.to_bytes();
1415 bytes.try_extend_from_slice(
1416 &([0u8;TcpHeader::MAX_LEN])[..bytes.remaining_capacity()]
1417 ).unwrap();
1418 bytes
1419 };
1420
1421 let (actual_header, actual_rest) = TcpHeader::from_slice(&bytes[..]).unwrap();
1422 assert_eq!(actual_header, header);
1423 assert_eq!(actual_rest, &bytes[header.header_len() as usize..]);
1424 }
1425
1426 for data_offset in 0..TcpHeader::MIN_DATA_OFFSET {
1428 let bytes = {
1429 let mut bytes = header.to_bytes();
1430 bytes[12] = (bytes[12] & 0b1111) | ((data_offset << 4) & 0b1111_0000);
1431 bytes
1432 };
1433 assert_eq!(
1434 TcpHeader::from_slice(&bytes[..]),
1435 Err(Content(DataOffsetTooSmall{ data_offset }))
1436 );
1437 }
1438
1439 {
1441 let bytes = header.to_bytes();
1442 for len in 0..(header.header_len() as usize) {
1443 assert_eq!(
1444 TcpHeader::from_slice(&bytes[..len])
1445 .unwrap_err(),
1446 Len(err::LenError {
1447 required_len: if len < TcpHeader::MIN_LEN {
1448 TcpHeader::MIN_LEN
1449 } else {
1450 header.header_len() as usize
1451 },
1452 len: len,
1453 len_source: LenSource::Slice,
1454 layer: err::Layer::TcpHeader,
1455 layer_start_offset: 0,
1456 })
1457 );
1458 }
1459 }
1460 }
1461 }
1462
1463 proptest! {
1464 #[test]
1465 fn read(header in tcp_any()) {
1466 {
1468 let bytes = header.to_bytes();
1469 let mut cursor = Cursor::new(&bytes[..]);
1470 let actual = TcpHeader::read(&mut cursor).unwrap();
1471 assert_eq!(header.header_len() as u64, cursor.position());
1472 assert_eq!(header, actual);
1473 }
1474
1475 for data_offset in 0..TcpHeader::MIN_DATA_OFFSET {
1477 let bytes = {
1478 let mut bytes = header.to_bytes();
1479 bytes[12] = (bytes[12] & 0xf) | ((data_offset << 4) & 0xf0);
1480 bytes
1481 };
1482 assert_eq!(
1483 TcpHeader::read(&mut Cursor::new(&bytes[..]))
1484 .unwrap_err()
1485 .content_error()
1486 .unwrap(),
1487 DataOffsetTooSmall{ data_offset }
1488 );
1489 }
1490
1491 {
1493 let bytes = header.to_bytes();
1494 for len in 0..(header.header_len() as usize) {
1495 let mut cursor = Cursor::new(&bytes[..len]);
1496 let err = TcpHeader::read(&mut cursor).unwrap_err();
1497 assert!(err.io_error().is_some());
1498 }
1499 }
1500 }
1501 }
1502
1503 proptest! {
1504 #[test]
1505 fn write(header in tcp_any()) {
1506 {
1508 let mut bytes = [0u8;TcpHeader::MAX_LEN];
1509 let len = {
1510 let mut cursor = Cursor::new(&mut bytes[..]);
1511 header.write(&mut cursor).unwrap();
1512
1513 cursor.position() as usize
1514 };
1515 assert_eq!(header.header_len() as usize, len);
1516 assert_eq!(
1517 header,
1518 TcpHeader::from_slice(&bytes[..len]).unwrap().0
1519 );
1520 }
1521 for len in 0..header.header_len() {
1523 let mut bytes = [0u8;TcpHeader::MAX_LEN];
1524 let mut cursor = Cursor::new(&mut bytes[..len as usize]);
1525 let result = header.write(&mut cursor);
1526 assert!(result.is_err());
1527 }
1528 }
1529 }
1530
1531 proptest! {
1532 #[test]
1533 fn to_bytes(header in tcp_any()) {
1534 let bytes = header.to_bytes();
1535 let actual = TcpHeader::from_slice(&bytes).unwrap().0;
1536 assert_eq!(actual, header);
1537 }
1538 }
1539
1540 #[test]
1541 fn calc_checksum_ipv4() {
1542 use crate::TcpOptionElement::*;
1543
1544 {
1546 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
1547 let tcp = TcpHeader::new(0, 0, 40905, 0);
1549 let ip_header = Ipv4Header::new(
1550 tcp.header_len_u16() + (tcp_payload.len() as u16),
1552 0,
1554 ip_number::TCP,
1555 [0; 4],
1557 [0; 4],
1559 )
1560 .unwrap();
1561 assert_eq!(Ok(0x0), tcp.calc_checksum_ipv4(&ip_header, &tcp_payload));
1562 assert_eq!(
1563 Ok(0x0),
1564 tcp.calc_checksum_ipv4_raw(ip_header.source, ip_header.destination, &tcp_payload)
1565 );
1566 }
1567
1568 {
1570 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
1571
1572 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1573 tcp.urgent_pointer = 0xE26E;
1574 tcp.ns = true;
1575 tcp.fin = true;
1576 tcp.syn = true;
1577 tcp.rst = true;
1578 tcp.psh = true;
1579 tcp.ack = true;
1580 tcp.ece = true;
1581 tcp.urg = true;
1582 tcp.cwr = true;
1583
1584 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1585 .unwrap();
1586
1587 let ip_header = Ipv4Header::new(
1588 tcp.header_len_u16() + (tcp_payload.len() as u16),
1590 20,
1592 ip_number::TCP,
1594 [192, 168, 1, 42],
1596 [192, 168, 1, 1],
1598 )
1599 .unwrap();
1600
1601 assert_eq!(Ok(0xdeeb), tcp.calc_checksum_ipv4(&ip_header, &tcp_payload));
1603 }
1604
1605 {
1607 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8, 9];
1608
1609 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1610 tcp.urgent_pointer = 0xE26E;
1611 tcp.ns = true;
1612 tcp.fin = true;
1613 tcp.syn = true;
1614 tcp.rst = true;
1615 tcp.psh = true;
1616 tcp.ack = true;
1617 tcp.ece = true;
1618 tcp.urg = true;
1619 tcp.cwr = true;
1620
1621 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1622 .unwrap();
1623
1624 let ip_header = Ipv4Header::new(
1625 tcp.header_len_u16() + (tcp_payload.len() as u16),
1627 20,
1629 ip_number::TCP,
1631 [192, 168, 1, 42],
1633 [192, 168, 1, 1],
1635 )
1636 .unwrap();
1637
1638 assert_eq!(Ok(0xd5ea), tcp.calc_checksum_ipv4(&ip_header, &tcp_payload));
1640 }
1641
1642 {
1644 let tcp: TcpHeader = Default::default();
1646 let len = (core::u16::MAX - tcp.header_len_u16()) as usize + 1;
1647 let mut tcp_payload = Vec::with_capacity(len);
1648 tcp_payload.resize(len, 0);
1649 let ip_header = Ipv4Header::new(0, 0, ip_number::TCP, [0; 4], [0; 4]).unwrap();
1650 assert_eq!(
1651 Err(ValueTooBigError {
1652 actual: len,
1653 max_allowed: usize::from(core::u16::MAX) - usize::from(tcp.header_len()),
1654 value_type: ValueType::TcpPayloadLengthIpv4,
1655 }),
1656 tcp.calc_checksum_ipv4(&ip_header, &tcp_payload)
1657 );
1658 }
1659 }
1660
1661 #[test]
1662 fn calc_checksum_ipv4_raw() {
1663 {
1665 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
1666 let tcp = TcpHeader::new(0, 0, 40905, 0);
1668 assert_eq!(
1669 Ok(0x0),
1670 tcp.calc_checksum_ipv4_raw([0; 4], [0; 4], &tcp_payload)
1671 );
1672 }
1673
1674 {
1676 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
1677
1678 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1679 tcp.urgent_pointer = 0xE26E;
1680 tcp.ns = true;
1681 tcp.fin = true;
1682 tcp.syn = true;
1683 tcp.rst = true;
1684 tcp.psh = true;
1685 tcp.ack = true;
1686 tcp.ece = true;
1687 tcp.urg = true;
1688 tcp.cwr = true;
1689
1690 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1691 .unwrap();
1692
1693 assert_eq!(
1695 Ok(0xdeeb),
1696 tcp.calc_checksum_ipv4_raw([192, 168, 1, 42], [192, 168, 1, 1], &tcp_payload)
1697 );
1698 }
1699
1700 {
1702 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8, 9];
1703
1704 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1705 tcp.urgent_pointer = 0xE26E;
1706 tcp.ns = true;
1707 tcp.fin = true;
1708 tcp.syn = true;
1709 tcp.rst = true;
1710 tcp.psh = true;
1711 tcp.ack = true;
1712 tcp.ece = true;
1713 tcp.urg = true;
1714 tcp.cwr = true;
1715
1716 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1717 .unwrap();
1718
1719 assert_eq!(
1721 Ok(0xd5ea),
1722 tcp.calc_checksum_ipv4_raw([192, 168, 1, 42], [192, 168, 1, 1], &tcp_payload)
1723 );
1724 }
1725
1726 {
1728 let tcp: TcpHeader = Default::default();
1730 let len = (core::u16::MAX - tcp.header_len_u16()) as usize + 1;
1731 let mut tcp_payload = Vec::with_capacity(len);
1732 tcp_payload.resize(len, 0);
1733 assert_eq!(
1734 Err(ValueTooBigError {
1735 actual: len,
1736 max_allowed: usize::from(core::u16::MAX) - usize::from(tcp.header_len()),
1737 value_type: ValueType::TcpPayloadLengthIpv4,
1738 }),
1739 tcp.calc_checksum_ipv4_raw([0; 4], [0; 4], &tcp_payload)
1740 );
1741 }
1742 }
1743
1744 #[test]
1745 fn calc_checksum_ipv6() {
1746 {
1748 let tcp_payload = [51, 52, 53, 54, 55, 56, 57, 58];
1749
1750 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1752 tcp.urgent_pointer = 0xE26E;
1753
1754 tcp.ns = true;
1755 tcp.fin = true;
1756 tcp.syn = true;
1757 tcp.rst = true;
1758 tcp.psh = true;
1759 tcp.ack = true;
1760 tcp.ece = true;
1761 tcp.urg = true;
1762 tcp.cwr = true;
1763
1764 use crate::TcpOptionElement::*;
1765 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1766 .unwrap();
1767
1768 let ip_header = Ipv6Header {
1769 traffic_class: 1,
1770 flow_label: 0x81806.try_into().unwrap(),
1771 payload_length: tcp_payload.len() as u16 + tcp.header_len_u16(),
1772 next_header: ip_number::TCP,
1773 hop_limit: 40,
1774 source: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
1775 destination: [
1776 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1777 ],
1778 };
1779 assert_eq!(Ok(0x786e), tcp.calc_checksum_ipv6(&ip_header, &tcp_payload));
1781 }
1782
1783 #[cfg(target_pointer_width = "64")]
1785 {
1786 let tcp: TcpHeader = Default::default();
1788 let len = (core::u32::MAX - tcp.header_len() as u32) as usize + 1;
1789
1790 let tcp_payload = unsafe {
1793 use core::ptr::NonNull;
1797 core::slice::from_raw_parts(NonNull::<u8>::dangling().as_ptr(), len)
1798 };
1799 let ip_header = Ipv6Header {
1800 traffic_class: 1,
1801 flow_label: 0x81806.try_into().unwrap(),
1802 payload_length: 0, next_header: ip_number::TCP,
1804 hop_limit: 40,
1805 source: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
1806 destination: [
1807 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1808 ],
1809 };
1810
1811 assert_eq!(
1812 Err(ValueTooBigError {
1813 actual: len,
1814 max_allowed: core::u32::MAX as usize - usize::from(tcp.header_len()),
1815 value_type: ValueType::TcpPayloadLengthIpv6,
1816 }),
1817 tcp.calc_checksum_ipv6(&ip_header, &tcp_payload)
1818 );
1819 }
1820 }
1821
1822 #[test]
1823 fn calc_checksum_ipv6_raw() {
1824 {
1826 let tcp_payload = [51, 52, 53, 54, 55, 56, 57, 58];
1827
1828 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
1830 tcp.urgent_pointer = 0xE26E;
1831
1832 tcp.ns = true;
1833 tcp.fin = true;
1834 tcp.syn = true;
1835 tcp.rst = true;
1836 tcp.psh = true;
1837 tcp.ack = true;
1838 tcp.ece = true;
1839 tcp.urg = true;
1840 tcp.cwr = true;
1841
1842 use crate::TcpOptionElement::*;
1843 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
1844 .unwrap();
1845
1846 assert_eq!(
1848 Ok(0x786e),
1849 tcp.calc_checksum_ipv6_raw(
1850 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
1851 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,],
1852 &tcp_payload
1853 )
1854 );
1855 }
1856
1857 #[cfg(target_pointer_width = "64")]
1859 {
1860 let tcp: TcpHeader = Default::default();
1862 let len = (core::u32::MAX - tcp.header_len() as u32) as usize + 1;
1863
1864 let tcp_payload = unsafe {
1867 use core::ptr::NonNull;
1871 core::slice::from_raw_parts(NonNull::<u8>::dangling().as_ptr(), len)
1872 };
1873
1874 assert_eq!(
1875 Err(ValueTooBigError {
1876 actual: len,
1877 max_allowed: core::u32::MAX as usize - usize::from(tcp.header_len()),
1878 value_type: ValueType::TcpPayloadLengthIpv6,
1879 }),
1880 tcp.calc_checksum_ipv6_raw(
1881 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
1882 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,],
1883 &tcp_payload
1884 )
1885 );
1886 }
1887 }
1888}