use std::cmp;
use std::fmt;
use std::hash;
#[derive(Clone, Copy, Debug)]
pub enum Rcode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
Int(u8)
}
impl Rcode {
pub fn from_int(value: u8) -> Rcode {
use self::Rcode::*;
match value & 0x0F {
0 => NoError,
1 => FormErr,
2 => ServFail,
3 => NXDomain,
4 => NotImp,
5 => Refused,
6 => YXDomain,
7 => YXRRSet,
8 => NXRRSet,
9 => NotAuth,
10 => NotZone,
value => Int(value)
}
}
pub fn to_int(self) -> u8 {
use self::Rcode::*;
match self {
NoError => 0,
FormErr => 1,
ServFail => 2,
NXDomain => 3,
NotImp => 4,
Refused => 5,
YXDomain => 6,
YXRRSet => 7,
NXRRSet => 8,
NotAuth => 9,
NotZone => 10,
Int(value) => value & 0x0F
}
}
}
impl From<u8> for Rcode {
fn from(value: u8) -> Rcode { Rcode::from_int(value) }
}
impl From<Rcode> for u8 {
fn from(value: Rcode) -> u8 { value.to_int() }
}
impl fmt::Display for Rcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Rcode::*;
match *self {
NoError => "NOERROR".fmt(f),
FormErr => "FORMERR".fmt(f),
ServFail => "SERVFAIL".fmt(f),
NXDomain => "NXDOMAIN".fmt(f),
NotImp => "NOTIMP".fmt(f),
Refused => "REFUSED".fmt(f),
YXDomain => "YXDOMAIN".fmt(f),
YXRRSet => "YXRRSET".fmt(f),
NXRRSet => "NXRRSET".fmt(f),
NotAuth => "NOAUTH".fmt(f),
NotZone => "NOTZONE".fmt(f),
Int(i) => {
match Rcode::from_int(i) {
Rcode::Int(i) => i.fmt(f),
value => value.fmt(f)
}
}
}
}
}
impl cmp::PartialEq for Rcode {
fn eq(&self, other: &Rcode) -> bool {
self.to_int() == other.to_int()
}
}
impl cmp::PartialEq<u8> for Rcode {
fn eq(&self, other: &u8) -> bool {
self.to_int() == *other
}
}
impl cmp::PartialEq<Rcode> for u8 {
fn eq(&self, other: &Rcode) -> bool {
*self == other.to_int()
}
}
impl cmp::Eq for Rcode { }
impl cmp::PartialOrd for Rcode {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.to_int().partial_cmp(&other.to_int())
}
}
impl cmp::PartialOrd<u8> for Rcode {
fn partial_cmp(&self, other: &u8) -> Option<cmp::Ordering> {
self.to_int().partial_cmp(other)
}
}
impl cmp::PartialOrd<Rcode> for u8 {
fn partial_cmp(&self, other: &Rcode) -> Option<cmp::Ordering> {
self.partial_cmp(&other.to_int())
}
}
impl cmp::Ord for Rcode {
fn cmp(&self, other: &Rcode) -> cmp::Ordering {
self.to_int().cmp(&other.to_int())
}
}
impl hash::Hash for Rcode {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.to_int().hash(state)
}
}
#[derive(Clone, Copy, Debug)]
pub enum OptRcode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
BadVers,
BadCookie,
Int(u16)
}
impl OptRcode {
pub fn from_int(value: u16) -> OptRcode {
use self::OptRcode::*;
match value & 0x0FFF {
0 => NoError,
1 => FormErr,
2 => ServFail,
3 => NXDomain,
4 => NotImp,
5 => Refused,
6 => YXDomain,
7 => YXRRSet,
8 => NXRRSet,
9 => NotAuth,
10 => NotZone,
16 => BadVers,
23 => BadCookie,
value => Int(value)
}
}
pub fn to_int(self) -> u16 {
use self::OptRcode::*;
match self {
NoError => 0,
FormErr => 1,
ServFail => 2,
NXDomain => 3,
NotImp => 4,
Refused => 5,
YXDomain => 6,
YXRRSet => 7,
NXRRSet => 8,
NotAuth => 9,
NotZone => 10,
BadVers => 16,
BadCookie => 23,
Int(value) => value & 0x0F
}
}
pub fn from_parts(rcode: Rcode, ext: u8) -> OptRcode {
if ext == 0 {
rcode.into()
}
else {
OptRcode::from_int(
u16::from(ext) << 4 | u16::from(rcode.to_int())
)
}
}
pub fn to_parts(self) -> (Rcode, u8) {
let res = self.to_int();
(Rcode::from_int(res as u8), (res >> 8) as u8)
}
pub fn rcode(self) -> Rcode {
self.to_parts().0
}
pub fn ext(self) -> u8 {
self.to_parts().1
}
}
impl From<u16> for OptRcode {
fn from(value: u16) -> OptRcode { OptRcode::from_int(value) }
}
impl From<OptRcode> for u16 {
fn from(value: OptRcode) -> u16 { value.to_int() }
}
impl From<Rcode> for OptRcode {
fn from(value: Rcode) -> OptRcode { OptRcode::from_parts(value, 0) }
}
impl fmt::Display for OptRcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::OptRcode::*;
match *self {
NoError => "NOERROR".fmt(f),
FormErr => "FORMERR".fmt(f),
ServFail => "SERVFAIL".fmt(f),
NXDomain => "NXDOMAIN".fmt(f),
NotImp => "NOTIMP".fmt(f),
Refused => "REFUSED".fmt(f),
YXDomain => "YXDOMAIN".fmt(f),
YXRRSet => "YXRRSET".fmt(f),
NXRRSet => "NXRRSET".fmt(f),
NotAuth => "NOAUTH".fmt(f),
NotZone => "NOTZONE".fmt(f),
BadVers => "BADVER".fmt(f),
BadCookie => "BADCOOKIE".fmt(f),
Int(i) => {
match OptRcode::from_int(i) {
Int(i) => i.fmt(f),
value => value.fmt(f)
}
}
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum TsigRcode {
NoError,
FormErr,
ServFail,
NXDomain,
NotImp,
Refused,
YXDomain,
YXRRSet,
NXRRSet,
NotAuth,
NotZone,
BadSig,
BadKey,
BadTime,
BadMode,
BadName,
BadAlg,
BadTrunc,
BadCookie,
Int(u16)
}
impl TsigRcode {
pub fn from_int(value: u16) -> TsigRcode {
use self::TsigRcode::*;
match value {
0 => NoError,
1 => FormErr,
2 => ServFail,
3 => NXDomain,
4 => NotImp,
5 => Refused,
6 => YXDomain,
7 => YXRRSet,
8 => NXRRSet,
9 => NotAuth,
10 => NotZone,
16 => BadSig,
17 => BadKey,
18 => BadTime,
19 => BadMode,
20 => BadName,
21 => BadAlg,
22 => BadTrunc,
23 => BadCookie,
value => Int(value)
}
}
pub fn to_int(self) -> u16 {
use self::TsigRcode::*;
match self {
NoError => 0,
FormErr => 1,
ServFail => 2,
NXDomain => 3,
NotImp => 4,
Refused => 5,
YXDomain => 6,
YXRRSet => 7,
NXRRSet => 8,
NotAuth => 9,
NotZone => 10,
BadSig => 16,
BadKey => 17,
BadTime => 18,
BadMode => 19,
BadName => 20,
BadAlg => 21,
BadTrunc => 22,
BadCookie => 23,
Int(value) => value & 0x0F
}
}
}
impl From<u16> for TsigRcode {
fn from(value: u16) -> TsigRcode { TsigRcode::from_int(value) }
}
impl From<TsigRcode> for u16 {
fn from(value: TsigRcode) -> u16 { value.to_int() }
}
impl From<Rcode> for TsigRcode {
fn from(value: Rcode) -> TsigRcode {
TsigRcode::from_int(u16::from(value.to_int()))
}
}
impl From<OptRcode> for TsigRcode {
fn from(value: OptRcode) -> TsigRcode {
TsigRcode::from_int(value.to_int())
}
}
impl fmt::Display for TsigRcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::TsigRcode::*;
match *self {
NoError => "NOERROR".fmt(f),
FormErr => "FORMERR".fmt(f),
ServFail => "SERVFAIL".fmt(f),
NXDomain => "NXDOMAIN".fmt(f),
NotImp => "NOTIMP".fmt(f),
Refused => "REFUSED".fmt(f),
YXDomain => "YXDOMAIN".fmt(f),
YXRRSet => "YXRRSET".fmt(f),
NXRRSet => "NXRRSET".fmt(f),
NotAuth => "NOAUTH".fmt(f),
NotZone => "NOTZONE".fmt(f),
BadSig => "BADSIG".fmt(f),
BadKey => "BADKEY".fmt(f),
BadTime => "BADTIME".fmt(f),
BadMode => "BADMODE".fmt(f),
BadName => "BADNAME".fmt(f),
BadAlg => "BADALG".fmt(f),
BadTrunc => "BADTRUNC".fmt(f),
BadCookie => "BADCOOKIE".fmt(f),
Int(i) => {
match TsigRcode::from_int(i) {
Int(i) => i.fmt(f),
value => value.fmt(f)
}
}
}
}
}