Skip to content

Commit

Permalink
Chromecast packet filtering/forwarding mechanism is added
Browse files Browse the repository at this point in the history
Signed-off-by: Enes Öztürk <enes.ozturk@unikie.com>

* packet forwarding/masquerading mechanism
* mdns query/response filtering/forwarding for chromecast
* ssdp port filtering for chromecast
* cli args
  • Loading branch information
enesoztrk committed Jan 20, 2025
1 parent 4268d94 commit 3c2f83c
Show file tree
Hide file tree
Showing 9 changed files with 1,938 additions and 20 deletions.
425 changes: 411 additions & 14 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@
name = "nw-pckt-fwd"
version = "0.1.0"
edition = "2021"

license = "MIT OR Apache-2.0"
#build = "./custom_task/generate_compile_time_info.rs"
[dependencies]
pnet = "0.35"
tokio = { version = "1.42.0", features = ["full"] }
tokio-util = "0.7.13"
clap = { version = "4.5.23", features = ["derive"] }
log = "0.4.22"
env_logger = "0.11.5"
clap = { version = "4.5.26", features = ["derive"] }
log = "0.4.25"
env_logger = "0.11.6"
pcap = "2.2.0"
lazy_static = "1.5.0"
syslog = "7.0.0"
mdns-parser = "0.1.0"
[build-dependencies]
chrono = "0.4.39"
76 changes: 76 additions & 0 deletions custom_task/generate_compile_time_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use chrono::{DateTime, Utc};
use std::process::Command;
pub fn main() {
// Get the current timestamp
// Get the current date and time in ISO 8601 format
let now: DateTime<Utc> = Utc::now();
let formatted_time = now.to_rfc3339();

// Get the current git commit SHA
let git_sha = Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.output()
.expect("Failed to get git SHA")
.stdout;
let git_sha = String::from_utf8(git_sha)
.expect("Invalid UTF-8")
.trim()
.to_string();

let git_commit_date_time = Command::new("git")
.arg("show")
.arg("-s")
.arg("--format=%ci")
.arg("HEAD")
.output()
.expect("Failed to get git commit date and time")
.stdout;
let git_commit_date_time = String::from_utf8(git_commit_date_time)
.expect("Invalid UTF-8")
.trim()
.to_string();

let git_commit_author_name = Command::new("git")
.arg("show")
.arg("-s")
.arg("--format=%an")
.arg("HEAD")
.output()
.expect("Failed to get git commit date and time")
.stdout;
let git_commit_author_name = String::from_utf8(git_commit_author_name)
.expect("Invalid UTF-8")
.trim()
.to_string();
let git_commit_author_email = Command::new("git")
.arg("show")
.arg("-s")
.arg("--format=%ae")
.arg("HEAD")
.output()
.expect("Failed to get git commit date and time")
.stdout;
let git_commit_author_email = String::from_utf8(git_commit_author_email)
.expect("Invalid UTF-8")
.trim()
.to_string();
// Set environment variables

println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-env=BUILD_TIMESTAMP_UTC={}", formatted_time);
println!("cargo:rustc-env=GIT_SHA={}", git_sha);
println!(
"cargo:rustc-env=GIT_COMMIT_DATE_TIME={}",
git_commit_date_time
);
println!(
"cargo:rustc-env=GIT_COMMIT_AUTHOR_NAME={}",
git_commit_author_name
);
println!(
"cargo:rustc-env=GIT_COMMIT_EMAIL={}",
git_commit_author_email
);
}
2 changes: 2 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
clang
#cargo-audit
cargo-tarpaulin
libpcap
];
};

