Struct etherparse::Ipv4Header

source ·
pub struct Ipv4Header {
Show 13 fields pub dscp: Ipv4Dscp, pub ecn: Ipv4Ecn, pub total_len: u16, pub identification: u16, pub dont_fragment: bool, pub more_fragments: bool, pub fragment_offset: IpFragOffset, pub time_to_live: u8, pub protocol: IpNumber, pub header_checksum: u16, pub source: [u8; 4], pub destination: [u8; 4], pub options: Ipv4Options,
}
Expand description

IPv4 header with options.

§Example Usage:

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 usecase 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, &[]);

Fields§

§dscp: Ipv4Dscp

Differentiated Services Code Point

§ecn: Ipv4Ecn

Explicit Congestion Notification

§total_len: u16

Total length of the IPv4 header (including extension headers) and the payload after it.

§identification: u16

Number used to identify packets that contain an originally fragmented packet.

§dont_fragment: bool

If set the packet is not allowed to fragmented.

§more_fragments: bool

Indicates that the packet contains part of an fragmented message and that additional data is needed to reconstruct the original packet.

§fragment_offset: IpFragOffset

In case this message contains parts of a fragmented packet the fragment offset is the offset of payload the current message relative to the original payload of the message.

§time_to_live: u8

Number of hops the packet is allowed to take before it should be discarded.

§protocol: IpNumber

IP protocol number specifying the next header or transport layer protocol.

See IpNumber or ip_number for a definitions of ids.

§header_checksum: u16§source: [u8; 4]

IPv4 source address

§destination: [u8; 4]

IPv4 destination address

§options: Ipv4Options

Options in the header (in raw).

Implementations§

source§

impl Ipv4Header

source

pub const MIN_LEN: usize = 20usize

Minimum length of an IPv4 header in bytes/octets.

source

pub const MIN_LEN_U16: u16 = 20u16

Minimum length of an IPv4 header in bytes/octets as an u16.

source

pub const MAX_LEN: usize = 60usize

Maximum length of an IPv4 header in bytes/octets.

This number is calculated by taking the maximum value that the “internet header length” field supports (0xf, as the field is only 4 bits long) and multiplying it with 4 as the “internet header length” specifies how many 4 bytes words are present in the header.

source

pub const SERIALIZED_SIZE: usize = 20usize

👎Deprecated since 0.14.0: Use Ipv4Header::MIN_LEN instead

Deprecated use Ipv4Header::MIN_LEN instead.

source

pub fn new( payload_len: u16, time_to_live: u8, protocol: IpNumber, source: [u8; 4], destination: [u8; 4] ) -> Result<Ipv4Header, ValueTooBigError<u16>>

Constructs an Ipv4Header with standard values for non specified values.

This method is equivalent to partially initializing a struct with default values:

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();
source

pub fn ihl(&self) -> u8

Length of the header in multiples of 4 bytes (often also called IHL - Internet Header length). This field is part of the serialized header and determines / is determined by the byte length of the options.

The minimum allowed length of a header is 5 (= 20 bytes) and the maximum length is 15 (= 60 bytes).

use etherparse::Ipv4Header;
{
    let header = Ipv4Header {
        options: [].into(),
        ..Default::default()
    };
    // minimum IHL is 5
    assert_eq!(5, header.ihl());
}
{
    let header = Ipv4Header {
        options: [1,2,3,4].into(),
        ..Default::default()
    };
    // IHL is increased by 1 for every 4 bytes of options
    assert_eq!(6, header.ihl());
}
{
    let header = Ipv4Header {
        options: [0;40].into(),
        ..Default::default()
    };
    // maximum ihl
    assert_eq!(15, header.ihl());
}
source

pub fn header_len(&self) -> usize

Length of the header (includes options) in bytes.

The minimum allowed length of a header is 5 (= 20 bytes) and the maximum length is 15 (= 60 bytes).

use etherparse::Ipv4Header;
{
    let header = Ipv4Header {
        options: [].into(),
        ..Default::default()
    };
    // minimum IHL is 5
    assert_eq!(5, header.ihl());
}
{
    let header = Ipv4Header {
        options: [1,2,3,4].into(),
        ..Default::default()
    };
    // IHL is increased by 1 for every 4 bytes of options
    assert_eq!(6, header.ihl());
}
{
    let header = Ipv4Header {
        options: [0;40].into(),
        ..Default::default()
    };
    // maximum ihl
    assert_eq!(15, header.ihl());
}
source

pub fn payload_len(&self) -> Result<u16, LenError>

Determine the payload length based on the ihl & total_length field of the header.

§Example Usage
use etherparse::{Ipv4Header, Ipv4HeaderSlice};

let header = Ipv4Header{
    // the payload len will be calculated by subtracting the
    // header length from the total length
    total_len: Ipv4Header::MIN_LEN as u16 + 100,
    ..Default::default()
};

assert_eq!(Ok(100), header.payload_len());

// error case
let bad_header = Ipv4Header {
    // total len should also include the header, in case it does
    // not it is not possible to calculate the payload length
    total_len: Ipv4Header::MIN_LEN as u16 - 1,
    ..Default::default()
};

