Config loading
This commit is contained in:
parent
c76325b42b
commit
4baae22c25
22
Cargo.toml
22
Cargo.toml
@ -1,23 +1,29 @@
|
||||
[package]
|
||||
name = "<crate_name>"
|
||||
name = "protomask"
|
||||
version = "0.1.0"
|
||||
authors = ["Evan Pratten <ewpratten@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "<description>"
|
||||
documentation = "https://docs.rs/<crate_name>"
|
||||
readme = "README.md"
|
||||
homepage = "https://github.com/ewpratten/<repo_name>"
|
||||
repository = "https://github.com/ewpratten/<repo_name>"
|
||||
homepage = "https://github.com/ewpratten/protomask"
|
||||
repository = "https://github.com/ewpratten/protomask"
|
||||
license = "GPL-3.0"
|
||||
keywords = []
|
||||
categories = []
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
|
||||
clap = { version = "4.3.11", features = ["derive"] }
|
||||
serde = { version = "1.0.171", features = ["derive"] }
|
||||
ipnet = { version = "2.8.0", features = ["serde"] }
|
||||
toml = "0.7.6"
|
||||
log = "0.4.19"
|
||||
fern = "0.6.2"
|
||||
serde_path_to_error = "0.1.13"
|
||||
thiserror = "1.0.43"
|
||||
colored = "2.0.4"
|
||||
|
||||
[[bin]]
|
||||
name = "<crate_name>"
|
||||
name = "protomask"
|
||||
path = "src/main.rs"
|
||||
|
||||
|
12
README.md
12
README.md
@ -1,8 +1,8 @@
|
||||
# <repo_name>
|
||||
[](https://crates.io/crates/<crate_name>)
|
||||
[](https://docs.rs/<crate_name>)
|
||||
[](https://github.com/Ewpratten/<repo_name>/actions/workflows/build.yml)
|
||||
[](https://github.com/Ewpratten/<repo_name>/actions/workflows/clippy.yml)
|
||||
# protomask
|
||||
[](https://crates.io/crates/protomask)
|
||||
[](https://docs.rs/protomask)
|
||||
[](https://github.com/Ewpratten/protomask/actions/workflows/build.yml)
|
||||
[](https://github.com/Ewpratten/protomask/actions/workflows/clippy.yml)
|
||||
|
||||
|
||||
repo description
|
||||
@ -12,5 +12,5 @@ repo description
|
||||
This crate can be installed via `cargo` with:
|
||||
|
||||
```sh
|
||||
cargo install <crate_name>
|
||||
cargo install protomask
|
||||
```
|
||||
|
22
protomask.toml
Normal file
22
protomask.toml
Normal file
@ -0,0 +1,22 @@
|
||||
# Example configuration file for protomask
|
||||
|
||||
# Options for configuring the NAT64 interface
|
||||
[interface]
|
||||
# A list of IPv4 prefixes to use as the NAT64 pool
|
||||
# The first address of the pool will be assigned to protomask itself (for ICMP messaging)
|
||||
pool = ["192.0.2.0/24"]
|
||||
|
||||
# The IPv6 prefix to use for the NAT64 interface.
|
||||
prefix = "64:ff9b::/96"
|
||||
|
||||
# A unique IPv6 address to use for ICMP messaging
|
||||
# This will also serve DNS64
|
||||
icmpv6_address = "2001:db8:1::1"
|
||||
|
||||
# Rules for controlling address mapping
|
||||
[rules]
|
||||
# A static mapping of IPv4 and IPv6 addresses
|
||||
# These addresses will be exclusively reserved, and not used in the general pool
|
||||
static_map = [
|
||||
{ v4 = "192.0.2.2", v6 = "2001:db8:1::2" }
|
||||
]
|
15
src/cli.rs
Normal file
15
src/cli.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Args {
|
||||
|
||||
/// Path to the config file
|
||||
pub config_file: PathBuf,
|
||||
|
||||
/// Enable verbose logging
|
||||
#[clap(short, long)]
|
||||
pub verbose: bool,
|
||||
}
|
67
src/config.rs
Normal file
67
src/config.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use std::{
|
||||
net::{Ipv4Addr, Ipv6Addr},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use colored::Colorize;
|
||||
use ipnet::{Ipv4Net, Ipv6Net};
|
||||
|
||||
/// Interface config
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct InterfaceConfig {
|
||||
/// Ipv4 pool
|
||||
pub pool: Vec<Ipv4Net>,
|
||||
/// IPv6 prefix
|
||||
pub prefix: Ipv6Net,
|
||||
/// IPv6 router addr
|
||||
pub icmpv6_address: Ipv6Addr,
|
||||
}
|
||||
|
||||
/// A static mapping rule
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct AddressMappingRule {
|
||||
/// IPv4 address
|
||||
pub v4: Ipv4Addr,
|
||||
/// IPv6 address
|
||||
pub v6: Ipv6Addr,
|
||||
}
|
||||
|
||||
/// Rules config
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct RulesConfig {
|
||||
/// Static mapping rules
|
||||
pub static_map: Vec<AddressMappingRule>,
|
||||
}
|
||||
|
||||
/// Representation of the `protomask.toml` config file
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct Config {
|
||||
/// Interface config
|
||||
pub interface: InterfaceConfig,
|
||||
/// Rules config
|
||||
pub rules: RulesConfig,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Load the config from a file
|
||||
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, std::io::Error> {
|
||||
// Load the file
|
||||
let file_contents = std::fs::read_to_string(path)?;
|
||||
|
||||
// Build the deserializer
|
||||
let deserializer = toml::Deserializer::new(&file_contents);
|
||||
|
||||
// Parse
|
||||
match serde_path_to_error::deserialize(deserializer) {
|
||||
Ok(config) => Ok(config),
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Failed to parse config file due to:\n {}\n at {}",
|
||||
e.inner().message().bright_red(),
|
||||
e.path().to_string().bright_cyan()
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![deny(unsafe_code)]
|
32
src/main.rs
32
src/main.rs
@ -1,4 +1,30 @@
|
||||
use clap::Parser;
|
||||
use config::Config;
|
||||
|
||||
pub fn main(){
|
||||
|
||||
}
|
||||
mod config;
|
||||
mod cli;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
// Parse CLI args
|
||||
let args = cli::Args::parse();
|
||||
|
||||
// Set up logging
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| out.finish(format_args!("{}: {}", record.level(), message)))
|
||||
.level(match args.verbose {
|
||||
true => log::LevelFilter::Debug,
|
||||
false => log::LevelFilter::Info,
|
||||
})
|
||||
.chain(std::io::stdout())
|
||||
.apply()
|
||||
.unwrap();
|
||||
if args.verbose {
|
||||
log::debug!("Verbose logging enabled");
|
||||
}
|
||||
|
||||
// Parse the config file
|
||||
let config = Config::load(args.config_file).unwrap();
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user