Expand Down Expand Up @@ -137,6 +138,7 @@
lldb
clang
cargo-audit
libpcap
];
buildPhaseCargoCommand = ''
if [[ "${buildType}" == "release" ]]; then
Expand Down
148 changes: 148 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2022-2023 TII (SSRC) and the contributors
SPDX-License-Identifier: Apache-2.0
*/
use clap::ArgAction;
use clap::Parser;
use lazy_static::lazy_static;
use log::{debug, error, info, trace};
use pnet::datalink::{self};
use pnet::ipnetwork::IpNetwork;
use pnet::util::MacAddr;
use std::error::Error;
use std::net::IpAddr;
use std::net::Ipv4Addr;
use std::str;
lazy_static! {
static ref CLI_ARGS: Args = {


// Initialize the IP address using a function or any other logic
let args=handling_args().expect("Error in argument handling");
println!("{args:?}");
args
};
}
const TRUE: &str = "true";
const FALSE: &str = "false";
// const VERSION: &str = concat!(
// "\nversion: ",
// env!("CARGO_PKG_VERSION"),
// "\ncommit sha: ",
// env!("GIT_SHA"),
// "\ncommit date: ",
// env!("GIT_COMMIT_DATE_TIME"),
// "\ncommit author name: ",
// env!("GIT_COMMIT_AUTHOR_NAME"),
// "\ncommit author e-mail: ",
// env!("GIT_COMMIT_EMAIL"),
// "\nbuild timestamp(utc): ",
// env!("BUILD_TIMESTAMP_UTC"),
// "\nlicense: ",
// env!("CARGO_PKG_LICENSE")
// );

/// Network Packet forwarder tool for Ghaf
#[derive(Parser, Debug)]
#[command(author = "Enes Öztürk")]
#[command(name = "Network Packet Forwarder")]
#[command(about = "Packet forwarder between two network interfaces for Ghaf.")]
#[command(long_about =None /* ,version =VERSION*/)]
struct Args {
/// Name of the external network interface
#[arg(long)]
external_iface: String,

/// Name of the internal network interface
#[arg(long)]
internal_iface: String,

/// IP address of the external network interface
#[arg(long)]
external_ip: Option<IpNetwork>,

/// IP address of the internal network interface
#[arg(long)]
internal_ip: Option<IpNetwork>,

/// Enable Chromecast packet forwarding functionality
#[arg(long,default_value_t=String::from(TRUE),value_parser=is_true_false)]
chromecast: String,

/// Chrome VM Ip address
#[arg(long)]
chromevm_ip: Option<IpNetwork>,

/// Chrome VM Mac address
#[arg(long)]
chromevm_mac: Option<MacAddr>,

/// Log severity
#[arg(long, default_value_t = String::from("info"))]
pub log_level: String,

/// Log output
#[arg(long, default_value_t = String::from("syslog"))]
pub log_output: String,
}

fn handling_args() -> Result<Args, Box<dyn Error>> {
let args: Args = Args::parse();
args.validate();
Ok(args)
}

impl Args {
fn validate(&self) {
if self.chromecast == TRUE || self.chromecast == "1" {
if self.chromevm_ip.is_none() || self.chromevm_mac.is_none() {
panic!("Error: --chromevm_ip and --chromevm_mac are required when --chromecast is enabled.");
}
}
}
}

fn is_true_false(s: &str) -> Result<String, String> {
let val: String = s.parse().map_err(|_| format!("`{s}` isn't a string"))?;
if val == TRUE || val == FALSE || val == "1" || val == "0" {
Ok(val)
} else {
Err("Value can be true or false".to_string())
}
}

pub fn get_ext_iface_name() -> String {
CLI_ARGS.external_iface.clone()
}

pub fn get_int_iface_name() -> String {
CLI_ARGS.internal_iface.clone()
}

pub fn get_ext_ip() -> Option<IpNetwork> {
CLI_ARGS.external_ip
}

pub fn get_int_ip() -> Option<IpNetwork> {
CLI_ARGS.internal_ip
}

pub fn get_chromecast() -> bool {
CLI_ARGS.chromecast == TRUE || CLI_ARGS.chromecast == "1"
}

pub fn get_chromevm_ip() -> IpNetwork {
CLI_ARGS.chromevm_ip.unwrap()
}

pub fn get_chromevm_mac() -> MacAddr {
CLI_ARGS.chromevm_mac.unwrap()
}

pub fn get_log_level() -> &'static str {
&CLI_ARGS.log_level
}

pub fn get_log_output() -> &'static str {
&CLI_ARGS.log_output
}
Loading

0 comments on commit 3c2f83c

Please sign in to comment.