1 use etherparse::*;
2 use std::io::Write;
3 
main()4 fn main() {
5     let with_udp_checksum = true;
6 
7     //Any struct implementing the "Write" trait can be used to write to (e.g. File).
8     //For this example lets use a simple Vec as it implements the write trait.
9     let mut out = Vec::<u8>::with_capacity(
10         //lets reserve enough memory to avoid unnecessary allocations
11         Ethernet2Header::LEN + Ipv4Header::MAX_LEN + UdpHeader::LEN + 8, //payload
12     );
13 
14     //setup the actual payload of the udp packet
15     let udp_payload = [1, 2, 3, 4, 5, 6, 7, 8];
16 
17     //Lets start out with an ethernet II header containing the mac addresses
18     Ethernet2Header {
19         destination: [1, 2, 3, 4, 5, 6],
20         source: [11, 12, 13, 14, 15, 16],
21         ether_type: ether_type::IPV4,
22     }
23     .write(&mut out)
24     .unwrap();
25 
26     //create the ipv4 header with the helper function
27     //Note: It is also possible to define the rest of the header values via Ipv4Header {...}
28     let ip_header = Ipv4Header::new(
29         //payload length
30         (UdpHeader::LEN + udp_payload.len()) as u16,
31         20,                //time to live
32         ip_number::UDP,    //contained protocol is udp
33         [192, 168, 1, 42], //source ip address
34         [192, 168, 1, 1],  //destination ip address
35     )
36     .unwrap();
37 
38     //write the ipv4 header
39     //
40     //The "write" call automatically calculates the ipv4 checksum.
41     //Alternatively "write_raw" can be used to skip the checksum
42     //calculation and just write out the checksum set in the header.
43     ip_header.write(&mut out).unwrap();
44 
45     //write the udp header
46     //
47     //There is the option to write it with a checksum or without.
48     //If yes, the ipv4 header & payload are needed to calculate the header
49     if with_udp_checksum {
50         UdpHeader::with_ipv4_checksum(
51             0,            //source port
52             42,           //destination port
53             &ip_header,   //ip header
54             &udp_payload, //udp payload
55         )
56         .unwrap()
57         .write(&mut out)
58         .unwrap();
59     } else {
60         //write the header with the checksum disabled
61         UdpHeader::without_ipv4_checksum(
62             0,                 //source port
63             42,                //destination port
64             udp_payload.len(), //payload length
65         )
66         .unwrap()
67         .write(&mut out)
68         .unwrap();
69     }
70 
71     out.write_all(&udp_payload).unwrap();
72 
73     println!("{:?}", &out);
74 }
75