xref: /webrtc/util/src/vnet/interface.rs (revision ffe74184)
1*ffe74184SMartin Algesten use crate::error::*;
2*ffe74184SMartin Algesten use ipnet::*;
3*ffe74184SMartin Algesten use std::net::SocketAddr;
4*ffe74184SMartin Algesten use std::str::FromStr;
5*ffe74184SMartin Algesten 
6*ffe74184SMartin Algesten #[derive(Debug, Clone, Default)]
7*ffe74184SMartin Algesten pub struct Interface {
8*ffe74184SMartin Algesten     pub(crate) name: String,
9*ffe74184SMartin Algesten     pub(crate) addrs: Vec<IpNet>,
10*ffe74184SMartin Algesten }
11*ffe74184SMartin Algesten 
12*ffe74184SMartin Algesten impl Interface {
new(name: String, addrs: Vec<IpNet>) -> Self13*ffe74184SMartin Algesten     pub fn new(name: String, addrs: Vec<IpNet>) -> Self {
14*ffe74184SMartin Algesten         Interface { name, addrs }
15*ffe74184SMartin Algesten     }
16*ffe74184SMartin Algesten 
add_addr(&mut self, addr: IpNet)17*ffe74184SMartin Algesten     pub fn add_addr(&mut self, addr: IpNet) {
18*ffe74184SMartin Algesten         self.addrs.push(addr);
19*ffe74184SMartin Algesten     }
20*ffe74184SMartin Algesten 
name(&self) -> &str21*ffe74184SMartin Algesten     pub fn name(&self) -> &str {
22*ffe74184SMartin Algesten         &self.name
23*ffe74184SMartin Algesten     }
addrs(&self) -> &[IpNet]24*ffe74184SMartin Algesten     pub fn addrs(&self) -> &[IpNet] {
25*ffe74184SMartin Algesten         &self.addrs
26*ffe74184SMartin Algesten     }
27*ffe74184SMartin Algesten 
convert(addr: SocketAddr, mask: Option<SocketAddr>) -> Result<IpNet>28*ffe74184SMartin Algesten     pub fn convert(addr: SocketAddr, mask: Option<SocketAddr>) -> Result<IpNet> {
29*ffe74184SMartin Algesten         let prefix = if let Some(mask) = mask {
30*ffe74184SMartin Algesten             match (addr, mask) {
31*ffe74184SMartin Algesten                 (SocketAddr::V4(_), SocketAddr::V4(mask)) => {
32*ffe74184SMartin Algesten                     let octets = mask.ip().octets();
33*ffe74184SMartin Algesten                     let mut prefix = 0;
34*ffe74184SMartin Algesten                     for octet in &octets {
35*ffe74184SMartin Algesten                         for i in 0..8 {
36*ffe74184SMartin Algesten                             prefix += (*octet >> (7 - i)) & 0x1;
37*ffe74184SMartin Algesten                         }
38*ffe74184SMartin Algesten                     }
39*ffe74184SMartin Algesten                     prefix
40*ffe74184SMartin Algesten                 }
41*ffe74184SMartin Algesten                 (SocketAddr::V6(_), SocketAddr::V6(mask)) => {
42*ffe74184SMartin Algesten                     let octets = mask.ip().octets();
43*ffe74184SMartin Algesten                     let mut prefix = 0;
44*ffe74184SMartin Algesten                     for octet in &octets {
45*ffe74184SMartin Algesten                         for i in 0..8 {
46*ffe74184SMartin Algesten                             prefix += (*octet >> (7 - i)) & 0x1;
47*ffe74184SMartin Algesten                         }
48*ffe74184SMartin Algesten                     }
49*ffe74184SMartin Algesten                     prefix
50*ffe74184SMartin Algesten                 }
51*ffe74184SMartin Algesten                 _ => return Err(Error::ErrInvalidMask),
52*ffe74184SMartin Algesten             }
53*ffe74184SMartin Algesten         } else {
54*ffe74184SMartin Algesten             32
55*ffe74184SMartin Algesten         };
56*ffe74184SMartin Algesten         let s = format!("{}/{}", addr.ip(), prefix);
57*ffe74184SMartin Algesten 
58*ffe74184SMartin Algesten         Ok(IpNet::from_str(&s)?)
59*ffe74184SMartin Algesten     }
60*ffe74184SMartin Algesten }
61