use super::super::*;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum IpHeader {
Version4(Ipv4Header, Ipv4Extensions),
Version6(Ipv6Header, Ipv6Extensions)
}
impl IpHeader {
#[deprecated(
since = "0.10.0",
note = "Renamed to `IpHeader::from_slice`"
)]
#[inline]
pub fn read_from_slice(slice: &[u8]) -> Result<(IpHeader, u8, &[u8]), ReadError> {
IpHeader::from_slice(slice)
}
pub fn from_slice(slice: &[u8]) -> Result<(IpHeader, u8, &[u8]), ReadError> {
use crate::ReadError::*;
if slice.is_empty() {
Err(UnexpectedEndOfSlice(1))
} else {
match slice[0] >> 4 {
4 => {
let (header, rest) = Ipv4Header::from_slice(slice)?;
Ipv4Extensions::from_slice(header.protocol, rest).map(
|(ext, next_protocol, rest)|
(IpHeader::Version4(header, ext), next_protocol, rest)
)
},
6 => {
let (header, rest) = Ipv6Header::from_slice(slice)?;
Ipv6Extensions::from_slice(header.next_header, rest).map(
|(ext, next_protocol, rest)|
(IpHeader::Version6(header, ext), next_protocol, rest)
)
},
version => Err(ReadError::IpUnsupportedVersion(version))
}
}
}
pub fn read<T: io::Read + io::Seek + Sized>(reader: &mut T) -> Result<(IpHeader, u8), ReadError> {
let value = {
let mut buf = [0;1];
reader.read_exact(&mut buf)?;
buf[0]
};
match value >> 4 {
4 => {
let header = Ipv4Header::read_without_version(reader, value & 0xf)?;
Ipv4Extensions::read(reader, header.protocol).map(
|(ext, next)| (IpHeader::Version4(header, ext), next)
)
},
6 => {
let header = Ipv6Header::read_without_version(reader, value & 0xf)?;
Ipv6Extensions::read(reader, header.next_header).map(
|(ext, next)| (IpHeader::Version6(header, ext), next)
)
},
version => Err(ReadError::IpUnsupportedVersion(version))
}
}
pub fn write<T: io::Write + Sized>(&self, writer: &mut T) -> Result<(), WriteError> {
use crate::IpHeader::*;
match *self {
Version4(ref header, ref extensions) => {
header.write(writer)?;
extensions.write(writer, header.protocol)
}
Version6(ref header, ref extensions) => {
header.write(writer)?;
extensions.write(writer, header.next_header)
}
}
}
pub fn header_len(&self) -> usize {
use crate::IpHeader::*;
match *self {
Version4(ref header, ref extensions) => {
header.header_len() + extensions.header_len()
}
Version6(_, ref extensions) => {
Ipv6Header::SERIALIZED_SIZE + extensions.header_len()
}
}
}
pub fn next_header(&self) -> Result<u8, ValueError> {
use crate::IpHeader::*;
match *self {
Version4(ref header, ref extensions) => {
extensions.next_header(header.protocol)
}
Version6(ref header, ref extensions) => {
extensions.next_header(header.next_header)
}
}
}
pub fn set_next_headers(&mut self, last_next_header: u8) -> EtherType {
use IpHeader::*;
match self {
Version4(ref mut header, ref mut extensions) => {
header.protocol = extensions.set_next_headers(last_next_header);
EtherType::Ipv4
},
Version6(ref mut header, ref mut extensions) => {
header.next_header = extensions.set_next_headers(last_next_header);
EtherType::Ipv6
},
}
}
}
#[deprecated(
since = "0.10.0",
note = "Please use the type IpNumber instead"
)]
pub type IpTrafficClass = IpNumber;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum IpNumber {
IPv6HeaderHopByHop = 0,
Icmp = 1,
Igmp = 2,
Ggp = 3,
IPv4 = 4,
Stream = 5,
Tcp = 6,
Cbt = 7,
Egp = 8,
Igp = 9,
BbnRccMon = 10,
NvpII = 11,
Pup = 12,
Argus = 13,
Emcon = 14,
Xnet = 15,
Chaos = 16,
Udp = 17,
Mux = 18,
DcnMeas = 19,
Hmp = 20,
Prm = 21,
XnsIdp = 22,
Trunk1 = 23,
Trunk2 = 24,
Leaf1 = 25,
Leaf2 = 26,
Rdp = 27,
Irtp = 28,
IsoTp4 = 29,
NetBlt = 30,
MfeNsp = 31,
MeritInp = 32,
Dccp = 33,
ThirdPartyConnectProtocol = 34,
Idpr = 35,
Xtp = 36,
Ddp = 37,
IdprCmtp = 38,
TpPlusPlus = 39,
Il = 40,
Ipv6 = 41,
Sdrp = 42,
IPv6RouteHeader = 43,
IPv6FragmentationHeader = 44,
Idrp = 45,
Rsvp = 46,
Gre = 47,
Dsr = 48,
Bna = 49,
EncapsulatingSecurityPayload = 50,
AuthenticationHeader = 51,
Inlsp = 52,
Swipe = 53,
Narp = 54,
Mobile = 55,
Tlsp = 56,
Skip = 57,
IPv6Icmp = 58,
IPv6NoNextHeader = 59,
IPv6DestinationOptions = 60,
AnyHostInternalProtocol = 61,
Cftp = 62,
AnyLocalNetwork = 63,
SatExpak = 64,
Krytolan = 65,
Rvd = 66,
Ippc = 67,
AnyDistributedFileSystem = 68,
SatMon = 69,
Visa = 70,
Ipcv = 71,
Cpnx = 72,
Cphb = 73,
Wsn = 74,
Pvp = 75,
BrSatMon = 76,
SunNd = 77,
WbMon = 78,
WbExpak = 79,
IsoIp = 80,
Vmtp = 81,
SecureVmtp = 82,
Vines = 83,
TtpOrIptm = 84,
NsfnetIgp = 85,
Dgp = 86,
Tcf = 87,
Eigrp = 88,
Ospfigp = 89,
SpriteRpc = 90,
Larp = 91,
Mtp = 92,
Ax25 = 93,
Ipip = 94,
Micp = 95,
SccSp = 96,
EtherIp = 97,
Encap = 98,
Gmtp = 100,
Ifmp = 101,
Pnni = 102,
Pim = 103,
Aris = 104,
Scps = 105,
Qnx = 106,
ActiveNetworks = 107,
IpComp = 108,
SitraNetworksProtocol = 109,
CompaqPeer = 110,
IpxInIp = 111,
Vrrp = 112,
Pgm = 113,
AnyZeroHopProtocol = 114,
Layer2TunnelingProtocol = 115,
Ddx = 116,
Iatp = 117,
Stp = 118,
Srp = 119,
Uti = 120,
SimpleMessageProtocol = 121,
Sm = 122,
Ptp = 123,
IsisOverIpv4 = 124,
Fire = 125,
Crtp = 126,
Crudp = 127,
Sscopmce = 128,
Iplt = 129,
Sps = 130,
Pipe = 131,
Sctp = 132,
Fc = 133,
RsvpE2eIgnore = 134,
MobilityHeader = 135,
UdpLite = 136,
MplsInIp = 137,
Manet = 138,
Hip = 139,
Shim6 = 140,
Wesp = 141,
Rohc = 142,
ExperimentalAndTesting0 = 253,
ExperimentalAndTesting1 = 254
}
impl IpNumber {
pub fn is_ipv6_ext_header_value(value: u8) -> bool {
use crate::ip_number::*;
matches!(
value,
IPV6_HOP_BY_HOP | IPV6_ROUTE | IPV6_FRAG | ENCAP_SEC | AUTH
| IPV6_DEST_OPTIONS | MOBILITY | HIP | SHIM6 | EXP0 | EXP1
)
}
}
pub mod ip_number {
use crate::IpNumber::*;
pub const IPV6_HOP_BY_HOP: u8 = IPv6HeaderHopByHop as u8; pub const ICMP: u8 = Icmp as u8; pub const IGMP: u8 = Igmp as u8; pub const GGP: u8 = Ggp as u8; pub const IPV4: u8 = IPv4 as u8; pub const STREAM: u8 = Stream as u8; pub const TCP: u8 = Tcp as u8; pub const UDP: u8 = Udp as u8; pub const IPV6: u8 = Ipv6 as u8; pub const IPV6_ROUTE: u8 = IPv6RouteHeader as u8; pub const IPV6_FRAG: u8 = IPv6FragmentationHeader as u8; pub const ENCAP_SEC: u8 = EncapsulatingSecurityPayload as u8; pub const AUTH: u8 = AuthenticationHeader as u8; pub const IPV6_DEST_OPTIONS: u8 = IPv6DestinationOptions as u8; pub const MOBILITY: u8 = MobilityHeader as u8; pub const HIP: u8 = Hip as u8; pub const SHIM6: u8 = Shim6 as u8; pub const EXP0: u8 = ExperimentalAndTesting0 as u8; pub const EXP1: u8 = ExperimentalAndTesting1 as u8; }