From 44c96b85b8fbcdce22a887695f723e8e051fa84c Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Wed, 1 Jun 2016 18:08:07 +0800 Subject: [PATCH 01/10] fix for newer Rust --- src/ffi.rs | 3 +-- src/message.rs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index d166dc6..f978542 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -23,8 +23,7 @@ pub struct nfgenmsg; #[repr(C)] pub struct nfq_data; -#[repr(C)] -#[packed] +#[repr(C,packed)] /// The NFQueue specific packet data pub struct nfqnl_msg_packet_hdr { /// The packet id diff --git a/src/message.rs b/src/message.rs index 8f0942f..f2d2d6b 100644 --- a/src/message.rs +++ b/src/message.rs @@ -6,7 +6,6 @@ use libc::*; use std::mem; use std::ptr::null; use std::net::Ipv4Addr; -use num::traits::PrimInt; use error::*; use util::*; use ffi::*; From 52d46c2655ff2b53d2ca98baac2a0c1fb4f627d4 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Wed, 1 Jun 2016 18:14:51 +0800 Subject: [PATCH 02/10] use c_void struct to avoid warnings --- src/ffi.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index f978542..e5c4240 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -1,7 +1,6 @@ #![allow(non_camel_case_types)] use libc::*; -use num::traits::PrimInt; pub const NF_DROP: u32 = 0; pub const NF_ACCEPT: u32 = 1; @@ -11,17 +10,17 @@ pub const NF_REPEAT: u32 = 4; pub const NF_STOP: u32 = 5; #[repr(C)] -pub struct nfq_handle; +pub struct nfq_handle(c_void); #[repr(C)] /// The handle into NFQueue -pub struct nfq_q_handle; +pub struct nfq_q_handle(c_void); #[repr(C)] -pub struct nfgenmsg; +pub struct nfgenmsg(c_void); #[repr(C)] -pub struct nfq_data; +pub struct nfq_data(c_void); #[repr(C,packed)] /// The NFQueue specific packet data From dd3af608312cdc3e78c471ddca174fdbb6c24956 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Mon, 29 Apr 2019 14:45:34 +0800 Subject: [PATCH 03/10] remove Error.cause since it's not used --- src/error.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/error.rs b/src/error.rs index 0f3e073..bf55b8c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,13 +21,11 @@ pub enum Reason { pub struct Error { reason: Reason, description: String, - cause: Option>, } impl fmt::Debug for Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let msg = format!("{:?}: {:?} (cause: {:?})", - self.reason, self.description, self.cause); + let msg = format!("{:?}: {:?}", self.reason, self.description); formatter.write_str(msg.as_ref()) } } @@ -44,12 +42,12 @@ impl Base for Error { self.description.as_ref() } fn cause(&self) -> Option<&Base> { - self.cause.as_ref().map(|c| &**c) + None } } pub fn error(reason: Reason, msg: &str, res: Option) -> Error { - let errno = nfq_errno; + let errno = unsafe { nfq_errno }; let desc = match res { Some(r) => format!("{} (errno: {}, res: {})", msg, errno, r), None => format!("{}, (errno: {})", msg, errno) @@ -57,6 +55,5 @@ pub fn error(reason: Reason, msg: &str, res: Option) -> Error { Error { reason: reason, description: desc, - cause: None, } } From a10e8ea55412c71f182e484b8d86227c0391ce87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Fri, 15 Jul 2016 18:15:09 +0800 Subject: [PATCH 04/10] make payload return the actual length of the payload --- src/message.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/message.rs b/src/message.rs index f2d2d6b..f04b137 100644 --- a/src/message.rs +++ b/src/message.rs @@ -95,7 +95,7 @@ impl<'a> Message<'a> { /// and `handle.start_sized_to_payload` methods. /// See `examples/get_addrs.rs`. pub unsafe fn ip_header(&self) -> Result<&IPHeader, Error> { - self.payload::() + self.payload::().map(|x| x.0) } /// Parse a sized `Payload` from the message @@ -104,15 +104,15 @@ impl<'a> Message<'a> { /// The best way to do this is with the `queue_builder.set_copy_mode_sized_to_payload` /// and `handle.start_sized_to_payload` methods. /// See `examples/get_addrs.rs`. - pub unsafe fn payload(&self) -> Result<&A, Error> { + pub unsafe fn payload(&self) -> Result<(&A, usize), Error> { let data: *const A = null(); let ptr: *mut *mut A = &mut (data as *mut A); - let _ = match nfq_get_payload(self.ptr, ptr as *mut *mut c_uchar) { + let n = match nfq_get_payload(self.ptr, ptr as *mut *mut c_uchar) { -1 => return Err(error(Reason::GetPayload, "Failed to get payload", Some(-1))), - _ => () + n => n }; match as_ref(&data) { - Some(payload) => Ok(payload), + Some(payload) => Ok((payload, n as usize)), None => Err(error(Reason::GetPayload, "Failed to get payload", None)) } } From bdcb854bd0ea927dfef9bb9aa74c4d544c7f13b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Mon, 18 Jul 2016 12:13:02 +0800 Subject: [PATCH 05/10] unbind before bind --- src/handle.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/handle.rs b/src/handle.rs index a9fc064..e4bf959 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -16,6 +16,7 @@ use ffi::*; /// Protocol Family /// /// NFQueue will only deal with IP, so only those families are made available. +#[derive(Clone,Copy)] pub enum ProtocolFamily { /// IPv4 Address Family INET = AF_INET as isize, @@ -58,6 +59,7 @@ impl Handle { pub fn bind(&mut self, proto: ProtocolFamily) -> Result<(), Error> { let _lock = LOCK.lock().unwrap(); + unsafe { nfq_unbind_pf(self.ptr, proto as uint16_t) }; let res = unsafe { nfq_bind_pf(self.ptr, proto as uint16_t) }; if res < 0 { Err(error(Reason::Bind, "Failed to bind handle", Some(res))) From 18c708b8e2ca2e4fdc6dbf3ba3e053aacc580fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Sun, 18 Sep 2016 18:55:36 +0800 Subject: [PATCH 06/10] fix nfq_get_payload call: don't use *const T as *mut T --- src/message.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/message.rs b/src/message.rs index f04b137..fda982e 100644 --- a/src/message.rs +++ b/src/message.rs @@ -4,7 +4,7 @@ use libc::*; use std::mem; -use std::ptr::null; +use std::ptr::null_mut; use std::net::Ipv4Addr; use error::*; use util::*; @@ -105,13 +105,14 @@ impl<'a> Message<'a> { /// and `handle.start_sized_to_payload` methods. /// See `examples/get_addrs.rs`. pub unsafe fn payload(&self) -> Result<(&A, usize), Error> { - let data: *const A = null(); - let ptr: *mut *mut A = &mut (data as *mut A); + let mut data: *mut A = null_mut(); + let ptr: *mut *mut A = &mut data; let n = match nfq_get_payload(self.ptr, ptr as *mut *mut c_uchar) { -1 => return Err(error(Reason::GetPayload, "Failed to get payload", Some(-1))), n => n }; - match as_ref(&data) { + println!("{:?}, n={}", data, n); + match as_mut(&data) { Some(payload) => Ok((payload, n as usize)), None => Err(error(Reason::GetPayload, "Failed to get payload", None)) } From 33db11602582e7bd97480ede7bb8e1b5865853a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Sun, 18 Sep 2016 19:01:23 +0800 Subject: [PATCH 07/10] oops, removing debugging statement --- src/message.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/message.rs b/src/message.rs index fda982e..66d5d5c 100644 --- a/src/message.rs +++ b/src/message.rs @@ -111,7 +111,6 @@ impl<'a> Message<'a> { -1 => return Err(error(Reason::GetPayload, "Failed to get payload", Some(-1))), n => n }; - println!("{:?}, n={}", data, n); match as_mut(&data) { Some(payload) => Ok((payload, n as usize)), None => Err(error(Reason::GetPayload, "Failed to get payload", None)) From f3cb1125d157f84b9488488ab51fb214b06c286f Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Mon, 29 Apr 2019 14:55:48 +0800 Subject: [PATCH 08/10] update deps --- Cargo.toml | 11 ++++++----- src/ffi.rs | 7 ------- src/handle.rs | 4 ++-- src/queue/verdict.rs | 6 +++--- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 25cbc7b..ecfbf91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "netfilter_queue" -version = "0.2.1" +version = "0.2.2" authors = [ + "lilydjwg ", "Laurie Clark-Michalek ", "Zach Pomerantz " ] @@ -13,7 +14,7 @@ keywords = ["iptables", "nf", "nfq", "netfilter", "netfilter_queue"] exclude = [".gitignore"] [dependencies] -lazy_static = "0.1.*" -libc = "0.1" -num = "0.1.*" -errno = "0.1.*" +lazy_static = "1" +libc = "0.2" +num = "0.2" +errno = "0.2" diff --git a/src/ffi.rs b/src/ffi.rs index e5c4240..cb91c55 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -2,13 +2,6 @@ use libc::*; -pub const NF_DROP: u32 = 0; -pub const NF_ACCEPT: u32 = 1; -pub const NF_STOLEN: u32 = 2; -pub const NF_QUEUE: u32 = 3; -pub const NF_REPEAT: u32 = 4; -pub const NF_STOP: u32 = 5; - #[repr(C)] pub struct nfq_handle(c_void); diff --git a/src/handle.rs b/src/handle.rs index e4bf959..d66e010 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -97,14 +97,14 @@ impl Handle { pub fn start(&mut self, length: u16) -> Result<(), Error> { unsafe { // TODO: Get rid of malloc - let buffer: *mut c_void = malloc(length as u64); + let buffer: *mut c_void = malloc(length as usize); if buffer.is_null() { panic!("Failed to allocate packet buffer"); } let fd = nfq_fd(self.ptr); loop { - match recv(fd, buffer, length as u64, 0) { + match recv(fd, buffer, length as usize, 0) { rv if rv >=0 => { nfq_handle_packet(self.ptr, buffer as *mut c_char, length as i32); }, diff --git a/src/queue/verdict.rs b/src/queue/verdict.rs index 3837a0c..94ae69c 100644 --- a/src/queue/verdict.rs +++ b/src/queue/verdict.rs @@ -39,12 +39,12 @@ pub enum Verdict { impl Verdict { // Encodes the enum into a u32 suitible for use by nfq_set_verdict - fn as_u32(&self) -> u32 { + fn as_i32(&self) -> i32 { match *self { Verdict::Drop => NF_DROP, Verdict::Accept => NF_ACCEPT, Verdict::Stolen => NF_STOLEN, - Verdict::Queue(t) => NF_QUEUE | (t as u32) << 16, + Verdict::Queue(t) => NF_QUEUE | (t as i32) << 16, Verdict::Repeat => NF_REPEAT, Verdict::Stop => NF_STOP, } @@ -55,7 +55,7 @@ impl Verdict { /// The `packet_id` must be used to identify a packet, fetched from `packet.header.id()`. /// For simpler cases, pass `data_len = 0` and `buffer = std::ptr::null()`. pub fn set_verdict(qh: QueueHandle, packet_id: u32, verdict: Verdict, data_len: u32, buffer: *const c_uchar) -> Result { - let c_verdict = verdict.as_u32() as uint32_t; + let c_verdict = verdict.as_i32() as int32_t; match unsafe { nfq_set_verdict(qh.0, packet_id as uint32_t, c_verdict as uint32_t, data_len as uint32_t, buffer) } { -1 => Err(error(Reason::SetVerdict, "Failed to set verdict", None)), From e15cdec84416d01b9f4f0dab2a149980f5d231c5 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Mon, 29 Apr 2019 15:02:22 +0800 Subject: [PATCH 09/10] IPHeader should be repr(C) --- src/message.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/message.rs b/src/message.rs index 66d5d5c..00e291d 100644 --- a/src/message.rs +++ b/src/message.rs @@ -17,6 +17,7 @@ pub trait Payload {} #[allow(dead_code)] #[allow(missing_docs)] /// A `Payload` to fetch and parse an IP packet header +#[repr(C)] pub struct IPHeader { pub version_and_header_raw: u8, pub dscp_raw: u8, From 4fb103db900fd34fbde09f9a12b3f2de9b3af00d Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Tue, 18 Feb 2020 19:57:28 +0800 Subject: [PATCH 10/10] update --- src/error.rs | 2 +- src/ffi.rs | 24 ++++++++++++------------ src/handle.rs | 8 ++++---- src/message.rs | 4 ++++ src/queue/mod.rs | 12 ++++++------ src/queue/verdict.rs | 4 ++-- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/error.rs b/src/error.rs index bf55b8c..1f83644 100644 --- a/src/error.rs +++ b/src/error.rs @@ -41,7 +41,7 @@ impl Base for Error { fn description(&self) -> &str { self.description.as_ref() } - fn cause(&self) -> Option<&Base> { + fn cause(&self) -> Option<&dyn Base> { None } } diff --git a/src/ffi.rs b/src/ffi.rs index cb91c55..b6a9bca 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -22,11 +22,11 @@ pub struct nfqnl_msg_packet_hdr { /// /// This id is necessary to identify the packet to `set_verdict`. /// However, it may have the wrong endianness, so `id()` should be used instead. - pub packet_id: uint32_t, + pub packet_id: u32, /// HW protocol (network order) - pub hw_protocol: uint16_t, + pub hw_protocol: u16, /// Netfilter hook - pub hook: uint8_t + pub hook: u8, } impl nfqnl_msg_packet_hdr { @@ -43,12 +43,12 @@ extern { // Library setup pub fn nfq_open() -> *mut nfq_handle; pub fn nfq_close(handle: *mut nfq_handle) -> c_int; - pub fn nfq_bind_pf(handle: *mut nfq_handle, pf: uint16_t) -> c_int; - pub fn nfq_unbind_pf(handle: *mut nfq_handle, pf: uint16_t) -> c_int; + pub fn nfq_bind_pf(handle: *mut nfq_handle, pf: u16) -> c_int; + pub fn nfq_unbind_pf(handle: *mut nfq_handle, pf: u16) -> c_int; // Queue handling pub fn nfq_create_queue(handle: *mut nfq_handle, - num: uint16_t, + num: u16, cb: extern "C" fn(h: *mut nfq_q_handle, nfmsg: *mut nfgenmsg, nfad: *mut nfq_data, @@ -56,10 +56,10 @@ extern { data: *mut c_void) -> *mut nfq_q_handle; pub fn nfq_destroy_queue(handle: *mut nfq_q_handle) -> c_int; pub fn nfq_set_mode(handle: *mut nfq_q_handle, - mode: uint8_t, - range: uint32_t) -> c_int; + mode: u8, + range: u32) -> c_int; pub fn nfq_set_queue_maxlen(handle: *mut nfq_q_handle, - queuelen: uint32_t) -> c_int; + queuelen: u32) -> c_int; // Iterating through a queue pub fn nfq_fd(handle: *mut nfq_handle) -> c_int; @@ -69,9 +69,9 @@ extern { // Deciding on a verdict pub fn nfq_set_verdict(handle: *mut nfq_q_handle, - id: uint32_t, - verdict: uint32_t, - data_len: uint32_t, + id: u32, + verdict: u32, + data_len: u32, buf: *const c_uchar) -> c_int; // Parsing the message diff --git a/src/handle.rs b/src/handle.rs index d66e010..e9dbdc4 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -59,8 +59,8 @@ impl Handle { pub fn bind(&mut self, proto: ProtocolFamily) -> Result<(), Error> { let _lock = LOCK.lock().unwrap(); - unsafe { nfq_unbind_pf(self.ptr, proto as uint16_t) }; - let res = unsafe { nfq_bind_pf(self.ptr, proto as uint16_t) }; + unsafe { nfq_unbind_pf(self.ptr, proto as u16) }; + let res = unsafe { nfq_bind_pf(self.ptr, proto as u16) }; if res < 0 { Err(error(Reason::Bind, "Failed to bind handle", Some(res))) } else { @@ -74,7 +74,7 @@ impl Handle { pub fn unbind(&mut self, proto: ProtocolFamily) -> Result<(), Error> { let _lock = LOCK.lock().unwrap(); - let res = unsafe { nfq_unbind_pf(self.ptr, proto as uint16_t) }; + let res = unsafe { nfq_unbind_pf(self.ptr, proto as u16) }; if res < 0 { Err(error(Reason::Unbind, "Failed to unbind handle", Some(res))) } else { @@ -86,7 +86,7 @@ impl Handle { pub fn queue(&mut self, queue_number: u16, handler: F) -> Result>, Error> { - Queue::new(self.ptr, queue_number as uint16_t, handler) + Queue::new(self.ptr, queue_number, handler) } /// Start listening using any attached queues diff --git a/src/message.rs b/src/message.rs index 00e291d..74acb53 100644 --- a/src/message.rs +++ b/src/message.rs @@ -105,6 +105,10 @@ impl<'a> Message<'a> { /// The best way to do this is with the `queue_builder.set_copy_mode_sized_to_payload` /// and `handle.start_sized_to_payload` methods. /// See `examples/get_addrs.rs`. + /// + /// # Safety + /// + /// ffi call to C. pub unsafe fn payload(&self) -> Result<(&A, usize), Error> { let mut data: *mut A = null_mut(); let ptr: *mut *mut A = &mut data; diff --git a/src/queue/mod.rs b/src/queue/mod.rs index 25c3809..c4f4324 100644 --- a/src/queue/mod.rs +++ b/src/queue/mod.rs @@ -16,9 +16,9 @@ use lock::NFQ_LOCK as LOCK; use ffi::*; -const NFQNL_COPY_NONE: uint8_t = 0; -const NFQNL_COPY_META: uint8_t = 1; -const NFQNL_COPY_PACKET: uint8_t = 2; +const NFQNL_COPY_NONE: u8 = 0; +const NFQNL_COPY_META: u8 = 1; +const NFQNL_COPY_PACKET: u8 = 2; /// The amount of data to be copied to userspace for each packet queued. pub enum CopyMode { @@ -67,7 +67,7 @@ impl Drop for Queue { impl Queue { #[doc(hidden)] pub fn new(handle: *mut nfq_handle, - queue_number: uint16_t, + queue_number: u16, packet_handler: F) -> Result>, Error> { let _lock = LOCK.lock().unwrap(); @@ -100,11 +100,11 @@ impl Queue { CopyMode::None => NFQNL_COPY_NONE, CopyMode::Metadata => NFQNL_COPY_META, CopyMode::Packet(_) => NFQNL_COPY_PACKET - } as uint8_t; + }; let range = match mode { CopyMode::Packet(r) => r, _ => 0 - } as uint32_t; + } as u32; let res = unsafe { nfq_set_mode(self.ptr, copy_mode, range) }; if res != 0 { diff --git a/src/queue/verdict.rs b/src/queue/verdict.rs index 94ae69c..57d36b3 100644 --- a/src/queue/verdict.rs +++ b/src/queue/verdict.rs @@ -55,9 +55,9 @@ impl Verdict { /// The `packet_id` must be used to identify a packet, fetched from `packet.header.id()`. /// For simpler cases, pass `data_len = 0` and `buffer = std::ptr::null()`. pub fn set_verdict(qh: QueueHandle, packet_id: u32, verdict: Verdict, data_len: u32, buffer: *const c_uchar) -> Result { - let c_verdict = verdict.as_i32() as int32_t; + let c_verdict = verdict.as_i32() as u32; - match unsafe { nfq_set_verdict(qh.0, packet_id as uint32_t, c_verdict as uint32_t, data_len as uint32_t, buffer) } { + match unsafe { nfq_set_verdict(qh.0, packet_id, c_verdict, data_len, buffer) } { -1 => Err(error(Reason::SetVerdict, "Failed to set verdict", None)), r @ _ => Ok(r) }