Skip to content

Commit

Permalink
fix(dc): support updated wireshark definitions (#2346)
Browse files Browse the repository at this point in the history
  • Loading branch information
camshaft authored Oct 9, 2024
1 parent 6b872aa commit 032f326
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 32 deletions.
12 changes: 10 additions & 2 deletions dc/wireshark/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

fn main() {
let plugin_name = option_env("PLUGIN_NAME").unwrap_or_else(|| "dcQUIC".to_string());
println!("cargo:rustc-env=PLUGIN_NAME={plugin_name}");
let plugin_name = fwd("PLUGIN_NAME", "dcQUIC");
let _ = fwd("PLUGIN_MAJOR_VERSION", "4");
let _ = fwd("PLUGIN_MINOR_VERSION", "2");
println!(
"cargo:rustc-env=PLUGIN_NAME_LOWER={}",
plugin_name.to_lowercase()
Expand All @@ -18,6 +19,13 @@ fn main() {
}
}

fn fwd<N: AsRef<str>, D: AsRef<str>>(name: N, default: D) -> String {
let name = name.as_ref();
let value = option_env(name).unwrap_or_else(|| default.as_ref().to_string());
println!("cargo:rustc-env={name}={value}");
value
}

fn env<N: AsRef<str>>(name: N) -> String {
let name = name.as_ref();
option_env(name).unwrap_or_else(|| panic!("missing env {name}"))
Expand Down
34 changes: 24 additions & 10 deletions dc/wireshark/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@ use std::{ffi::CStr, sync::OnceLock};
#[used]
static plugin_version: [std::ffi::c_char; 4] = [b'0' as _, b'.' as _, b'1' as _, b'\0' as _];

macro_rules! env_version {
($name:literal) => {{
let v = env!($name);
if v.len() != 1 {
panic!("unexpected version");
}
let v = v.as_bytes()[0] as char;
match v.to_digit(10) {
Some(v) => v as _,
None => panic!("unexpected version"),
}
}};
}

// When bumping, make sure that the bindgen bindings are updated to the new version.
#[no_mangle]
#[used]
static plugin_want_major: std::ffi::c_int = 4;
static plugin_want_major: std::ffi::c_int = env_version!("PLUGIN_MAJOR_VERSION");

// When bumping, make sure that the bindgen bindings are updated to the new version.
#[no_mangle]
#[used]
static plugin_want_minor: std::ffi::c_int = 2;
static plugin_want_minor: std::ffi::c_int = env_version!("PLUGIN_MINOR_VERSION");

#[no_mangle]
pub extern "C" fn plugin_register() {
Expand Down Expand Up @@ -80,12 +94,12 @@ pub fn copy_to_rust(tvb: *mut wireshark_sys::tvbuff_t) -> Vec<u8> {
buffer
}

unsafe extern "C" fn dissect_heur_udp(
unsafe extern "C" fn dissect_heur_udp<Ret: From<bool>>(
tvb: *mut wireshark_sys::tvbuff_t,
mut pinfo: *mut wireshark_sys::_packet_info,
proto: *mut wireshark_sys::_proto_node,
_: *mut std::ffi::c_void,
) -> i32 {
) -> Ret {
let fields = field::get();

let packet = copy_to_rust(tvb);
Expand Down Expand Up @@ -116,7 +130,7 @@ unsafe extern "C" fn dissect_heur_udp(

// Didn't look like a dcQUIC packet.
if accepted_offset == 0 {
return 0;
return false.into();
}

if !info.is_empty() {
Expand All @@ -128,15 +142,15 @@ unsafe extern "C" fn dissect_heur_udp(

set_protocol(pinfo, c"dcQUIC");

accepted_offset as _
(accepted_offset != 0).into()
}

unsafe extern "C" fn dissect_heur_tcp(
unsafe extern "C" fn dissect_heur_tcp<Ret: From<bool>>(
tvb: *mut wireshark_sys::tvbuff_t,
mut pinfo: *mut wireshark_sys::_packet_info,
proto: *mut wireshark_sys::_proto_node,
_: *mut std::ffi::c_void,
) -> i32 {
) -> Ret {
let fields = field::get();

let packet = copy_to_rust(tvb);
Expand Down Expand Up @@ -179,7 +193,7 @@ unsafe extern "C" fn dissect_heur_tcp(

// Didn't look like a dcQUIC segment.
if accepted_offset == 0 {
return 0;
return false.into();
}

if !info.is_empty() {
Expand All @@ -191,7 +205,7 @@ unsafe extern "C" fn dissect_heur_tcp(

set_protocol(pinfo, c"TCP/dcQUIC");

accepted_offset as _
(accepted_offset != 0).into()
}

unsafe fn register_root_node(
Expand Down
8 changes: 4 additions & 4 deletions dc/wireshark/src/wireshark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ mod wireshark_sys_impl {
buffer.tvb,
parsed.offset as _,
parsed.len as _,
parsed.value as u32,
parsed.value as _,
)
}
}
Expand All @@ -186,7 +186,7 @@ mod wireshark_sys_impl {
buffer.tvb,
parsed.offset as _,
parsed.len as _,
parsed.value.into() as u32,
parsed.value.into() as _,
)
}
}
Expand Down Expand Up @@ -237,8 +237,8 @@ mod wireshark_sys_impl {
parsed: Parsed<Duration>,
) -> Self::AddedItem {
let time = wireshark_sys::nstime_t {
secs: parsed.value.as_secs() as i64,
nsecs: parsed.value.subsec_nanos() as i32,
secs: parsed.value.as_secs() as _,
nsecs: parsed.value.subsec_nanos() as _,
};
unsafe {
wireshark_sys::proto_tree_add_time(
Expand Down
114 changes: 98 additions & 16 deletions dc/wireshark/xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,46 @@ struct Build {
profile: Option<String>,
#[arg(long)]
target: Option<String>,
#[command(flatten)]
wireshark_version: WiresharkVersion,
}

impl Build {
fn run(self, sh: &Shell) -> Result {
fn run(mut self, sh: &Shell) -> Result {
self.wireshark_version.load(sh);

let target = if let Some(target) = self.target.as_ref() {
let _ = cmd!(sh, "rustup target add {target}").run();
vec!["--target", target]
} else {
vec![]
};
let profile = self.profile.as_deref().unwrap_or("release");

let _env = sh.push_env(
"PLUGIN_MAJOR_VERSION",
self.wireshark_version.major_version(),
);
let _env = sh.push_env(
"PLUGIN_MINOR_VERSION",
self.wireshark_version.minor_version(),
);

cmd!(sh, "cargo build --profile {profile} {target...}").run()?;
Ok(())
}
}

#[derive(Debug, Parser)]
struct Test {}
struct Test {
#[command(flatten)]
wireshark_version: WiresharkVersion,
}

impl Test {
fn run(self, sh: &Shell) -> Result {
fn run(mut self, sh: &Shell) -> Result {
cmd!(sh, "cargo test").run()?;
let plugin_dir = plugin_dir();
let plugin_dir = self.wireshark_version.plugin_dir(sh);

sh.create_dir(format!("target/wireshark/{plugin_dir}"))?;
sh.create_dir("target/pcaps")?;
Expand All @@ -76,6 +93,14 @@ impl Test {
let plugin_name = "dcQUIC__DEV";
let plugin_name_lower = &plugin_name.to_lowercase();
let _env = sh.push_env("PLUGIN_NAME", plugin_name);
let _env = sh.push_env(
"PLUGIN_MAJOR_VERSION",
self.wireshark_version.major_version(),
);
let _env = sh.push_env(
"PLUGIN_MINOR_VERSION",
self.wireshark_version.minor_version(),
);

let profile = "release-test";

Expand Down Expand Up @@ -176,26 +201,27 @@ fn so() -> &'static str {
}
}

fn plugin_dir() -> &'static str {
if cfg!(target_os = "macos") {
"plugins/4-2/epan"
} else {
"plugins/4.2/epan"
}
}

#[derive(Debug, Parser)]
struct Install {}
struct Install {
#[command(flatten)]
wireshark_version: WiresharkVersion,
}

impl Install {
fn run(self, sh: &Shell) -> Result {
Build::default().run(sh)?;
fn run(mut self, sh: &Shell) -> Result {
let plugin_dir = self.wireshark_version.plugin_dir(sh);

Build {
wireshark_version: self.wireshark_version.clone(),
..Default::default()
}
.run(sh)?;

let dir = if cfg!(unix) {
homedir::get_my_home()?
.expect("missing home dir")
.join(".local/lib/wireshark")
.join(plugin_dir())
.join(plugin_dir)
} else {
todo!("OS is currently unsupported")
};
Expand All @@ -212,6 +238,62 @@ impl Install {
}
}

#[derive(Clone, Debug, Default, Parser)]
struct WiresharkVersion {
#[arg(long, default_value = "DYNAMIC")]
wireshark_version: String,
}

impl WiresharkVersion {
fn plugin_dir(&mut self, sh: &Shell) -> String {
self.load(sh);

let value = &self.wireshark_version;
if cfg!(target_os = "macos") {
format!("plugins/{}/epan", value.replace('.', "-"))
} else {
format!("plugins/{value}/epan")
}
}

fn load(&mut self, sh: &Shell) {
if !(self.wireshark_version.is_empty() || self.wireshark_version == "DYNAMIC") {
return;
}

let tshark = tshark(sh).unwrap();
let output = cmd!(sh, "{tshark} --version").read().unwrap();
let version = output.lines().next().unwrap();
let version = version.trim_start_matches(|v: char| !v.is_digit(10));
let (version, _) = version
.split_once(char::is_whitespace)
.unwrap_or((version, ""));

let version = version.trim_end_matches('.');

match version.split('.').count() {
2 => {
self.wireshark_version = version.to_string();
}
3 => {
let (version, _) = version.rsplit_once('.').unwrap();
self.wireshark_version = version.to_string();
}
_ => panic!("invalid tshark version: {version}"),
}
}

fn major_version(&self) -> &str {
let (version, _) = self.wireshark_version.split_once('.').unwrap();
version
}

fn minor_version(&self) -> &str {
let (_, version) = self.wireshark_version.split_once('.').unwrap();
version
}
}

fn main() {
Args::parse().run();
}

0 comments on commit 032f326

Please sign in to comment.