rawsock 0.3.0

Library for receiving and sending raw packets. While most crate wrap just one library, rawsock allows you to use pcap, wpcap, npcap and pf_ring (pfring) using a consistent API for all of them.
Documentation
/*!
Code hat helps you use the original DLL API.
*/

use libc::c_int;
use std::convert::TryFrom;
use std::mem::transmute;
use crate::BorrowedPacket;
use time::Timespec;
use crate::pfring::dll::structs::PFRingPacketHeader;
use std::slice::from_raw_parts;

/// Safe wrapper around error codes returned by pfring API.
#[allow(dead_code)]
#[repr(i32)]
pub enum PFRingErrCode{
    Generic = -1,
    InvalidArgument = -2,
    NoPacketsAvailable = -3,
    NoTxSlotsAvailable = -4,
    WrongConfiguration = -5,
    EndOfDemoMode = -6,
    NotSupported = -7,
    InvalidLibVersion = -8,
    UnknownAdapter = -9,
    NotEnoughMemory = -10,
    InvalidStatus = -11,
    RingNotEnabled = -12
}

impl TryFrom<c_int> for PFRingErrCode{
    type Error = ();

    fn try_from(value: c_int) -> Result<Self, <Self as TryFrom<c_int>>::Error> {
        if PFRingErrCode::Generic as c_int >= value && PFRingErrCode::RingNotEnabled as c_int <= value {
            Ok(unsafe{transmute(value as i32)})
        } else {
            Err(())
        }
    }
}

impl PFRingErrCode {
    pub fn to_description(&self) -> &'static str {
        use self::PFRingErrCode::*;
        match *self {
            Generic => "Generic",
            InvalidArgument => "Invalid argument",
            NoPacketsAvailable => "No packets available",
            NoTxSlotsAvailable => "No TX slots available",
            WrongConfiguration => "Wront configuration",
            EndOfDemoMode => "End of demo mode",
            NotSupported => "Not supported",
            InvalidLibVersion => "Invalid library version",
            UnknownAdapter => "Unknown adapter",
            NotEnoughMemory => "Not enough memory",
            InvalidStatus => "Invalid status",
            RingNotEnabled => "Ring not enabled"
        }
    }
}

/// Converts pfring error code into human-friendly text.
pub fn string_from_pfring_err_code(err_code: c_int) -> String {
    if let Ok(err) = PFRingErrCode::try_from(err_code){
        String::from(err.to_description())
    } else {
        format!("Unknown PF Ring error code: {}", err_code)
    }
}

pub fn borrowed_packet_from_header<'a, 'b>(header: &'a PFRingPacketHeader, data: * const u8) -> BorrowedPacket<'b> {
    unsafe {
        BorrowedPacket::new(Timespec::new(header.ts.tv_sec as i64, (header.ts.tv_usec * 1000) as i32), from_raw_parts(data, header.caplen as usize))
    }
}