• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::err::packet::BuildWriteError;
2 
3 use super::*;
4 
5 use std::{io, marker};
6 
7 /// Helper for building packets.
8 ///
9 /// The packet builder allows the easy construction of a packet from the
10 /// ethernet II layer downwards including ipv6, ipv4, the udp header and the
11 /// actual payload. The packet builder automatically calculates lengths & checksums
12 /// for ip & udp and set type identifiers for ethernetII and ip. This makes it
13 /// easy and less error prone to construct custom packets.
14 ///
15 /// # Example:
16 ///
17 /// Generating a packet that starts with an Ethernet II header:
18 ///
19 /// ```
20 /// use etherparse::PacketBuilder;
21 ///
22 /// let builder = PacketBuilder::
23 ///     ethernet2([1,2,3,4,5,6],     //source mac
24 ///               [7,8,9,10,11,12]) //destination mac
25 ///    .ipv4([192,168,1,1], //source ip
26 ///          [192,168,1,2], //destination ip
27 ///          20)            //time to life
28 ///    .udp(21,    //source port
29 ///         1234); //destination port
30 ///
31 /// //payload of the udp packet
32 /// let payload = [1,2,3,4,5,6,7,8];
33 ///
34 /// //get some memory to store the result
35 /// let mut result = Vec::<u8>::with_capacity(
36 ///                     builder.size(payload.len()));
37 ///
38 /// //serialize
39 /// builder.write(&mut result, &payload).unwrap();
40 /// println!("{:?}", result);
41 /// ```
42 ///
43 /// # Options
44 ///
45 /// * Starting Options:
46 ///     * [`PacketBuilder::ethernet2`]
47 ///     * [`PacketBuilder::linux_sll`]
48 ///     * [`PacketBuilder::ip`]
49 ///     * [`PacketBuilder::ipv4`]
50 ///     * [`PacketBuilder::ipv6`]
51 /// * Options after an Ethernet2 header was added:
52 ///     * [`PacketBuilderStep<Ethernet2Header>::arp`]
53 ///     * [`PacketBuilderStep<Ethernet2Header>::vlan`]
54 ///     * [`PacketBuilderStep<Ethernet2Header>::single_vlan`]
55 ///     * [`PacketBuilderStep<Ethernet2Header>::double_vlan`]
56 ///     * [`PacketBuilderStep<Ethernet2Header>::ip`]
57 ///     * [`PacketBuilderStep<Ethernet2Header>::ipv4`]
58 ///     * [`PacketBuilderStep<Ethernet2Header>::ipv6`]
59 /// * Options after a Linux Cooked Capture v1 (SLL) was added:
60 ///     * [`PacketBuilderStep<LinuxSllHeader>::ip`]
61 ///     * [`PacketBuilderStep<LinuxSllHeader>::ipv4`]
62 ///     * [`PacketBuilderStep<LinuxSllHeader>::ipv6`]
63 /// * Options after an Vlan header was added:
64 ///     * [`PacketBuilderStep<VlanHeader>::ip`]
65 ///     * [`PacketBuilderStep<VlanHeader>::ipv4`]
66 ///     * [`PacketBuilderStep<VlanHeader>::ipv6`]
67 /// * Options after an IP header was added:
68 ///     * [`PacketBuilderStep<IpHeaders>::write`]
69 ///     * [`PacketBuilderStep<IpHeaders>::tcp`]
70 ///     * [`PacketBuilderStep<IpHeaders>::udp`]
71 ///     * [`PacketBuilderStep<IpHeaders>::icmpv4`]
72 ///     * [`PacketBuilderStep<IpHeaders>::icmpv4_raw`]
73 ///     * [`PacketBuilderStep<IpHeaders>::icmpv4_echo_request`]
74 ///     * [`PacketBuilderStep<IpHeaders>::icmpv4_echo_reply`]
75 ///     * [`PacketBuilderStep<IpHeaders>::icmpv6`]
76 ///     * [`PacketBuilderStep<IpHeaders>::icmpv6_raw`]
77 ///     * [`PacketBuilderStep<IpHeaders>::icmpv6_echo_request`]
78 ///     * [`PacketBuilderStep<IpHeaders>::icmpv6_echo_reply`]
79 /// * Options after an TCP header was added:
80 ///     * [`PacketBuilderStep<TcpHeader>::write`]
81 ///     * [`PacketBuilderStep<TcpHeader>::size`]
82 ///     * [`PacketBuilderStep<TcpHeader>::ns`]
83 ///     * [`PacketBuilderStep<TcpHeader>::fin`]
84 ///     * [`PacketBuilderStep<TcpHeader>::syn`]
85 ///     * [`PacketBuilderStep<TcpHeader>::rst`]
86 ///     * [`PacketBuilderStep<TcpHeader>::psh`]
87 ///     * [`PacketBuilderStep<TcpHeader>::ack`]
88 ///     * [`PacketBuilderStep<TcpHeader>::urg`]
89 ///     * [`PacketBuilderStep<TcpHeader>::ece`]
90 ///     * [`PacketBuilderStep<TcpHeader>::cwr`]
91 ///     * [`PacketBuilderStep<TcpHeader>::options`]
92 ///     * [`PacketBuilderStep<TcpHeader>::options_raw`]
93 /// * Options after an UDP header was added:
94 ///     * [`PacketBuilderStep<UdpHeader>::write`]
95 ///     * [`PacketBuilderStep<UdpHeader>::size`]
96 /// * Options after an ICMPv4 header was added:
97 ///     * [`PacketBuilderStep<Icmpv4Header>::write`]
98 ///     * [`PacketBuilderStep<Icmpv4Header>::size`]
99 /// * Options after an ICMPv6 header was added:
100 ///     * [`PacketBuilderStep<Icmpv6Header>::write`]
101 ///     * [`PacketBuilderStep<Icmpv6Header>::size`]
102 ///
103 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
104 pub struct PacketBuilder {}
105 
106 impl PacketBuilder {
107     /// Start an packet with an ethernetII header.
108     ///
109     /// # Example
110     ///
111     /// Basic usage:
112     ///
113     /// ```
114     /// # use etherparse::PacketBuilder;
115     /// #
116     /// let builder = PacketBuilder::
117     ///     ethernet2([1,2,3,4,5,6],     //source mac
118     ///               [7,8,9,10,11,12]) //destination mac
119     ///    .ipv4([192,168,1,1], //source ip
120     ///          [192,168,1,2], //destination ip
121     ///          20)            //time to life
122     ///    .udp(21,    //source port
123     ///         1234); //destination port
124     ///
125     /// //payload of the udp packet
126     /// let payload = [1,2,3,4,5,6,7,8];
127     ///
128     /// //get some memory to store the result
129     /// let mut result = Vec::<u8>::with_capacity(
130     ///                     builder.size(payload.len()));
131     ///
132     /// //serialize
133     /// builder.write(&mut result, &payload).unwrap();
134     /// ```
ethernet2(source: [u8; 6], destination: [u8; 6]) -> PacketBuilderStep<Ethernet2Header>135     pub fn ethernet2(source: [u8; 6], destination: [u8; 6]) -> PacketBuilderStep<Ethernet2Header> {
136         PacketBuilderStep {
137             state: PacketImpl {
138                 link_header: Some(LinkHeader::Ethernet2(Ethernet2Header {
139                     source,
140                     destination,
141                     ether_type: EtherType(0), //the type identifier
142                 })),
143                 vlan_header: None,
144                 net_header: None,
145                 transport_header: None,
146             },
147             _marker: marker::PhantomData::<Ethernet2Header> {},
148         }
149     }
150 
151     /// Start an packet with an Linux Cooked Catpure (v1) header.
152     ///
153     /// # Example
154     ///
155     /// Basic usage:
156     ///
157     /// ```
158     /// # use etherparse::{PacketBuilder, LinuxSllPacketType};
159     /// #
160     /// let builder = PacketBuilder::
161     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
162     ///               6, //sender address valid length
163     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
164     ///    .ipv4([192,168,1,1], //source ip
165     ///          [192,168,1,2], //destination ip
166     ///          20)            //time to life
167     ///    .udp(21,    //source port
168     ///         1234); //destination port
169     ///
170     /// //payload of the udp packet
171     /// let payload = [1,2,3,4,5,6,7,8];
172     ///
173     /// //get some memory to store the result
174     /// let mut result = Vec::<u8>::with_capacity(
175     ///                     builder.size(payload.len()));
176     ///
177     /// //serialize
178     /// builder.write(&mut result, &payload).unwrap();
179     /// ```
linux_sll( packet_type: LinuxSllPacketType, sender_address_valid_length: u16, sender_address: [u8; 8], ) -> PacketBuilderStep<LinuxSllHeader>180     pub fn linux_sll(
181         packet_type: LinuxSllPacketType,
182         sender_address_valid_length: u16,
183         sender_address: [u8; 8],
184     ) -> PacketBuilderStep<LinuxSllHeader> {
185         PacketBuilderStep {
186             state: PacketImpl {
187                 link_header: Some(LinkHeader::LinuxSll(LinuxSllHeader {
188                     packet_type,
189                     arp_hrd_type: ArpHardwareId::ETHERNET,
190                     sender_address_valid_length,
191                     sender_address,
192                     protocol_type: LinuxSllProtocolType::EtherType(EtherType(0)), // Will be overwitten when writing depending on the net layer
193                 })),
194                 vlan_header: None,
195                 net_header: None,
196                 transport_header: None,
197             },
198             _marker: marker::PhantomData::<LinuxSllHeader> {},
199         }
200     }
201 
202     /// Starts a packet with an IPv4 header.
203     ///
204     /// # Example
205     ///
206     /// Basic usage:
207     ///
208     /// ```
209     /// # use etherparse::PacketBuilder;
210     /// #
211     /// let builder = PacketBuilder::
212     ///    ipv4([192,168,1,1],  //source ip
213     ///          [192,168,1,2], //destination ip
214     ///          20)            //time to life
215     ///    .udp(21,    //source port
216     ///         1234); //destination port
217     ///
218     /// //payload of the udp packet
219     /// let payload = [1,2,3,4,5,6,7,8];
220     ///
221     /// //get some memory to store the result
222     /// let mut result = Vec::<u8>::with_capacity(
223     ///                     builder.size(payload.len()));
224     ///
225     /// //serialize
226     /// builder.write(&mut result, &payload).unwrap();
227     /// ```
ipv4( source: [u8; 4], destination: [u8; 4], time_to_live: u8, ) -> PacketBuilderStep<IpHeaders>228     pub fn ipv4(
229         source: [u8; 4],
230         destination: [u8; 4],
231         time_to_live: u8,
232     ) -> PacketBuilderStep<IpHeaders> {
233         PacketBuilderStep {
234             state: PacketImpl {
235                 link_header: None,
236                 vlan_header: None,
237                 net_header: None,
238                 transport_header: None,
239             },
240             _marker: marker::PhantomData::<Ethernet2Header> {},
241         }
242         .ipv4(source, destination, time_to_live)
243     }
244 
245     /// Start a packet with an IPv6 header.
246     ///
247     /// # Example
248     ///
249     /// Basic usage:
250     ///
251     /// ```
252     /// # use etherparse::PacketBuilder;
253     /// #
254     /// let builder = PacketBuilder::
255     ///     ipv6(
256     ///         //source
257     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
258     ///         //destination
259     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
260     ///         //hop_limit
261     ///         47)
262     ///    .udp(21,    //source port
263     ///         1234); //destination port
264     ///
265     /// //payload of the udp packet
266     /// let payload = [1,2,3,4,5,6,7,8];
267     ///
268     /// //get some memory to store the result
269     /// let mut result = Vec::<u8>::with_capacity(
270     ///                     builder.size(payload.len()));
271     ///
272     /// //serialize
273     /// builder.write(&mut result, &payload).unwrap();
274     /// ```
ipv6( source: [u8; 16], destination: [u8; 16], hop_limit: u8, ) -> PacketBuilderStep<IpHeaders>275     pub fn ipv6(
276         source: [u8; 16],
277         destination: [u8; 16],
278         hop_limit: u8,
279     ) -> PacketBuilderStep<IpHeaders> {
280         PacketBuilderStep {
281             state: PacketImpl {
282                 link_header: None,
283                 vlan_header: None,
284                 net_header: None,
285                 transport_header: None,
286             },
287             _marker: marker::PhantomData::<Ethernet2Header> {},
288         }
289         .ipv6(source, destination, hop_limit)
290     }
291 
292     /// Starts a packet with an arbitrary IP header (length, protocol/next_header & checksum fields will be overwritten based on the rest of the packet).
293     ///
294     /// # Examples
295     ///
296     /// With an IPv4 header:
297     ///
298     /// ```
299     /// # use etherparse::*;
300     /// #
301     /// let builder = PacketBuilder::
302     ///    //payload_len, protocol & checksum will be replaced during write
303     ///    ip(IpHeaders::Ipv4(
304     ///        Ipv4Header::new(
305     ///            0, //payload_len will be replaced during write
306     ///            12, //time_to_live
307     ///            ip_number::UDP, //will be replaced during write
308     ///            [0,1,2,3], //source
309     ///            [4,5,6,7] //destination
310     ///        ).unwrap(),
311     ///        Default::default()))
312     ///    .udp(21,    //source port
313     ///         1234); //destination port
314     ///
315     /// //payload of the udp packet
316     /// let payload = [1,2,3,4,5,6,7,8];
317     ///
318     /// //get some memory to store the result
319     /// let mut result = Vec::<u8>::with_capacity(
320     ///                     builder.size(payload.len()));
321     ///
322     /// //serialize
323     /// builder.write(&mut result, &payload).unwrap();
324     /// ```
325     ///
326     /// With an IPv6 header:
327     ///
328     /// ```
329     /// # use etherparse::*;
330     /// #
331     /// let builder = PacketBuilder::
332     ///    ip(IpHeaders::Ipv6(
333     ///         Ipv6Header{
334     ///             traffic_class: 0,
335     ///             flow_label: 0.try_into().unwrap(),
336     ///             hop_limit: 4.try_into().unwrap(),
337     ///             source: [0;16],
338     ///             destination: [0;16],
339     ///             // payload_length & next_header will be replaced during write
340     ///             ..Default::default()
341     ///         },
342     ///         Default::default()))
343     ///    .udp(21,    //source port
344     ///         1234); //destination port
345     ///
346     /// //payload of the udp packet
347     /// let payload = [1,2,3,4,5,6,7,8];
348     ///
349     /// //get some memory to store the result
350     /// let mut result = Vec::<u8>::with_capacity(
351     ///                     builder.size(payload.len()));
352     ///
353     /// //serialize
354     /// builder.write(&mut result, &payload).unwrap();
355     /// ```
ip(ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders>356     pub fn ip(ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders> {
357         PacketBuilderStep {
358             state: PacketImpl {
359                 link_header: None,
360                 vlan_header: None,
361                 net_header: None,
362                 transport_header: None,
363             },
364             _marker: marker::PhantomData::<Ethernet2Header> {},
365         }
366         .ip(ip_header)
367     }
368 }
369 
370 struct PacketImpl {
371     link_header: Option<LinkHeader>,
372     net_header: Option<NetHeaders>,
373     vlan_header: Option<VlanHeader>,
374     transport_header: Option<TransportHeader>,
375 }
376 
377 ///An unfinished packet that is build with the packet builder
378 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
379 pub struct PacketBuilderStep<LastStep> {
380     state: PacketImpl,
381     _marker: marker::PhantomData<LastStep>,
382 }
383 
384 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
385 impl PacketBuilderStep<Ethernet2Header> {
386     /// Add an IPv4 header
387     ///
388     /// # Example
389     ///
390     /// Basic usage:
391     ///
392     /// ```
393     /// # use etherparse::PacketBuilder;
394     /// #
395     /// let builder = PacketBuilder::
396     ///     ethernet2([1,2,3,4,5,6],     //source mac
397     ///               [7,8,9,10,11,12]) //destination mac
398     ///    .ipv4([192,168,1,1], //source ip
399     ///          [192,168,1,2], //destination ip
400     ///          20)            //time to life
401     ///    .udp(21,    //source port
402     ///         1234); //destination port
403     ///
404     /// //payload of the udp packet
405     /// let payload = [1,2,3,4,5,6,7,8];
406     ///
407     /// //get some memory to store the result
408     /// let mut result = Vec::<u8>::with_capacity(
409     ///                     builder.size(payload.len()));
410     ///
411     /// //serialize
412     /// builder.write(&mut result, &payload).unwrap();
413     /// ```
ipv4( mut self, source: [u8; 4], destination: [u8; 4], time_to_live: u8, ) -> PacketBuilderStep<IpHeaders>414     pub fn ipv4(
415         mut self,
416         source: [u8; 4],
417         destination: [u8; 4],
418         time_to_live: u8,
419     ) -> PacketBuilderStep<IpHeaders> {
420         //add ip header
421         self.state.net_header = Some(NetHeaders::Ipv4(
422             Ipv4Header {
423                 source,
424                 destination,
425                 time_to_live,
426                 ..Default::default()
427             },
428             Default::default(),
429         ));
430         //return for next step
431         PacketBuilderStep {
432             state: self.state,
433             _marker: marker::PhantomData::<IpHeaders> {},
434         }
435     }
436 
437     /// Add an IP header (length, protocol/next_header & checksum fields will be overwritten based on the rest of the packet).
438     ///
439     /// # Examples
440     ///
441     /// With an IPv4 header:
442     ///
443     /// ```
444     /// # use etherparse::*;
445     /// #
446     /// let builder = PacketBuilder::
447     ///     ethernet2([1,2,3,4,5,6],
448     ///               [7,8,9,10,11,12])
449     ///    //payload_len, protocol & checksum will be replaced during write
450     ///    .ip(IpHeaders::Ipv4(
451     ///        Ipv4Header::new(
452     ///            0, //payload_len will be replaced during write
453     ///            12, //time_to_live
454     ///            ip_number::UDP, //will be replaced during write
455     ///            [0,1,2,3], //source
456     ///            [4,5,6,7] //destination
457     ///        ).unwrap(),
458     ///        Default::default()));
459     /// ```
460     ///
461     /// With an IPv6 header:
462     ///
463     /// ```
464     /// # use etherparse::*;
465     /// #
466     /// let builder = PacketBuilder::
467     ///     ethernet2([1,2,3,4,5,6],
468     ///               [7,8,9,10,11,12])
469     ///    .ip(IpHeaders::Ipv6(
470     ///         Ipv6Header{
471     ///             traffic_class: 0,
472     ///             flow_label: 0.try_into().unwrap(),
473     ///             hop_limit: 4,
474     ///             source: [0;16],
475     ///             destination: [0;16],
476     ///             // payload_length & next_header will be replaced during write
477     ///             ..Default::default()
478     ///         },
479     ///         Default::default()));
480     /// ```
ip(mut self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders>481     pub fn ip(mut self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders> {
482         //add ip header
483         self.state.net_header = Some(match ip_header {
484             IpHeaders::Ipv4(header, exts) => NetHeaders::Ipv4(header, exts),
485             IpHeaders::Ipv6(header, exts) => NetHeaders::Ipv6(header, exts),
486         });
487         //return for next step
488         PacketBuilderStep {
489             state: self.state,
490             _marker: marker::PhantomData::<IpHeaders> {},
491         }
492     }
493 
494     /// Add an IPv6 header
495     ///
496     /// # Example
497     ///
498     /// Basic usage:
499     ///
500     /// ```
501     /// # use etherparse::PacketBuilder;
502     /// #
503     /// let builder = PacketBuilder::
504     ///     ethernet2([1,2,3,4,5,6],
505     ///               [7,8,9,10,11,12])
506     ///     .ipv6(
507     ///         //source
508     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
509     ///         //destination
510     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
511     ///         //hop_limit
512     ///         47)
513     ///    .udp(21,    //source port
514     ///         1234); //destination port
515     ///
516     /// //payload of the udp packet
517     /// let payload = [1,2,3,4,5,6,7,8];
518     ///
519     /// //get some memory to store the result
520     /// let mut result = Vec::<u8>::with_capacity(
521     ///                     builder.size(payload.len()));
522     ///
523     /// //serialize
524     /// builder.write(&mut result, &payload).unwrap();
525     /// ```
ipv6( mut self, source: [u8; 16], destination: [u8; 16], hop_limit: u8, ) -> PacketBuilderStep<IpHeaders>526     pub fn ipv6(
527         mut self,
528         source: [u8; 16],
529         destination: [u8; 16],
530         hop_limit: u8,
531     ) -> PacketBuilderStep<IpHeaders> {
532         self.state.net_header = Some(NetHeaders::Ipv6(
533             Ipv6Header {
534                 traffic_class: 0,
535                 flow_label: Ipv6FlowLabel::ZERO,
536                 payload_length: 0,          //filled in on write
537                 next_header: IpNumber(255), //filled in on write
538                 hop_limit,
539                 source,
540                 destination,
541             },
542             Default::default(),
543         ));
544 
545         //return for next step
546         PacketBuilderStep {
547             state: self.state,
548             _marker: marker::PhantomData::<IpHeaders> {},
549         }
550     }
551 
552     /// Adds a vlan tagging header with the given vlan identifier
553     ///
554     /// # Example
555     ///
556     /// Basic usage:
557     ///
558     /// ```
559     /// # use etherparse::{PacketBuilder, SingleVlanHeader, VlanHeader};
560     /// #
561     /// let builder = PacketBuilder::
562     ///     ethernet2([1,2,3,4,5,6],     //source mac
563     ///               [7,8,9,10,11,12]) //destination mac
564     ///     .vlan(VlanHeader::Single(
565     ///         SingleVlanHeader{
566     ///             pcp: 1.try_into().unwrap(),
567     ///             drop_eligible_indicator: false,
568     ///             vlan_id: 0x123.try_into().unwrap(),
569     ///             ether_type: 0.into() // will be overwritten during write
570     ///         }))
571     ///     .ipv4([192,168,1,1], //source ip
572     ///           [192,168,1,2], //destination ip
573     ///           20)            //time to life
574     ///     .udp(21,    //source port
575     ///          1234); //destination port
576     ///
577     /// //payload of the udp packet
578     /// let payload = [1,2,3,4,5,6,7,8];
579     ///
580     /// //get some memory to store the result
581     /// let mut result = Vec::<u8>::with_capacity(
582     ///                     builder.size(payload.len()));
583     ///
584     /// //serialize
585     /// builder.write(&mut result, &payload).unwrap();
586     /// ```
vlan(mut self, vlan: VlanHeader) -> PacketBuilderStep<VlanHeader>587     pub fn vlan(mut self, vlan: VlanHeader) -> PacketBuilderStep<VlanHeader> {
588         self.state.vlan_header = Some(vlan);
589         //return for next step
590         PacketBuilderStep {
591             state: self.state,
592             _marker: marker::PhantomData::<VlanHeader> {},
593         }
594     }
595 
596     /// Adds a vlan tagging header with the given vlan identifier
597     ///
598     /// # Example
599     ///
600     /// Basic usage:
601     ///
602     /// ```
603     /// # use etherparse::{PacketBuilder, SingleVlanHeader, VlanHeader};
604     /// #
605     /// let builder = PacketBuilder::
606     ///     ethernet2([1,2,3,4,5,6],     //source mac
607     ///               [7,8,9,10,11,12]) //destination mac
608     ///     .single_vlan(0x123.try_into().unwrap()) // vlan identifier
609     ///     .ipv4([192,168,1,1], //source ip
610     ///           [192,168,1,2], //destination ip
611     ///           20)            //time to life
612     ///     .udp(21,    //source port
613     ///          1234); //destination port
614     ///
615     /// //payload of the udp packet
616     /// let payload = [1,2,3,4,5,6,7,8];
617     ///
618     /// //get some memory to store the result
619     /// let mut result = Vec::<u8>::with_capacity(
620     ///                     builder.size(payload.len()));
621     ///
622     /// //serialize
623     /// builder.write(&mut result, &payload).unwrap();
624     /// ```
single_vlan(mut self, vlan_identifier: VlanId) -> PacketBuilderStep<VlanHeader>625     pub fn single_vlan(mut self, vlan_identifier: VlanId) -> PacketBuilderStep<VlanHeader> {
626         self.state.vlan_header = Some(VlanHeader::Single(SingleVlanHeader {
627             pcp: VlanPcp::ZERO,
628             drop_eligible_indicator: false,
629             vlan_id: vlan_identifier,
630             ether_type: EtherType(0), //will be set automatically during write
631         }));
632         //return for next step
633         PacketBuilderStep {
634             state: self.state,
635             _marker: marker::PhantomData::<VlanHeader> {},
636         }
637     }
638 
639     /// Adds two vlan tagging header with the given vlan identifiers (also known as double vlan tagging).
640     ///
641     /// # Example
642     ///
643     /// Basic usage:
644     ///
645     /// ```
646     /// # use etherparse::{PacketBuilder, SingleVlanHeader, VlanHeader};
647     /// #
648     /// let builder = PacketBuilder::
649     ///     ethernet2([1,2,3,4,5,6],     //source mac
650     ///               [7,8,9,10,11,12]) //destination mac
651     ///     .double_vlan(0x123.try_into().unwrap(), // outer vlan identifier
652     ///                  0x234.try_into().unwrap()) // inner vlan identifier
653     ///     .ipv4([192,168,1,1], //source ip
654     ///           [192,168,1,2], //destination ip
655     ///           20)            //time to life
656     ///     .udp(21,    //source port
657     ///          1234); //destination port
658     ///
659     /// //payload of the udp packet
660     /// let payload = [1,2,3,4,5,6,7,8];
661     ///
662     /// //get some memory to store the result
663     /// let mut result = Vec::<u8>::with_capacity(
664     ///                     builder.size(payload.len()));
665     ///
666     /// //serialize
667     /// builder.write(&mut result, &payload).unwrap();
668     /// ```
double_vlan( mut self, outer_vlan_identifier: VlanId, inner_vlan_identifier: VlanId, ) -> PacketBuilderStep<VlanHeader>669     pub fn double_vlan(
670         mut self,
671         outer_vlan_identifier: VlanId,
672         inner_vlan_identifier: VlanId,
673     ) -> PacketBuilderStep<VlanHeader> {
674         self.state.vlan_header = Some(VlanHeader::Double(DoubleVlanHeader {
675             outer: SingleVlanHeader {
676                 pcp: VlanPcp::ZERO,
677                 drop_eligible_indicator: false,
678                 vlan_id: outer_vlan_identifier,
679                 ether_type: EtherType(0), //will be set automatically during write
680             },
681             inner: SingleVlanHeader {
682                 pcp: VlanPcp::ZERO,
683                 drop_eligible_indicator: false,
684                 vlan_id: inner_vlan_identifier,
685                 ether_type: EtherType(0), //will be set automatically during write
686             },
687         }));
688         //return for next step
689         PacketBuilderStep {
690             state: self.state,
691             _marker: marker::PhantomData::<VlanHeader> {},
692         }
693     }
694 
695     /// Adds an ARP packet.
696     ///
697     /// # Example
698     ///
699     /// Basic usage:
700     ///
701     /// ```
702     /// use etherparse::*;
703     ///
704     /// let builder = PacketBuilder::
705     ///     ethernet2([1,2,3,4,5,6],    // source mac
706     ///               [7,8,9,10,11,12]) // destination mac
707     ///     .arp(ArpPacket::new(
708     ///         ArpHardwareId::ETHERNET,
709     ///         EtherType::IPV4,
710     ///         ArpOperation::REQUEST,
711     ///         &[1,2,3,4,5,6], // sender_hw_addr
712     ///         &[7,6,8,9],     // sender_protocol_addr
713     ///         &[10,11,12,14,15,16], // target_hw_addr
714     ///         &[17,18,19,20]        // target_protocol_addr
715     ///     ).unwrap());
716     ///
717     /// // get some memory to store the result
718     /// let mut result = Vec::<u8>::with_capacity(builder.size());
719     ///
720     /// // serialize
721     /// builder.write(&mut result).unwrap();
722     /// ```
arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket>723     pub fn arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket> {
724         self.state.net_header = Some(NetHeaders::Arp(arp_packet));
725         //return for next step
726         PacketBuilderStep {
727             state: self.state,
728             _marker: marker::PhantomData::<ArpPacket> {},
729         }
730     }
731 }
732 
733 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
734 impl PacketBuilderStep<LinuxSllHeader> {
735     /// Add an ip header (length, protocol/next_header & checksum fields will be overwritten based on the rest of the packet).
736     ///
737     /// # Example IPv4
738     /// ```
739     /// # use etherparse::*;
740     /// #
741     /// let builder = PacketBuilder::
742     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
743     ///               6, //sender address valid length
744     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
745     ///    //payload_len, protocol & checksum will be replaced during write
746     ///    .ip(IpHeaders::Ipv4(
747     ///         Ipv4Header::new(
748     ///             0, //payload_len will be replaced during write
749     ///             12, //time_to_live
750     ///             ip_number::UDP, //will be replaced during write
751     ///             [0,1,2,3], //source
752     ///             [4,5,6,7] //destination
753     ///         ).unwrap(),
754     ///         Default::default() // IPv4 extension headers (default is none)
755     ///     ));
756     /// ```
757     ///
758     /// # Example IPv6
759     /// ```
760     /// # use etherparse::*;
761     /// #
762     /// let builder = PacketBuilder::
763     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
764     ///               6, //sender address valid length
765     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
766     ///    .ip(IpHeaders::Ipv6(
767     ///         Ipv6Header{
768     ///             traffic_class: 0,
769     ///             flow_label: 0.try_into().unwrap(),
770     ///             hop_limit: 4,
771     ///             source: [0;16],
772     ///             destination: [0;16],
773     ///             // payload_length & next_header will be replaced during write
774     ///             ..Default::default()
775     ///         },
776     ///         Default::default() // IPv6 extension headers (default is none)
777     ///     ));
778     /// ```
ip(self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders>779     pub fn ip(self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders> {
780         //use the method from the Ethernet2Header implementation
781         PacketBuilderStep {
782             state: self.state,
783             _marker: marker::PhantomData::<Ethernet2Header> {},
784         }
785         .ip(ip_header)
786     }
787 
788     /// Add an IPv6 header
789     ///
790     /// # Example
791     ///
792     /// Basic usage:
793     ///
794     /// ```
795     /// # use etherparse::{PacketBuilder, LinuxSllPacketType, ArpHardwareId, LinuxSllProtocolType, EtherType};
796     /// #
797     /// let builder = PacketBuilder::
798     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
799     ///               6, //sender address valid length
800     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
801     ///     .ipv6(
802     ///         //source
803     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
804     ///         //destination
805     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
806     ///         //hop_limit
807     ///         47)
808     ///     .udp(21,    //source port
809     ///          1234); //destination port
810     ///
811     /// //payload of the udp packet
812     /// let payload = [1,2,3,4,5,6,7,8];
813     ///
814     /// //get some memory to store the result
815     /// let mut result = Vec::<u8>::with_capacity(
816     ///                     builder.size(payload.len()));
817     ///
818     /// //serialize
819     /// builder.write(&mut result, &payload).unwrap();
820     /// ```
ipv6( self, source: [u8; 16], destination: [u8; 16], hop_limit: u8, ) -> PacketBuilderStep<IpHeaders>821     pub fn ipv6(
822         self,
823         source: [u8; 16],
824         destination: [u8; 16],
825         hop_limit: u8,
826     ) -> PacketBuilderStep<IpHeaders> {
827         //use the method from the Ethernet2Header implementation
828         PacketBuilderStep {
829             state: self.state,
830             _marker: marker::PhantomData::<Ethernet2Header> {},
831         }
832         .ipv6(source, destination, hop_limit)
833     }
834 
835     /// Add an IPv4 header
836     ///
837     /// # Example
838     ///
839     /// Basic usage:
840     ///
841     /// ```
842     /// # use etherparse::{PacketBuilder, LinuxSllPacketType, ArpHardwareId, LinuxSllProtocolType, EtherType};
843     /// #
844     /// let builder = PacketBuilder::
845     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
846     ///               6, //sender address valid length
847     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
848     ///     .ipv4([192,168,1,1], //source ip
849     ///           [192,168,1,2], //destination ip
850     ///           20)            //time to life
851     ///     .udp(21,    //source port
852     ///          1234); //destination port
853     ///
854     /// //payload of the udp packet
855     /// let payload = [1,2,3,4,5,6,7,8];
856     ///
857     /// //get some memory to store the result
858     /// let mut result = Vec::<u8>::with_capacity(
859     ///                     builder.size(payload.len()));
860     ///
861     /// //serialize
862     /// builder.write(&mut result, &payload).unwrap();
863     /// ```
ipv4( self, source: [u8; 4], destination: [u8; 4], time_to_live: u8, ) -> PacketBuilderStep<IpHeaders>864     pub fn ipv4(
865         self,
866         source: [u8; 4],
867         destination: [u8; 4],
868         time_to_live: u8,
869     ) -> PacketBuilderStep<IpHeaders> {
870         //use the method from the Ethernet2Header implementation
871         PacketBuilderStep {
872             state: self.state,
873             _marker: marker::PhantomData::<Ethernet2Header> {},
874         }
875         .ipv4(source, destination, time_to_live)
876     }
877 
878     /// Adds an ARP packet.
879     ///
880     /// # Example
881     ///
882     /// Basic usage:
883     ///
884     /// ```
885     /// use etherparse::*;
886     ///
887     /// let builder = PacketBuilder::
888     ///     linux_sll(LinuxSllPacketType::OTHERHOST, //packet type
889     ///               6, //sender address valid length
890     ///               [1,2,3,4,5,6,0,0]) //sender address with padding
891     ///     .arp(ArpPacket::new(
892     ///         ArpHardwareId::ETHERNET,
893     ///         EtherType::IPV4,
894     ///         ArpOperation::REQUEST,
895     ///         &[1,2,3,4,5,6], // sender_hw_addr
896     ///         &[7,6,8,9],     // sender_protocol_addr
897     ///         &[10,11,12,14,15,16], // target_hw_addr
898     ///         &[17,18,19,20]        // target_protocol_addr
899     ///     ).unwrap());
900     ///
901     /// // get some memory to store the result
902     /// let mut result = Vec::<u8>::with_capacity(builder.size());
903     ///
904     /// // serialize
905     /// builder.write(&mut result).unwrap();
906     /// ```
arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket>907     pub fn arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket> {
908         self.state.net_header = Some(NetHeaders::Arp(arp_packet));
909         // return for next step
910         PacketBuilderStep {
911             state: self.state,
912             _marker: marker::PhantomData::<ArpPacket> {},
913         }
914     }
915 }
916 
917 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
918 impl PacketBuilderStep<VlanHeader> {
919     ///Add an ip header (length, protocol/next_header & checksum fields will be overwritten based on the rest of the packet).
920     ///
921     /// # Example IPv4
922     /// ```
923     /// # use etherparse::*;
924     /// #
925     /// let builder = PacketBuilder::
926     ///     ethernet2([1,2,3,4,5,6],
927     ///               [7,8,9,10,11,12])
928     ///    .single_vlan(0x132.try_into().unwrap())
929     ///    //payload_len, protocol & checksum will be replaced during write
930     ///    .ip(IpHeaders::Ipv4(
931     ///         Ipv4Header::new(
932     ///             0, //payload_len will be replaced during write
933     ///             12, //time_to_live
934     ///             ip_number::UDP, //will be replaced during write
935     ///             [0,1,2,3], //source
936     ///             [4,5,6,7] //destination
937     ///         ).unwrap(),
938     ///         Default::default() // IPv4 extension headers (default is none)
939     ///     ));
940     /// ```
941     ///
942     /// # Example IPv6
943     /// ```
944     /// # use etherparse::*;
945     /// #
946     /// let builder = PacketBuilder::
947     ///     ethernet2([1,2,3,4,5,6],
948     ///               [7,8,9,10,11,12])
949     ///    .single_vlan(0x132.try_into().unwrap())
950     ///    .ip(IpHeaders::Ipv6(
951     ///         Ipv6Header{
952     ///             traffic_class: 0,
953     ///             flow_label: 0.try_into().unwrap(),
954     ///             hop_limit: 4,
955     ///             source: [0;16],
956     ///             destination: [0;16],
957     ///             // payload_length & next_header will be replaced during write
958     ///             ..Default::default()
959     ///         },
960     ///         Default::default() // IPv6 extension headers (default is none)
961     ///     ));
962     /// ```
ip(self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders>963     pub fn ip(self, ip_header: IpHeaders) -> PacketBuilderStep<IpHeaders> {
964         //use the method from the Ethernet2Header implementation
965         PacketBuilderStep {
966             state: self.state,
967             _marker: marker::PhantomData::<Ethernet2Header> {},
968         }
969         .ip(ip_header)
970     }
971 
972     /// Add an IPv6 header
973     ///
974     /// # Example
975     ///
976     /// Basic usage:
977     ///
978     /// ```
979     /// # use etherparse::{PacketBuilder, SingleVlanHeader, VlanHeader};
980     /// #
981     /// let builder = PacketBuilder::
982     ///     ethernet2([1,2,3,4,5,6],     //source mac
983     ///               [7,8,9,10,11,12]) //destination mac
984     ///     .single_vlan(0x123.try_into().unwrap()) // vlan identifier
985     ///     .ipv6(
986     ///         //source
987     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
988     ///         //destination
989     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
990     ///         //hop_limit
991     ///         47)
992     ///     .udp(21,    //source port
993     ///          1234); //destination port
994     ///
995     /// //payload of the udp packet
996     /// let payload = [1,2,3,4,5,6,7,8];
997     ///
998     /// //get some memory to store the result
999     /// let mut result = Vec::<u8>::with_capacity(
1000     ///                     builder.size(payload.len()));
1001     ///
1002     /// //serialize
1003     /// builder.write(&mut result, &payload).unwrap();
1004     /// ```
ipv6( self, source: [u8; 16], destination: [u8; 16], hop_limit: u8, ) -> PacketBuilderStep<IpHeaders>1005     pub fn ipv6(
1006         self,
1007         source: [u8; 16],
1008         destination: [u8; 16],
1009         hop_limit: u8,
1010     ) -> PacketBuilderStep<IpHeaders> {
1011         //use the method from the Ethernet2Header implementation
1012         PacketBuilderStep {
1013             state: self.state,
1014             _marker: marker::PhantomData::<Ethernet2Header> {},
1015         }
1016         .ipv6(source, destination, hop_limit)
1017     }
1018 
1019     /// Add an IPv4 header
1020     ///
1021     /// # Example
1022     ///
1023     /// Basic usage:
1024     ///
1025     /// ```
1026     /// # use etherparse::{PacketBuilder, SingleVlanHeader, VlanHeader};
1027     /// #
1028     /// let builder = PacketBuilder::
1029     ///     ethernet2([1,2,3,4,5,6],     //source mac
1030     ///               [7,8,9,10,11,12]) //destination mac
1031     ///     .single_vlan(0x123.try_into().unwrap()) // vlan identifier
1032     ///     .ipv4([192,168,1,1], //source ip
1033     ///           [192,168,1,2], //destination ip
1034     ///           20)            //time to life
1035     ///     .udp(21,    //source port
1036     ///          1234); //destination port
1037     ///
1038     /// //payload of the udp packet
1039     /// let payload = [1,2,3,4,5,6,7,8];
1040     ///
1041     /// //get some memory to store the result
1042     /// let mut result = Vec::<u8>::with_capacity(
1043     ///                     builder.size(payload.len()));
1044     ///
1045     /// //serialize
1046     /// builder.write(&mut result, &payload).unwrap();
1047     /// ```
ipv4( self, source: [u8; 4], destination: [u8; 4], time_to_live: u8, ) -> PacketBuilderStep<IpHeaders>1048     pub fn ipv4(
1049         self,
1050         source: [u8; 4],
1051         destination: [u8; 4],
1052         time_to_live: u8,
1053     ) -> PacketBuilderStep<IpHeaders> {
1054         //use the method from the Ethernet2Header implementation
1055         PacketBuilderStep {
1056             state: self.state,
1057             _marker: marker::PhantomData::<Ethernet2Header> {},
1058         }
1059         .ipv4(source, destination, time_to_live)
1060     }
1061 
1062     /// Adds an ARP packet.
1063     ///
1064     /// # Example
1065     ///
1066     /// Basic usage:
1067     ///
1068     /// ```
1069     /// use etherparse::*;
1070     ///
1071     /// let builder = PacketBuilder::
1072     ///     ethernet2([1,2,3,4,5,6],    // source mac
1073     ///               [7,8,9,10,11,12]) // destination mac
1074     ///     .single_vlan(0x123.try_into().unwrap()) // vlan identifier
1075     ///     .arp(ArpPacket::new(
1076     ///         ArpHardwareId::ETHERNET,
1077     ///         EtherType::IPV4,
1078     ///         ArpOperation::REQUEST,
1079     ///         &[1,2,3,4,5,6], // sender_hw_addr
1080     ///         &[7,6,8,9],     // sender_protocol_addr
1081     ///         &[10,11,12,14,15,16], // target_hw_addr
1082     ///         &[17,18,19,20]        // target_protocol_addr
1083     ///     ).unwrap());
1084     ///
1085     /// // get some memory to store the result
1086     /// let mut result = Vec::<u8>::with_capacity(builder.size());
1087     ///
1088     /// // serialize
1089     /// builder.write(&mut result).unwrap();
1090     /// ```
arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket>1091     pub fn arp(mut self, arp_packet: ArpPacket) -> PacketBuilderStep<ArpPacket> {
1092         self.state.net_header = Some(NetHeaders::Arp(arp_packet));
1093         //return for next step
1094         PacketBuilderStep {
1095             state: self.state,
1096             _marker: marker::PhantomData::<ArpPacket> {},
1097         }
1098     }
1099 }
1100 
1101 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1102 impl PacketBuilderStep<IpHeaders> {
1103     /// Adds an ICMPv4 header of the given [`Icmpv4Type`] to the packet.
1104     ///
1105     /// If an ICMPv4 header gets added the payload used during the builders `write`
1106     /// call contains the bytes after the header and has different meanings
1107     /// and contents based on the type. Usually all statically sized values
1108     /// known based on the ICMPv4 type & code are part of the header and the
1109     /// payload is used to store contains the dynamic parts of the ICMPv4 packet.
1110     ///
1111     /// Check [`Icmpv4Type`] for a documentation which values are part of the
1112     /// header and what is stored as part of the payload.
1113     ///
1114     /// # Example
1115     ///
1116     /// Basic usage:
1117     ///
1118     /// ```
1119     /// # use etherparse::{PacketBuilder, Icmpv4Type, icmpv4};
1120     /// #
1121     /// let builder = PacketBuilder::
1122     ///    ipv4([192,168,1,1],  //source ip
1123     ///          [192,168,1,2], //destination ip
1124     ///          20)            //time to life
1125     ///    .icmpv4(
1126     ///         Icmpv4Type::TimeExceeded(
1127     ///             icmpv4::TimeExceededCode::TtlExceededInTransit
1128     ///         )
1129     ///     );
1130     ///
1131     /// // what is part of the payload depends on the Icmpv4Type
1132     /// //
1133     /// // In case of `Icmpv4Type::TimeExceeded` the "internet header
1134     /// // + 64 bits of the original data datagram" should be given as
1135     /// // the payload
1136     /// let payload = [1,2,3,4,5,6,7,8];
1137     ///
1138     /// //get some memory to store the result
1139     /// let mut result = Vec::<u8>::with_capacity(
1140     ///                     builder.size(payload.len()));
1141     ///
1142     /// //serialize
1143     /// builder.write(&mut result, &payload).unwrap();
1144     /// ```
icmpv4(mut self, icmp_type: Icmpv4Type) -> PacketBuilderStep<Icmpv4Header>1145     pub fn icmpv4(mut self, icmp_type: Icmpv4Type) -> PacketBuilderStep<Icmpv4Header> {
1146         self.state.transport_header = Some(TransportHeader::Icmpv4(Icmpv4Header {
1147             icmp_type,
1148             checksum: 0, // calculated later
1149         }));
1150         //return for next step
1151         PacketBuilderStep {
1152             state: self.state,
1153             _marker: marker::PhantomData::<Icmpv4Header> {},
1154         }
1155     }
1156 
1157     /// Adds an ICMPv4 header based on raw numbers.
1158     ///
1159     /// This can be useful when trying to build an ICMPv4 packet
1160     /// which is not fully supported by etherparse and is the equivalent
1161     /// of using [`Icmpv4Type::Unknown`] together with
1162     /// [`PacketBuilderStep<IpHeaders>::icmpv4`].
1163     ///
1164     /// # Example
1165     ///
1166     /// Basic usage:
1167     ///
1168     /// ```
1169     /// # use etherparse::PacketBuilder;
1170     /// #
1171     /// let builder = PacketBuilder::
1172     ///    ipv4([192,168,1,1],  //source ip
1173     ///          [192,168,1,2], //destination ip
1174     ///          20)            //time to life
1175     ///    .icmpv4_raw(
1176     ///         253, // ICMPv4 type (e.g. 253 is RFC3692-style Experiment 1)
1177     ///         0, // ICMPv4 code
1178     ///         [1,2,3,4]  // bytes 5-8 in the ICMPv4 header
1179     ///     );
1180     ///
1181     /// // the payload is written after the 8 byte raw ICMPv4 header
1182     /// let payload = [1,2,3,4,5,6,7,8];
1183     ///
1184     /// // get some memory to store the result
1185     /// let mut result = Vec::<u8>::with_capacity(
1186     ///                     builder.size(payload.len()));
1187     ///
1188     /// // serialize
1189     /// builder.write(&mut result, &payload).unwrap();
1190     /// ```
icmpv4_raw( mut self, type_u8: u8, code_u8: u8, bytes5to8: [u8; 4], ) -> PacketBuilderStep<Icmpv4Header>1191     pub fn icmpv4_raw(
1192         mut self,
1193         type_u8: u8,
1194         code_u8: u8,
1195         bytes5to8: [u8; 4],
1196     ) -> PacketBuilderStep<Icmpv4Header> {
1197         let icmp_type = Icmpv4Type::Unknown {
1198             type_u8,
1199             code_u8,
1200             bytes5to8,
1201         };
1202         self.state.transport_header = Some(TransportHeader::Icmpv4(Icmpv4Header {
1203             icmp_type,
1204             checksum: 0, // calculated later
1205         }));
1206         //return for next step
1207         PacketBuilderStep {
1208             state: self.state,
1209             _marker: marker::PhantomData::<Icmpv4Header> {},
1210         }
1211     }
1212 
1213     /// Adds an ICMPv4 echo request packet.
1214     ///
1215     /// # Example
1216     ///
1217     /// Basic usage:
1218     ///
1219     /// ```
1220     /// # use etherparse::PacketBuilder;
1221     /// #
1222     /// let builder = PacketBuilder::
1223     ///    ipv4([192,168,1,1],  //source ip
1224     ///          [192,168,1,2], //destination ip
1225     ///          20)            //time to life
1226     ///    .icmpv4_echo_request(
1227     ///         123, // identifier
1228     ///         456, // sequence number
1229     ///     );
1230     ///
1231     /// // payload of the echo request
1232     /// let payload = [1,2,3,4,5,6,7,8];
1233     ///
1234     /// // get some memory to store the result
1235     /// let mut result = Vec::<u8>::with_capacity(
1236     ///                     builder.size(payload.len()));
1237     ///
1238     /// // serialize
1239     /// builder.write(&mut result, &payload).unwrap();
1240     /// ```
icmpv4_echo_request(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv4Header>1241     pub fn icmpv4_echo_request(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv4Header> {
1242         let echo_header = IcmpEchoHeader { id, seq };
1243         let icmpv4_echo = Icmpv4Header::new(Icmpv4Type::EchoRequest(echo_header));
1244         self.state.transport_header = Some(TransportHeader::Icmpv4(icmpv4_echo));
1245         //return for next step
1246         PacketBuilderStep {
1247             state: self.state,
1248             _marker: marker::PhantomData::<Icmpv4Header> {},
1249         }
1250     }
1251 
1252     /// Adds an ICMPv4 echo reply packet.
1253     ///
1254     /// # Example
1255     ///
1256     /// Basic usage:
1257     ///
1258     /// ```
1259     /// # use etherparse::PacketBuilder;
1260     /// #
1261     /// let builder = PacketBuilder::
1262     ///    ipv4([192,168,1,1],  //source ip
1263     ///          [192,168,1,2], //destination ip
1264     ///          20)            //time to life
1265     ///    .icmpv4_echo_reply(
1266     ///         123, // identifier
1267     ///         456, // sequence number
1268     ///     );
1269     ///
1270     /// // payload of the echo reply
1271     /// let payload = [1,2,3,4,5,6,7,8];
1272     ///
1273     /// // get some memory to store the result
1274     /// let mut result = Vec::<u8>::with_capacity(
1275     ///                     builder.size(payload.len()));
1276     ///
1277     /// // serialize
1278     /// builder.write(&mut result, &payload).unwrap();
1279     /// ```
icmpv4_echo_reply(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv4Header>1280     pub fn icmpv4_echo_reply(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv4Header> {
1281         let echo_header = IcmpEchoHeader { id, seq };
1282         let icmpv4_echo = Icmpv4Header::new(Icmpv4Type::EchoReply(echo_header));
1283         self.state.transport_header = Some(TransportHeader::Icmpv4(icmpv4_echo));
1284         //return for next step
1285         PacketBuilderStep {
1286             state: self.state,
1287             _marker: marker::PhantomData::<Icmpv4Header> {},
1288         }
1289     }
1290 
1291     /// Adds an ICMPv6 header of the given [`Icmpv6Type`] to the packet.
1292     ///
1293     /// If an ICMPv6 header gets added the payload used during the builders `write`
1294     /// call contains the bytes after the header and has different meanings
1295     /// and contents based on the type. Usually all statically sized values
1296     /// known based on the ICMPv6 type & code are part of the header and the
1297     /// payload is used to store contains the dynamic parts of the ICMPv6 packet.
1298     ///
1299     /// Check [`Icmpv6Type`] for a documentation which values are part of the
1300     /// header and what is stored as part of the payload.
1301     ///
1302     /// # Example
1303     ///
1304     /// Basic usage:
1305     ///
1306     /// ```
1307     /// # use etherparse::{PacketBuilder, Icmpv6Type, icmpv6};
1308     /// #
1309     /// let builder = PacketBuilder::
1310     ///     ipv6(
1311     ///         //source
1312     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
1313     ///         //destination
1314     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
1315     ///         //hop_limit
1316     ///         47)
1317     ///    .icmpv6(
1318     ///         Icmpv6Type::TimeExceeded(
1319     ///             icmpv6::TimeExceededCode::HopLimitExceeded
1320     ///         )
1321     ///     );
1322     ///
1323     /// // what is part of the payload depends on the Icmpv6Type
1324     /// //
1325     /// // In case of `Icmpv6Type::TimeExceeded` "As much of invoking packet
1326     /// // as possible without the ICMPv6 packet exceeding the minimum IPv6 MTU"
1327     /// // should be given as the payload.
1328     /// let payload = [1,2,3,4,5,6,7,8];
1329     ///
1330     /// //get some memory to store the result
1331     /// let mut result = Vec::<u8>::with_capacity(
1332     ///                     builder.size(payload.len()));
1333     ///
1334     /// //serialize
1335     /// builder.write(&mut result, &payload).unwrap();
1336     /// ```
icmpv6(mut self, icmp_type: Icmpv6Type) -> PacketBuilderStep<Icmpv6Header>1337     pub fn icmpv6(mut self, icmp_type: Icmpv6Type) -> PacketBuilderStep<Icmpv6Header> {
1338         self.state.transport_header = Some(TransportHeader::Icmpv6(Icmpv6Header {
1339             icmp_type,
1340             checksum: 0, // calculated later
1341         }));
1342         //return for next step
1343         PacketBuilderStep {
1344             state: self.state,
1345             _marker: marker::PhantomData::<Icmpv6Header> {},
1346         }
1347     }
1348 
1349     /// Adds an ICMPv6 header based on raw values.
1350     ///
1351     /// This can be useful when trying to build an ICMPv6 packet
1352     /// which is not fully supported by etherparse and is the equivalent
1353     /// of using [`Icmpv6Type::Unknown`] together with
1354     /// [`PacketBuilderStep<IpHeaders>::icmpv6`].
1355     ///
1356     /// # Example
1357     ///
1358     /// Basic usage:
1359     ///
1360     /// ```
1361     /// # use etherparse::PacketBuilder;
1362     /// #
1363     /// let builder = PacketBuilder::
1364     ///     ipv6(
1365     ///         //source
1366     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
1367     ///         //destination
1368     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
1369     ///         //hop_limit
1370     ///         47)
1371     ///    .icmpv4_raw(
1372     ///         200, // ICMPv6 type (e.g. 200 is for "private experimentation")
1373     ///         0, // ICMPv6 code
1374     ///         [1,2,3,4]  // bytes 5-8 in the ICMPv6 header
1375     ///     );
1376     ///
1377     /// // the payload is written after the 8 byte raw ICMPv6 header
1378     /// let payload = [1,2,3,4,5,6,7,8];
1379     ///
1380     /// //get some memory to store the result
1381     /// let mut result = Vec::<u8>::with_capacity(
1382     ///                     builder.size(payload.len()));
1383     ///
1384     /// //serialize
1385     /// builder.write(&mut result, &payload).unwrap();
1386     /// ```
icmpv6_raw( mut self, type_u8: u8, code_u8: u8, bytes5to8: [u8; 4], ) -> PacketBuilderStep<Icmpv6Header>1387     pub fn icmpv6_raw(
1388         mut self,
1389         type_u8: u8,
1390         code_u8: u8,
1391         bytes5to8: [u8; 4],
1392     ) -> PacketBuilderStep<Icmpv6Header> {
1393         let icmp_type = Icmpv6Type::Unknown {
1394             type_u8,
1395             code_u8,
1396             bytes5to8,
1397         };
1398         self.state.transport_header = Some(TransportHeader::Icmpv6(Icmpv6Header {
1399             icmp_type,
1400             checksum: 0, // calculated later
1401         }));
1402         //return for next step
1403         PacketBuilderStep {
1404             state: self.state,
1405             _marker: marker::PhantomData::<Icmpv6Header> {},
1406         }
1407     }
1408 
1409     /// Adds an ICMPv6 echo reply packet.
1410     ///
1411     /// # Example
1412     ///
1413     /// Basic usage:
1414     ///
1415     /// ```
1416     /// # use etherparse::PacketBuilder;
1417     /// #
1418     /// let builder = PacketBuilder::
1419     ///     ipv6(
1420     ///         //source
1421     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
1422     ///         //destination
1423     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
1424     ///         //hop_limit
1425     ///         47)
1426     ///    .icmpv6_echo_request(
1427     ///         123, // identifier
1428     ///         456, // sequence number
1429     ///     );
1430     ///
1431     /// // payload of the echo request
1432     /// let payload = [1,2,3,4,5,6,7,8];
1433     ///
1434     /// //get some memory to store the result
1435     /// let mut result = Vec::<u8>::with_capacity(
1436     ///                     builder.size(payload.len()));
1437     ///
1438     /// //serialize
1439     /// builder.write(&mut result, &payload).unwrap();
1440     /// ```
icmpv6_echo_request(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv6Header>1441     pub fn icmpv6_echo_request(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv6Header> {
1442         let echo_header = IcmpEchoHeader { id, seq };
1443         let icmpv6_echo = Icmpv6Header::new(Icmpv6Type::EchoRequest(echo_header));
1444         self.state.transport_header = Some(TransportHeader::Icmpv6(icmpv6_echo));
1445         //return for next step
1446         PacketBuilderStep {
1447             state: self.state,
1448             _marker: marker::PhantomData::<Icmpv6Header> {},
1449         }
1450     }
1451 
1452     /// Adds an ICMPv6 echo request packet.
1453     ///
1454     /// # Example
1455     ///
1456     /// Basic usage:
1457     ///
1458     /// ```
1459     /// # use etherparse::PacketBuilder;
1460     /// #
1461     /// let builder = PacketBuilder::
1462     ///     ipv6(
1463     ///         //source
1464     ///         [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
1465     ///         //destination
1466     ///         [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
1467     ///         //hop_limit
1468     ///         47)
1469     ///    .icmpv6_echo_reply(
1470     ///         123, // identifier
1471     ///         456, // sequence number
1472     ///     );
1473     ///
1474     /// // payload of the echo reply
1475     /// let payload = [1,2,3,4,5,6,7,8];
1476     ///
1477     /// //get some memory to store the result
1478     /// let mut result = Vec::<u8>::with_capacity(
1479     ///                     builder.size(payload.len()));
1480     ///
1481     /// //serialize
1482     /// builder.write(&mut result, &payload).unwrap();
1483     /// ```
icmpv6_echo_reply(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv6Header>1484     pub fn icmpv6_echo_reply(mut self, id: u16, seq: u16) -> PacketBuilderStep<Icmpv6Header> {
1485         let echo_header = IcmpEchoHeader { seq, id };
1486         let icmpv6_echo = Icmpv6Header::new(Icmpv6Type::EchoReply(echo_header));
1487         self.state.transport_header = Some(TransportHeader::Icmpv6(icmpv6_echo));
1488         //return for next step
1489         PacketBuilderStep {
1490             state: self.state,
1491             _marker: marker::PhantomData::<Icmpv6Header> {},
1492         }
1493     }
1494 
1495     /// Adds an UDP header.
1496     ///
1497     /// # Example
1498     ///
1499     /// Basic usage:
1500     ///
1501     /// ```
1502     /// # use etherparse::PacketBuilder;
1503     /// #
1504     /// let builder = PacketBuilder::
1505     ///     ethernet2([1,2,3,4,5,6],     //source mac
1506     ///               [7,8,9,10,11,12]) //destination mac
1507     ///    .ipv4([192,168,1,1], //source ip
1508     ///          [192,168,1,2], //destination ip
1509     ///          20)            //time to life
1510     ///    .udp(21,    //source port
1511     ///         1234); //destination port
1512     ///
1513     /// //payload of the udp packet
1514     /// let payload = [1,2,3,4,5,6,7,8];
1515     ///
1516     /// //get some memory to store the result
1517     /// let mut result = Vec::<u8>::with_capacity(
1518     ///                     builder.size(payload.len()));
1519     ///
1520     /// //serialize
1521     /// builder.write(&mut result, &payload).unwrap();
1522     /// ```
udp(mut self, source_port: u16, destination_port: u16) -> PacketBuilderStep<UdpHeader>1523     pub fn udp(mut self, source_port: u16, destination_port: u16) -> PacketBuilderStep<UdpHeader> {
1524         self.state.transport_header = Some(TransportHeader::Udp(UdpHeader {
1525             source_port,
1526             destination_port,
1527             length: 0,   //calculated later
1528             checksum: 0, //calculated later
1529         }));
1530         //return for next step
1531         PacketBuilderStep {
1532             state: self.state,
1533             _marker: marker::PhantomData::<UdpHeader> {},
1534         }
1535     }
1536 
1537     /// Adds a simple TCP header.
1538     ///
1539     /// # Example
1540     ///
1541     /// Basic usage:
1542     ///
1543     /// ```
1544     /// # use etherparse::PacketBuilder;
1545     /// #
1546     /// let builder = PacketBuilder::
1547     ///     ethernet2([1,2,3,4,5,6],     // source mac
1548     ///               [7,8,9,10,11,12]) // destination mac
1549     ///    .ipv4([192,168,1,1], // source ip
1550     ///          [192,168,1,2], // destination ip
1551     ///          20)            // time to life
1552     ///    .tcp(21,    // source port
1553     ///         12,    // destination port
1554     ///         12345, // sequence number
1555     ///         4000); // window size
1556     ///
1557     /// //payload of the udp packet
1558     /// let payload = [1,2,3,4,5,6,7,8];
1559     ///
1560     /// //get some memory to store the result
1561     /// let mut result = Vec::<u8>::with_capacity(
1562     ///                     builder.size(payload.len()));
1563     ///
1564     /// //serialize
1565     /// builder.write(&mut result, &payload).unwrap();
1566     /// ```
tcp( mut self, source_port: u16, destination_port: u16, sequence_number: u32, window_size: u16, ) -> PacketBuilderStep<TcpHeader>1567     pub fn tcp(
1568         mut self,
1569         source_port: u16,
1570         destination_port: u16,
1571         sequence_number: u32,
1572         window_size: u16,
1573     ) -> PacketBuilderStep<TcpHeader> {
1574         self.state.transport_header = Some(TransportHeader::Tcp(TcpHeader::new(
1575             source_port,
1576             destination_port,
1577             sequence_number,
1578             window_size,
1579         )));
1580         //return for next step
1581         PacketBuilderStep {
1582             state: self.state,
1583             _marker: marker::PhantomData::<TcpHeader> {},
1584         }
1585     }
1586 
1587     /// Adds a more complicated TCP header.
1588     ///
1589     /// # Example
1590     ///
1591     /// Basic usage:
1592     ///
1593     /// ```
1594     /// # use etherparse::PacketBuilder;
1595     /// use etherparse::TcpHeader;
1596     ///
1597     /// let mut tcp_header = TcpHeader::new(
1598     ///     21,     // source port
1599     ///     12,     // destination port
1600     ///     12345,  // sequence number
1601     ///     4000,   // window size
1602     /// );
1603     /// tcp_header.psh = true;
1604     /// tcp_header.ack = true;
1605     /// tcp_header.acknowledgment_number = 1;
1606     ///
1607     /// let builder = PacketBuilder::
1608     ///     ethernet2([1,2,3,4,5,6],     // source mac
1609     ///               [7,8,9,10,11,12]) // destination mac
1610     ///    .ipv4([192,168,1,1], // source ip
1611     ///          [192,168,1,2], // destination ip
1612     ///          20)            // time to life
1613     ///    .tcp_header(tcp_header);
1614     ///
1615     /// //payload of the udp packet
1616     /// let payload = [1,2,3,4,5,6,7,8];
1617     ///
1618     /// //get some memory to store the result
1619     /// let mut result = Vec::<u8>::with_capacity(
1620     ///                     builder.size(payload.len()));
1621     ///
1622     /// //serialize
1623     /// builder.write(&mut result, &payload).unwrap();
1624     /// ```
tcp_header(mut self, tcp_header: TcpHeader) -> PacketBuilderStep<TcpHeader>1625     pub fn tcp_header(mut self, tcp_header: TcpHeader) -> PacketBuilderStep<TcpHeader> {
1626         self.state.transport_header = Some(TransportHeader::Tcp(tcp_header));
1627         //return for next step
1628         PacketBuilderStep {
1629             state: self.state,
1630             _marker: marker::PhantomData::<TcpHeader> {},
1631         }
1632     }
1633 
1634     /// Write all the headers and the payload with the given ip number.
1635     ///
1636     /// `last_next_header_ip_number` will be set in the last extension header
1637     /// or if no extension header exists the ip header as the "next header" or
1638     /// "protocol number".
write<T: io::Write + Sized>( mut self, writer: &mut T, last_next_header_ip_number: IpNumber, payload: &[u8], ) -> Result<(), BuildWriteError>1639     pub fn write<T: io::Write + Sized>(
1640         mut self,
1641         writer: &mut T,
1642         last_next_header_ip_number: IpNumber,
1643         payload: &[u8],
1644     ) -> Result<(), BuildWriteError> {
1645         match &mut (self.state.net_header) {
1646             Some(NetHeaders::Ipv4(ref mut ip, ref mut exts)) => {
1647                 ip.protocol = exts.set_next_headers(last_next_header_ip_number);
1648             }
1649             Some(NetHeaders::Ipv6(ref mut ip, ref mut exts)) => {
1650                 ip.next_header = exts.set_next_headers(last_next_header_ip_number);
1651             }
1652             _ => {}
1653         }
1654         final_write_with_net(self, writer, payload)
1655     }
1656 
1657     ///Returns the size of the packet when it is serialized
size(&self, payload_size: usize) -> usize1658     pub fn size(&self, payload_size: usize) -> usize {
1659         final_size(self, payload_size)
1660     }
1661 }
1662 
1663 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1664 impl PacketBuilderStep<Icmpv4Header> {
1665     /// Write all the headers and the payload.
write<T: io::Write + Sized>( self, writer: &mut T, payload: &[u8], ) -> Result<(), BuildWriteError>1666     pub fn write<T: io::Write + Sized>(
1667         self,
1668         writer: &mut T,
1669         payload: &[u8],
1670     ) -> Result<(), BuildWriteError> {
1671         final_write_with_net(self, writer, payload)
1672     }
1673 
1674     /// Returns the size of the packet when it is serialized
size(&self, payload_size: usize) -> usize1675     pub fn size(&self, payload_size: usize) -> usize {
1676         final_size(self, payload_size)
1677     }
1678 }
1679 
1680 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1681 impl PacketBuilderStep<Icmpv6Header> {
1682     ///Write all the headers and the payload.
write<T: io::Write + Sized>( self, writer: &mut T, payload: &[u8], ) -> Result<(), BuildWriteError>1683     pub fn write<T: io::Write + Sized>(
1684         self,
1685         writer: &mut T,
1686         payload: &[u8],
1687     ) -> Result<(), BuildWriteError> {
1688         final_write_with_net(self, writer, payload)
1689     }
1690 
1691     ///Returns the size of the packet when it is serialized
size(&self, payload_size: usize) -> usize1692     pub fn size(&self, payload_size: usize) -> usize {
1693         final_size(self, payload_size)
1694     }
1695 }
1696 
1697 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1698 impl PacketBuilderStep<UdpHeader> {
1699     ///Write all the headers and the payload.
write<T: io::Write + Sized>( self, writer: &mut T, payload: &[u8], ) -> Result<(), BuildWriteError>1700     pub fn write<T: io::Write + Sized>(
1701         self,
1702         writer: &mut T,
1703         payload: &[u8],
1704     ) -> Result<(), BuildWriteError> {
1705         final_write_with_net(self, writer, payload)
1706     }
1707 
1708     ///Returns the size of the packet when it is serialized
size(&self, payload_size: usize) -> usize1709     pub fn size(&self, payload_size: usize) -> usize {
1710         final_size(self, payload_size)
1711     }
1712 }
1713 
1714 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1715 impl PacketBuilderStep<TcpHeader> {
1716     ///Set ns flag (ECN-nonce - concealment protection; experimental: see RFC 3540)
ns(mut self) -> PacketBuilderStep<TcpHeader>1717     pub fn ns(mut self) -> PacketBuilderStep<TcpHeader> {
1718         self.state
1719             .transport_header
1720             .as_mut()
1721             .unwrap()
1722             .mut_tcp()
1723             .unwrap()
1724             .ns = true;
1725         self
1726     }
1727     ///Set fin flag (No more data from sender)
fin(mut self) -> PacketBuilderStep<TcpHeader>1728     pub fn fin(mut self) -> PacketBuilderStep<TcpHeader> {
1729         self.state
1730             .transport_header
1731             .as_mut()
1732             .unwrap()
1733             .mut_tcp()
1734             .unwrap()
1735             .fin = true;
1736         self
1737     }
1738     ///Set the syn flag (synchronize sequence numbers)
syn(mut self) -> PacketBuilderStep<TcpHeader>1739     pub fn syn(mut self) -> PacketBuilderStep<TcpHeader> {
1740         self.state
1741             .transport_header
1742             .as_mut()
1743             .unwrap()
1744             .mut_tcp()
1745             .unwrap()
1746             .syn = true;
1747         self
1748     }
1749     ///Sets the rst flag (reset the connection)
rst(mut self) -> PacketBuilderStep<TcpHeader>1750     pub fn rst(mut self) -> PacketBuilderStep<TcpHeader> {
1751         self.state
1752             .transport_header
1753             .as_mut()
1754             .unwrap()
1755             .mut_tcp()
1756             .unwrap()
1757             .rst = true;
1758         self
1759     }
1760     ///Sets the psh flag (push function)
psh(mut self) -> PacketBuilderStep<TcpHeader>1761     pub fn psh(mut self) -> PacketBuilderStep<TcpHeader> {
1762         self.state
1763             .transport_header
1764             .as_mut()
1765             .unwrap()
1766             .mut_tcp()
1767             .unwrap()
1768             .psh = true;
1769         self
1770     }
1771     ///Sets the ack flag and the acknowledgment_number.
ack(mut self, acknowledgment_number: u32) -> PacketBuilderStep<TcpHeader>1772     pub fn ack(mut self, acknowledgment_number: u32) -> PacketBuilderStep<TcpHeader> {
1773         {
1774             let header = self
1775                 .state
1776                 .transport_header
1777                 .as_mut()
1778                 .unwrap()
1779                 .mut_tcp()
1780                 .unwrap();
1781             header.ack = true;
1782             header.acknowledgment_number = acknowledgment_number;
1783         }
1784         self
1785     }
1786     ///Set the urg flag & the urgent pointer field.
1787     ///
1788     ///The urgent pointer points to the sequence number of the octet following
1789     ///the urgent data.
urg(mut self, urgent_pointer: u16) -> PacketBuilderStep<TcpHeader>1790     pub fn urg(mut self, urgent_pointer: u16) -> PacketBuilderStep<TcpHeader> {
1791         {
1792             let header = self
1793                 .state
1794                 .transport_header
1795                 .as_mut()
1796                 .unwrap()
1797                 .mut_tcp()
1798                 .unwrap();
1799             header.urg = true;
1800             header.urgent_pointer = urgent_pointer;
1801         }
1802         self
1803     }
1804     ///Sets ece flag (ECN-Echo, RFC 3168)
ece(mut self) -> PacketBuilderStep<TcpHeader>1805     pub fn ece(mut self) -> PacketBuilderStep<TcpHeader> {
1806         self.state
1807             .transport_header
1808             .as_mut()
1809             .unwrap()
1810             .mut_tcp()
1811             .unwrap()
1812             .ece = true;
1813         self
1814     }
1815 
1816     ///Set cwr flag (Congestion Window Reduced)
1817     ///
1818     ///This flag is set by the sending host to indicate that it received a TCP segment with the ECE flag set and had responded in congestion control mechanism (added to header by RFC 3168).
cwr(mut self) -> PacketBuilderStep<TcpHeader>1819     pub fn cwr(mut self) -> PacketBuilderStep<TcpHeader> {
1820         self.state
1821             .transport_header
1822             .as_mut()
1823             .unwrap()
1824             .mut_tcp()
1825             .unwrap()
1826             .cwr = true;
1827         self
1828     }
1829 
1830     ///Set the tcp options of the header.
options( mut self, options: &[TcpOptionElement], ) -> Result<PacketBuilderStep<TcpHeader>, TcpOptionWriteError>1831     pub fn options(
1832         mut self,
1833         options: &[TcpOptionElement],
1834     ) -> Result<PacketBuilderStep<TcpHeader>, TcpOptionWriteError> {
1835         self.state
1836             .transport_header
1837             .as_mut()
1838             .unwrap()
1839             .mut_tcp()
1840             .unwrap()
1841             .set_options(options)?;
1842         Ok(self)
1843     }
1844 
1845     ///Set the tcp options of the header (setting the bytes directly).
options_raw( mut self, options: &[u8], ) -> Result<PacketBuilderStep<TcpHeader>, TcpOptionWriteError>1846     pub fn options_raw(
1847         mut self,
1848         options: &[u8],
1849     ) -> Result<PacketBuilderStep<TcpHeader>, TcpOptionWriteError> {
1850         self.state
1851             .transport_header
1852             .as_mut()
1853             .unwrap()
1854             .mut_tcp()
1855             .unwrap()
1856             .set_options_raw(options)?;
1857         Ok(self)
1858     }
1859 
1860     ///Write all the headers and the payload.
write<T: io::Write + Sized>( self, writer: &mut T, payload: &[u8], ) -> Result<(), BuildWriteError>1861     pub fn write<T: io::Write + Sized>(
1862         self,
1863         writer: &mut T,
1864         payload: &[u8],
1865     ) -> Result<(), BuildWriteError> {
1866         final_write_with_net(self, writer, payload)
1867     }
1868 
1869     ///Returns the size of the packet when it is serialized
size(&self, payload_size: usize) -> usize1870     pub fn size(&self, payload_size: usize) -> usize {
1871         final_size(self, payload_size)
1872     }
1873 }
1874 
1875 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1876 impl PacketBuilderStep<ArpPacket> {
write<T: io::Write + Sized>(self, writer: &mut T) -> Result<(), BuildWriteError>1877     pub fn write<T: io::Write + Sized>(self, writer: &mut T) -> Result<(), BuildWriteError> {
1878         final_write_with_net(self, writer, &[])?;
1879         Ok(())
1880     }
1881 
size(&self) -> usize1882     pub fn size(&self) -> usize {
1883         final_size(self, 0)
1884     }
1885 }
1886 
1887 /// Write all the headers and the payload.
final_write_with_net<T: io::Write + Sized, B>( builder: PacketBuilderStep<B>, writer: &mut T, payload: &[u8], ) -> Result<(), BuildWriteError>1888 fn final_write_with_net<T: io::Write + Sized, B>(
1889     builder: PacketBuilderStep<B>,
1890     writer: &mut T,
1891     payload: &[u8],
1892 ) -> Result<(), BuildWriteError> {
1893     use BuildWriteError::*;
1894     use NetHeaders::*;
1895 
1896     // unpack builder (makes things easier with the borrow checker)
1897     let link = builder.state.link_header;
1898     let vlan = builder.state.vlan_header;
1899     let net = builder.state.net_header;
1900     let mut transport = builder.state.transport_header;
1901 
1902     // determine
1903     let net_ether_type = match &net {
1904         Some(Ipv4(_, _)) => ether_type::IPV4,
1905         Some(Ipv6(_, _)) => ether_type::IPV6,
1906         Some(Arp(_)) => ether_type::ARP,
1907         None => unreachable!(),
1908     };
1909 
1910     // link header
1911     if let Some(link) = link {
1912         match link {
1913             LinkHeader::Ethernet2(mut eth) => {
1914                 eth.ether_type = {
1915                     use crate::VlanHeader::*;
1916                     //determine the ether type depending on if there is a vlan tagging header
1917                     match &vlan {
1918                         Some(Single(_)) => ether_type::VLAN_TAGGED_FRAME,
1919                         Some(Double(_)) => ether_type::PROVIDER_BRIDGING,
1920                         //if no vlan header exists, the id is purely defined by the ip type
1921                         None => net_ether_type,
1922                     }
1923                 };
1924                 eth.write(writer).map_err(Io)?;
1925             }
1926             LinkHeader::LinuxSll(mut linux_sll) => {
1927                 // Assumes that next layers are ether based. If more types of
1928                 // layers are supported, this should be updated
1929                 debug_assert_eq!(linux_sll.arp_hrd_type, ArpHardwareId::ETHERNET);
1930 
1931                 linux_sll.protocol_type.change_value(net_ether_type.into());
1932                 linux_sll.write(writer).map_err(Io)?;
1933             }
1934         }
1935     }
1936 
1937     // write the vlan header if it exists
1938     use crate::VlanHeader::*;
1939     match vlan {
1940         Some(Single(mut value)) => {
1941             //set ether types
1942             value.ether_type = net_ether_type;
1943             //serialize
1944             value.write(writer).map_err(Io)?;
1945         }
1946         Some(Double(mut value)) => {
1947             //set ether types
1948             value.outer.ether_type = ether_type::VLAN_TAGGED_FRAME;
1949             value.inner.ether_type = net_ether_type;
1950             //serialize
1951             value.write(writer).map_err(Io)?;
1952         }
1953         None => {}
1954     }
1955 
1956     // set transport header length (needs to be done here
1957     // so following steps can correctly calculate the checksum)
1958     use TransportHeader::*;
1959     match &mut transport {
1960         Some(Udp(ref mut udp)) => {
1961             udp.length = (UdpHeader::LEN + payload.len()) as u16;
1962         }
1963         Some(Tcp(_)) => {}
1964         Some(Icmpv4(_)) => {}
1965         Some(Icmpv6(_)) => {}
1966         None => {}
1967     }
1968 
1969     // net header
1970     match net {
1971         Some(NetHeaders::Ipv4(mut ip, mut ip_exts)) => {
1972             // set payload length & ip number
1973             ip.set_payload_len(
1974                 ip_exts.header_len()
1975                     + transport.as_ref().map(|v| v.header_len()).unwrap_or(0)
1976                     + payload.len(),
1977             )
1978             .map_err(PayloadLen)?;
1979 
1980             if let Some(transport) = &transport {
1981                 ip.protocol = ip_exts.set_next_headers(match &transport {
1982                     Icmpv4(_) => ip_number::ICMP,
1983                     Icmpv6(_) => ip_number::IPV6_ICMP,
1984                     Udp(_) => ip_number::UDP,
1985                     Tcp(_) => ip_number::TCP,
1986                 });
1987             }
1988 
1989             // write ip header & extensions
1990             ip.write(writer).map_err(Io)?;
1991             ip_exts.write(writer, ip.protocol).map_err(|err| {
1992                 use err::ipv4_exts::HeaderWriteError as I;
1993                 match err {
1994                     I::Io(err) => Io(err),
1995                     I::Content(err) => Ipv4Exts(err),
1996                 }
1997             })?;
1998 
1999             // update the transport layer checksum
2000             if let Some(t) = &mut transport {
2001                 t.update_checksum_ipv4(&ip, payload).map_err(|err| {
2002                     use err::packet::TransportChecksumError as I;
2003                     match err {
2004                         I::PayloadLen(err) => PayloadLen(err),
2005                         I::Icmpv6InIpv4 => Icmpv6InIpv4,
2006                     }
2007                 })?;
2008             }
2009         }
2010         Some(NetHeaders::Ipv6(mut ip, mut ip_exts)) => {
2011             // set payload length & ip number
2012             ip.set_payload_length(
2013                 ip_exts.header_len()
2014                     + transport.as_ref().map(|v| v.header_len()).unwrap_or(0)
2015                     + payload.len(),
2016             )
2017             .map_err(PayloadLen)?;
2018 
2019             if let Some(transport) = &transport {
2020                 ip.next_header = ip_exts.set_next_headers(match &transport {
2021                     Icmpv4(_) => ip_number::ICMP,
2022                     Icmpv6(_) => ip_number::IPV6_ICMP,
2023                     Udp(_) => ip_number::UDP,
2024                     Tcp(_) => ip_number::TCP,
2025                 });
2026             }
2027 
2028             // write ip header & extensions
2029             ip.write(writer).map_err(Io)?;
2030             ip_exts.write(writer, ip.next_header).map_err(|err| {
2031                 use err::ipv6_exts::HeaderWriteError as I;
2032                 match err {
2033                     I::Io(err) => Io(err),
2034                     I::Content(err) => Ipv6Exts(err),
2035                 }
2036             })?;
2037 
2038             // update the transport layer checksum
2039             if let Some(t) = &mut transport {
2040                 t.update_checksum_ipv6(&ip, payload).map_err(PayloadLen)?;
2041             }
2042         }
2043         Some(NetHeaders::Arp(arp)) => {
2044             writer.write_all(&arp.to_bytes()).map_err(Io)?;
2045         }
2046         None => {}
2047     }
2048 
2049     // write transport header
2050     if let Some(transport) = transport {
2051         transport.write(writer).map_err(Io)?;
2052     }
2053 
2054     // and finally the payload
2055     writer.write_all(payload).map_err(Io)?;
2056 
2057     Ok(())
2058 }
2059 
2060 ///Returns the size of the packet when it is serialized
final_size<B>(builder: &PacketBuilderStep<B>, payload_size: usize) -> usize2061 fn final_size<B>(builder: &PacketBuilderStep<B>, payload_size: usize) -> usize {
2062     use crate::NetHeaders::*;
2063     use crate::TransportHeader::*;
2064     use crate::VlanHeader::*;
2065     (match builder.state.link_header {
2066         Some(ref header) => header.header_len(),
2067         None => 0,
2068     }) + match builder.state.vlan_header {
2069         Some(Single(_)) => SingleVlanHeader::LEN,
2070         Some(Double(_)) => DoubleVlanHeader::LEN,
2071         None => 0,
2072     } + match builder.state.net_header {
2073         Some(Ipv4(ref value, ref ext)) => value.header_len() + ext.header_len(),
2074         Some(Ipv6(_, ref ext)) => Ipv6Header::LEN + ext.header_len(),
2075         Some(Arp(ref packet)) => packet.packet_len(),
2076         None => 0,
2077     } + match builder.state.transport_header {
2078         Some(Icmpv4(ref value)) => value.header_len(),
2079         Some(Icmpv6(ref value)) => value.header_len(),
2080         Some(Udp(_)) => UdpHeader::LEN,
2081         Some(Tcp(ref value)) => value.header_len(),
2082         None => 0,
2083     } + payload_size
2084 }
2085 
2086 #[cfg(test)]
2087 mod white_box_tests {
2088     use super::*;
2089     use alloc::vec::Vec;
2090 
2091     //white box tests that need internal access
2092     #[test]
size()2093     fn size() {
2094         assert_eq!(
2095             0,
2096             PacketBuilderStep::<UdpHeader> {
2097                 state: PacketImpl {
2098                     link_header: None,
2099                     net_header: None,
2100                     vlan_header: None,
2101                     transport_header: None,
2102                 },
2103                 _marker: marker::PhantomData::<UdpHeader> {}
2104             }
2105             .size(0)
2106         );
2107     }
2108 
2109     #[test]
2110     #[should_panic]
final_write_panic_missing_ip()2111     fn final_write_panic_missing_ip() {
2112         let mut writer = Vec::new();
2113         final_write_with_net(
2114             PacketBuilderStep::<UdpHeader> {
2115                 state: PacketImpl {
2116                     link_header: None,
2117                     net_header: None,
2118                     vlan_header: None,
2119                     transport_header: None,
2120                 },
2121                 _marker: marker::PhantomData::<UdpHeader> {},
2122             },
2123             &mut writer,
2124             &[],
2125         )
2126         .unwrap();
2127     }
2128 }
2129 
2130 #[cfg(test)]
2131 mod test {
2132     use super::*;
2133     use crate::test_gens::*;
2134     use alloc::{vec, vec::Vec};
2135     use proptest::prelude::*;
2136     use std::io::Read;
2137 
2138     #[test]
eth_arp()2139     fn eth_arp() {
2140         let expected_header = ArpPacket::new(
2141             ArpHardwareId::ETHERNET,
2142             EtherType::IPV4,
2143             ArpOperation::REQUEST,
2144             &[20, 30, 40, 50, 60, 70],
2145             &[10, 1, 1, 5],
2146             &[00, 01, 02, 03, 04, 05],
2147             &[192, 168, 1, 2],
2148         )
2149         .unwrap();
2150 
2151         let mut serialized = Vec::new();
2152 
2153         let pkg = PacketBuilder::ethernet2(
2154             [0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b],
2155             [0xde, 0xad, 0xc0, 0x00, 0xff, 0xee],
2156         )
2157         .arp(expected_header.clone());
2158 
2159         let target_size = pkg.size();
2160         pkg.write(&mut serialized).unwrap();
2161 
2162         // validate that the predicted size was matching
2163         assert_eq!(serialized.len(), target_size);
2164 
2165         // deserialize each part of the message and check it
2166         use std::io::Cursor;
2167         let mut cursor = Cursor::new(&serialized);
2168 
2169         // ethernet 2 header
2170         assert_eq!(
2171             Ethernet2Header::read(&mut cursor).unwrap(),
2172             Ethernet2Header {
2173                 source: [0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b],
2174                 destination: [0xde, 0xad, 0xc0, 0x00, 0xff, 0xee],
2175                 ether_type: ether_type::ARP
2176             }
2177         );
2178 
2179         // arp packet
2180         assert_eq!(ArpPacket::read(&mut cursor).unwrap(), expected_header);
2181     }
2182 
2183     #[test]
eth_vlan_arp()2184     fn eth_vlan_arp() {
2185         let expected_arp = ArpPacket::new(
2186             ArpHardwareId::ETHERNET,
2187             EtherType::IPV4,
2188             ArpOperation::REQUEST,
2189             &[20, 30, 40, 50, 60, 70],
2190             &[10, 1, 1, 5],
2191             &[00, 01, 02, 03, 04, 05],
2192             &[192, 168, 1, 2],
2193         )
2194         .unwrap();
2195         let vlan = SingleVlanHeader {
2196             pcp: VlanPcp::ZERO,
2197             drop_eligible_indicator: false,
2198             vlan_id: VlanId::try_new(123).unwrap(),
2199             ether_type: EtherType(0), // should get overwritten
2200         };
2201 
2202         let mut serialized = Vec::new();
2203 
2204         let pkg = PacketBuilder::ethernet2(
2205             [0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b],
2206             [0xde, 0xad, 0xc0, 0x00, 0xff, 0xee],
2207         )
2208         .vlan(VlanHeader::Single(vlan.clone()))
2209         .arp(expected_arp.clone());
2210 
2211         let target_size = pkg.size();
2212         pkg.write(&mut serialized).unwrap();
2213 
2214         // validate that the predicted size was matching
2215         assert_eq!(serialized.len(), target_size);
2216 
2217         // deserialize each part of the message and check it
2218         use std::io::Cursor;
2219         let mut cursor = Cursor::new(&serialized);
2220 
2221         // ethernet 2 header
2222         assert_eq!(
2223             Ethernet2Header::read(&mut cursor).unwrap(),
2224             Ethernet2Header {
2225                 source: [0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b],
2226                 destination: [0xde, 0xad, 0xc0, 0x00, 0xff, 0xee],
2227                 ether_type: ether_type::VLAN_TAGGED_FRAME
2228             }
2229         );
2230 
2231         // vlan header
2232         let mut expected_vlan = vlan.clone();
2233         expected_vlan.ether_type = EtherType::ARP;
2234         assert_eq!(SingleVlanHeader::read(&mut cursor).unwrap(), expected_vlan);
2235 
2236         // arp packet
2237         assert_eq!(ArpPacket::read(&mut cursor).unwrap(), expected_arp);
2238     }
2239 
2240     #[test]
eth_ipv4_udp()2241     fn eth_ipv4_udp() {
2242         //generate
2243         let in_payload = [24, 25, 26, 27];
2244         let mut serialized = Vec::new();
2245         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
2246             .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
2247             .udp(22, 23)
2248             .write(&mut serialized, &in_payload)
2249             .unwrap();
2250 
2251         //check the deserialized size
2252         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2253         assert_eq!(
2254             expected_ip_size + Ethernet2Header::LEN + Ipv4Header::MIN_LEN,
2255             serialized.len()
2256         );
2257 
2258         //deserialize and check that everything is as expected
2259         use std::io::Cursor;
2260         //deserialize each part of the message and check it
2261         let mut cursor = Cursor::new(&serialized);
2262 
2263         //ethernet 2 header
2264         assert_eq!(
2265             Ethernet2Header::read(&mut cursor).unwrap(),
2266             Ethernet2Header {
2267                 source: [1, 2, 3, 4, 5, 6],
2268                 destination: [7, 8, 9, 10, 11, 12],
2269                 ether_type: ether_type::IPV4
2270             }
2271         );
2272 
2273         //ip header
2274         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2275         let mut ip_expected = Ipv4Header::new(
2276             expected_ip_size as u16,
2277             21, //ttl
2278             ip_number::UDP,
2279             [13, 14, 15, 16],
2280             [17, 18, 19, 20],
2281         )
2282         .unwrap();
2283         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2284         assert_eq!(ip_actual, ip_expected);
2285 
2286         //udp header
2287         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2288         let udp_expected =
2289             UdpHeader::with_ipv4_checksum(22, 23, &ip_expected, &in_payload).unwrap();
2290         assert_eq!(udp_actual, udp_expected);
2291 
2292         //payload
2293         let mut actual_payload: [u8; 4] = [0; 4];
2294         cursor.read_exact(&mut actual_payload).unwrap();
2295         assert_eq!(actual_payload, in_payload);
2296     }
2297 
2298     #[test]
linuxsll_ipv4_udp()2299     fn linuxsll_ipv4_udp() {
2300         //generate
2301         let in_payload = [24, 25, 26, 27];
2302         let mut serialized = Vec::new();
2303         PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
2304             .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
2305             .udp(22, 23)
2306             .write(&mut serialized, &in_payload)
2307             .unwrap();
2308 
2309         //check the deserialized size
2310         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2311         assert_eq!(
2312             expected_ip_size + LinuxSllHeader::LEN + Ipv4Header::MIN_LEN,
2313             serialized.len()
2314         );
2315 
2316         //deserialize and check that everything is as expected
2317         use std::io::Cursor;
2318         //deserialize each part of the message and check it
2319         let mut cursor = Cursor::new(&serialized);
2320 
2321         //ethernet 2 header
2322         assert_eq!(
2323             LinuxSllHeader::read(&mut cursor).unwrap(),
2324             LinuxSllHeader {
2325                 packet_type: LinuxSllPacketType::OUTGOING,
2326                 arp_hrd_type: ArpHardwareId::ETHERNET,
2327                 sender_address_valid_length: 6,
2328                 sender_address: [7, 8, 9, 10, 11, 12, 0, 0],
2329                 protocol_type: LinuxSllProtocolType::EtherType(EtherType::IPV4)
2330             }
2331         );
2332 
2333         //ip header
2334         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2335         let mut ip_expected = Ipv4Header::new(
2336             expected_ip_size as u16,
2337             21, //ttl
2338             ip_number::UDP,
2339             [13, 14, 15, 16],
2340             [17, 18, 19, 20],
2341         )
2342         .unwrap();
2343         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2344         assert_eq!(ip_actual, ip_expected);
2345 
2346         //udp header
2347         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2348         let udp_expected =
2349             UdpHeader::with_ipv4_checksum(22, 23, &ip_expected, &in_payload).unwrap();
2350         assert_eq!(udp_actual, udp_expected);
2351 
2352         //payload
2353         let mut actual_payload: [u8; 4] = [0; 4];
2354         cursor.read_exact(&mut actual_payload).unwrap();
2355         assert_eq!(actual_payload, in_payload);
2356     }
2357 
2358     #[test]
linuxsll_arp()2359     fn linuxsll_arp() {
2360         let expected_arp = ArpPacket::new(
2361             ArpHardwareId::ETHERNET,
2362             EtherType::IPV4,
2363             ArpOperation::REQUEST,
2364             &[20, 30, 40, 50, 60, 70],
2365             &[10, 1, 1, 5],
2366             &[00, 01, 02, 03, 04, 05],
2367             &[192, 168, 1, 2],
2368         )
2369         .unwrap();
2370 
2371         // build packet
2372         let builder =
2373             PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
2374                 .arp(expected_arp.clone());
2375 
2376         let predicted_size = builder.size();
2377 
2378         let mut serialized = Vec::with_capacity(builder.size());
2379         builder.write(&mut serialized).unwrap();
2380 
2381         // validate predicted size
2382         assert_eq!(predicted_size, serialized.len());
2383 
2384         // deserialize each part of the message and check it
2385         use std::io::Cursor;
2386         let mut cursor = Cursor::new(&serialized);
2387 
2388         // linux sll header
2389         assert_eq!(
2390             LinuxSllHeader::read(&mut cursor).unwrap(),
2391             LinuxSllHeader {
2392                 packet_type: LinuxSllPacketType::OUTGOING,
2393                 arp_hrd_type: ArpHardwareId::ETHERNET,
2394                 sender_address_valid_length: 6,
2395                 sender_address: [7, 8, 9, 10, 11, 12, 0, 0],
2396                 protocol_type: LinuxSllProtocolType::EtherType(EtherType::ARP)
2397             }
2398         );
2399 
2400         // arp
2401         assert_eq!(ArpPacket::read(&mut cursor).unwrap(), expected_arp);
2402     }
2403 
2404     #[test]
ipv4()2405     fn ipv4() {
2406         let auth_ext = IpAuthHeader::new(0.into(), 1, 2, &[3, 4, 5, 6]).unwrap();
2407 
2408         //generate
2409         let in_payload = [22, 23, 24, 25];
2410         let mut serialized = Vec::new();
2411         let builder = PacketBuilder::ip(IpHeaders::Ipv4(
2412             Ipv4Header::new(
2413                 in_payload.len() as u16,
2414                 21,
2415                 0.into(),
2416                 [13, 14, 15, 16],
2417                 [17, 18, 19, 20],
2418             )
2419             .unwrap(),
2420             Ipv4Extensions {
2421                 auth: Some(auth_ext.clone()),
2422             },
2423         ));
2424 
2425         // check size
2426         assert_eq!(
2427             builder.size(in_payload.len()),
2428             Ipv4Header::MIN_LEN + auth_ext.header_len() + in_payload.len()
2429         );
2430 
2431         // write
2432         serialized.reserve(builder.size(in_payload.len()));
2433         builder
2434             .write(&mut serialized, 200.into(), &in_payload)
2435             .unwrap();
2436 
2437         //check the deserialized size
2438         assert_eq!(
2439             Ipv4Header::MIN_LEN + auth_ext.header_len() + in_payload.len(),
2440             serialized.len()
2441         );
2442 
2443         //deserialize and check that everything is as expected
2444         use std::io::{Cursor, Read};
2445 
2446         //deserialize each part of the message and check it
2447         let mut cursor = Cursor::new(&serialized);
2448 
2449         //ip header
2450         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2451         let mut ip_expected = Ipv4Header::new(
2452             (auth_ext.header_len() + in_payload.len()) as u16,
2453             21,              //ttl
2454             ip_number::AUTH, // should have been set
2455             [13, 14, 15, 16],
2456             [17, 18, 19, 20],
2457         )
2458         .unwrap();
2459         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2460         assert_eq!(ip_actual, ip_expected);
2461 
2462         // auth header
2463         let auth_actual = IpAuthHeader::read(&mut cursor).unwrap();
2464         assert_eq!(
2465             auth_actual,
2466             IpAuthHeader::new(
2467                 200.into(), // ip number should have been set
2468                 1,
2469                 2,
2470                 &[3, 4, 5, 6]
2471             )
2472             .unwrap()
2473         );
2474 
2475         //payload
2476         let mut actual_payload: [u8; 4] = [0; 4];
2477         cursor.read_exact(&mut actual_payload).unwrap();
2478         assert_eq!(actual_payload, in_payload);
2479     }
2480 
2481     #[test]
ipv6()2482     fn ipv6() {
2483         let auth_ext = IpAuthHeader::new(0.into(), 1, 2, &[3, 4, 5, 6]).unwrap();
2484 
2485         //generate
2486         let in_payload = [48, 49, 50, 51];
2487         let mut serialized = Vec::new();
2488         let builder = PacketBuilder::ip(IpHeaders::Ipv6(
2489             Ipv6Header {
2490                 traffic_class: 0,
2491                 flow_label: Ipv6FlowLabel::ZERO,
2492                 payload_length: in_payload.len() as u16,
2493                 next_header: 0.into(),
2494                 hop_limit: 47,
2495                 source: [
2496                     11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2497                 ],
2498                 destination: [
2499                     31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2500                 ],
2501             },
2502             Ipv6Extensions {
2503                 hop_by_hop_options: None,
2504                 destination_options: None,
2505                 routing: None,
2506                 fragment: None,
2507                 auth: Some(auth_ext.clone()),
2508             },
2509         ));
2510 
2511         // check size
2512         assert_eq!(
2513             builder.size(in_payload.len()),
2514             Ipv6Header::LEN + auth_ext.header_len() + in_payload.len()
2515         );
2516 
2517         // write
2518         builder
2519             .write(&mut serialized, 200.into(), &in_payload)
2520             .unwrap();
2521 
2522         //check the deserialized size
2523         assert_eq!(
2524             Ipv6Header::LEN + auth_ext.header_len() + in_payload.len(),
2525             serialized.len()
2526         );
2527 
2528         //deserialize and check that everything is as expected
2529         use std::io::{Cursor, Read};
2530 
2531         //deserialize each part of the message and check it
2532         let mut cursor = Cursor::new(&serialized);
2533 
2534         //ip header
2535         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
2536         let ip_expected = Ipv6Header {
2537             traffic_class: 0,
2538             flow_label: Ipv6FlowLabel::ZERO,
2539             payload_length: (auth_ext.header_len() + in_payload.len()) as u16,
2540             next_header: ip_number::AUTH, // should have been set
2541             hop_limit: 47,
2542             source: [
2543                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2544             ],
2545             destination: [
2546                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2547             ],
2548         };
2549 
2550         assert_eq!(ip_actual, ip_expected);
2551 
2552         // auth header
2553         let auth_actual = IpAuthHeader::read(&mut cursor).unwrap();
2554         assert_eq!(
2555             auth_actual,
2556             IpAuthHeader::new(
2557                 200.into(), // ip number should have been set
2558                 1,
2559                 2,
2560                 &[3, 4, 5, 6]
2561             )
2562             .unwrap()
2563         );
2564 
2565         //payload
2566         let mut actual_payload: [u8; 4] = [0; 4];
2567         cursor.read_exact(&mut actual_payload).unwrap();
2568         assert_eq!(actual_payload, in_payload);
2569     }
2570 
2571     #[test]
ipv4_udp()2572     fn ipv4_udp() {
2573         //generate
2574         let in_payload = [24, 25, 26, 27];
2575         let mut serialized = Vec::new();
2576         PacketBuilder::ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
2577             .udp(22, 23)
2578             .write(&mut serialized, &in_payload)
2579             .unwrap();
2580 
2581         //check the deserialized size
2582         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2583         assert_eq!(expected_ip_size + Ipv4Header::MIN_LEN, serialized.len());
2584 
2585         //deserialize and check that everything is as expected
2586         use std::io::{Cursor, Read};
2587 
2588         //deserialize each part of the message and check it
2589         let mut cursor = Cursor::new(&serialized);
2590 
2591         //ip header
2592         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2593         let mut ip_expected = Ipv4Header::new(
2594             expected_ip_size as u16,
2595             21, //ttl
2596             ip_number::UDP,
2597             [13, 14, 15, 16],
2598             [17, 18, 19, 20],
2599         )
2600         .unwrap();
2601         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2602         assert_eq!(ip_actual, ip_expected);
2603 
2604         //udp header
2605         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2606         let udp_expected =
2607             UdpHeader::with_ipv4_checksum(22, 23, &ip_expected, &in_payload).unwrap();
2608         assert_eq!(udp_actual, udp_expected);
2609 
2610         //payload
2611         let mut actual_payload: [u8; 4] = [0; 4];
2612         cursor.read_exact(&mut actual_payload).unwrap();
2613         assert_eq!(actual_payload, in_payload);
2614     }
2615 
2616     #[test]
ipv6_udp()2617     fn ipv6_udp() {
2618         //generate
2619         let in_payload = [24, 25, 26, 27];
2620         let mut serialized = Vec::new();
2621         PacketBuilder::ipv6(
2622             //source
2623             [
2624                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2625             ],
2626             //destination
2627             [
2628                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2629             ],
2630             //hop_limit
2631             47,
2632         )
2633         .udp(22, 23)
2634         .write(&mut serialized, &in_payload)
2635         .unwrap();
2636 
2637         //check the deserialized size
2638         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2639         assert_eq!(expected_ip_size + Ipv6Header::LEN, serialized.len());
2640 
2641         //deserialize and check that everything is as expected
2642         use std::io::{Cursor, Read};
2643 
2644         //deserialize each part of the message and check it
2645         let mut cursor = Cursor::new(&serialized);
2646 
2647         //ip header
2648         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
2649         let ip_expected = Ipv6Header {
2650             traffic_class: 0,
2651             flow_label: Ipv6FlowLabel::ZERO,
2652             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
2653             next_header: ip_number::UDP,
2654             hop_limit: 47,
2655             source: [
2656                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2657             ],
2658             destination: [
2659                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2660             ],
2661         };
2662 
2663         assert_eq!(ip_actual, ip_expected);
2664 
2665         //udp header
2666         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2667         let udp_expected =
2668             UdpHeader::with_ipv6_checksum(22, 23, &ip_expected, &in_payload).unwrap();
2669         assert_eq!(udp_actual, udp_expected);
2670 
2671         //payload
2672         let mut actual_payload: [u8; 4] = [0; 4];
2673         cursor.read_exact(&mut actual_payload).unwrap();
2674         assert_eq!(actual_payload, in_payload);
2675     }
2676 
2677     #[test]
ipv4_custom_udp()2678     fn ipv4_custom_udp() {
2679         //generate
2680         let in_payload = [24, 25, 26, 27];
2681         let mut serialized = Vec::new();
2682         PacketBuilder::ip(IpHeaders::Ipv4(
2683             Ipv4Header::new(
2684                 0,                //payload_len will be replaced during write
2685                 12,               //time_to_live
2686                 ip_number::TCP,   //will be replaced during write
2687                 [13, 14, 15, 16], //source
2688                 [17, 18, 19, 20], //destination
2689             )
2690             .unwrap(),
2691             Default::default(),
2692         ))
2693         .udp(22, 23)
2694         .write(&mut serialized, &in_payload)
2695         .unwrap();
2696 
2697         //check the deserialized size
2698         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2699         assert_eq!(expected_ip_size + Ipv4Header::MIN_LEN, serialized.len());
2700 
2701         //deserialize and check that everything is as expected
2702         use std::io::{Cursor, Read};
2703 
2704         //deserialize each part of the message and check it
2705         let mut cursor = Cursor::new(&serialized);
2706 
2707         //ip header
2708         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2709         let mut ip_expected = Ipv4Header::new(
2710             expected_ip_size as u16,
2711             12, //ttl
2712             ip_number::UDP,
2713             [13, 14, 15, 16],
2714             [17, 18, 19, 20],
2715         )
2716         .unwrap();
2717         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2718         assert_eq!(ip_actual, ip_expected);
2719 
2720         //udp header
2721         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2722         let udp_expected =
2723             UdpHeader::with_ipv4_checksum(22, 23, &ip_expected, &in_payload).unwrap();
2724         assert_eq!(udp_actual, udp_expected);
2725 
2726         //payload
2727         let mut actual_payload: [u8; 4] = [0; 4];
2728         cursor.read_exact(&mut actual_payload).unwrap();
2729         assert_eq!(actual_payload, in_payload);
2730     }
2731 
2732     #[test]
eth_ipv6_udp()2733     fn eth_ipv6_udp() {
2734         //generate
2735         let in_payload = [50, 51, 52, 53];
2736         let mut serialized = Vec::new();
2737         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
2738             .ipv6(
2739                 [
2740                     11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2741                 ],
2742                 [
2743                     31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2744                 ],
2745                 47,
2746             )
2747             .udp(48, 49)
2748             .write(&mut serialized, &in_payload)
2749             .unwrap();
2750 
2751         //check the deserialized size
2752         assert_eq!(
2753             Ethernet2Header::LEN + Ipv6Header::LEN + UdpHeader::LEN + in_payload.len(),
2754             serialized.len()
2755         );
2756 
2757         //deserialize and check that everything is as expected
2758         use std::io::Cursor;
2759         use std::io::Read;
2760         //deserialize each part of the message and check it
2761         let mut cursor = Cursor::new(&serialized);
2762 
2763         //ethernet 2 header
2764         assert_eq!(
2765             Ethernet2Header::read(&mut cursor).unwrap(),
2766             Ethernet2Header {
2767                 source: [1, 2, 3, 4, 5, 6],
2768                 destination: [7, 8, 9, 10, 11, 12],
2769                 ether_type: ether_type::IPV6
2770             }
2771         );
2772 
2773         //ip header
2774         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
2775         let ip_expected = Ipv6Header {
2776             traffic_class: 0,
2777             flow_label: Ipv6FlowLabel::ZERO,
2778             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
2779             next_header: ip_number::UDP,
2780             hop_limit: 47,
2781             source: [
2782                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2783             ],
2784             destination: [
2785                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2786             ],
2787         };
2788         assert_eq!(ip_actual, ip_expected);
2789 
2790         //udp header
2791         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2792         let udp_expected =
2793             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
2794         assert_eq!(udp_actual, udp_expected);
2795 
2796         //payload
2797         let mut actual_payload: [u8; 4] = [0; 4];
2798         cursor.read_exact(&mut actual_payload).unwrap();
2799         assert_eq!(actual_payload, in_payload);
2800     }
2801 
2802     #[test]
linuxsll_ipv6_udp()2803     fn linuxsll_ipv6_udp() {
2804         //generate
2805         let in_payload = [50, 51, 52, 53];
2806         let mut serialized = Vec::new();
2807         PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
2808             .ipv6(
2809                 [
2810                     11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2811                 ],
2812                 [
2813                     31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2814                 ],
2815                 47,
2816             )
2817             .udp(48, 49)
2818             .write(&mut serialized, &in_payload)
2819             .unwrap();
2820 
2821         //check the deserialized size
2822         assert_eq!(
2823             LinuxSllHeader::LEN + Ipv6Header::LEN + UdpHeader::LEN + in_payload.len(),
2824             serialized.len()
2825         );
2826 
2827         //deserialize and check that everything is as expected
2828         use std::io::Cursor;
2829         use std::io::Read;
2830         //deserialize each part of the message and check it
2831         let mut cursor = Cursor::new(&serialized);
2832 
2833         //ethernet 2 header
2834         assert_eq!(
2835             LinuxSllHeader::read(&mut cursor).unwrap(),
2836             LinuxSllHeader {
2837                 packet_type: LinuxSllPacketType::OUTGOING,
2838                 arp_hrd_type: ArpHardwareId::ETHERNET,
2839                 sender_address_valid_length: 6,
2840                 sender_address: [7, 8, 9, 10, 11, 12, 0, 0],
2841                 protocol_type: LinuxSllProtocolType::EtherType(EtherType::IPV6)
2842             }
2843         );
2844 
2845         //ip header
2846         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
2847         let ip_expected = Ipv6Header {
2848             traffic_class: 0,
2849             flow_label: Ipv6FlowLabel::ZERO,
2850             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
2851             next_header: ip_number::UDP,
2852             hop_limit: 47,
2853             source: [
2854                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2855             ],
2856             destination: [
2857                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2858             ],
2859         };
2860         assert_eq!(ip_actual, ip_expected);
2861 
2862         //udp header
2863         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2864         let udp_expected =
2865             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
2866         assert_eq!(udp_actual, udp_expected);
2867 
2868         //payload
2869         let mut actual_payload: [u8; 4] = [0; 4];
2870         cursor.read_exact(&mut actual_payload).unwrap();
2871         assert_eq!(actual_payload, in_payload);
2872     }
2873 
2874     #[test]
eth_single_vlan_ipv4_udp()2875     fn eth_single_vlan_ipv4_udp() {
2876         //generate
2877         let in_payload = [50, 51, 52, 53];
2878         let mut serialized = Vec::new();
2879         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
2880             .single_vlan(0x123.try_into().unwrap())
2881             .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
2882             .udp(48, 49)
2883             .write(&mut serialized, &in_payload)
2884             .unwrap();
2885 
2886         //check the deserialized size
2887 
2888         //check the deserialized size
2889         let expected_ip_size: usize = UdpHeader::LEN + in_payload.len();
2890         assert_eq!(
2891             expected_ip_size + Ethernet2Header::LEN + Ipv4Header::MIN_LEN + SingleVlanHeader::LEN,
2892             serialized.len()
2893         );
2894 
2895         //deserialize and check that everything is as expected
2896         use std::io::Cursor;
2897         use std::io::Read;
2898         //deserialize each part of the message and check it
2899         let mut cursor = Cursor::new(&serialized);
2900 
2901         //ethernet 2 header
2902         assert_eq!(
2903             Ethernet2Header::read(&mut cursor).unwrap(),
2904             Ethernet2Header {
2905                 source: [1, 2, 3, 4, 5, 6],
2906                 destination: [7, 8, 9, 10, 11, 12],
2907                 ether_type: ether_type::VLAN_TAGGED_FRAME
2908             }
2909         );
2910 
2911         //vlan header
2912         assert_eq!(
2913             SingleVlanHeader::read(&mut cursor).unwrap(),
2914             SingleVlanHeader {
2915                 pcp: VlanPcp::ZERO,
2916                 drop_eligible_indicator: false,
2917                 vlan_id: 0x123.try_into().unwrap(),
2918                 ether_type: ether_type::IPV4
2919             }
2920         );
2921 
2922         //ip header
2923         let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
2924         let mut ip_expected = Ipv4Header::new(
2925             expected_ip_size as u16, //payload_len
2926             21,                      //ttl
2927             ip_number::UDP,
2928             [13, 14, 15, 16],
2929             [17, 18, 19, 20],
2930         )
2931         .unwrap();
2932         ip_expected.header_checksum = ip_expected.calc_header_checksum();
2933         assert_eq!(ip_actual, ip_expected);
2934 
2935         //udp header
2936         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
2937         let udp_expected =
2938             UdpHeader::with_ipv4_checksum(48, 49, &ip_expected, &in_payload).unwrap();
2939         assert_eq!(udp_actual, udp_expected);
2940 
2941         //payload
2942         let mut actual_payload: [u8; 4] = [0; 4];
2943         cursor.read_exact(&mut actual_payload).unwrap();
2944         assert_eq!(actual_payload, in_payload);
2945     }
2946 
2947     #[test]
eth_double_vlan_ipv6_udp()2948     fn eth_double_vlan_ipv6_udp() {
2949         //generate
2950         let in_payload = [50, 51, 52, 53];
2951         let mut serialized = Vec::new();
2952         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
2953             .double_vlan(0x123.try_into().unwrap(), 0x234.try_into().unwrap())
2954             .ipv6(
2955                 [
2956                     11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
2957                 ],
2958                 [
2959                     31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
2960                 ],
2961                 47,
2962             )
2963             .udp(48, 49)
2964             .write(&mut serialized, &in_payload)
2965             .unwrap();
2966 
2967         //check the deserialized size
2968         assert_eq!(
2969             Ethernet2Header::LEN
2970                 + DoubleVlanHeader::LEN
2971                 + Ipv6Header::LEN
2972                 + UdpHeader::LEN
2973                 + in_payload.len(),
2974             serialized.len()
2975         );
2976 
2977         //deserialize and check that everything is as expected
2978         use std::io::Cursor;
2979         use std::io::Read;
2980 
2981         //deserialize each part of the message and check it
2982         let mut cursor = Cursor::new(&serialized);
2983 
2984         //ethernet 2 header
2985         assert_eq!(
2986             Ethernet2Header::read(&mut cursor).unwrap(),
2987             Ethernet2Header {
2988                 source: [1, 2, 3, 4, 5, 6],
2989                 destination: [7, 8, 9, 10, 11, 12],
2990                 ether_type: ether_type::PROVIDER_BRIDGING,
2991             }
2992         );
2993 
2994         //outer vlan header
2995         assert_eq!(
2996             SingleVlanHeader::read(&mut cursor).unwrap(),
2997             SingleVlanHeader {
2998                 pcp: VlanPcp::ZERO,
2999                 drop_eligible_indicator: false,
3000                 vlan_id: 0x123.try_into().unwrap(),
3001                 ether_type: ether_type::VLAN_TAGGED_FRAME
3002             }
3003         );
3004 
3005         //inner vlan header
3006         assert_eq!(
3007             SingleVlanHeader::read(&mut cursor).unwrap(),
3008             SingleVlanHeader {
3009                 pcp: VlanPcp::ZERO,
3010                 drop_eligible_indicator: false,
3011                 vlan_id: 0x234.try_into().unwrap(),
3012                 ether_type: ether_type::IPV6
3013             }
3014         );
3015 
3016         //ip header
3017         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
3018         let ip_expected = Ipv6Header {
3019             traffic_class: 0,
3020             flow_label: Ipv6FlowLabel::ZERO,
3021             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3022             next_header: ip_number::UDP,
3023             hop_limit: 47,
3024             source: [
3025                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3026             ],
3027             destination: [
3028                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3029             ],
3030         };
3031         assert_eq!(ip_actual, ip_expected);
3032 
3033         //udp header
3034         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
3035         let udp_expected =
3036             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
3037         assert_eq!(udp_actual, udp_expected);
3038 
3039         //payload
3040         let mut actual_payload: [u8; 4] = [0; 4];
3041         cursor.read_exact(&mut actual_payload).unwrap();
3042         assert_eq!(actual_payload, in_payload);
3043     }
3044 
3045     #[test]
eth_ip_udp()3046     fn eth_ip_udp() {
3047         //generate
3048         let in_payload = [50, 51, 52, 53];
3049         let mut serialized = Vec::new();
3050         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3051             .ip(IpHeaders::Ipv6(
3052                 Ipv6Header {
3053                     traffic_class: 1,
3054                     flow_label: 2.try_into().unwrap(),
3055                     payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3056                     next_header: ip_number::UDP,
3057                     hop_limit: 47,
3058                     source: [
3059                         11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3060                     ],
3061                     destination: [
3062                         31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3063                     ],
3064                 },
3065                 Default::default(),
3066             ))
3067             .udp(48, 49)
3068             .write(&mut serialized, &in_payload)
3069             .unwrap();
3070 
3071         //check the deserialized size
3072         assert_eq!(
3073             Ethernet2Header::LEN + Ipv6Header::LEN + UdpHeader::LEN + in_payload.len(),
3074             serialized.len()
3075         );
3076 
3077         //deserialize and check that everything is as expected
3078         use std::io::Cursor;
3079         use std::io::Read;
3080 
3081         //deserialize each part of the message and check it
3082         let mut cursor = Cursor::new(&serialized);
3083 
3084         //ethernet 2 header
3085         assert_eq!(
3086             Ethernet2Header::read(&mut cursor).unwrap(),
3087             Ethernet2Header {
3088                 source: [1, 2, 3, 4, 5, 6],
3089                 destination: [7, 8, 9, 10, 11, 12],
3090                 ether_type: ether_type::IPV6
3091             }
3092         );
3093 
3094         //ip header
3095         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
3096         let ip_expected = Ipv6Header {
3097             traffic_class: 1,
3098             flow_label: 2.try_into().unwrap(),
3099             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3100             next_header: ip_number::UDP,
3101             hop_limit: 47,
3102             source: [
3103                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3104             ],
3105             destination: [
3106                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3107             ],
3108         };
3109         assert_eq!(ip_actual, ip_expected);
3110 
3111         //udp header
3112         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
3113         let udp_expected =
3114             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
3115         assert_eq!(udp_actual, udp_expected);
3116 
3117         //payload
3118         let mut actual_payload: [u8; 4] = [0; 4];
3119         cursor.read_exact(&mut actual_payload).unwrap();
3120         assert_eq!(actual_payload, in_payload);
3121     }
3122 
3123     #[test]
linuxsll_ip_udp()3124     fn linuxsll_ip_udp() {
3125         //generate
3126         let in_payload = [50, 51, 52, 53];
3127         let mut serialized = Vec::new();
3128         PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
3129             .ip(IpHeaders::Ipv6(
3130                 Ipv6Header {
3131                     traffic_class: 1,
3132                     flow_label: 2.try_into().unwrap(),
3133                     payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3134                     next_header: ip_number::UDP,
3135                     hop_limit: 47,
3136                     source: [
3137                         11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3138                     ],
3139                     destination: [
3140                         31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3141                     ],
3142                 },
3143                 Default::default(),
3144             ))
3145             .udp(48, 49)
3146             .write(&mut serialized, &in_payload)
3147             .unwrap();
3148 
3149         //check the deserialized size
3150         assert_eq!(
3151             LinuxSllHeader::LEN + Ipv6Header::LEN + UdpHeader::LEN + in_payload.len(),
3152             serialized.len()
3153         );
3154 
3155         //deserialize and check that everything is as expected
3156         use std::io::Cursor;
3157         use std::io::Read;
3158 
3159         //deserialize each part of the message and check it
3160         let mut cursor = Cursor::new(&serialized);
3161 
3162         //ethernet 2 header
3163         assert_eq!(
3164             LinuxSllHeader::read(&mut cursor).unwrap(),
3165             LinuxSllHeader {
3166                 packet_type: LinuxSllPacketType::OUTGOING,
3167                 arp_hrd_type: ArpHardwareId::ETHERNET,
3168                 sender_address_valid_length: 6,
3169                 sender_address: [7, 8, 9, 10, 11, 12, 0, 0],
3170                 protocol_type: LinuxSllProtocolType::EtherType(EtherType::IPV6)
3171             }
3172         );
3173 
3174         //ip header
3175         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
3176         let ip_expected = Ipv6Header {
3177             traffic_class: 1,
3178             flow_label: 2.try_into().unwrap(),
3179             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3180             next_header: ip_number::UDP,
3181             hop_limit: 47,
3182             source: [
3183                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3184             ],
3185             destination: [
3186                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3187             ],
3188         };
3189         assert_eq!(ip_actual, ip_expected);
3190 
3191         //udp header
3192         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
3193         let udp_expected =
3194             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
3195         assert_eq!(udp_actual, udp_expected);
3196 
3197         //payload
3198         let mut actual_payload: [u8; 4] = [0; 4];
3199         cursor.read_exact(&mut actual_payload).unwrap();
3200         assert_eq!(actual_payload, in_payload);
3201     }
3202 
3203     #[test]
eth_vlan_ip_udp()3204     fn eth_vlan_ip_udp() {
3205         //generate
3206         let in_payload = [50, 51, 52, 53];
3207         let mut serialized = Vec::new();
3208         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3209             .vlan(VlanHeader::Single(SingleVlanHeader {
3210                 pcp: 1.try_into().unwrap(),
3211                 drop_eligible_indicator: true,
3212                 vlan_id: 0x123.try_into().unwrap(),
3213                 ether_type: 0.into(), //should be overwritten
3214             }))
3215             .ip(IpHeaders::Ipv6(
3216                 Ipv6Header {
3217                     traffic_class: 1,
3218                     flow_label: 2.try_into().unwrap(),
3219                     payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3220                     next_header: ip_number::UDP,
3221                     hop_limit: 47,
3222                     source: [
3223                         11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3224                     ],
3225                     destination: [
3226                         31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3227                     ],
3228                 },
3229                 Default::default(),
3230             ))
3231             .udp(48, 49)
3232             .write(&mut serialized, &in_payload)
3233             .unwrap();
3234 
3235         //check the deserialized size
3236         assert_eq!(
3237             Ethernet2Header::LEN
3238                 + SingleVlanHeader::LEN
3239                 + Ipv6Header::LEN
3240                 + UdpHeader::LEN
3241                 + in_payload.len(),
3242             serialized.len()
3243         );
3244 
3245         //deserialize and check that everything is as expected
3246         use std::io::Cursor;
3247         use std::io::Read;
3248 
3249         //deserialize each part of the message and check it
3250         let mut cursor = Cursor::new(&serialized);
3251 
3252         //ethernet 2 header
3253         assert_eq!(
3254             Ethernet2Header::read(&mut cursor).unwrap(),
3255             Ethernet2Header {
3256                 source: [1, 2, 3, 4, 5, 6],
3257                 destination: [7, 8, 9, 10, 11, 12],
3258                 ether_type: ether_type::VLAN_TAGGED_FRAME
3259             }
3260         );
3261 
3262         //outer vlan header
3263         assert_eq!(
3264             SingleVlanHeader::read(&mut cursor).unwrap(),
3265             SingleVlanHeader {
3266                 pcp: 1.try_into().unwrap(),
3267                 drop_eligible_indicator: true,
3268                 vlan_id: 0x123.try_into().unwrap(),
3269                 ether_type: ether_type::IPV6
3270             }
3271         );
3272 
3273         //ip header
3274         let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
3275         let ip_expected = Ipv6Header {
3276             traffic_class: 1,
3277             flow_label: 2.try_into().unwrap(),
3278             payload_length: (UdpHeader::LEN + in_payload.len()) as u16,
3279             next_header: ip_number::UDP,
3280             hop_limit: 47,
3281             source: [
3282                 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26,
3283             ],
3284             destination: [
3285                 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
3286             ],
3287         };
3288         assert_eq!(ip_actual, ip_expected);
3289 
3290         //udp header
3291         let udp_actual = UdpHeader::read(&mut cursor).unwrap();
3292         let udp_expected =
3293             UdpHeader::with_ipv6_checksum(48, 49, &ip_expected, &in_payload).unwrap();
3294         assert_eq!(udp_actual, udp_expected);
3295 
3296         //payload
3297         let mut actual_payload: [u8; 4] = [0; 4];
3298         cursor.read_exact(&mut actual_payload).unwrap();
3299         assert_eq!(actual_payload, in_payload);
3300     }
3301 
3302     proptest! {
3303         #[test]
3304         fn tcp_ipv4(ref input in tcp_any()) {
3305 
3306             //payload
3307             let in_payload = [24,25,26,27];
3308 
3309             //ip v4 header
3310             let mut ip_expected = Ipv4Header::new(
3311                 in_payload.len() as u16 + input.header_len_u16(),
3312                 21, //ttl
3313                 ip_number::TCP,
3314                 [13,14,15,16],
3315                 [17,18,19,20]
3316             ).unwrap();
3317             ip_expected.header_checksum = ip_expected.calc_header_checksum();
3318 
3319             //generated the expected output
3320             let expected = {
3321                 let mut expected = input.clone();
3322                 //replace urg & ack if the flags are not set
3323                 if !expected.ack {
3324                     expected.acknowledgment_number = 0;
3325                 }
3326                 if !expected.urg {
3327                     expected.urgent_pointer = 0;
3328                 }
3329                 //calculate the checksum
3330                 expected.checksum = expected.calc_checksum_ipv4(&ip_expected, &in_payload[..]).unwrap();
3331                 //done
3332                 expected
3333             };
3334 
3335             //generate
3336             let serialized = {
3337 
3338                 //create builder
3339                 let mut builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3340                                                 .ipv4([13,14,15,16], [17,18,19,20], 21)
3341                                                 .tcp(input.source_port,
3342                                                     input.destination_port,
3343                                                     input.sequence_number,
3344                                                     input.window_size)
3345                                                 .options_raw(input.options.as_slice()).unwrap();
3346                 //set the flags
3347                 if input.ns {
3348                     builder = builder.ns();
3349                 }
3350                 if input.fin {
3351                     builder = builder.fin();
3352                 }
3353                 if input.syn {
3354                     builder = builder.syn();
3355                 }
3356                 if input.rst {
3357                     builder = builder.rst();
3358                 }
3359                 if input.psh {
3360                     builder = builder.psh();
3361                 }
3362                 if input.ack {
3363                     builder = builder.ack(input.acknowledgment_number);
3364                 }
3365                 if input.urg {
3366                     builder = builder.urg(input.urgent_pointer);
3367                 }
3368                 if input.ece {
3369                     builder = builder.ece();
3370                 }
3371                 if input.cwr {
3372                     builder = builder.cwr();
3373                 }
3374 
3375                 let mut serialized = Vec::new();
3376                 builder.write(&mut serialized, &in_payload).unwrap();
3377                 serialized
3378             };
3379 
3380             //deserialize and check that everything is as expected
3381             use std::io::Cursor;
3382             use std::io::Read;
3383             //deserialize each part of the message and check it
3384             let mut cursor = Cursor::new(&serialized);
3385 
3386             //ethernet 2 header
3387             assert_eq!(Ethernet2Header::read(&mut cursor).unwrap(),
3388                     Ethernet2Header{
3389                             source: [1,2,3,4,5,6],
3390                             destination: [7,8,9,10,11,12],
3391                             ether_type: ether_type::IPV4
3392                     });
3393 
3394             //ip header
3395             let ip_actual = Ipv4Header::read(&mut cursor).unwrap();
3396             assert_eq!(ip_actual,
3397                     ip_expected);
3398 
3399             //tcp header
3400             assert_eq!(TcpHeader::read(&mut cursor).unwrap(),
3401                     expected);
3402 
3403             //payload
3404             let mut actual_payload: [u8;4] = [0;4];
3405             cursor.read_exact(&mut actual_payload).unwrap();
3406             assert_eq!(actual_payload, in_payload);
3407         }
3408     }
3409 
3410     proptest! {
3411         #[test]
3412         fn tcp_ipv6(ref input in tcp_any()) {
3413 
3414             //payload
3415             let in_payload = [24,25,26,27];
3416 
3417             //ip v4 header
3418             let ip_expected = Ipv6Header{
3419                 traffic_class: 0,
3420                 flow_label: Ipv6FlowLabel::ZERO,
3421                 payload_length: (input.header_len() as usize + in_payload.len()) as u16,
3422                 next_header: ip_number::TCP,
3423                 hop_limit: 47,
3424                 source: [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
3425                 destination: [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46]
3426             };
3427 
3428             //generated the expected output
3429             let expected = {
3430                 let mut expected = input.clone();
3431                 //replace urg & ack if the flags are not set
3432                 if !expected.ack {
3433                     expected.acknowledgment_number = 0;
3434                 }
3435                 if !expected.urg {
3436                     expected.urgent_pointer = 0;
3437                 }
3438                 //calculate the checksum
3439                 expected.checksum = expected.calc_checksum_ipv6(&ip_expected, &in_payload[..]).unwrap();
3440                 //done
3441                 expected
3442             };
3443 
3444             //generate
3445             let serialized = {
3446 
3447                 //create builder
3448                 let mut builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3449                                                 .ipv6([11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26],
3450                                                     [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],
3451                                                     47,
3452                                                 )
3453                                                 .tcp(input.source_port,
3454                                                     input.destination_port,
3455                                                     input.sequence_number,
3456                                                     input.window_size)
3457                                                 .options_raw(input.options.as_slice()).unwrap();
3458                 //set the flags
3459                 if input.ns {
3460                     builder = builder.ns();
3461                 }
3462                 if input.fin {
3463                     builder = builder.fin();
3464                 }
3465                 if input.syn {
3466                     builder = builder.syn();
3467                 }
3468                 if input.rst {
3469                     builder = builder.rst();
3470                 }
3471                 if input.psh {
3472                     builder = builder.psh();
3473                 }
3474                 if input.ack {
3475                     builder = builder.ack(input.acknowledgment_number);
3476                 }
3477                 if input.urg {
3478                     builder = builder.urg(input.urgent_pointer);
3479                 }
3480                 if input.ece {
3481                     builder = builder.ece();
3482                 }
3483                 if input.cwr {
3484                     builder = builder.cwr();
3485                 }
3486 
3487                 let mut serialized = Vec::new();
3488                 builder.write(&mut serialized, &in_payload).unwrap();
3489                 serialized
3490             };
3491 
3492             //deserialize and check that everything is as expected
3493             use std::io::Cursor;
3494             use std::io::Read;
3495             //deserialize each part of the message and check it
3496             let mut cursor = Cursor::new(&serialized);
3497 
3498             //ethernet 2 header
3499             assert_eq!(Ethernet2Header::read(&mut cursor).unwrap(),
3500                     Ethernet2Header{
3501                             source: [1,2,3,4,5,6],
3502                             destination: [7,8,9,10,11,12],
3503                             ether_type: ether_type::IPV6
3504                     });
3505 
3506             //ip header
3507             let ip_actual = Ipv6Header::read(&mut cursor).unwrap();
3508             assert_eq!(ip_actual,
3509                     ip_expected);
3510 
3511             //tcp header
3512             assert_eq!(TcpHeader::read(&mut cursor).unwrap(),
3513                     expected);
3514 
3515             //payload
3516             let mut actual_payload: [u8;4] = [0;4];
3517             cursor.read_exact(&mut actual_payload).unwrap();
3518             assert_eq!(actual_payload, in_payload);
3519         }
3520     }
3521 
3522     #[test]
eth_ipv4_tcp_options()3523     fn eth_ipv4_tcp_options() {
3524         let mut serialized = Vec::new();
3525 
3526         use crate::TcpOptionElement::*;
3527         let options = vec![MaximumSegmentSize(1234), Noop];
3528 
3529         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3530             .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
3531             .tcp(1, 2, 3, 4)
3532             .options(&options)
3533             .unwrap()
3534             .write(&mut serialized, &[])
3535             .unwrap();
3536 
3537         let decoded = PacketHeaders::from_ethernet_slice(&serialized[..]).unwrap();
3538         let dec_options: Vec<Result<TcpOptionElement, TcpOptionReadError>> = decoded
3539             .transport
3540             .unwrap()
3541             .tcp()
3542             .unwrap()
3543             .options_iterator()
3544             .collect();
3545         assert_eq!(&[Ok(MaximumSegmentSize(1234)), Ok(Noop)], &dec_options[..]);
3546     }
3547 
3548     #[test]
eth_ipv4_tcp_header()3549     fn eth_ipv4_tcp_header() {
3550         let mut serialized = Vec::new();
3551 
3552         let tcp_header = TcpHeader {
3553             source_port: 1234,
3554             destination_port: 2345,
3555             sequence_number: 3456,
3556             acknowledgment_number: 4567,
3557             ..Default::default()
3558         };
3559 
3560         PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3561             .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
3562             .tcp_header(tcp_header.clone())
3563             .write(&mut serialized, &[])
3564             .unwrap();
3565 
3566         let decoded = PacketHeaders::from_ethernet_slice(&serialized[..]).unwrap();
3567 
3568         let mut expected = tcp_header;
3569         expected.checksum = expected
3570             .calc_checksum_ipv4_raw([13, 14, 15, 16], [17, 18, 19, 20], &[])
3571             .unwrap();
3572 
3573         assert_eq!(decoded.transport, Some(TransportHeader::Tcp(expected)));
3574     }
3575 
3576     #[test]
size()3577     fn size() {
3578         //ipv4 no vlan ethernet
3579         assert_eq!(
3580             Ethernet2Header::LEN + Ipv4Header::MIN_LEN + UdpHeader::LEN + 123,
3581             PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3582                 .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
3583                 .udp(22, 23)
3584                 .size(123)
3585         );
3586 
3587         //ipv6 no vlan ethernet
3588         assert_eq!(
3589             Ethernet2Header::LEN + Ipv6Header::LEN + UdpHeader::LEN + 123,
3590             PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3591                 .ipv6(
3592                     [11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26],
3593                     [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46],
3594                     47,
3595                 )
3596                 .udp(22, 23)
3597                 .size(123)
3598         );
3599 
3600         //ipv4 linux_sll
3601         assert_eq!(
3602             LinuxSllHeader::LEN + Ipv4Header::MIN_LEN + UdpHeader::LEN + 123,
3603             PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
3604                 .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
3605                 .udp(22, 23)
3606                 .size(123)
3607         );
3608 
3609         //ipv6 linux_sll
3610         assert_eq!(
3611             LinuxSllHeader::LEN + Ipv6Header::LEN + UdpHeader::LEN + 123,
3612             PacketBuilder::linux_sll(LinuxSllPacketType::OUTGOING, 6, [7, 8, 9, 10, 11, 12, 0, 0])
3613                 .ipv6(
3614                     [11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26],
3615                     [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46],
3616                     47,
3617                 )
3618                 .udp(22, 23)
3619                 .size(123)
3620         );
3621 
3622         //ipv4 single vlan ethernet
3623         assert_eq!(
3624             Ethernet2Header::LEN
3625                 + SingleVlanHeader::LEN
3626                 + Ipv4Header::MIN_LEN
3627                 + UdpHeader::LEN
3628                 + 123,
3629             PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3630                 .single_vlan(0x123.try_into().unwrap())
3631                 .ipv4([13, 14, 15, 16], [17, 18, 19, 20], 21)
3632                 .udp(22, 23)
3633                 .size(123)
3634         );
3635 
3636         //ipv6 double vlan ethernet
3637         assert_eq!(
3638             Ethernet2Header::LEN + DoubleVlanHeader::LEN + Ipv6Header::LEN + UdpHeader::LEN + 123,
3639             PacketBuilder::ethernet2([1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12])
3640                 .double_vlan(0x123.try_into().unwrap(), 0x234.try_into().unwrap())
3641                 .ipv6(
3642                     [11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26],
3643                     [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46],
3644                     47,
3645                 )
3646                 .udp(22, 23)
3647                 .size(123)
3648         );
3649     }
3650 
3651     proptest! {
3652         #[test]
3653         fn size_tcp(ref input in tcp_any()) {
3654 
3655             assert_eq!(Ethernet2Header::LEN +
3656                     Ipv4Header::MIN_LEN +
3657                     input.header_len() as usize +
3658                     123,
3659 
3660                     PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3661                                     .ipv4([13,14,15,16], [17,18,19,20], 21)
3662                                     .tcp(input.source_port,
3663                                         input.destination_port,
3664                                         input.sequence_number,
3665                                         input.window_size)
3666                                     .options_raw(input.options.as_slice()).unwrap()
3667                                     .size(123));
3668         }
3669     }
3670 
3671     proptest! {
3672         #[test]
3673         fn ipv4_icmpv4(
3674             ipv4_source in any::<[u8;4]>(),
3675             ipv4_dest in any::<[u8;4]>(),
3676             ipv4_time_to_live in any::<u8>(),
3677             icmpv4_type_u8 in 15u8..u8::MAX,
3678             icmpv4_code_u8 in any::<u8>(),
3679             icmpv4_bytes5to8 in any::<[u8;4]>(),
3680             icmpv4 in icmpv4_type_any(),
3681             echo_id in any::<u16>(),
3682             echo_seq in any::<u16>(),
3683             payload in proptest::collection::vec(any::<u8>(), 0..64),
3684         ) {
3685             let test_builder = |builder: PacketBuilderStep<Icmpv4Header>, icmpv4_type: Icmpv4Type| {
3686                 use crate::Icmpv4Type::*;
3687                 let adapted_payload = match &icmpv4_type {
3688                     TimestampRequest(_) |
3689                     TimestampReply(_) => &[],
3690                     _ => &payload[..],
3691                 };
3692                 let icmp_expected = Icmpv4Header::with_checksum(icmpv4_type, &adapted_payload);
3693                 let ip_expected = {
3694                     let mut expected_ipv4 = Ipv4Header::new(
3695                         (icmp_expected.header_len() + adapted_payload.len()) as u16,
3696                         ipv4_time_to_live,
3697                         ip_number::ICMP,
3698                         ipv4_source,
3699                         ipv4_dest
3700                     ).unwrap();
3701                     expected_ipv4.header_checksum = expected_ipv4.calc_header_checksum();
3702                     expected_ipv4
3703                 };
3704 
3705                 // test builder.size()
3706                 assert_eq!(
3707                     builder.size(adapted_payload.len()),
3708                     Ethernet2Header::LEN +
3709                     Ipv4Header::MIN_LEN +
3710                     icmp_expected.header_len() +
3711                     adapted_payload.len()
3712                 );
3713 
3714                 // test builder.write()
3715                 let mut buffer = Vec::<u8>::with_capacity(builder.size(adapted_payload.len()));
3716                 builder.write(&mut buffer, adapted_payload).unwrap();
3717 
3718                 // decode packets
3719                 let actual = PacketHeaders::from_ethernet_slice(&buffer).unwrap();
3720 
3721                 // check the packets could be decoded
3722                 assert_eq!(
3723                     Some(LinkHeader::Ethernet2(Ethernet2Header{
3724                         source: [1,2,3,4,5,6],
3725                         destination: [7,8,9,10,11,12],
3726                         ether_type: ether_type::IPV4
3727                     })),
3728                     actual.link
3729                 );
3730                 assert_eq!(
3731                     Some(NetHeaders::Ipv4(ip_expected, Default::default())),
3732                     actual.net
3733                 );
3734                 assert_eq!(
3735                     Some(TransportHeader::Icmpv4(icmp_expected)),
3736                     actual.transport
3737                 );
3738                 assert_eq!(actual.payload.slice(), adapted_payload);
3739             };
3740 
3741             // icmpv4
3742             {
3743                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3744                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3745                     .icmpv4(icmpv4.clone());
3746 
3747                 test_builder(
3748                     builder,
3749                     icmpv4
3750                 );
3751             }
3752 
3753             // icmpv4_raw
3754             {
3755                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3756                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3757                     .icmpv4_raw(icmpv4_type_u8, icmpv4_code_u8, icmpv4_bytes5to8);
3758 
3759                 test_builder(
3760                     builder,
3761                     Icmpv4Type::Unknown{
3762                         type_u8: icmpv4_type_u8,
3763                         code_u8: icmpv4_code_u8,
3764                         bytes5to8: icmpv4_bytes5to8,
3765                     }
3766                 );
3767             }
3768 
3769             // icmpv4_echo_request
3770             {
3771                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3772                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3773                     .icmpv4_echo_request(echo_id, echo_seq);
3774 
3775                 test_builder(
3776                     builder,
3777                     Icmpv4Type::EchoRequest(IcmpEchoHeader{
3778                         id: echo_id,
3779                         seq: echo_seq,
3780                     })
3781                 );
3782             }
3783 
3784             // icmp4_echo_reply
3785             {
3786                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3787                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3788                     .icmpv4_echo_reply(echo_id, echo_seq);
3789 
3790                 test_builder(
3791                     builder,
3792                     Icmpv4Type::EchoReply(IcmpEchoHeader{
3793                         id: echo_id,
3794                         seq: echo_seq,
3795                     })
3796                 );
3797             }
3798         }
3799     }
3800 
3801     proptest! {
3802         #[test]
3803         fn ipv4_icmpv6(
3804             ipv4_source in any::<[u8;4]>(),
3805             ipv4_dest in any::<[u8;4]>(),
3806             ipv4_time_to_live in any::<u8>(),
3807             icmpv6_type_u8 in 162u8..u8::MAX,
3808             icmpv6_code_u8 in any::<u8>(),
3809             icmpv6_bytes5to8 in any::<[u8;4]>(),
3810             icmpv6 in icmpv6_type_any(),
3811             echo_id in any::<u16>(),
3812             echo_seq in any::<u16>(),
3813             payload in proptest::collection::vec(any::<u8>(), 0..64),
3814         ) {
3815             let test_builder = |builder: PacketBuilderStep<Icmpv6Header>, icmpv6_type: Icmpv6Type| {
3816                 // test builder.size()
3817                 assert_eq!(
3818                     builder.size(payload.len()),
3819                     Ethernet2Header::LEN +
3820                     Ipv4Header::MIN_LEN +
3821                     icmpv6_type.header_len() +
3822                     payload.len()
3823                 );
3824 
3825                 // test builder.write()
3826                 let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
3827                 // should trigger an error, was it is not possible to calculate the checksum
3828                 assert!(builder.write(&mut buffer, &payload).is_err());
3829             };
3830 
3831             // icmpv6
3832             {
3833                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3834                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3835                     .icmpv6(icmpv6.clone());
3836 
3837                 test_builder(
3838                     builder,
3839                     icmpv6
3840                 );
3841             }
3842 
3843             // icmpv6_raw
3844             {
3845                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3846                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3847                     .icmpv6_raw(icmpv6_type_u8, icmpv6_code_u8, icmpv6_bytes5to8);
3848 
3849                 test_builder(
3850                     builder,
3851                     Icmpv6Type::Unknown{
3852                         type_u8: icmpv6_type_u8,
3853                         code_u8: icmpv6_code_u8,
3854                         bytes5to8: icmpv6_bytes5to8,
3855                     }
3856                 );
3857             }
3858 
3859             // icmpv6_echo_request
3860             {
3861                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3862                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3863                     .icmpv6_echo_request(echo_id, echo_seq);
3864 
3865                 test_builder(
3866                     builder,
3867                     Icmpv6Type::EchoRequest(IcmpEchoHeader{
3868                         id: echo_id,
3869                         seq: echo_seq,
3870                     })
3871                 );
3872             }
3873 
3874             // icmp4_echo_reply
3875             {
3876                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3877                     .ipv4(ipv4_source, ipv4_dest, ipv4_time_to_live)
3878                     .icmpv6_echo_reply(echo_id, echo_seq);
3879 
3880                 test_builder(
3881                     builder,
3882                     Icmpv6Type::EchoReply(IcmpEchoHeader{
3883                         id: echo_id,
3884                         seq: echo_seq,
3885                     })
3886                 );
3887             }
3888         }
3889     }
3890 
3891     proptest! {
3892         #[test]
3893         fn ipv6_icmpv4(
3894             ipv6_source in any::<[u8;16]>(),
3895             ipv6_dest in any::<[u8;16]>(),
3896             ipv6_hop_limit in any::<u8>(),
3897             icmpv4_type_u8 in 15u8..u8::MAX,
3898             icmpv4_code_u8 in any::<u8>(),
3899             icmpv4_bytes5to8 in any::<[u8;4]>(),
3900             icmpv4 in icmpv4_type_any(),
3901             echo_id in any::<u16>(),
3902             echo_seq in any::<u16>(),
3903             payload in proptest::collection::vec(any::<u8>(), 0..64),
3904         ) {
3905             let test_builder = |builder: PacketBuilderStep<Icmpv4Header>, icmpv4_type: Icmpv4Type| {
3906 
3907                 use Icmpv4Type::*;
3908                 let adapted_payload = match icmpv4_type {
3909                     TimestampRequest(_) | TimestampReply(_) => &[],
3910                     _ => &payload[..],
3911                 };
3912 
3913                 let icmp_expected = Icmpv4Header::with_checksum(icmpv4_type, &adapted_payload);
3914                 let ip_expected = Ipv6Header{
3915                     traffic_class: 0,
3916                     flow_label: Ipv6FlowLabel::ZERO,
3917                     payload_length: (icmp_expected.header_len() + adapted_payload.len()) as u16,
3918                     next_header: ip_number::ICMP,
3919                     hop_limit: ipv6_hop_limit,
3920                     source: ipv6_source,
3921                     destination: ipv6_dest
3922                 };
3923 
3924                 // test builder.size()
3925                 assert_eq!(
3926                     builder.size(adapted_payload.len()),
3927                     Ethernet2Header::LEN +
3928                     Ipv6Header::LEN +
3929                     icmp_expected.header_len() +
3930                     adapted_payload.len()
3931                 );
3932 
3933                 // test builder.write()
3934                 let mut buffer = Vec::<u8>::with_capacity(builder.size(adapted_payload.len()));
3935                 builder.write(&mut buffer, adapted_payload).unwrap();
3936 
3937                 // decode packets
3938                 let actual = PacketHeaders::from_ethernet_slice(&buffer).unwrap();
3939 
3940                 // check the packets could be decoded
3941                 assert_eq!(
3942                     Some(LinkHeader::Ethernet2(Ethernet2Header{
3943                         source: [1,2,3,4,5,6],
3944                         destination: [7,8,9,10,11,12],
3945                         ether_type: ether_type::IPV6
3946                     })),
3947                     actual.link
3948                 );
3949                 assert_eq!(
3950                     Some(NetHeaders::Ipv6(ip_expected, Default::default())),
3951                     actual.net
3952                 );
3953                 assert_eq!(
3954                     Some(TransportHeader::Icmpv4(icmp_expected)),
3955                     actual.transport
3956                 );
3957                 assert_eq!(actual.payload.slice(), adapted_payload);
3958             };
3959 
3960             // icmpv4
3961             {
3962                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3963                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
3964                     .icmpv4(icmpv4.clone());
3965 
3966                 test_builder(
3967                     builder,
3968                     icmpv4
3969                 );
3970             }
3971 
3972             // icmpv4_raw
3973             {
3974                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3975                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
3976                     .icmpv4_raw(icmpv4_type_u8, icmpv4_code_u8, icmpv4_bytes5to8);
3977 
3978                 test_builder(
3979                     builder,
3980                     Icmpv4Type::Unknown{
3981                         type_u8: icmpv4_type_u8,
3982                         code_u8: icmpv4_code_u8,
3983                         bytes5to8: icmpv4_bytes5to8,
3984                     }
3985                 );
3986             }
3987 
3988             // icmpv4_echo_request
3989             {
3990                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
3991                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
3992                     .icmpv4_echo_request(echo_id, echo_seq);
3993 
3994                 test_builder(
3995                     builder,
3996                     Icmpv4Type::EchoRequest(IcmpEchoHeader{
3997                         id: echo_id,
3998                         seq: echo_seq,
3999                     })
4000                 );
4001             }
4002 
4003             // icmp4_echo_reply
4004             {
4005                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
4006                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
4007                     .icmpv4_echo_reply(echo_id, echo_seq);
4008 
4009                 test_builder(
4010                     builder,
4011                     Icmpv4Type::EchoReply(IcmpEchoHeader{
4012                         id: echo_id,
4013                         seq: echo_seq,
4014                     })
4015                 );
4016             }
4017         }
4018     }
4019 
4020     proptest! {
4021         #[test]
4022         fn ipv6_icmpv6(
4023             ipv6_source in any::<[u8;16]>(),
4024             ipv6_dest in any::<[u8;16]>(),
4025             ipv6_hop_limit in any::<u8>(),
4026             icmpv6_type_u8 in 162u8..u8::MAX,
4027             icmpv6_code_u8 in any::<u8>(),
4028             icmpv6_bytes5to8 in any::<[u8;4]>(),
4029             icmpv6 in icmpv6_type_any(),
4030             echo_id in any::<u16>(),
4031             echo_seq in any::<u16>(),
4032             payload in proptest::collection::vec(any::<u8>(), 0..64),
4033         ) {
4034             let test_builder = |builder: PacketBuilderStep<Icmpv6Header>, icmpv6_type: Icmpv6Type| {
4035                 let icmp_expected = Icmpv6Header::with_checksum(
4036                     icmpv6_type,
4037                     ipv6_source,
4038                     ipv6_dest,
4039                     &payload
4040                 ).unwrap();
4041                 let ip_expected = Ipv6Header{
4042                     traffic_class: 0,
4043                     flow_label: Ipv6FlowLabel::ZERO,
4044                     payload_length: (icmp_expected.header_len() + payload.len()) as u16,
4045                     next_header: ip_number::IPV6_ICMP,
4046                     hop_limit: ipv6_hop_limit,
4047                     source: ipv6_source,
4048                     destination: ipv6_dest
4049                 };
4050 
4051                 // test builder.size()
4052                 assert_eq!(
4053                     builder.size(payload.len()),
4054                     Ethernet2Header::LEN +
4055                     Ipv6Header::LEN +
4056                     icmp_expected.header_len() +
4057                     payload.len()
4058                 );
4059 
4060                 // test builder.write()
4061                 let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
4062                 builder.write(&mut buffer, &payload).unwrap();
4063 
4064                 // decode packets
4065                 let actual = PacketHeaders::from_ethernet_slice(&buffer).unwrap();
4066 
4067                 // check the packets could be decoded
4068                 assert_eq!(
4069                     Some(LinkHeader::Ethernet2(Ethernet2Header{
4070                         source: [1,2,3,4,5,6],
4071                         destination: [7,8,9,10,11,12],
4072                         ether_type: ether_type::IPV6
4073                     })),
4074                     actual.link
4075                 );
4076                 assert_eq!(
4077                     Some(NetHeaders::Ipv6(ip_expected, Default::default())),
4078                     actual.net
4079                 );
4080                 assert_eq!(
4081                     Some(TransportHeader::Icmpv6(icmp_expected)),
4082                     actual.transport
4083                 );
4084                 assert_eq!(actual.payload.slice(), &payload);
4085             };
4086 
4087             // icmpv6
4088             {
4089                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
4090                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
4091                     .icmpv6(icmpv6.clone());
4092 
4093                 test_builder(
4094                     builder,
4095                     icmpv6
4096                 );
4097             }
4098 
4099             // icmpv6_raw
4100             {
4101                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
4102                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
4103                     .icmpv6_raw(icmpv6_type_u8, icmpv6_code_u8, icmpv6_bytes5to8);
4104 
4105                 test_builder(
4106                     builder,
4107                     Icmpv6Type::Unknown{
4108                         type_u8: icmpv6_type_u8,
4109                         code_u8: icmpv6_code_u8,
4110                         bytes5to8: icmpv6_bytes5to8,
4111                     }
4112                 );
4113             }
4114 
4115             // icmpv6_echo_request
4116             {
4117                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
4118                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
4119                     .icmpv6_echo_request(echo_id, echo_seq);
4120 
4121                 test_builder(
4122                     builder,
4123                     Icmpv6Type::EchoRequest(IcmpEchoHeader{
4124                         id: echo_id,
4125                         seq: echo_seq,
4126                     })
4127                 );
4128             }
4129 
4130             // icmp4_echo_reply
4131             {
4132                 let builder = PacketBuilder::ethernet2([1,2,3,4,5,6],[7,8,9,10,11,12])
4133                     .ipv6(ipv6_source, ipv6_dest, ipv6_hop_limit)
4134                     .icmpv6_echo_reply(echo_id, echo_seq);
4135 
4136                 test_builder(
4137                     builder,
4138                     Icmpv6Type::EchoReply(IcmpEchoHeader{
4139                         id: echo_id,
4140                         seq: echo_seq,
4141                     })
4142                 );
4143             }
4144         }
4145     }
4146 }
4147