rustables 0.8.7

Safe abstraction for nftables manipulation on Linux
Documentation
use std::string::FromUtf8Error;

use nix::errno::Errno;
use thiserror::Error;

use crate::sys::nlmsgerr;

#[derive(Error, Debug)]
pub enum DecodeError {
    #[error("The buffer is too small to hold a valid message")]
    BufTooSmall,

    #[error("The message is too small")]
    NlMsgTooSmall,

    #[error("The message holds unexpected data")]
    InvalidDataSize,

    #[error("Invalid subsystem, expected NFTABLES")]
    InvalidSubsystem(u8),

    #[error("Invalid version, expected NFNETLINK_V0")]
    InvalidVersion(u8),

    #[error("Invalid port ID")]
    InvalidPortId(u32),

    #[error("Invalid sequence number")]
    InvalidSeq(u32),

    #[error("The generation number was bumped in the kernel while the operation was running, interrupting it")]
    ConcurrentGenerationUpdate,

    #[error("Unsupported message type")]
    UnsupportedType(u16),

    #[error("Invalid attribute type")]
    InvalidAttributeType,

    #[error("Invalid type for a chain")]
    UnknownChainType,

    #[error("Invalid policy for a chain")]
    UnknownChainPolicy,

    #[error("Unknown type for a Meta expression")]
    UnknownMetaType(u32),

    #[error("Unsupported value for an icmp reject type")]
    UnknownRejectType(u32),

    #[error("Unsupported value for an icmp code in a reject expression")]
    UnknownIcmpCode(u8),

    #[error("Invalid value for a register")]
    UnknownRegister(u32),

    #[error("Invalid type for a verdict expression")]
    UnknownVerdictType(i32),

    #[error("Invalid type for a nat expression")]
    UnknownNatType(i32),

    #[error("Invalid type for a payload expression")]
    UnknownPayloadType(u32),

    #[error("Invalid type for a compare expression")]
    UnknownCmpOp(u32),

    #[error("Invalid type for a conntrack key")]
    UnknownConntrackKey(u32),

    #[error("Unsupported value for a link layer header field")]
    UnknownLinkLayerHeaderField(u32, u32),

    #[error("Unsupported value for an IPv4 header field")]
    UnknownIPv4HeaderField(u32, u32),

    #[error("Unsupported value for an IPv6 header field")]
    UnknownIPv6HeaderField(u32, u32),

    #[error("Unsupported value for a TCP header field")]
    UnknownTCPHeaderField(u32, u32),

    #[error("Unsupported value for an UDP header field")]
    UnknownUDPHeaderField(u32, u32),

    #[error("Unsupported value for an ICMPv6 header field")]
    UnknownICMPv6HeaderField(u32, u32),

    #[error("Missing the 'base' attribute to deserialize the payload object")]
    PayloadMissingBase,

    #[error("Missing the 'offset' attribute to deserialize the payload object")]
    PayloadMissingOffset,

    #[error("Missing the 'len' attribute to deserialize the payload object")]
    PayloadMissingLen,

    #[error("The object does not contain a name for the expression being parsed")]
    MissingExpressionName,

    #[error("Unsupported attribute type")]
    UnsupportedAttributeType(u16),

    #[error("Unexpected message type")]
    UnexpectedType(u16),

    #[error("The decoded String is not UTF8 compliant")]
    StringDecodeFailure(#[from] FromUtf8Error),

    #[error("Invalid value for a protocol family")]
    UnknownProtocolFamily(i32),
}

#[derive(thiserror::Error, Debug)]
pub enum BuilderError {
    #[error("The length of the arguments are not compatible with each other")]
    IncompatibleLength,

    #[error("The table does not have a name")]
    MissingTableName,

    #[error("Missing information in the chain to create a rule")]
    MissingChainInformationError,

    #[error("Missing name for the set")]
    MissingSetName,

    #[error("The interface name is too long to be written")]
    InterfaceNameTooLong,

    #[error("The log prefix string is more than 127 characters long")]
    TooLongLogPrefix,
}

#[derive(thiserror::Error, Debug)]
pub enum QueryError {
    #[error("Unable to open netlink socket to netfilter")]
    NetlinkOpenError(#[source] nix::Error),

    #[error("Unable to send netlink command to netfilter")]
    NetlinkSendError(#[source] nix::Error),

    #[error("Error while reading from netlink socket")]
    NetlinkRecvError(#[source] nix::Error),

    #[error("Error while processing an incoming netlink message")]
    ProcessNetlinkError(#[from] DecodeError),

    #[error("Error while building netlink objects in Rust")]
    BuilderError(#[from] BuilderError),

    #[error("Error received from the kernel")]
    NetlinkError(nlmsgerr),

    #[error("Couldn't allocate a netlink object, out of memory ?")]
    NetlinkAllocationFailed,

    #[error("This socket is not a netlink socket")]
    NotNetlinkSocket,

    #[error("Couldn't retrieve information on a socket")]
    RetrievingSocketInfoFailed,

    #[error("Only a part of the message was sent")]
    TruncatedSend,

    #[error("Got a message without the NLM_F_MULTI flag, but a maximum sequence number was not specified")]
    UndecidableMessageTermination,

    #[error("Couldn't close the socket")]
    CloseFailed(#[source] Errno),

    #[error("Couldn't bind the socket")]
    BindFailed,
}