rust_rsm/net_ext/
ipnetwork.rs

1#![allow(non_snake_case)]
2#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4
5use std::net::{IpAddr};
6use crate::common::errcode;
7use super::*;
8use serde::{Deserialize,Serialize};
9
10#[derive(Clone,Debug,Deserialize,Serialize)]
11pub struct IpNetwork {
12    ip:IpAddr,
13    mask:IpAddr,
14    mask_len:u8,
15}
16
17impl IpNetwork {
18    pub fn new(ip:IpAddr,mask_len:u8)->Result<Self,errcode::RESULT> {
19        if (ip.is_ipv4() && mask_len>IPV4_ADDR_LEN as u8*8) || (ip.is_ipv6() && mask_len>IPV6_ADDR_LEN as u8*8) {
20            return Err(errcode::ERROR_INVALID_PARAM)
21        }
22        let mask = match Self::get_ip_mask(ip.is_ipv6(),mask_len) {
23            Some(m)=>m,
24            None=>return Err(errcode::ERROR_INVALID_PARAM),
25        };
26        let ipnet= Self{
27            ip:ip,
28            mask:mask,
29            mask_len:mask_len,
30        };
31
32        Ok(ipnet)
33    }
34
35    pub fn new_host_ipnet(ip:IpAddr)->Self {
36        let mask_len=match ip {
37            IpAddr::V4(_)=>(IPV4_ADDR_LEN*8) as u8,
38            IpAddr::V6(_)=>(IPV6_ADDR_LEN*8) as u8,
39        };
40        let mask = Self::get_ip_mask(ip.is_ipv6(),mask_len).unwrap();
41        return Self {
42            ip,
43            mask,
44            mask_len,
45        }
46    }
47
48    ///从IP、掩码构建一个IpNetwork
49    pub fn from(ip:IpAddr,mask:IpAddr)->IpNetwork {
50        let mask_len = Self::get_ip_mask_len(&mask);
51        let ipnet =  Self{
52            ip:ip,
53            mask:mask,
54            mask_len:mask_len,
55        };
56        return ipnet
57    }
58
59    ///get_ip_mask_len,根据一个掩码格式的IP,获取ip addr的mask_len
60    pub fn get_ip_mask_len(ip:&IpAddr)->u8 {
61        match ip {
62            IpAddr::V4(addr)=> {
63                let u32_addr = u32::from_be_bytes(addr.octets());
64                //println!("ip={},u32={}",ip,u32_addr);
65                if u32_addr==0 {
66                    return 0;
67                }
68                let mask:u32=0xFFFFFFFF;
69                for i in 0..32 {
70                    let prefix = mask << i;
71                    if u32_addr == prefix {
72                        return 32-i as u8
73                    }
74                }
75                return 0
76            },
77            IpAddr::V6(addr)=> {
78                let u128_addr = u128::from_be_bytes(addr.octets());
79                let mask:u128 = !0u128;
80                if u128_addr==0 {
81                    return 0;
82                }
83                for i in 0..128 {
84                    let prefix = mask << i;
85                    if u128_addr == prefix {
86                        return 128-i as u8
87                    }
88                }
89                return 0
90            }
91        }
92    }
93
94    pub fn get_ip_mask(isv6:bool,mask_len:u8)->Option<IpAddr> {
95        if isv6 {
96            if mask_len >128 {
97                return None;
98            }
99            let umask=!0u128 << (128-mask_len);
100            return Some(IpAddr::from(umask.to_be_bytes()));
101        } else {
102            if mask_len >128 {
103                return None;
104            }
105            let umask=!0u32 << (32-mask_len);
106            return Some(IpAddr::from(umask.to_be_bytes()));
107        }
108    }
109
110    ///get_ip_netmask,根据IP地址和掩码长度返回子网号
111    pub fn get_ip_subnet(ip:&IpAddr,mask_len:u8)->IpAddr {
112        match ip {
113            IpAddr::V4(addr)=> {
114                if mask_len==0 {
115                    return IpAddr::from(Ipv4Addr::from(0));
116                }
117                let mut u32_addr = u32::from_be_bytes(addr.octets());
118                let mask:u32 = 0xFFFFFFFF << ((32-mask_len) as usize);
119                u32_addr &= mask;
120                let masked_addr = u32_addr.to_be_bytes();
121                return IpAddr::from(masked_addr);
122            },
123            IpAddr::V6(addr)=> {
124                if mask_len==0 {
125                    return IpAddr::from(Ipv6Addr::from(0));
126                }
127                let mut u128_addr = u128::from_be_bytes(addr.octets());
128                let mask:u128 = !0u128 << ((128-mask_len) as usize);
129                u128_addr &= mask;
130                let masked_addr = u128_addr.to_be_bytes();
131                return IpAddr::from(masked_addr);
132            }
133        }
134        
135    }
136
137
138    pub fn get_ip_prefix(&self)->IpAddr {
139        self.mask
140    }
141    pub fn get_mask_len(&self)->u8 {
142        self.mask_len
143    }
144
145    pub fn get_ip_addr(&self)->IpAddr {
146        self.ip
147    }
148    ///libpnet兼容
149    pub fn ip(&self)->IpAddr {
150        self.ip
151    }
152    pub fn mask(&self)->IpAddr {
153        self.mask
154    }
155    pub fn prefix(&self)->IpAddr {
156        self.ip
157    }
158
159    pub fn is_ipv4(&self)->bool {
160        self.ip.is_ipv4()
161    }
162
163    pub fn is_ipv6(&self)->bool {
164        self.ip.is_ipv6()
165    }
166
167    ///判断一个IP、Mask是否有效
168    pub fn is_valid_ipmask(ip:&IpAddr,mask_len:u8)->bool {
169        if ip.is_ipv4() && mask_len as usize<=IPV4_ADDR_LEN*8 {
170            return true
171        }
172        if ip.is_ipv6() && mask_len as usize<=IPV6_ADDR_LEN*8 {
173            return true
174        }
175        false
176    }
177}
178
179impl std::cmp::PartialEq for IpNetwork {
180    fn eq(&self,other:&Self)->bool {
181        return self.ip.eq(&other.ip) && self.mask_len==other.mask_len
182    }
183
184}