1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*cf78ab8cSAndroid Build Coastguard Worker //
3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cf78ab8cSAndroid Build Coastguard Worker //
7*cf78ab8cSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*cf78ab8cSAndroid Build Coastguard Worker //
9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License.
14*cf78ab8cSAndroid Build Coastguard Worker
15*cf78ab8cSAndroid Build Coastguard Worker /// Configuration file for netsim
16*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::config::Config;
17*cf78ab8cSAndroid Build Coastguard Worker use protobuf_json_mapping::merge_from_str;
18*cf78ab8cSAndroid Build Coastguard Worker use std::fs;
19*cf78ab8cSAndroid Build Coastguard Worker use std::net::{Ipv4Addr, Ipv6Addr};
20*cf78ab8cSAndroid Build Coastguard Worker
21*cf78ab8cSAndroid Build Coastguard Worker #[allow(dead_code)]
new_from_file(filename: &str) -> Result<Config, String>22*cf78ab8cSAndroid Build Coastguard Worker pub fn new_from_file(filename: &str) -> Result<Config, String> {
23*cf78ab8cSAndroid Build Coastguard Worker let contents = fs::read_to_string(filename)
24*cf78ab8cSAndroid Build Coastguard Worker .map_err(|e| format!("Failed to read config file {}: {} ", filename, e))?;
25*cf78ab8cSAndroid Build Coastguard Worker from_str(&contents)
26*cf78ab8cSAndroid Build Coastguard Worker }
27*cf78ab8cSAndroid Build Coastguard Worker
from_str(contents: &str) -> Result<Config, String>28*cf78ab8cSAndroid Build Coastguard Worker pub fn from_str(contents: &str) -> Result<Config, String> {
29*cf78ab8cSAndroid Build Coastguard Worker let mut config = Config::new();
30*cf78ab8cSAndroid Build Coastguard Worker merge_from_str(&mut config, contents).map_err(|e| format!("Failed to parse config: {}", e))?;
31*cf78ab8cSAndroid Build Coastguard Worker validate_wifi(&config.wifi)?;
32*cf78ab8cSAndroid Build Coastguard Worker Ok(config)
33*cf78ab8cSAndroid Build Coastguard Worker }
34*cf78ab8cSAndroid Build Coastguard Worker
validate_wifi(wifi: &netsim_proto::config::WiFi) -> Result<(), String>35*cf78ab8cSAndroid Build Coastguard Worker fn validate_wifi(wifi: &netsim_proto::config::WiFi) -> Result<(), String> {
36*cf78ab8cSAndroid Build Coastguard Worker validate_ipv4(&wifi.slirp_options.vnet, "vnet")?;
37*cf78ab8cSAndroid Build Coastguard Worker validate_ipv4(&wifi.slirp_options.vhost, "vhost")?;
38*cf78ab8cSAndroid Build Coastguard Worker validate_ipv4(&wifi.slirp_options.vmask, "vmask")?;
39*cf78ab8cSAndroid Build Coastguard Worker validate_ipv6(&wifi.slirp_options.vprefix6, "vprefix6")?;
40*cf78ab8cSAndroid Build Coastguard Worker validate_ipv6(&wifi.slirp_options.vhost6, "vhost6")?;
41*cf78ab8cSAndroid Build Coastguard Worker Ok(())
42*cf78ab8cSAndroid Build Coastguard Worker }
43*cf78ab8cSAndroid Build Coastguard Worker
validate_ipv4(in_addr: &str, field: &str) -> Result<(), String>44*cf78ab8cSAndroid Build Coastguard Worker fn validate_ipv4(in_addr: &str, field: &str) -> Result<(), String> {
45*cf78ab8cSAndroid Build Coastguard Worker if !in_addr.is_empty() {
46*cf78ab8cSAndroid Build Coastguard Worker in_addr.parse::<Ipv4Addr>().map_err(|e| format!("Invalid {}: {}", field, e))?;
47*cf78ab8cSAndroid Build Coastguard Worker }
48*cf78ab8cSAndroid Build Coastguard Worker Ok(())
49*cf78ab8cSAndroid Build Coastguard Worker }
50*cf78ab8cSAndroid Build Coastguard Worker
validate_ipv6(in6_addr: &str, field: &str) -> Result<(), String>51*cf78ab8cSAndroid Build Coastguard Worker fn validate_ipv6(in6_addr: &str, field: &str) -> Result<(), String> {
52*cf78ab8cSAndroid Build Coastguard Worker if !in6_addr.is_empty() {
53*cf78ab8cSAndroid Build Coastguard Worker in6_addr.parse::<Ipv6Addr>().map_err(|e| format!("Invalid {}: {}", field, e))?;
54*cf78ab8cSAndroid Build Coastguard Worker }
55*cf78ab8cSAndroid Build Coastguard Worker Ok(())
56*cf78ab8cSAndroid Build Coastguard Worker }
57*cf78ab8cSAndroid Build Coastguard Worker
58*cf78ab8cSAndroid Build Coastguard Worker #[cfg(test)]
59*cf78ab8cSAndroid Build Coastguard Worker mod tests {
60*cf78ab8cSAndroid Build Coastguard Worker use super::*;
61*cf78ab8cSAndroid Build Coastguard Worker
62*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_json()63*cf78ab8cSAndroid Build Coastguard Worker fn test_json() {
64*cf78ab8cSAndroid Build Coastguard Worker let config = from_str(
65*cf78ab8cSAndroid Build Coastguard Worker r#"
66*cf78ab8cSAndroid Build Coastguard Worker {
67*cf78ab8cSAndroid Build Coastguard Worker "wifi" : {
68*cf78ab8cSAndroid Build Coastguard Worker "slirp_options" : {
69*cf78ab8cSAndroid Build Coastguard Worker "disabled" : true,
70*cf78ab8cSAndroid Build Coastguard Worker "vnet" : "192.168.1.1"
71*cf78ab8cSAndroid Build Coastguard Worker }
72*cf78ab8cSAndroid Build Coastguard Worker }
73*cf78ab8cSAndroid Build Coastguard Worker }"#,
74*cf78ab8cSAndroid Build Coastguard Worker );
75*cf78ab8cSAndroid Build Coastguard Worker eprintln!("{:?}", config);
76*cf78ab8cSAndroid Build Coastguard Worker assert!(config.as_ref().ok().is_some());
77*cf78ab8cSAndroid Build Coastguard Worker let config = config.unwrap();
78*cf78ab8cSAndroid Build Coastguard Worker assert!(config.wifi.slirp_options.as_ref().unwrap().disabled);
79*cf78ab8cSAndroid Build Coastguard Worker }
80*cf78ab8cSAndroid Build Coastguard Worker }
81