// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /// Configuration file for netsim use netsim_proto::config::Config; use protobuf_json_mapping::merge_from_str; use std::fs; use std::net::{Ipv4Addr, Ipv6Addr}; #[allow(dead_code)] pub fn new_from_file(filename: &str) -> Result { let contents = fs::read_to_string(filename) .map_err(|e| format!("Failed to read config file {}: {} ", filename, e))?; from_str(&contents) } pub fn from_str(contents: &str) -> Result { let mut config = Config::new(); merge_from_str(&mut config, contents).map_err(|e| format!("Failed to parse config: {}", e))?; validate_wifi(&config.wifi)?; Ok(config) } fn validate_wifi(wifi: &netsim_proto::config::WiFi) -> Result<(), String> { validate_ipv4(&wifi.slirp_options.vnet, "vnet")?; validate_ipv4(&wifi.slirp_options.vhost, "vhost")?; validate_ipv4(&wifi.slirp_options.vmask, "vmask")?; validate_ipv6(&wifi.slirp_options.vprefix6, "vprefix6")?; validate_ipv6(&wifi.slirp_options.vhost6, "vhost6")?; Ok(()) } fn validate_ipv4(in_addr: &str, field: &str) -> Result<(), String> { if !in_addr.is_empty() { in_addr.parse::().map_err(|e| format!("Invalid {}: {}", field, e))?; } Ok(()) } fn validate_ipv6(in6_addr: &str, field: &str) -> Result<(), String> { if !in6_addr.is_empty() { in6_addr.parse::().map_err(|e| format!("Invalid {}: {}", field, e))?; } Ok(()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_json() { let config = from_str( r#" { "wifi" : { "slirp_options" : { "disabled" : true, "vnet" : "192.168.1.1" } } }"#, ); eprintln!("{:?}", config); assert!(config.as_ref().ok().is_some()); let config = config.unwrap(); assert!(config.wifi.slirp_options.as_ref().unwrap().disabled); } }