1use crate::{
2 err::{ValueTooBigError, ValueType},
3 *,
4};
5
6#[derive(Clone, Debug, Eq, PartialEq)]
8pub struct TcpHeaderSlice<'a> {
9 pub(crate) slice: &'a [u8],
10}
11
12impl<'a> TcpHeaderSlice<'a> {
13 pub fn from_slice(slice: &'a [u8]) -> Result<TcpHeaderSlice<'a>, err::tcp::HeaderSliceError> {
15 use err::tcp::{HeaderError::*, HeaderSliceError::*};
16
17 if slice.len() < TcpHeader::MIN_LEN {
19 return Err(Len(err::LenError {
20 required_len: TcpHeader::MIN_LEN,
21 len: slice.len(),
22 len_source: LenSource::Slice,
23 layer: err::Layer::TcpHeader,
24 layer_start_offset: 0,
25 }));
26 }
27
28 let header_len = unsafe {
32 usize::from((*slice.get_unchecked(12) & 0xf0) >> 2)
62 };
63
64 if header_len < TcpHeader::MIN_LEN {
65 Err(Content(DataOffsetTooSmall {
66 data_offset: (header_len >> 2) as u8,
67 }))
68 } else if slice.len() < header_len {
69 Err(Len(err::LenError {
70 required_len: header_len,
71 len: slice.len(),
72 len_source: LenSource::Slice,
73 layer: err::Layer::TcpHeader,
74 layer_start_offset: 0,
75 }))
76 } else {
77 Ok(TcpHeaderSlice::<'a> {
79 slice: unsafe { core::slice::from_raw_parts(slice.as_ptr(), header_len) },
83 })
84 }
85 }
86
87 #[inline]
89 pub fn slice(&self) -> &'a [u8] {
90 self.slice
91 }
92
93 #[inline]
95 pub fn source_port(&self) -> u16 {
96 unsafe { get_unchecked_be_u16(self.slice.as_ptr()) }
100 }
101
102 #[inline]
104 pub fn destination_port(&self) -> u16 {
105 unsafe { get_unchecked_be_u16(self.slice.as_ptr().add(2)) }
109 }
110
111 #[inline]
117 pub fn sequence_number(&self) -> u32 {
118 unsafe { get_unchecked_be_u32(self.slice.as_ptr().add(4)) }
122 }
123
124 #[inline]
132 pub fn acknowledgment_number(&self) -> u32 {
133 unsafe { get_unchecked_be_u32(self.slice.as_ptr().add(8)) }
137 }
138
139 #[inline]
144 pub fn data_offset(&self) -> u8 {
145 unsafe { (*self.slice.get_unchecked(12) & 0b1111_0000) >> 4 }
149 }
150
151 #[inline]
153 pub fn ns(&self) -> bool {
154 unsafe { 0 != (*self.slice.get_unchecked(12) & 0b0000_0001) }
158 }
159
160 #[inline]
162 pub fn fin(&self) -> bool {
163 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0000_0001) }
167 }
168
169 #[inline]
171 pub fn syn(&self) -> bool {
172 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0000_0010) }
176 }
177
178 #[inline]
180 pub fn rst(&self) -> bool {
181 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0000_0100) }
185 }
186
187 #[inline]
189 pub fn psh(&self) -> bool {
190 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0000_1000) }
194 }
195
196 #[inline]
198 pub fn ack(&self) -> bool {
199 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0001_0000) }
203 }
204
205 #[inline]
207 pub fn urg(&self) -> bool {
208 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0010_0000) }
212 }
213
214 #[inline]
216 pub fn ece(&self) -> bool {
217 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b0100_0000) }
221 }
222
223 #[inline]
229 pub fn cwr(&self) -> bool {
230 unsafe { 0 != (*self.slice.get_unchecked(13) & 0b1000_0000) }
234 }
235
236 #[inline]
240 pub fn window_size(&self) -> u16 {
241 u16::from_be_bytes(
242 unsafe { [*self.slice.get_unchecked(14), *self.slice.get_unchecked(15)] },
246 )
247 }
248
249 #[inline]
251 pub fn checksum(&self) -> u16 {
252 u16::from_be_bytes(
253 unsafe { [*self.slice.get_unchecked(16), *self.slice.get_unchecked(17)] },
257 )
258 }
259
260 #[inline]
267 pub fn urgent_pointer(&self) -> u16 {
268 u16::from_be_bytes(
269 unsafe { [*self.slice.get_unchecked(18), *self.slice.get_unchecked(19)] },
273 )
274 }
275
276 #[inline]
278 pub fn options(&self) -> &[u8] {
279 &self.slice[TcpHeader::MIN_LEN..self.data_offset() as usize * 4]
280 }
281
282 #[inline]
284 pub fn options_iterator(&self) -> TcpOptionsIterator {
285 TcpOptionsIterator::from_slice(self.options())
286 }
287
288 pub fn to_header(&self) -> TcpHeader {
290 TcpHeader {
291 source_port: self.source_port(),
292 destination_port: self.destination_port(),
293 sequence_number: self.sequence_number(),
294 acknowledgment_number: self.acknowledgment_number(),
295 ns: self.ns(),
296 fin: self.fin(),
297 syn: self.syn(),
298 rst: self.rst(),
299 psh: self.psh(),
300 ack: self.ack(),
301 ece: self.ece(),
302 urg: self.urg(),
303 cwr: self.cwr(),
304 window_size: self.window_size(),
305 checksum: self.checksum(),
306 urgent_pointer: self.urgent_pointer(),
307 options: {
308 let options_slice = self.options();
309 let mut options = TcpOptions {
310 len: options_slice.len() as u8,
311 buf: [0; 40],
312 };
313 options.buf[..options_slice.len()].clone_from_slice(options_slice);
314 options
315 },
316 }
317 }
318
319 pub fn calc_checksum_ipv4(
321 &self,
322 ip_header: &Ipv4HeaderSlice,
323 payload: &[u8],
324 ) -> Result<u16, ValueTooBigError<usize>> {
325 self.calc_checksum_ipv4_raw(ip_header.source(), ip_header.destination(), payload)
326 }
327
328 pub fn calc_checksum_ipv4_raw(
330 &self,
331 source_ip: [u8; 4],
332 destination_ip: [u8; 4],
333 payload: &[u8],
334 ) -> Result<u16, ValueTooBigError<usize>> {
335 let header_len = self.slice.len() as u16;
337 let max_payload = usize::from(u16::MAX) - usize::from(header_len);
338 if max_payload < payload.len() {
339 return Err(ValueTooBigError {
340 actual: payload.len(),
341 max_allowed: max_payload,
342 value_type: ValueType::TcpPayloadLengthIpv4,
343 });
344 }
345
346 let tcp_len = header_len + (payload.len() as u16);
348 Ok(self.calc_checksum_post_ip(
349 checksum::Sum16BitWords::new()
350 .add_4bytes(source_ip)
351 .add_4bytes(destination_ip)
352 .add_2bytes([0, ip_number::TCP.0])
353 .add_2bytes((tcp_len).to_be_bytes()),
354 payload,
355 ))
356 }
357
358 pub fn calc_checksum_ipv6(
360 &self,
361 ip_header: &Ipv6HeaderSlice,
362 payload: &[u8],
363 ) -> Result<u16, ValueTooBigError<usize>> {
364 self.calc_checksum_ipv6_raw(ip_header.source(), ip_header.destination(), payload)
365 }
366
367 pub fn calc_checksum_ipv6_raw(
369 &self,
370 source: [u8; 16],
371 destination: [u8; 16],
372 payload: &[u8],
373 ) -> Result<u16, ValueTooBigError<usize>> {
374 let header_len = self.slice.len() as u32;
376 let max_payload = (u32::MAX as usize) - (header_len as usize);
377 if max_payload < payload.len() {
378 return Err(ValueTooBigError {
379 actual: payload.len(),
380 max_allowed: max_payload,
381 value_type: ValueType::TcpPayloadLengthIpv6,
382 });
383 }
384
385 let tcp_len = header_len + (payload.len() as u32);
387 Ok(self.calc_checksum_post_ip(
388 checksum::Sum16BitWords::new()
389 .add_16bytes(source)
390 .add_16bytes(destination)
391 .add_2bytes([0, ip_number::TCP.0])
392 .add_4bytes((tcp_len).to_be_bytes()),
393 payload,
394 ))
395 }
396
397 fn calc_checksum_post_ip(
399 &self,
400 ip_pseudo_header_sum: checksum::Sum16BitWords,
401 payload: &[u8],
402 ) -> u16 {
403 ip_pseudo_header_sum
404 .add_slice(&self.slice[..16]) .add_slice(&self.slice[18..self.slice.len()])
406 .add_slice(payload)
407 .ones_complement()
408 .to_be()
409 }
410}
411
412#[cfg(test)]
413mod test {
414 use crate::{
415 err::{
416 tcp::{HeaderError::*, HeaderSliceError::*},
417 ValueTooBigError, ValueType,
418 },
419 test_gens::*,
420 TcpOptionElement::*,
421 *,
422 };
423 use alloc::{format, vec::Vec};
424 use proptest::prelude::*;
425
426 proptest! {
427 #[test]
428 fn debug(header in tcp_any()) {
429 let buffer = header.to_bytes();
430 let slice = TcpHeaderSlice::from_slice(&buffer).unwrap();
431 assert_eq!(
432 format!("{:?}", slice),
433 format!("TcpHeaderSlice {{ slice: {:?} }}", slice.slice())
434 );
435 }
436 }
437
438 proptest! {
439 #[test]
440 fn clone_eq(header in tcp_any()) {
441 let bytes = header.to_bytes();
442 let slice = TcpHeaderSlice::from_slice(&bytes).unwrap();
443 assert_eq!(slice.clone(), slice);
444 }
445 }
446
447 proptest! {
448 #[test]
449 fn from_slice(header in tcp_any()) {
450 {
452 let bytes = {
453 let mut bytes = header.to_bytes();
454 bytes.try_extend_from_slice(
455 &([0u8;TcpHeader::MAX_LEN])[..bytes.remaining_capacity()]
456 ).unwrap();
457 bytes
458 };
459
460 let slice = TcpHeaderSlice::from_slice(&bytes[..]).unwrap();
461 assert_eq!(slice.slice(), &bytes[..header.header_len() as usize]);
462 assert_eq!(slice.to_header(), header);
463 }
464
465 for data_offset in 0..TcpHeader::MIN_DATA_OFFSET {
467 let bytes = {
468 let mut bytes = header.to_bytes();
469 bytes[12] = (bytes[12] & 0xf) | ((data_offset << 4) & 0xf0);
470 bytes
471 };
472 assert_eq!(
473 TcpHeaderSlice::from_slice(&bytes[..]),
474 Err(Content(DataOffsetTooSmall{ data_offset }))
475 );
476 }
477
478 {
480 let bytes = header.to_bytes();
481 for len in 0..(header.header_len() as usize) {
482 assert_eq!(
483 TcpHeaderSlice::from_slice(&bytes[..len])
484 .unwrap_err(),
485 Len(err::LenError {
486 required_len: if len < TcpHeader::MIN_LEN {
487 TcpHeader::MIN_LEN
488 } else {
489 header.header_len() as usize
490 },
491 len: len,
492 len_source: LenSource::Slice,
493 layer: err::Layer::TcpHeader,
494 layer_start_offset: 0,
495 })
496 );
497 }
498 }
499 }
500 }
501
502 proptest! {
503 #[test]
504 fn getters(header in tcp_any()) {
505 let bytes = header.to_bytes();
506 let slice = TcpHeaderSlice::from_slice(&bytes).unwrap();
507
508 assert_eq!(header.source_port, slice.source_port());
509 assert_eq!(header.destination_port, slice.destination_port());
510 assert_eq!(header.sequence_number, slice.sequence_number());
511 assert_eq!(header.acknowledgment_number, slice.acknowledgment_number());
512 assert_eq!(header.data_offset(), slice.data_offset());
513 assert_eq!(header.ns, slice.ns());
514 assert_eq!(header.fin, slice.fin());
515 assert_eq!(header.syn, slice.syn());
516 assert_eq!(header.rst, slice.rst());
517 assert_eq!(header.psh, slice.psh());
518 assert_eq!(header.ack, slice.ack());
519 assert_eq!(header.urg, slice.urg());
520 assert_eq!(header.ece, slice.ece());
521 assert_eq!(header.cwr, slice.cwr());
522 assert_eq!(header.window_size, slice.window_size());
523 assert_eq!(header.checksum, slice.checksum());
524 assert_eq!(header.urgent_pointer, slice.urgent_pointer());
525 assert_eq!(header.options.as_slice(), slice.options());
526 }
527 }
528
529 proptest! {
530 #[test]
531 fn options_iterator(header in tcp_any()) {
532 let bytes = header.to_bytes();
533 let slice = TcpHeaderSlice::from_slice(&bytes).unwrap();
534 assert_eq!(
535 TcpOptionsIterator::from_slice(header.options.as_slice()),
536 slice.options_iterator()
537 );
538 }
539 }
540
541 proptest! {
542 #[test]
543 fn to_header(header in tcp_any()) {
544 let bytes = header.to_bytes();
545 let slice = TcpHeaderSlice::from_slice(&bytes).unwrap();
546 assert_eq!(header, slice.to_header());
547 }
548 }
549
550 #[test]
551 fn calc_checksum_ipv4() {
552 {
554 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
555
556 let tcp = TcpHeader::new(0, 0, 40905, 0);
558 let ip_header = Ipv4Header::new(
559 tcp.header_len_u16() + (tcp_payload.len() as u16),
561 0,
563 ip_number::TCP,
564 [0; 4],
566 [0; 4],
568 )
569 .unwrap();
570
571 let ip_bytes = ip_header.to_bytes();
573 let ip_slice = Ipv4HeaderSlice::from_slice(&ip_bytes).unwrap();
574
575 let tcp_bytes = tcp.to_bytes();
576 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_bytes).unwrap();
577
578 assert_eq!(
579 Ok(0x0),
580 tcp_slice.calc_checksum_ipv4(&ip_slice, &tcp_payload)
581 );
582 }
583
584 {
586 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
587
588 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
589 tcp.urgent_pointer = 0xE26E;
590 tcp.ns = true;
591 tcp.fin = true;
592 tcp.syn = true;
593 tcp.rst = true;
594 tcp.psh = true;
595 tcp.ack = true;
596 tcp.ece = true;
597 tcp.urg = true;
598 tcp.cwr = true;
599
600 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
601 .unwrap();
602
603 let ip_header = Ipv4Header::new(
604 tcp.header_len_u16() + (tcp_payload.len() as u16),
606 20,
608 ip_number::TCP,
609 [192, 168, 1, 42],
611 [192, 168, 1, 1],
613 )
614 .unwrap();
615
616 let ip_buffer = ip_header.to_bytes();
618 let ip_slice = Ipv4HeaderSlice::from_slice(&ip_buffer).unwrap();
619
620 let tcp_buffer = tcp.to_bytes();
621 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer).unwrap();
622
623 assert_eq!(
624 Ok(0xdeeb),
625 tcp_slice.calc_checksum_ipv4(&ip_slice, &tcp_payload)
626 );
627 }
628
629 {
631 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8, 9];
632
633 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
634 tcp.urgent_pointer = 0xE26E;
635 tcp.ns = true;
636 tcp.fin = true;
637 tcp.syn = true;
638 tcp.rst = true;
639 tcp.psh = true;
640 tcp.ack = true;
641 tcp.ece = true;
642 tcp.urg = true;
643 tcp.cwr = true;
644
645 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
646 .unwrap();
647
648 let ip_header = Ipv4Header::new(
649 tcp.header_len_u16() + (tcp_payload.len() as u16),
651 20,
653 ip_number::TCP,
654 [192, 168, 1, 42],
656 [192, 168, 1, 1],
658 )
659 .unwrap();
660
661 let ip_buffer = ip_header.to_bytes();
663 let ip_slice = Ipv4HeaderSlice::from_slice(&ip_buffer[..]).unwrap();
664
665 let tcp_buffer = tcp.to_bytes();
666 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer[..]).unwrap();
667
668 assert_eq!(
669 Ok(0xd5ea),
670 tcp_slice.calc_checksum_ipv4(&ip_slice, &tcp_payload)
671 );
672 }
673
674 {
676 let tcp: TcpHeader = Default::default();
678 let len = (core::u16::MAX - tcp.header_len_u16()) as usize + 1;
679 let mut tcp_payload = Vec::with_capacity(len);
680 tcp_payload.resize(len, 0);
681 let ip_header = Ipv4Header::new(0, 0, ip_number::TCP, [0; 4], [0; 4]).unwrap();
682
683 let ip_buffer = ip_header.to_bytes();
685 let ip_slice = Ipv4HeaderSlice::from_slice(&ip_buffer).unwrap();
686
687 let tcp_buffer = tcp.to_bytes();
688 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer).unwrap();
689
690 assert_eq!(
691 tcp_slice.calc_checksum_ipv4(&ip_slice, &tcp_payload),
692 Err(ValueTooBigError {
693 actual: len,
694 max_allowed: usize::from(core::u16::MAX - tcp.header_len_u16()),
695 value_type: ValueType::TcpPayloadLengthIpv4,
696 })
697 );
698 }
699 }
700
701 #[test]
702 fn calc_checksum_ipv4_raw() {
703 {
705 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
706
707 let tcp = TcpHeader::new(0, 0, 40905, 0);
709
710 let tcp_bytes = tcp.to_bytes();
712 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_bytes).unwrap();
713
714 assert_eq!(
715 Ok(0x0),
716 tcp_slice.calc_checksum_ipv4_raw([0; 4], [0; 4], &tcp_payload)
717 );
718 }
719
720 {
722 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
723
724 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
725 tcp.urgent_pointer = 0xE26E;
726 tcp.ns = true;
727 tcp.fin = true;
728 tcp.syn = true;
729 tcp.rst = true;
730 tcp.psh = true;
731 tcp.ack = true;
732 tcp.ece = true;
733 tcp.urg = true;
734 tcp.cwr = true;
735
736 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
737 .unwrap();
738
739 let tcp_buffer = tcp.to_bytes();
741 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer).unwrap();
742
743 assert_eq!(
744 Ok(0xdeeb),
745 tcp_slice.calc_checksum_ipv4_raw([192, 168, 1, 42], [192, 168, 1, 1], &tcp_payload)
746 );
747 }
748
749 {
751 let tcp_payload = [1, 2, 3, 4, 5, 6, 7, 8, 9];
752
753 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
754 tcp.urgent_pointer = 0xE26E;
755 tcp.ns = true;
756 tcp.fin = true;
757 tcp.syn = true;
758 tcp.rst = true;
759 tcp.psh = true;
760 tcp.ack = true;
761 tcp.ece = true;
762 tcp.urg = true;
763 tcp.cwr = true;
764
765 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
766 .unwrap();
767
768 let tcp_buffer = tcp.to_bytes();
770 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer[..]).unwrap();
771
772 assert_eq!(
773 Ok(0xd5ea),
774 tcp_slice.calc_checksum_ipv4_raw([192, 168, 1, 42], [192, 168, 1, 1], &tcp_payload)
775 );
776 }
777
778 {
780 let tcp: TcpHeader = Default::default();
782 let len = (core::u16::MAX - tcp.header_len_u16()) as usize + 1;
783 let mut tcp_payload = Vec::with_capacity(len);
784 tcp_payload.resize(len, 0);
785
786 let tcp_buffer = tcp.to_bytes();
788 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer).unwrap();
789
790 assert_eq!(
791 tcp_slice.calc_checksum_ipv4_raw([0; 4], [0; 4], &tcp_payload),
792 Err(ValueTooBigError {
793 actual: len,
794 max_allowed: usize::from(core::u16::MAX - tcp.header_len_u16()),
795 value_type: ValueType::TcpPayloadLengthIpv4,
796 })
797 );
798 }
799 }
800
801 #[test]
802 fn calc_checksum_ipv6() {
803 {
805 let tcp_payload = [51, 52, 53, 54, 55, 56, 57, 58];
806
807 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
809 tcp.urgent_pointer = 0xE26E;
810
811 tcp.ns = true;
812 tcp.fin = true;
813 tcp.syn = true;
814 tcp.rst = true;
815 tcp.psh = true;
816 tcp.ack = true;
817 tcp.ece = true;
818 tcp.urg = true;
819 tcp.cwr = true;
820
821 use crate::TcpOptionElement::*;
822 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
823 .unwrap();
824
825 let ip_header = Ipv6Header {
827 traffic_class: 1,
828 flow_label: 0x81806.try_into().unwrap(),
829 payload_length: tcp_payload.len() as u16 + tcp.header_len_u16(),
830 next_header: ip_number::TCP,
831 hop_limit: 40,
832 source: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
833 destination: [
834 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
835 ],
836 };
837
838 let ip_buffer = ip_header.to_bytes();
840 let ip_slice = Ipv6HeaderSlice::from_slice(&ip_buffer[..]).unwrap();
841
842 let tcp_bytes = tcp.to_bytes();
843 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_bytes).unwrap();
844
845 assert_eq!(
847 Ok(0x786e),
848 tcp_slice.calc_checksum_ipv6(&ip_slice, &tcp_payload)
849 );
850 }
851
852 #[cfg(target_pointer_width = "64")]
854 {
855 let tcp: TcpHeader = Default::default();
857 let len = (core::u32::MAX - tcp.header_len() as u32) as usize + 1;
858
859 let tcp_payload = unsafe {
862 use core::ptr::NonNull;
866 core::slice::from_raw_parts(NonNull::<u8>::dangling().as_ptr(), len)
867 };
868 let ip_header = Ipv6Header {
869 traffic_class: 1,
870 flow_label: 0x81806.try_into().unwrap(),
871 payload_length: 0, next_header: ip_number::TCP,
873 hop_limit: 40,
874 source: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
875 destination: [
876 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
877 ],
878 };
879
880 let mut ip_buffer = Vec::new();
882 ip_header.write(&mut ip_buffer).unwrap();
883 let ip_slice = Ipv6HeaderSlice::from_slice(&ip_buffer[..]).unwrap();
884
885 let mut tcp_buffer = Vec::new();
886 tcp.write(&mut tcp_buffer).unwrap();
887 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer[..]).unwrap();
888
889 assert_eq!(
891 tcp_slice.calc_checksum_ipv6(&ip_slice, &tcp_payload),
892 Err(ValueTooBigError {
893 actual: len,
894 max_allowed: core::u32::MAX as usize - tcp.header_len() as usize,
895 value_type: ValueType::TcpPayloadLengthIpv6,
896 })
897 );
898 }
899 }
900
901 #[test]
902 fn calc_checksum_ipv6_raw() {
903 {
905 let tcp_payload = [51, 52, 53, 54, 55, 56, 57, 58];
906
907 let mut tcp = TcpHeader::new(69, 42, 0x24900448, 0x3653);
909 tcp.urgent_pointer = 0xE26E;
910
911 tcp.ns = true;
912 tcp.fin = true;
913 tcp.syn = true;
914 tcp.rst = true;
915 tcp.psh = true;
916 tcp.ack = true;
917 tcp.ece = true;
918 tcp.urg = true;
919 tcp.cwr = true;
920
921 use crate::TcpOptionElement::*;
922 tcp.set_options(&[Noop, Noop, Noop, Noop, Timestamp(0x4161008, 0x84161708)])
923 .unwrap();
924
925 let tcp_buffer = tcp.to_bytes();
927 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer[..]).unwrap();
928
929 assert_eq!(
931 Ok(0x786e),
932 tcp_slice.calc_checksum_ipv6_raw(
933 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
934 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,],
935 &tcp_payload
936 )
937 );
938 }
939
940 #[cfg(target_pointer_width = "64")]
942 {
943 let tcp: TcpHeader = Default::default();
945 let len = (core::u32::MAX - tcp.header_len() as u32) as usize + 1;
946
947 let tcp_payload = unsafe {
950 use core::ptr::NonNull;
954 core::slice::from_raw_parts(NonNull::<u8>::dangling().as_ptr(), len)
955 };
956
957 let tcp_buffer = tcp.to_bytes();
959 let tcp_slice = TcpHeaderSlice::from_slice(&tcp_buffer).unwrap();
960
961 assert_eq!(
963 tcp_slice.calc_checksum_ipv6_raw(
964 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
965 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,],
966 &tcp_payload
967 ),
968 Err(ValueTooBigError {
969 actual: len,
970 max_allowed: core::u32::MAX as usize - tcp.header_len() as usize,
971 value_type: ValueType::TcpPayloadLengthIpv6,
972 })
973 );
974 }
975 }
976}