### Constructing an IPv6 Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Demonstrates building a packet starting with an IPv6 header. ```rust let builder = PacketBuilder:: ipv6( //source [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26], //destination [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46], //hop_limit 47) .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Constructing an IPv4 Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Demonstrates building a packet starting with an IPv4 header. ```rust let builder = PacketBuilder:: ipv4([192,168,1,1], //source ip [192,168,1,2], //destination ip 20) //time to life .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Constructing a Linux SLL Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Demonstrates building a packet starting with a Linux SLL header. ```rust let builder = PacketBuilder:: linux_sll(LinuxSllPacketType::OTHERHOST, //packet type 6, //sender address valid length [1,2,3,4,5,6,0,0]) //sender address with padding .ipv4([192,168,1,1], //source ip [192,168,1,2], //destination ip 20) //time to life .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### IpFragOffset Usage Examples Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.IpFragOffset.html Demonstrates various ways to instantiate and convert IpFragOffset, including safe and unsafe methods. ```rust use etherparse::IpFragOffset; // try into { let frag_offset: IpFragOffset = 123.try_into().unwrap(); assert_eq!(frag_offset.value(), 123); // fragment offset can always be converted back to an u16 let value: u16 = frag_offset.into(); assert_eq!(123, value); } // via try_new { let frag_offset = IpFragOffset::try_new(123).unwrap(); assert_eq!(frag_offset.value(), 123); // note that only 13 bit numbers are allowed (meaning // 0b0001_1111_1111_1111 is the maximum allowed value) use etherparse::err::{ValueTooBigError, ValueType}; assert_eq!( IpFragOffset::try_new(IpFragOffset::MAX_U16 + 1), Err(ValueTooBigError{ actual: IpFragOffset::MAX_U16 + 1, max_allowed: IpFragOffset::MAX_U16, value_type: ValueType::IpFragmentOffset, }) ); } // via new_unchecked { // in case you are sure the number does not exceed the max // you can use the unsafe new_unchecked function let frag_offset = unsafe { // please make sure that the value is not greater than IpFragOffset::MAX_U16 // before calling this method IpFragOffset::new_unchecked(123) }; assert_eq!(frag_offset.value(), 123); } ``` -------------------------------- ### Construct a packet with PacketBuilder Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Example demonstrating the construction of an Ethernet II packet with IPv4 and UDP headers. ```rust use etherparse::PacketBuilder; let builder = PacketBuilder:: ethernet2([1,2,3,4,5,6], //source mac [7,8,9,10,11,12]) //destination mac .ipv4([192,168,1,1], //source ip [192,168,1,2], //destination ip 20) //time to life .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); println!("{:?}", result); ``` ```rust let builder = PacketBuilder:: ethernet2([1,2,3,4,5,6], //source mac [7,8,9,10,11,12]) //destination mac .ipv4([192,168,1,1], //source ip [192,168,1,2], //destination ip 20) //time to life .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Example LenError for Insufficient UDP Header Data Source: https://docs.rs/etherparse/0.19.0/etherparse/err/struct.LenError.html Illustrates a LenError scenario where there isn't enough data to decode a UDP header. This example shows how to construct a LenError to represent this specific situation, including the expected length, the actual available length, and the source of the length information. ```rust use etherparse::* err::LenError{ // Expected to have at least the length of an UDP header present: required_len: UdpHeader::LEN, // Could not decode the UDP header: layer: err::Layer::UdpHeader, // There was only 1 byte left (not enough for an UDP header): len: 1, // The provided length was determined by the total length field in the // IPv4 header: len_source: LenSource::Ipv4HeaderTotalLen, // Offset in bytes from the start of decoding (ethernet in this) case // to the expected UDP header start: layer_start_offset: Ethernet2Header::LEN + Ipv4Header::MIN_LEN }; ``` -------------------------------- ### Calculate TCP Data Offset Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpHeader.html Example demonstrating how to calculate the data offset for a TCP header with and without options. ```rust use etherparse::{TcpHeader, TcpOptions}; { let header = TcpHeader{ options: TcpOptions::try_from_slice(&[]).unwrap(), .. Default::default() }; // in case there are no options the minimum size of the tcp // is returned. assert_eq!(5, header.data_offset()); } { let header = TcpHeader{ options: TcpOptions::try_from_slice(&[1,2,3,4,5,6,7,8]).unwrap(), .. Default::default() }; // otherwise the base TCP header size plus the number of 4 byte // words in the options is returned assert_eq!(5 + 2, header.data_offset()); } ``` -------------------------------- ### Parse Ethernet packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.SlicedPacket.html Example usage of SlicedPacket::from_ethernet to parse a packet starting with an Ethernet II header. ```rust match SlicedPacket::from_ethernet(&packet) { Err(value) => println!("Err {:?}", value), Ok(value) => { println!("link: {:?}", value.link); println!("link_exts: {:?}", value.link_exts); // vlan & macsec println!("net: {:?}", value.net); // ip & arp println!("transport: {:?}", value.transport); } }; ``` -------------------------------- ### Parse Linux SLL packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.SlicedPacket.html Example usage of SlicedPacket::from_linux_sll to parse a packet starting with a Linux Cooked Capture v1 header. ```rust match SlicedPacket::from_linux_sll(&packet) { Err(value) => println!("Err {:?}", value), Ok(value) => { println!("link: {:?}", value.link); println!("link_exts: {:?}", value.link_exts); // vlan & macsec println!("net: {:?}", value.net); // ip & arp println!("transport: {:?}", value.transport); } }; ``` -------------------------------- ### Example: PacketHeaders::from_ether_type Usage Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketHeaders.html Demonstrates basic usage of `PacketHeaders::from_ether_type` to parse a packet. Shows how to access different header layers after successful parsing. ```rust use etherparse::{ether_type, PacketHeaders}; match PacketHeaders::from_ether_type(ether_type::IPV4, packet) { Err(value) => println!("Err {:?}", value), Ok(value) => { println!("link: {:?}", value.link); println!("link_exts: {:?}", value.link_exts); // vlan & macsec println!("net: {:?}", value.net); // ip & arp println!("transport: {:?}", value.transport); } } ``` -------------------------------- ### Reverse Split Mutable Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Shows how to use `rsplit_mut` to get mutable subslices separated by elements matching a predicate. The example modifies the first element of each subslice. ```rust let mut v = [100, 400, 300, 200, 600, 500]; let mut count = 0; for group in v.rsplit_mut(|num| *num % 3 == 0) { count += 1; group[0] = count; } assert_eq!(v, [3, 400, 300, 2, 600, 1]); ``` -------------------------------- ### Example Usage of Ipv4Header Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Header.html Demonstrates how to create, serialize, and deserialize an Ipv4Header. It shows initializing a header with specific fields, calculating the header checksum, converting it to bytes, and then decoding it back from a byte slice. ```rust use etherparse::{Ipv4Header, IpNumber}; let mut header = Ipv4Header { source: [1,2,3,4], destination: [1,2,3,4], time_to_live: 4, total_len: Ipv4Header::MIN_LEN as u16 + 100, protocol: IpNumber::UDP, ..Default::default() }; // depending on your use case you might want to set the correct checksum header.header_checksum = header.calc_header_checksum(); // header can be serialized into the "on the wire" format // using the "write" or "to_bytes" methods let bytes = header.to_bytes(); // IPv4 headers can be decoded via "read" or "from_slice" let (decoded, slice_rest) = Ipv4Header::from_slice(&bytes).unwrap(); assert_eq!(header, decoded); assert_eq!(slice_rest, &[]); ``` -------------------------------- ### Slice Starts With Method Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Checks if a slice starts with a given prefix slice. ```APIDOC ## GET /slice/starts_with ### Description Returns `true` if `needle` is a prefix of the slice or equal to the slice. Always returns `true` if `needle` is an empty slice. ### Method GET ### Endpoint `/slice/starts_with` ### Parameters #### Query Parameters - **needle** (array) - Required - The slice to check as a prefix. ### Request Example ```json { "slice": [10, 40, 30], "needle": [10, 40] } ``` ### Response #### Success Response (200) - **result** (boolean) - `true` if the slice starts with the needle, `false` otherwise. #### Response Example ```json { "result": true } ``` ``` -------------------------------- ### Example: PacketHeaders::from_ip_slice Usage Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketHeaders.html Illustrates basic usage of `PacketHeaders::from_ip_slice` for parsing IP packets. Shows how to access parsed header information. ```rust use etherparse::PacketHeaders; match PacketHeaders::from_ip_slice(&packet) { Err(value) => println!("Err {:?}", value), Ok(value) => { println!("link: {:?}", value.link); println!("link_exts: {:?}", value.link_exts); // vlan & macsec println!("net: {:?}", value.net); // ip & arp println!("transport: {:?}", value.transport); } } ``` -------------------------------- ### GET /slice/as_array Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Attempts to get a reference to the underlying array of a specific size. ```APIDOC ## GET /slice/as_array ### Description Gets a reference to the underlying array. If the requested size N is not exactly equal to the length of the slice, it returns None. ### Parameters #### Query Parameters - **N** (usize) - Required - The expected length of the array. ### Response #### Success Response (200) - **array** (Option<&[T; N]>) - The reference to the array if lengths match, otherwise None. ``` -------------------------------- ### Constructing Packets with Arbitrary IP Headers Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Demonstrates using the ip method to start a packet with a pre-configured IPv4 or IPv6 header. ```rust let builder = PacketBuilder:: //payload_len, protocol & checksum will be replaced during write ip(IpHeaders::Ipv4( Ipv4Header::new( 0, //payload_len will be replaced during write 12, //time_to_live ip_number::UDP, //will be replaced during write [0,1,2,3], //source [4,5,6,7] //destination ).unwrap(), Default::default())) .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` ```rust let builder = PacketBuilder:: ip(IpHeaders::Ipv6( Ipv6Header{ traffic_class: 0, flow_label: 0.try_into().unwrap(), hop_limit: 4.try_into().unwrap(), source: [0;16], destination: [0;16], // payload_length & next_header will be replaced during write ..Default::default() }, Default::default())) .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Set Starting Position for a Layer Source: https://docs.rs/etherparse/0.19.0/etherparse/io/struct.LimitedReader.html Updates the current position to be the starting position for a specified layer. ```rust pub fn start_layer(&mut self, layer: Layer) ``` -------------------------------- ### Get Type ID Source: https://docs.rs/etherparse/0.19.0/etherparse/enum.LaxNetSlice.html Gets the `TypeId` of the current type. This is a blanket implementation for any type `T` that is `'static` and `?Sized`. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Constructing Ipv4Header with New Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Header.html Shows how to construct an Ipv4Header using the `new` function, which initializes standard fields with default values. It also demonstrates how to calculate the header checksum after construction. ```rust use etherparse::{Ipv4Header, IpNumber}; let mut header = Ipv4Header::new(100, 4, IpNumber::UDP, [1,2,3,4], [5,6,7,8]).unwrap(); assert_eq!( header, Ipv4Header { total_len: (100 + Ipv4Header::MIN_LEN) as u16, time_to_live: 4, protocol: IpNumber::UDP, source: [1,2,3,4], destination: [5,6,7,8], ..Default::default() } ); // for the rest of the fields the following default values will be used: assert_eq!(0, header.dscp.value()); assert_eq!(0, header.ecn.value()); assert_eq!(0, header.identification); assert_eq!(true, header.dont_fragment); assert_eq!(false, header.more_fragments); assert_eq!(0, header.fragment_offset.value()); assert_eq!(0, header.header_checksum); // in case you also want to have a correct checksum you will have to // additionally update it: header.header_checksum = header.calc_header_checksum(); ``` -------------------------------- ### Get Protocol String for IpNumber Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.IpNumber.html Use `protocol_str` to get the full name for a known IP protocol number. Unassigned numbers return None. ```rust use etherparse::IpNumber; assert_eq!(IpNumber::UDP.protocol_str(), Some("User Datagram")); // Unassigned values return None assert_eq!(IpNumber(145).protocol_str(), None); ``` -------------------------------- ### Get Keyword String for IpNumber Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.IpNumber.html Use `keyword_str` to get the common abbreviation for a known IP protocol number. Unassigned numbers return None. ```rust use etherparse::IpNumber; assert_eq!(IpNumber::UDP.keyword_str(), Some("UDP")); // Unassigned values return None assert_eq!(IpNumber(145).keyword_str(), None); ``` -------------------------------- ### Remove and Get Last Element of Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `split_off_last` to remove the last element from an immutable slice and get a reference to it. Returns `None` if the slice is empty. ```rust let mut slice: &[_] = &['a', 'b', 'c']; let last = slice.split_off_last().unwrap(); assert_eq!(slice, &['a', 'b']); assert_eq!(last, &'c'); ``` -------------------------------- ### Remove and Get First Element of Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `split_off_first` to remove the first element from an immutable slice and get a reference to it. Returns `None` if the slice is empty. ```rust let mut slice: &[_] = &['a', 'b', 'c']; let first = slice.split_off_first().unwrap(); assert_eq!(slice, &['b', 'c']); assert_eq!(first, &'a'); ``` -------------------------------- ### TryFrom Implementation for IpFragOffset Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.IpFragOffset.html Conversion from u16 to IpFragOffset. ```APIDOC ## TryFrom for IpFragOffset ### `type Error = ValueTooBigError` The error type returned when conversion fails because the value is too large. ### `try_from(value: u16) -> Result` Attempts to convert a `u16` value into an `IpFragOffset`. Returns an error if the value is too large. ``` -------------------------------- ### Create and Use Ipv6FlowLabel Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv6FlowLabel.html Demonstrates creating an Ipv6FlowLabel using try_into and try_new, and converting it back to a u32. Also shows error handling for values exceeding the 20-bit limit. ```rust use etherparse::Ipv6FlowLabel; // try into { let flow_label: Ipv6FlowLabel = 123.try_into().unwrap(); assert_eq!(flow_label.value(), 123); // fragment offset can always be converted back to an u32 let value: u32 = flow_label.into(); assert_eq!(123, value); } // via try_new { let flow_label = Ipv6FlowLabel::try_new(123).unwrap(); assert_eq!(flow_label.value(), 123); // note that only 20 bit numbers are allowed ( // meaning // 0b1111_11111111_11111111 is the maximum allowed value) use etherparse::err::{ValueTooBigError, ValueType}; assert_eq!( Ipv6FlowLabel::try_new(Ipv6FlowLabel::MAX_U32 + 1), Err(ValueTooBigError{ actual: Ipv6FlowLabel::MAX_U32 + 1, max_allowed: Ipv6FlowLabel::MAX_U32, value_type: ValueType::Ipv6FlowLabel, }) ); } // via new_unchecked { // in case you are sure the number does not exceed the max // you can use the unsafe new_unchecked function let flow_label = unsafe { // please make sure that the value is not greater than Ipv6FlowLabel::MAX_U32 // before calling this method Ipv6FlowLabel::new_unchecked(123) }; assert_eq!(flow_label.value(), 123); } ``` -------------------------------- ### Remove and Get Last Mutable Element of Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `split_off_last_mut` to remove the last element from a mutable slice and get a mutable reference to it. Returns `None` if the slice is empty. ```rust let mut slice: &mut [_] = &mut ['a', 'b', 'c']; let last = slice.split_off_last_mut().unwrap(); *last = 'd'; assert_eq!(slice, &['a', 'b']); assert_eq!(last, &'d'); ``` -------------------------------- ### Remove and Get First Mutable Element of Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `split_off_first_mut` to remove the first element from a mutable slice and get a mutable reference to it. Returns `None` if the slice is empty. ```rust let mut slice: &mut [_] = &mut ['a', 'b', 'c']; let first = slice.split_off_first_mut().unwrap(); *first = 'd'; assert_eq!(slice, &['b', 'c']); assert_eq!(first, &'d'); ``` -------------------------------- ### Constructing an ARP Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilderStep.html Demonstrates building an ARP request packet. ```rust use etherparse::*; let builder = PacketBuilder:: ethernet2([1,2,3,4,5,6], // source mac [7,8,9,10,11,12]) // destination mac .arp(ArpPacket::new( ArpHardwareId::ETHERNET, EtherType::IPV4, ArpOperation::REQUEST, &[1,2,3,4,5,6], // sender_hw_addr &[7,6,8,9], // sender_protocol_addr &[10,11,12,14,15,16], // target_hw_addr &[17,18,19,20] // target_protocol_addr ).unwrap()); // get some memory to store the result let mut result = Vec::::with_capacity(builder.size()); // serialize builder.write(&mut result).unwrap(); ``` -------------------------------- ### Get Mutable Last N Elements of a Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `last_chunk_mut` to get a mutable array reference to the last `N` items in the slice. Returns `None` if the slice is shorter than `N`. ```rust let x = &mut [0, 1, 2]; if let Some(last) = x.last_chunk_mut::<2>() { last[0] = 10; last[1] = 20; } assert_eq!(x, &[0, 10, 20]); assert_eq!(None, x.last_chunk_mut::<4>()); ``` -------------------------------- ### CloneToUninit Implementation Source: https://docs.rs/etherparse/0.19.0/etherparse/icmpv6/enum.DestUnreachableCode.html Provides the `clone_to_uninit` method for nightly-only experimental cloning to uninitialized memory. ```APIDOC ## impl CloneToUninit for T where T: Clone, ### unsafe fn clone_to_uninit(&self, dest: *mut u8) Performs copy-assignment from `self` to `dest`. ``` -------------------------------- ### Using EtherType Constants Source: https://docs.rs/etherparse/0.19.0/etherparse/ether_type/index.html Demonstrates how to import and use ethertype constants, access their u16 values, and perform conversions. Ensure the etherparse crate is added as a dependency. ```rust use etherparse::{ether_type::IPV4, EtherType}; assert_eq!(IPV4.0, 0x0800); assert_eq!(IPV4, EtherType(0x0800)); let num: EtherType = 0x0800.into(); assert_eq!(IPV4, num); ``` -------------------------------- ### GET /slice/iter Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Returns an iterator over the slice. ```APIDOC ## GET /slice/iter ### Description Returns an iterator that yields all items from the start to the end of the slice. ### Method GET ### Response - **iterator** (Iter<'_, T>) - An iterator over the slice elements. ``` -------------------------------- ### Unsafe Get Disjoint Mutable Elements by Index Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Use `get_disjoint_unchecked_mut` to get mutable references to multiple elements or slices by their indices without bounds or overlap checks. This is unsafe and requires careful handling to avoid undefined behavior. ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([0, 2]); *a *= 10; *b *= 100; } assert_eq!(x, &[10, 2, 400]); ``` ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([0..1, 1..3]); a[0] = 8; b[0] = 88; b[1] = 888; } assert_eq!(x, &[8, 88, 888]); ``` ```rust let x = &mut [1, 2, 4]; unsafe { let [a, b] = x.get_disjoint_unchecked_mut([1..=2, 0..=0]); a[0] = 11; a[1] = 111; b[0] = 1; } assert_eq!(x, &[1, 11, 111]); ``` -------------------------------- ### Constructing an IPv6 Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilderStep.html Demonstrates building an IPv6 packet with a UDP payload. ```rust let builder = PacketBuilder:: linux_sll(LinuxSllPacketType::OTHERHOST, //packet type 6, //sender address valid length [1,2,3,4,5,6,0,0]) //sender address with padding .ipv6( //source [11,12,13,14,15,16,17,18,19,10,21,22,23,24,25,26], //destination [31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46], //hop_limit 47) .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Check for Prefix Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Checks if a slice starts with a given sequence of elements. ```APIDOC ## starts_with ### Description Returns `true` if `needle` is a prefix of the slice or equal to the slice. ### Method `starts_with` ### Parameters - **needle** (&[T]) - Required - The slice to check as a prefix. ### Request Example ```rust let v = [10, 40, 30]; assert!(v.starts_with(&[10])); assert!(v.starts_with(&[10, 40])); assert!(v.starts_with(&v)); assert!(!v.starts_with(&[50])); assert!(!v.starts_with(&[10, 50])); ``` ### Response - **bool** - `true` if the slice starts with the `needle`, `false` otherwise. ``` -------------------------------- ### PacketBuilder with Linux SLL, IPv4, and UDP Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Demonstrates building a packet starting with a Linux SLL header, followed by an IPv4 header and a UDP header, including a payload. ```APIDOC ## POST /packetbuilder/linux_sll/ipv4/udp ### Description Constructs a network packet starting with a Linux SLL header, then an IPv4 header, and finally a UDP header. This method is useful for creating packets that need to be compatible with systems that use the Linux SLL encapsulation. ### Method POST ### Endpoint /packetbuilder/linux_sll/ipv4/udp ### Parameters #### Request Body - **packet_type** (LinuxSllPacketType) - Required - The type of the Linux SLL packet. - **sender_address_len** (usize) - Required - The length of the sender's hardware address. - **sender_address** ([u8; 6]) - Required - The sender's hardware address. - **source_ip** ([u8; 4]) - Required - The source IPv4 address. - **destination_ip** ([u8; 4]) - Required - The destination IPv4 address. - **time_to_live** (u8) - Required - The IPv4 time-to-live value. - **source_port** (u16) - Required - The UDP source port. - **destination_port** (u16) - Required - The UDP destination port. - **payload** (Vec) - Required - The data payload for the UDP packet. ### Request Example ```json { "packet_type": "OTHERHOST", "sender_address_len": 6, "sender_address": [1,2,3,4,5,6], "source_ip": [192,168,1,1], "destination_ip": [192,168,1,2], "time_to_live": 20, "source_port": 21, "destination_port": 1234, "payload": [1,2,3,4,5,6,7,8] } ``` ### Response #### Success Response (200) - **packet_data** (Vec) - The serialized network packet. #### Response Example ```json { "packet_data": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] } ``` ``` -------------------------------- ### Check slice prefix Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Verifies if a slice starts with a specific sequence. ```rust let v = [10, 40, 30]; assert!(v.starts_with(&[10])); assert!(v.starts_with(&[10, 40])); assert!(v.starts_with(&v)); assert!(!v.starts_with(&[50])); assert!(!v.starts_with(&[10, 50])); ``` ```rust let v = &[10, 40, 30]; assert!(v.starts_with(&[])); let v: &[u8] = &[]; assert!(v.starts_with(&[])); ``` -------------------------------- ### Validate and create VlanPcp Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.VlanPcp.html Demonstrates creating a VlanPcp instance with validation and handling potential errors for out-of-bounds values. ```rust use etherparse::VlanPcp; let pcp = VlanPcp::try_new(2).unwrap(); assert_eq!(pcp.value(), 2); // if a number that can not be represented in an 3 bit integer // gets passed in an error is returned use etherparse::err::{ValueTooBigError, ValueType}; assert_eq!( VlanPcp::try_new(VlanPcp::MAX_U8 + 1), Err(ValueTooBigError{ actual: VlanPcp::MAX_U8 + 1, max_allowed: VlanPcp::MAX_U8, value_type: ValueType::VlanPcp, }) ); ``` -------------------------------- ### GET /slice/chunks Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Returns an iterator over non-overlapping chunks of a specified size. ```APIDOC ## GET /slice/chunks ### Description Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning. The chunks do not overlap. ### Parameters #### Query Parameters - **chunk_size** (usize) - Required - The size of each chunk. ### Response - **iterator** (Chunks<'_, T>) - An iterator yielding non-overlapping slices. ``` -------------------------------- ### IpFragOffset Struct Methods Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.IpFragOffset.html Methods for creating and interacting with the IpFragOffset structure. ```APIDOC ## IpFragOffset Struct ### Description Represents a 13-bit unsigned integer for IP fragmentation offsets. ### Methods - **try_new(value: u16) -> Result>**: Creates an IpFragOffset if the value is <= 8191. - **new_unchecked(value: u16) -> IpFragOffset**: Creates an IpFragOffset without validation. Safety: value must be <= 8191. - **value() -> u16**: Returns the raw 13-bit value. - **byte_offset() -> u16**: Returns the offset in bytes (value * 8). ### Constants - **ZERO**: IpFragOffset with value 0. - **MAX_U16**: 8191 (Maximum allowed value). ### Example Usage ```rust use etherparse::IpFragOffset; // Safe creation let frag_offset = IpFragOffset::try_new(123).unwrap(); assert_eq!(frag_offset.value(), 123); // Byte offset calculation assert_eq!(frag_offset.byte_offset(), 984); ``` ``` -------------------------------- ### Create Ipv6FlowLabel with try_new Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv6FlowLabel.html Demonstrates creating an Ipv6FlowLabel using try_new, checking for valid 20-bit values and handling errors for out-of-range values. ```rust use etherparse::Ipv6FlowLabel; let frag_offset = Ipv6FlowLabel::try_new(123).unwrap(); assert_eq!(frag_offset.value(), 123); // if a number that can not be represented in an 20 bit integer // gets passed in an error is returned use etherparse::err::{ValueTooBigError, ValueType}; assert_eq!( Ipv6FlowLabel::try_new(Ipv6FlowLabel::MAX_U32 + 1), Err(ValueTooBigError{ actual: Ipv6FlowLabel::MAX_U32 + 1, max_allowed: Ipv6FlowLabel::MAX_U32, value_type: ValueType::Ipv6FlowLabel, }) ); ``` -------------------------------- ### GET /slice/windows Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Returns an iterator over all contiguous windows of a specified length. ```APIDOC ## GET /slice/windows ### Description Returns an iterator over all contiguous windows of length size. The windows overlap. ### Parameters #### Query Parameters - **size** (usize) - Required - The length of each window. ### Response - **iterator** (Windows<'_, T>) - An iterator yielding overlapping slices of the specified size. ``` -------------------------------- ### Ipv4Options TryFrom Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4Options.html Explains how to attempt conversion of a byte slice to Ipv4Options, handling potential errors. ```APIDOC ## Ipv4Options TryFrom Slice ### Description Attempts to convert a slice of bytes (`&[u8]`) into an Ipv4Options type. This operation can fail if the slice length is invalid, returning a `BadOptionsLen` error. ### Method `try_from` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **value** (&[u8]) - Required - The byte slice to convert. ### Request Example ```json { "value": [0, 1, 2, 3, 4, 5] } ``` ### Response #### Success Response (200) - **Ipv4Options** - The successfully converted Ipv4Options type. #### Error Response (BadOptionsLen) - **Error** - Indicates an invalid length of the input byte slice. #### Response Example ```json { "result": {"Ok": {"options": "converted_data"}} } ``` #### Error Example ```json { "result": {"Err": "BadOptionsLen"} } ``` ``` -------------------------------- ### GET /slice/as_ptr Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Returns a raw pointer to the slice's buffer. ```APIDOC ## GET /slice/as_ptr ### Description Returns a raw pointer to the slice's buffer. The caller must ensure the slice outlives the pointer and that the memory is not mutated via this pointer. ### Method GET ### Response - **pointer** (*const T) - A raw pointer to the start of the slice buffer. ``` -------------------------------- ### Using IP protocol number constants Source: https://docs.rs/etherparse/0.19.0/etherparse/ip_number/index.html Demonstrates importing IP protocol constants and converting between IpNumber and u8 types. ```rust use etherparse::{ip_number::TCP, IpNumber}; assert_eq!(TCP.0, 6); assert_eq!(TCP, IpNumber(6)); let num: IpNumber = 6.into(); assert_eq!(TCP, num); ``` -------------------------------- ### Create MacsecShortLen with try_from_u8 Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.MacsecShortLen.html Demonstrates creating a MacsecShortLen from a u8, including error handling for values exceeding the 6-bit limit. ```rust use etherparse::MacsecShortLen; let an = MacsecShortLen::try_from_u8(2).unwrap(); assert_eq!(an.value(), 2); // if a number that can not be represented in an 2 bit integer // gets passed in an error is returned use etherparse::err::{ValueTooBigError, ValueType}; assert_eq!( MacsecShortLen::try_from_u8(MacsecShortLen::MAX_U8 + 1), Err(ValueTooBigError{ actual: MacsecShortLen::MAX_U8 + 1, max_allowed: MacsecShortLen::MAX_U8, value_type: ValueType::MacsecShortLen, }) ); ``` -------------------------------- ### PacketBuilder::ethernet2 Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilder.html Starts the construction of a network packet with an Ethernet II header. ```APIDOC ## PacketBuilder::ethernet2 ### Description Starts a packet construction with an Ethernet II header. ### Parameters - **source** ([u8; 6]) - Required - The source MAC address. - **destination** ([u8; 6]) - Required - The destination MAC address. ### Request Example ```rust let builder = PacketBuilder::ethernet2([1,2,3,4,5,6], [7,8,9,10,11,12]); ``` ``` -------------------------------- ### Trait Implementations Overview Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptionsIterator.html Documentation for standard Rust traits providing conversion and ownership utilities. ```APIDOC ## Trait Implementations ### Into - **Method**: `into(self) -> U` - **Description**: Performs the conversion into type U using `U::from(self)`. ### IntoIterator - **Associated Types**: - `Item`: The type of elements being iterated over. - `IntoIter`: The type of the iterator. - **Method**: `into_iter(self) -> I` ### ToOwned - **Associated Types**: - `Owned`: The resulting type after obtaining ownership. - **Methods**: - `to_owned(&self) -> T`: Creates owned data from borrowed data. - `clone_into(&self, target: &mut T)`: Replaces owned data with borrowed data. ### TryFrom - **Associated Types**: - `Error`: The type returned in the event of a conversion error (Infallible). - **Method**: `try_from(value: U) -> Result` ### TryInto - **Associated Types**: - `Error`: The type returned in the event of a conversion error. - **Method**: `try_into(self) -> Result` ``` -------------------------------- ### Get UDP Header Slice Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.UdpSlice.html Returns the slice containing only the UDP header. ```rust pub fn header_slice(&self) -> &'a [u8] ``` -------------------------------- ### Constructing a Double VLAN Packet Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.PacketBuilderStep.html Demonstrates building an Ethernet packet with double VLAN tagging. ```rust let builder = PacketBuilder:: ethernet2([1,2,3,4,5,6], //source mac [7,8,9,10,11,12]) //destination mac .double_vlan(0x123.try_into().unwrap(), // outer vlan identifier 0x234.try_into().unwrap()) // inner vlan identifier .ipv4([192,168,1,1], //source ip [192,168,1,2], //destination ip 20) //time to life .udp(21, //source port 1234); //destination port //payload of the udp packet let payload = [1,2,3,4,5,6,7,8]; //get some memory to store the result let mut result = Vec::::with_capacity( builder.size(payload.len())); //serialize builder.write(&mut result, &payload).unwrap(); ``` -------------------------------- ### Parse IPv4 extensions with from_slice_lax Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Ipv4ExtensionsSlice.html Examples demonstrating the use of from_slice_lax to parse IPv4 extension headers under various conditions. ```rust use etherparse::{Ipv4ExtensionsSlice, IpAuthHeader, ip_number::{UDP, AUTHENTICATION_HEADER}}; let auth_header = IpAuthHeader::new(UDP, 0, 0, &[]).unwrap(); let data = auth_header.to_bytes(); let (ipv4_exts, next_ip_num, next_data, err) = Ipv4ExtensionsSlice::from_slice_lax(AUTHENTICATION_HEADER, &data); // authentication header is separated and no error occurred assert!(ipv4_exts.auth.is_some()); assert_eq!(next_ip_num, UDP); assert_eq!(next_data, &[]); assert!(err.is_none()); ``` ```rust use etherparse::{Ipv4ExtensionsSlice, ip_number::UDP}; let data = [0,1,2,3]; // passing a non "ip extension header" ip number let (ipv4_exts, next_ip_num, next_data, err) = Ipv4ExtensionsSlice::from_slice_lax(UDP, &data); // the original data gets returned as UDP is not a // an IP extension header assert!(ipv4_exts.is_empty()); assert_eq!(next_ip_num, UDP); assert_eq!(next_data, &data); // no errors gets triggered as the data is valid assert!(err.is_none()); ``` ```rust use etherparse::{ Ipv4ExtensionsSlice, IpAuthHeader, ip_number::AUTHENTICATION_HEADER, LenSource, err::{ip_auth::HeaderSliceError::Len, LenError, Layer} }; // providing not enough data let (ipv4_exts, next_ip_num, next_data, err) = Ipv4ExtensionsSlice::from_slice_lax(AUTHENTICATION_HEADER, &[]); // original data will be returned with no data parsed assert!(ipv4_exts.is_empty()); assert_eq!(next_ip_num, AUTHENTICATION_HEADER); assert_eq!(next_data, &[]); // the error that stopped the parsing will also be returned assert_eq!(err, Some(Len(LenError{ required_len: IpAuthHeader::MIN_LEN, len: 0, len_source: LenSource::Slice, layer: Layer::IpAuthHeader, layer_start_offset: 0, }))); ``` -------------------------------- ### Get ICMPv4 Checksum Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.Icmpv4Slice.html Returns the 'checksum' value of the ICMPv4 header as a u16. ```rust pub fn checksum(&self) -> u16 ``` -------------------------------- ### strip_prefix Source: https://docs.rs/etherparse/0.19.0/etherparse/struct.TcpOptions.html Removes a prefix from a slice. Returns `None` if the slice does not start with the specified prefix. ```APIDOC ## strip_prefix ### Description Returns a subslice with the prefix removed. If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`. If `prefix` is empty, simply returns the original slice. If `prefix` is equal to the original slice, returns an empty slice. If the slice does not start with `prefix`, returns `None`. ### Method `strip_prefix` ### Parameters - `prefix` (SlicePattern) - The prefix to remove. ### Request Example ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..])); ``` ### Response #### Success Response (Some) - `subslice` (&[T]) - The slice with the prefix removed. #### Failure Response (None) - `None` - If the slice does not start with the specified prefix. #### Response Example ```rust let v = &[10, 40, 30]; assert_eq!(v.strip_prefix(&[50]), None); ``` ``` -------------------------------- ### From and Into Conversions Source: https://docs.rs/etherparse/0.19.0/etherparse/err/struct.LenError.html Demonstrates the `From` and `Into` traits for type conversions. `From for U` allows conversion from `T` to `U`, and `Into for T` provides the reverse conversion. ```APIDOC ## fn from(t: T) -> T ### Description Returns the argument unchanged. This is a basic implementation of the `From` trait. ### Method `fn` ### Endpoint N/A (Method implementation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response None ### Error Handling None ## fn into(self) -> U ### Description Calls `U::from(self)`. This method provides a convenient way to perform conversions when `U: From` is implemented. ### Method `fn` ### Endpoint N/A (Method implementation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response None ### Error Handling None ```