1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2024 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 //! Conversion between Rust and C configurations.
16*cf78ab8cSAndroid Build Coastguard Worker use crate::libslirp_sys::{self, SLIRP_MAX_DNS_SERVERS};
17*cf78ab8cSAndroid Build Coastguard Worker use log::warn;
18*cf78ab8cSAndroid Build Coastguard Worker use std::ffi::CString;
19*cf78ab8cSAndroid Build Coastguard Worker use std::io;
20*cf78ab8cSAndroid Build Coastguard Worker use std::net::SocketAddr;
21*cf78ab8cSAndroid Build Coastguard Worker use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
22*cf78ab8cSAndroid Build Coastguard Worker use std::path::PathBuf;
23*cf78ab8cSAndroid Build Coastguard Worker use tokio;
24*cf78ab8cSAndroid Build Coastguard Worker
25*cf78ab8cSAndroid Build Coastguard Worker const MAX_DNS_SERVERS: usize = SLIRP_MAX_DNS_SERVERS as usize;
26*cf78ab8cSAndroid Build Coastguard Worker
27*cf78ab8cSAndroid Build Coastguard Worker /// Rust SlirpConfig
28*cf78ab8cSAndroid Build Coastguard Worker pub struct SlirpConfig {
29*cf78ab8cSAndroid Build Coastguard Worker pub version: u32,
30*cf78ab8cSAndroid Build Coastguard Worker pub restricted: i32,
31*cf78ab8cSAndroid Build Coastguard Worker pub in_enabled: bool,
32*cf78ab8cSAndroid Build Coastguard Worker pub vnetwork: Ipv4Addr,
33*cf78ab8cSAndroid Build Coastguard Worker pub vnetmask: Ipv4Addr,
34*cf78ab8cSAndroid Build Coastguard Worker pub vhost: Ipv4Addr,
35*cf78ab8cSAndroid Build Coastguard Worker pub in6_enabled: bool,
36*cf78ab8cSAndroid Build Coastguard Worker pub vprefix_addr6: Ipv6Addr,
37*cf78ab8cSAndroid Build Coastguard Worker pub vprefix_len: u8,
38*cf78ab8cSAndroid Build Coastguard Worker pub vhost6: Ipv6Addr,
39*cf78ab8cSAndroid Build Coastguard Worker pub vhostname: Option<String>,
40*cf78ab8cSAndroid Build Coastguard Worker pub tftp_server_name: Option<String>,
41*cf78ab8cSAndroid Build Coastguard Worker pub tftp_path: Option<PathBuf>,
42*cf78ab8cSAndroid Build Coastguard Worker pub bootfile: Option<String>,
43*cf78ab8cSAndroid Build Coastguard Worker pub vdhcp_start: Ipv4Addr,
44*cf78ab8cSAndroid Build Coastguard Worker pub vnameserver: Ipv4Addr,
45*cf78ab8cSAndroid Build Coastguard Worker pub vnameserver6: Ipv6Addr,
46*cf78ab8cSAndroid Build Coastguard Worker pub vdnssearch: Vec<String>,
47*cf78ab8cSAndroid Build Coastguard Worker pub vdomainname: Option<String>,
48*cf78ab8cSAndroid Build Coastguard Worker pub if_mtu: usize,
49*cf78ab8cSAndroid Build Coastguard Worker pub if_mru: usize,
50*cf78ab8cSAndroid Build Coastguard Worker pub disable_host_loopback: bool,
51*cf78ab8cSAndroid Build Coastguard Worker pub enable_emu: bool,
52*cf78ab8cSAndroid Build Coastguard Worker pub outbound_addr: Option<SocketAddrV4>,
53*cf78ab8cSAndroid Build Coastguard Worker pub outbound_addr6: Option<SocketAddrV6>,
54*cf78ab8cSAndroid Build Coastguard Worker pub disable_dns: bool,
55*cf78ab8cSAndroid Build Coastguard Worker pub disable_dhcp: bool,
56*cf78ab8cSAndroid Build Coastguard Worker pub mfr_id: u32,
57*cf78ab8cSAndroid Build Coastguard Worker pub oob_eth_addr: [u8; 6usize],
58*cf78ab8cSAndroid Build Coastguard Worker pub http_proxy_on: bool,
59*cf78ab8cSAndroid Build Coastguard Worker pub host_dns: Vec<SocketAddr>,
60*cf78ab8cSAndroid Build Coastguard Worker }
61*cf78ab8cSAndroid Build Coastguard Worker
62*cf78ab8cSAndroid Build Coastguard Worker impl Default for SlirpConfig {
default() -> Self63*cf78ab8cSAndroid Build Coastguard Worker fn default() -> Self {
64*cf78ab8cSAndroid Build Coastguard Worker SlirpConfig {
65*cf78ab8cSAndroid Build Coastguard Worker version: 5,
66*cf78ab8cSAndroid Build Coastguard Worker // No restrictions by default
67*cf78ab8cSAndroid Build Coastguard Worker restricted: 0,
68*cf78ab8cSAndroid Build Coastguard Worker in_enabled: true,
69*cf78ab8cSAndroid Build Coastguard Worker // Private network address
70*cf78ab8cSAndroid Build Coastguard Worker vnetwork: Ipv4Addr::new(10, 0, 2, 0),
71*cf78ab8cSAndroid Build Coastguard Worker vnetmask: Ipv4Addr::new(255, 255, 255, 0),
72*cf78ab8cSAndroid Build Coastguard Worker // Default host address
73*cf78ab8cSAndroid Build Coastguard Worker vhost: Ipv4Addr::new(10, 0, 2, 2),
74*cf78ab8cSAndroid Build Coastguard Worker // IPv6 disabled by default
75*cf78ab8cSAndroid Build Coastguard Worker in6_enabled: true,
76*cf78ab8cSAndroid Build Coastguard Worker vprefix_addr6: "fec0::".parse().unwrap(),
77*cf78ab8cSAndroid Build Coastguard Worker vprefix_len: 64,
78*cf78ab8cSAndroid Build Coastguard Worker vhost6: "fec0::2".parse().unwrap(),
79*cf78ab8cSAndroid Build Coastguard Worker vhostname: None, // Some("slirp".to_string()),
80*cf78ab8cSAndroid Build Coastguard Worker tftp_server_name: None,
81*cf78ab8cSAndroid Build Coastguard Worker tftp_path: None,
82*cf78ab8cSAndroid Build Coastguard Worker bootfile: None,
83*cf78ab8cSAndroid Build Coastguard Worker // DHCP starting address
84*cf78ab8cSAndroid Build Coastguard Worker vdhcp_start: Ipv4Addr::new(10, 0, 2, 16),
85*cf78ab8cSAndroid Build Coastguard Worker // Public DNS server
86*cf78ab8cSAndroid Build Coastguard Worker vnameserver: Ipv4Addr::new(10, 0, 2, 3),
87*cf78ab8cSAndroid Build Coastguard Worker vnameserver6: "fec0::3".parse().unwrap(),
88*cf78ab8cSAndroid Build Coastguard Worker vdnssearch: Vec::new(),
89*cf78ab8cSAndroid Build Coastguard Worker vdomainname: None,
90*cf78ab8cSAndroid Build Coastguard Worker // Ethernet MTU
91*cf78ab8cSAndroid Build Coastguard Worker if_mtu: 0,
92*cf78ab8cSAndroid Build Coastguard Worker // Ethernet MRU
93*cf78ab8cSAndroid Build Coastguard Worker if_mru: 0,
94*cf78ab8cSAndroid Build Coastguard Worker disable_host_loopback: false,
95*cf78ab8cSAndroid Build Coastguard Worker enable_emu: false,
96*cf78ab8cSAndroid Build Coastguard Worker outbound_addr: None,
97*cf78ab8cSAndroid Build Coastguard Worker outbound_addr6: None,
98*cf78ab8cSAndroid Build Coastguard Worker disable_dns: false,
99*cf78ab8cSAndroid Build Coastguard Worker disable_dhcp: false,
100*cf78ab8cSAndroid Build Coastguard Worker mfr_id: 0,
101*cf78ab8cSAndroid Build Coastguard Worker oob_eth_addr: [0; 6usize],
102*cf78ab8cSAndroid Build Coastguard Worker http_proxy_on: false,
103*cf78ab8cSAndroid Build Coastguard Worker host_dns: Vec::new(),
104*cf78ab8cSAndroid Build Coastguard Worker }
105*cf78ab8cSAndroid Build Coastguard Worker }
106*cf78ab8cSAndroid Build Coastguard Worker }
107*cf78ab8cSAndroid Build Coastguard Worker
108*cf78ab8cSAndroid Build Coastguard Worker /// Struct to hold a "C" SlirpConfig and the Rust storage that is
109*cf78ab8cSAndroid Build Coastguard Worker /// referenced by SlirpConfig.
110*cf78ab8cSAndroid Build Coastguard Worker #[allow(dead_code)]
111*cf78ab8cSAndroid Build Coastguard Worker pub struct SlirpConfigs {
112*cf78ab8cSAndroid Build Coastguard Worker pub c_slirp_config: libslirp_sys::SlirpConfig,
113*cf78ab8cSAndroid Build Coastguard Worker
114*cf78ab8cSAndroid Build Coastguard Worker // fields that hold the managed storage for "C" struct.
115*cf78ab8cSAndroid Build Coastguard Worker c_bootfile: Option<CString>,
116*cf78ab8cSAndroid Build Coastguard Worker c_tftp_server_name: Option<CString>,
117*cf78ab8cSAndroid Build Coastguard Worker c_vdomainname: Option<CString>,
118*cf78ab8cSAndroid Build Coastguard Worker c_vhostname: Option<CString>,
119*cf78ab8cSAndroid Build Coastguard Worker c_tftp_path: Option<CString>,
120*cf78ab8cSAndroid Build Coastguard Worker c_host_dns: [libslirp_sys::sockaddr_storage; MAX_DNS_SERVERS],
121*cf78ab8cSAndroid Build Coastguard Worker // TODO: add other fields
122*cf78ab8cSAndroid Build Coastguard Worker }
123*cf78ab8cSAndroid Build Coastguard Worker
lookup_host_dns(host_dns: &str) -> io::Result<Vec<SocketAddr>>124*cf78ab8cSAndroid Build Coastguard Worker pub async fn lookup_host_dns(host_dns: &str) -> io::Result<Vec<SocketAddr>> {
125*cf78ab8cSAndroid Build Coastguard Worker let mut set = tokio::task::JoinSet::new();
126*cf78ab8cSAndroid Build Coastguard Worker if host_dns.is_empty() {
127*cf78ab8cSAndroid Build Coastguard Worker return Ok(Vec::new());
128*cf78ab8cSAndroid Build Coastguard Worker }
129*cf78ab8cSAndroid Build Coastguard Worker
130*cf78ab8cSAndroid Build Coastguard Worker for addr in host_dns.split(",") {
131*cf78ab8cSAndroid Build Coastguard Worker set.spawn(tokio::net::lookup_host(format!("{addr}:0")));
132*cf78ab8cSAndroid Build Coastguard Worker }
133*cf78ab8cSAndroid Build Coastguard Worker
134*cf78ab8cSAndroid Build Coastguard Worker let mut addrs = Vec::new();
135*cf78ab8cSAndroid Build Coastguard Worker while let Some(result) = set.join_next().await {
136*cf78ab8cSAndroid Build Coastguard Worker addrs.push(result??.next().ok_or(io::Error::from(io::ErrorKind::NotFound))?);
137*cf78ab8cSAndroid Build Coastguard Worker }
138*cf78ab8cSAndroid Build Coastguard Worker Ok(addrs)
139*cf78ab8cSAndroid Build Coastguard Worker }
140*cf78ab8cSAndroid Build Coastguard Worker
to_socketaddr_storage(dns: &[SocketAddr]) -> [libslirp_sys::sockaddr_storage; MAX_DNS_SERVERS]141*cf78ab8cSAndroid Build Coastguard Worker fn to_socketaddr_storage(dns: &[SocketAddr]) -> [libslirp_sys::sockaddr_storage; MAX_DNS_SERVERS] {
142*cf78ab8cSAndroid Build Coastguard Worker let mut result = [libslirp_sys::sockaddr_storage::default(); MAX_DNS_SERVERS];
143*cf78ab8cSAndroid Build Coastguard Worker if dns.len() > MAX_DNS_SERVERS {
144*cf78ab8cSAndroid Build Coastguard Worker warn!("Too many DNS servers, only keeping the first {} ones", MAX_DNS_SERVERS);
145*cf78ab8cSAndroid Build Coastguard Worker }
146*cf78ab8cSAndroid Build Coastguard Worker for i in 0..usize::min(dns.len(), MAX_DNS_SERVERS) {
147*cf78ab8cSAndroid Build Coastguard Worker result[i] = dns[i].into();
148*cf78ab8cSAndroid Build Coastguard Worker }
149*cf78ab8cSAndroid Build Coastguard Worker result
150*cf78ab8cSAndroid Build Coastguard Worker }
151*cf78ab8cSAndroid Build Coastguard Worker
152*cf78ab8cSAndroid Build Coastguard Worker impl SlirpConfigs {
new(config: &SlirpConfig) -> SlirpConfigs153*cf78ab8cSAndroid Build Coastguard Worker pub fn new(config: &SlirpConfig) -> SlirpConfigs {
154*cf78ab8cSAndroid Build Coastguard Worker let as_cstring =
155*cf78ab8cSAndroid Build Coastguard Worker |s: &Option<String>| s.as_ref().and_then(|s| CString::new(s.as_bytes()).ok());
156*cf78ab8cSAndroid Build Coastguard Worker let c_tftp_path = config
157*cf78ab8cSAndroid Build Coastguard Worker .tftp_path
158*cf78ab8cSAndroid Build Coastguard Worker .as_ref()
159*cf78ab8cSAndroid Build Coastguard Worker .and_then(|s| CString::new(s.to_string_lossy().into_owned()).ok());
160*cf78ab8cSAndroid Build Coastguard Worker let c_vhostname = as_cstring(&config.vhostname);
161*cf78ab8cSAndroid Build Coastguard Worker let c_tftp_server_name = as_cstring(&config.tftp_server_name);
162*cf78ab8cSAndroid Build Coastguard Worker let c_bootfile = as_cstring(&config.bootfile);
163*cf78ab8cSAndroid Build Coastguard Worker let c_vdomainname = as_cstring(&config.vdomainname);
164*cf78ab8cSAndroid Build Coastguard Worker
165*cf78ab8cSAndroid Build Coastguard Worker let c_host_dns = to_socketaddr_storage(&config.host_dns);
166*cf78ab8cSAndroid Build Coastguard Worker
167*cf78ab8cSAndroid Build Coastguard Worker // Convert to a ptr::null() or a raw ptr to managed
168*cf78ab8cSAndroid Build Coastguard Worker // memory. Whenever storing a ptr in "C" Struct using `as_ptr`
169*cf78ab8cSAndroid Build Coastguard Worker // this code must have a Rust member is `SlirpConfigs` that
170*cf78ab8cSAndroid Build Coastguard Worker // holds the storage.
171*cf78ab8cSAndroid Build Coastguard Worker let as_ptr = |p: &Option<CString>| p.as_ref().map_or(std::ptr::null(), |s| s.as_ptr());
172*cf78ab8cSAndroid Build Coastguard Worker
173*cf78ab8cSAndroid Build Coastguard Worker let c_slirp_config = libslirp_sys::SlirpConfig {
174*cf78ab8cSAndroid Build Coastguard Worker version: config.version,
175*cf78ab8cSAndroid Build Coastguard Worker restricted: config.restricted,
176*cf78ab8cSAndroid Build Coastguard Worker in_enabled: config.in_enabled,
177*cf78ab8cSAndroid Build Coastguard Worker vnetwork: config.vnetwork.into(),
178*cf78ab8cSAndroid Build Coastguard Worker vnetmask: config.vnetmask.into(),
179*cf78ab8cSAndroid Build Coastguard Worker vhost: config.vhost.into(),
180*cf78ab8cSAndroid Build Coastguard Worker in6_enabled: config.in6_enabled,
181*cf78ab8cSAndroid Build Coastguard Worker vprefix_addr6: config.vprefix_addr6.into(),
182*cf78ab8cSAndroid Build Coastguard Worker vprefix_len: config.vprefix_len,
183*cf78ab8cSAndroid Build Coastguard Worker vhost6: config.vhost6.into(),
184*cf78ab8cSAndroid Build Coastguard Worker vhostname: as_ptr(&c_vhostname),
185*cf78ab8cSAndroid Build Coastguard Worker tftp_server_name: as_ptr(&c_tftp_server_name),
186*cf78ab8cSAndroid Build Coastguard Worker tftp_path: as_ptr(&c_tftp_path),
187*cf78ab8cSAndroid Build Coastguard Worker bootfile: as_ptr(&c_bootfile),
188*cf78ab8cSAndroid Build Coastguard Worker vdhcp_start: config.vdhcp_start.into(),
189*cf78ab8cSAndroid Build Coastguard Worker vnameserver: config.vnameserver.into(),
190*cf78ab8cSAndroid Build Coastguard Worker vnameserver6: config.vnameserver6.into(),
191*cf78ab8cSAndroid Build Coastguard Worker // TODO: add field
192*cf78ab8cSAndroid Build Coastguard Worker vdnssearch: std::ptr::null_mut(),
193*cf78ab8cSAndroid Build Coastguard Worker vdomainname: as_ptr(&c_vdomainname),
194*cf78ab8cSAndroid Build Coastguard Worker if_mtu: config.if_mtu,
195*cf78ab8cSAndroid Build Coastguard Worker if_mru: config.if_mru,
196*cf78ab8cSAndroid Build Coastguard Worker disable_host_loopback: config.disable_host_loopback,
197*cf78ab8cSAndroid Build Coastguard Worker enable_emu: config.enable_emu,
198*cf78ab8cSAndroid Build Coastguard Worker // TODO: add field
199*cf78ab8cSAndroid Build Coastguard Worker outbound_addr: std::ptr::null_mut(),
200*cf78ab8cSAndroid Build Coastguard Worker // TODO: add field
201*cf78ab8cSAndroid Build Coastguard Worker outbound_addr6: std::ptr::null_mut(),
202*cf78ab8cSAndroid Build Coastguard Worker disable_dns: config.disable_dns,
203*cf78ab8cSAndroid Build Coastguard Worker disable_dhcp: config.disable_dhcp,
204*cf78ab8cSAndroid Build Coastguard Worker mfr_id: config.mfr_id,
205*cf78ab8cSAndroid Build Coastguard Worker oob_eth_addr: config.oob_eth_addr,
206*cf78ab8cSAndroid Build Coastguard Worker http_proxy_on: config.http_proxy_on,
207*cf78ab8cSAndroid Build Coastguard Worker host_dns_count: config.host_dns.len(),
208*cf78ab8cSAndroid Build Coastguard Worker host_dns: c_host_dns,
209*cf78ab8cSAndroid Build Coastguard Worker };
210*cf78ab8cSAndroid Build Coastguard Worker
211*cf78ab8cSAndroid Build Coastguard Worker // Return the "C" struct and Rust members holding the storage
212*cf78ab8cSAndroid Build Coastguard Worker // referenced by the "C" struct.
213*cf78ab8cSAndroid Build Coastguard Worker SlirpConfigs {
214*cf78ab8cSAndroid Build Coastguard Worker c_slirp_config,
215*cf78ab8cSAndroid Build Coastguard Worker c_vhostname,
216*cf78ab8cSAndroid Build Coastguard Worker c_tftp_server_name,
217*cf78ab8cSAndroid Build Coastguard Worker c_bootfile,
218*cf78ab8cSAndroid Build Coastguard Worker c_vdomainname,
219*cf78ab8cSAndroid Build Coastguard Worker c_tftp_path,
220*cf78ab8cSAndroid Build Coastguard Worker c_host_dns,
221*cf78ab8cSAndroid Build Coastguard Worker }
222*cf78ab8cSAndroid Build Coastguard Worker }
223*cf78ab8cSAndroid Build Coastguard Worker }
224*cf78ab8cSAndroid Build Coastguard Worker
225*cf78ab8cSAndroid Build Coastguard Worker #[cfg(test)]
226*cf78ab8cSAndroid Build Coastguard Worker mod tests {
227*cf78ab8cSAndroid Build Coastguard Worker use super::*;
228*cf78ab8cSAndroid Build Coastguard Worker use tokio::runtime::Runtime;
229*cf78ab8cSAndroid Build Coastguard Worker
230*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_slirp_config_default()231*cf78ab8cSAndroid Build Coastguard Worker fn test_slirp_config_default() {
232*cf78ab8cSAndroid Build Coastguard Worker let config = SlirpConfig::default();
233*cf78ab8cSAndroid Build Coastguard Worker
234*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.version, 5);
235*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.restricted, 0);
236*cf78ab8cSAndroid Build Coastguard Worker assert!(config.in_enabled);
237*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vnetwork, Ipv4Addr::new(10, 0, 2, 0));
238*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vnetmask, Ipv4Addr::new(255, 255, 255, 0));
239*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vhost, Ipv4Addr::new(10, 0, 2, 2));
240*cf78ab8cSAndroid Build Coastguard Worker assert!(config.in6_enabled);
241*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vprefix_addr6, "fec0::".parse::<Ipv6Addr>().unwrap());
242*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vprefix_len, 64);
243*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vhost6, "fec0::2".parse::<Ipv6Addr>().unwrap());
244*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vhostname, None);
245*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.tftp_server_name, None);
246*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.tftp_path, None);
247*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.bootfile, None);
248*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vdhcp_start, Ipv4Addr::new(10, 0, 2, 16));
249*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vnameserver, Ipv4Addr::new(10, 0, 2, 3));
250*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vnameserver6, "fec0::3".parse::<Ipv6Addr>().unwrap());
251*cf78ab8cSAndroid Build Coastguard Worker assert!(config.vdnssearch.is_empty());
252*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.vdomainname, None);
253*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.if_mtu, 0);
254*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.if_mru, 0);
255*cf78ab8cSAndroid Build Coastguard Worker assert!(!config.disable_host_loopback);
256*cf78ab8cSAndroid Build Coastguard Worker assert!(!config.enable_emu);
257*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.outbound_addr, None);
258*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.outbound_addr6, None);
259*cf78ab8cSAndroid Build Coastguard Worker assert!(!config.disable_dns);
260*cf78ab8cSAndroid Build Coastguard Worker assert!(!config.disable_dhcp);
261*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.mfr_id, 0);
262*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.oob_eth_addr, [0; 6]);
263*cf78ab8cSAndroid Build Coastguard Worker assert!(!config.http_proxy_on);
264*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(config.host_dns.len(), 0);
265*cf78ab8cSAndroid Build Coastguard Worker }
266*cf78ab8cSAndroid Build Coastguard Worker
267*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_slirp_configs_new()268*cf78ab8cSAndroid Build Coastguard Worker fn test_slirp_configs_new() {
269*cf78ab8cSAndroid Build Coastguard Worker let rust_config = SlirpConfig::default();
270*cf78ab8cSAndroid Build Coastguard Worker let c_configs = SlirpConfigs::new(&rust_config);
271*cf78ab8cSAndroid Build Coastguard Worker
272*cf78ab8cSAndroid Build Coastguard Worker // Check basic field conversions
273*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(c_configs.c_slirp_config.version, rust_config.version);
274*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(c_configs.c_slirp_config.restricted, rust_config.restricted);
275*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(c_configs.c_slirp_config.in_enabled as i32, rust_config.in_enabled as i32);
276*cf78ab8cSAndroid Build Coastguard Worker
277*cf78ab8cSAndroid Build Coastguard Worker // Check string conversions and null pointers
278*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(c_configs.c_slirp_config.vhostname, std::ptr::null());
279*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(c_configs.c_slirp_config.tftp_server_name, std::ptr::null());
280*cf78ab8cSAndroid Build Coastguard Worker }
281*cf78ab8cSAndroid Build Coastguard Worker
282*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_lookup_host_dns() -> io::Result<()>283*cf78ab8cSAndroid Build Coastguard Worker fn test_lookup_host_dns() -> io::Result<()> {
284*cf78ab8cSAndroid Build Coastguard Worker let rt = Runtime::new().unwrap();
285*cf78ab8cSAndroid Build Coastguard Worker let results = rt.block_on(lookup_host_dns(""))?;
286*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(results.len(), 0);
287*cf78ab8cSAndroid Build Coastguard Worker
288*cf78ab8cSAndroid Build Coastguard Worker let results = rt.block_on(lookup_host_dns("localhost"))?;
289*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(results.len(), 1);
290*cf78ab8cSAndroid Build Coastguard Worker
291*cf78ab8cSAndroid Build Coastguard Worker let results = rt.block_on(lookup_host_dns("example.com"))?;
292*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(results.len(), 1);
293*cf78ab8cSAndroid Build Coastguard Worker
294*cf78ab8cSAndroid Build Coastguard Worker let results = rt.block_on(lookup_host_dns("localhost,example.com"))?;
295*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(results.len(), 2);
296*cf78ab8cSAndroid Build Coastguard Worker Ok(())
297*cf78ab8cSAndroid Build Coastguard Worker }
298*cf78ab8cSAndroid Build Coastguard Worker
299*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_to_socketaddr_storage_empty_input()300*cf78ab8cSAndroid Build Coastguard Worker fn test_to_socketaddr_storage_empty_input() {
301*cf78ab8cSAndroid Build Coastguard Worker let dns: [SocketAddr; 0] = [];
302*cf78ab8cSAndroid Build Coastguard Worker let result = to_socketaddr_storage(&dns);
303*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(result.len(), MAX_DNS_SERVERS);
304*cf78ab8cSAndroid Build Coastguard Worker for entry in result {
305*cf78ab8cSAndroid Build Coastguard Worker // Assuming `sockaddr_storage::default()` initializes all fields to 0
306*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(entry.ss_family, 0);
307*cf78ab8cSAndroid Build Coastguard Worker }
308*cf78ab8cSAndroid Build Coastguard Worker }
309*cf78ab8cSAndroid Build Coastguard Worker
310*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_to_socketaddr_storage()311*cf78ab8cSAndroid Build Coastguard Worker fn test_to_socketaddr_storage() {
312*cf78ab8cSAndroid Build Coastguard Worker let dns = ["1.1.1.1:53".parse().unwrap(), "8.8.8.8:53".parse().unwrap()];
313*cf78ab8cSAndroid Build Coastguard Worker let result = to_socketaddr_storage(&dns);
314*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(result.len(), MAX_DNS_SERVERS);
315*cf78ab8cSAndroid Build Coastguard Worker for i in 0..dns.len() {
316*cf78ab8cSAndroid Build Coastguard Worker assert_ne!(result[i].ss_family, 0); // Converted addresses should have a non-zero family
317*cf78ab8cSAndroid Build Coastguard Worker }
318*cf78ab8cSAndroid Build Coastguard Worker for i in dns.len()..MAX_DNS_SERVERS {
319*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(result[i].ss_family, 0); // Remaining entries should be default
320*cf78ab8cSAndroid Build Coastguard Worker }
321*cf78ab8cSAndroid Build Coastguard Worker }
322*cf78ab8cSAndroid Build Coastguard Worker
323*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_to_socketaddr_storage_valid_input_at_max()324*cf78ab8cSAndroid Build Coastguard Worker fn test_to_socketaddr_storage_valid_input_at_max() {
325*cf78ab8cSAndroid Build Coastguard Worker let dns = [
326*cf78ab8cSAndroid Build Coastguard Worker "1.1.1.1:53".parse().unwrap(),
327*cf78ab8cSAndroid Build Coastguard Worker "8.8.8.8:53".parse().unwrap(),
328*cf78ab8cSAndroid Build Coastguard Worker "9.9.9.9:53".parse().unwrap(),
329*cf78ab8cSAndroid Build Coastguard Worker "1.0.0.1:53".parse().unwrap(),
330*cf78ab8cSAndroid Build Coastguard Worker ];
331*cf78ab8cSAndroid Build Coastguard Worker let result = to_socketaddr_storage(&dns);
332*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(result.len(), MAX_DNS_SERVERS);
333*cf78ab8cSAndroid Build Coastguard Worker for i in 0..dns.len() {
334*cf78ab8cSAndroid Build Coastguard Worker assert_ne!(result[i].ss_family, 0);
335*cf78ab8cSAndroid Build Coastguard Worker }
336*cf78ab8cSAndroid Build Coastguard Worker }
337*cf78ab8cSAndroid Build Coastguard Worker
338*cf78ab8cSAndroid Build Coastguard Worker #[test]
test_to_socketaddr_storage_input_exceeds_max()339*cf78ab8cSAndroid Build Coastguard Worker fn test_to_socketaddr_storage_input_exceeds_max() {
340*cf78ab8cSAndroid Build Coastguard Worker let dns = [
341*cf78ab8cSAndroid Build Coastguard Worker "1.1.1.1:53".parse().unwrap(),
342*cf78ab8cSAndroid Build Coastguard Worker "8.8.8.8:53".parse().unwrap(),
343*cf78ab8cSAndroid Build Coastguard Worker "9.9.9.9:53".parse().unwrap(),
344*cf78ab8cSAndroid Build Coastguard Worker "1.0.0.1:53".parse().unwrap(),
345*cf78ab8cSAndroid Build Coastguard Worker "1.2.3.4:53".parse().unwrap(), // Extra address
346*cf78ab8cSAndroid Build Coastguard Worker ];
347*cf78ab8cSAndroid Build Coastguard Worker let result = to_socketaddr_storage(&dns);
348*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(result.len(), MAX_DNS_SERVERS);
349*cf78ab8cSAndroid Build Coastguard Worker for i in 0..MAX_DNS_SERVERS {
350*cf78ab8cSAndroid Build Coastguard Worker assert_ne!(result[i].ss_family, 0);
351*cf78ab8cSAndroid Build Coastguard Worker }
352*cf78ab8cSAndroid Build Coastguard Worker }
353*cf78ab8cSAndroid Build Coastguard Worker }
354