// in case the total_len is smaller then the header itself an
// error is returned
use etherparse::{LenSource, err::{LenError, Layer}};
assert_eq!(
    bad_header.payload_len(),
    Err(LenError {
        required_len: Ipv4Header::MIN_LEN,
        len: Ipv4Header::MIN_LEN - 1,
        len_source: LenSource::Ipv4HeaderTotalLen,
        layer: Layer::Ipv4Packet,
        layer_start_offset: 0,
    })
);
source

pub fn set_payload_len( &mut self, value: usize ) -> Result<(), ValueTooBigError<usize>>

Tries setting the Ipv4Header::total_len field given the length of the payload after the header & the current options length of the header.

If the value is not too big. Otherwise an error is returned.

Note that the set payload length is no longer valid if you change Ipv4Header::options length after calling Ipv4Header::set_payload_len as it uses the length of options to calculate the total_len value.

§Example Usage:
use etherparse::Ipv4Header;

let mut header = Ipv4Header{
    total_len: 100, // will be reset by set_payload
    options: [1,2,3,4].into(),
    ..Default::default()
};

// set_payload_len set the total_len field based on the header_len
// and given payload length
header.set_payload_len(100).unwrap();
assert_eq!(100 + header.header_len() as u16, header.total_len);

// in case the payload is len is bigger then can represented in the
// total_len field an error is returned
use etherparse::err::{ValueTooBigError, ValueType};
let err = header.set_payload_len(usize::from(u16::MAX) - header.header_len() + 1);
assert_eq!(
    err,
    Err(ValueTooBigError {
        actual: usize::from(u16::MAX) - header.header_len() + 1,
        max_allowed: usize::from(u16::MAX) - header.header_len(),
        value_type: ValueType::Ipv4PayloadLength
    })
);
source

pub fn max_payload_len(&self) -> u16

Returns the maximum payload size based on the current options size.

source

pub fn options(&self) -> &[u8]

👎Deprecated since 0.14.0: Directly use &(header.options[..]) instead.

Returns a slice to the options part of the header (empty if no options are present).

source

pub fn set_options(&mut self, data: &[u8]) -> Result<(), BadOptionsLen>

👎Deprecated since 0.14.0: Directly set it via the header.options field instead.

Sets the options & header_length based on the provided length. The length of the given slice must be a multiple of 4 and maximum 40 bytes. If the length is not fulfilling these constraints, no data is set and an error is returned.

source

pub fn read_from_slice( slice: &[u8] ) -> Result<(Ipv4Header, &[u8]), HeaderSliceError>

👎Deprecated since 0.10.1: Renamed to Ipv4Header::from_slice

Renamed to Ipv4Header::from_slice

source

pub fn from_slice(slice: &[u8]) -> Result<(Ipv4Header, &[u8]), HeaderSliceError>

Read an Ipv4Header from a slice and return the header & unused parts of the slice.

Note that this function DOES NOT seperate the payload based on the total_length field present in the IPv4 header. It just returns the left over slice after the header.

If you want to have correctly seperated payload including the IP extension headers use

or

for a laxer version which falls back to slice length when the total_length contains an inconsistent value.

source

pub fn read<T: Read + Seek + Sized>( reader: &mut T ) -> Result<Ipv4Header, HeaderReadError>

Available on crate feature std only.

Reads an IPv4 header from the current position (requires crate feature std).

source

pub fn read_without_version<T: Read + Seek + Sized>( reader: &mut T, first_byte: u8 ) -> Result<Ipv4Header, HeaderReadError>

Available on crate feature std only.

Reads an IPv4 header assuming the version & ihl field have already been read (requires crate feature std).

source

pub fn write<T: Write + Sized>(&self, writer: &mut T) -> Result<(), Error>

Available on crate feature std only.

Writes a given IPv4 header to the current position (this method automatically calculates the header length and checksum).

source

pub fn write_raw<T: Write + Sized>(&self, writer: &mut T) -> Result<(), Error>

Available on crate feature std only.

Writes a given IPv4 header to the current position (this method just writes the specified checksum and does note compute it).

source

pub fn to_bytes(&self) -> ArrayVec<u8, { Ipv4Header::MAX_LEN }>

Returns the serialized header (note that this method does NOT update & calculate the checksum).

source

pub fn calc_header_checksum(&self) -> u16

Calculate header checksum of the current ipv4 header.

source

pub fn is_fragmenting_payload(&self) -> bool

Returns true if the payload is fragmented.

Either data is missing (more_fragments set) or there is an fragment offset.

Trait Implementations§

source§

impl Clone for Ipv4Header

source§

fn clone(&self) -> Ipv4Header

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Ipv4Header

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Ipv4Header

source§

fn default() -> Ipv4Header

Returns the “default value” for a type. Read more
source§

impl Hash for Ipv4Header

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Ipv4Header

source§

fn eq(&self, other: &Ipv4Header) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for Ipv4Header

source§

impl StructuralPartialEq for Ipv4Header

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.