rust_rsm/net_ext/
mod.rs

1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4
5use crate::common::errcode;
6use std::net::{IpAddr,SocketAddr,Ipv4Addr,Ipv6Addr};
7#[cfg(unix)]
8use std::os::raw::{c_int};
9use std::process::Command;
10#[cfg(unix)]
11use std::fs::{OpenOptions};
12
13#[cfg(unix)]
14use std::os::unix::io::{RawFd};
15#[cfg(windows)]
16use std::os::windows::io::{RawHandle};
17#[cfg(windows)]
18use std::os::windows::io::{RawSocket};
19use std::ptr;
20
21pub mod arp;
22pub mod mac_addr;
23pub use mac_addr::mac_addr_t;
24
25pub mod ethernet_pkt;
26
27pub mod rawpacket;
28pub mod pktbuf;
29pub mod fec;
30pub mod ipnetwork;
31pub use ipnetwork::IpNetwork;
32
33pub mod netinterface;
34pub mod iprt;
35pub mod restserver;
36
37#[cfg(windows)]
38pub mod windows;
39#[cfg(unix)]
40pub mod unix;
41
42
43#[cfg(unix)]
44pub type RawFdType = RawFd;
45#[cfg(windows)]
46pub type RawFdType = RawSocket;
47
48#[cfg(unix)]
49pub type RawFileFd = RawFd;
50#[cfg(windows)]
51pub type RawFileFd = RawHandle;
52
53pub const MAC_ADDR_SIZE:usize = 6;
54pub const ETHERNET_HDR_SIZE:usize = 14;
55pub const IPV4_HDR_SIZE:usize = 20;
56pub const IPV6_HDR_SIZE:usize = 40;
57pub const UDP_HDR_SIZE:usize = 8;
58pub const TCP_HDR_SIZE:usize = 20;
59pub const ARP_PACKET_SIZE:usize = 28;
60pub const DEFAULT_ETHERNET_MTU:u16 = 1500;
61///net_ext共用的pakcet buffer size,比MTU大一些
62const MAX_PKT_BUF_SIZE:u16 = 2048;
63
64pub const AF_INET:u16=2;
65pub const AF_INET6:u16=23;
66
67pub mod EthernetTypes {
68    pub const Ethernet_Ipv4: u16 = 0x0800;
69    pub const Ethernet_ARP: u16 = 0x0806;
70    //Reverse Arp
71    pub const Ethernet_RARP: u16 = 0x8035;
72
73    pub const Ethernet_Ipv6: u16 = 0x86dd;
74    pub const Ethernet_Vlan: u16 = 0x8100;
75    pub const Ethernet_SVlan: u16 = 0x88a8;
76
77    pub const Ethernet_STP: u16 = 0x8181;
78    pub const Ethernet_LLDP: u16 = 0x88cc;
79
80    pub const Ethernet_MPLS: u16 = 0x8847;
81    pub const Ethernet_MPLS_USL: u16 = 0x8848;
82
83    pub const Ethernet_PPPoE_Discovery: u16 = 0x8863;
84    pub const Ethernet_PPPoE_Session: u16 = 0x8864;
85}
86
87pub const IPV4_ADDR_LEN:usize = 4;
88pub const IPV6_ADDR_LEN:usize = 16;
89
90pub mod IpProtos {
91    pub const Ip_Proto_ICMP: u8 = 1;
92    pub const Ip_Proto_IGMP: u8 = 2;
93    pub const Ip_Proto_IPv4inIP: u8 = 4;
94    pub const Ip_Proto_TCP: u8 = 6;
95    pub const Ip_Proto_UDP: u8 = 17;
96    pub const Ip_Proto_DCCP: u8 = 33;
97    pub const Ip_Proto_IPv6_Route: u8 = 43;
98    pub const Ip_Proto_IPv6_Frag: u8 = 44;
99
100    pub const Ip_Proto_RSVP: u8 = 46;
101    pub const Ip_Proto_GRE: u8 = 47;
102
103    pub const Ip_Proto_ESP: u8 = 50;
104    pub const Ip_Proto_AH: u8 = 51;
105
106    pub const Ip_Proto_ICMPv6: u8 = 58;
107
108    pub const Ip_Proto_EIGRP: u8 = 88;
109    pub const Ip_Proto_OSPF: u8 = 89;
110
111    pub const Ip_Proto_PIM: u8 = 103; //Protocol independant Multicast
112    pub const Ip_Proto_L2TP: u8 = 115;
113    pub const Ip_Proto_ISIS_IPv4: u8 = 124;
114    pub const Ip_Proto_SCTP: u8 = 132;
115    pub const Ip_Proto_MANET: u8 = 138;
116    pub const Ip_Proto_HIP: u8 = 139;
117    pub const Ip_Proto_ROHC: u8 = 142;
118}
119
120//典型业务的端口号
121pub mod ServicePorts {
122    pub const TP_PORT_FTP_DATA: u16 = 20;
123    pub const TP_PORT_FTP: u16 = 21;
124    pub const TP_PORT_SSH: u16 = 22;
125    pub const TP_PORT_TELNET: u16 = 23;
126    pub const TP_PORT_TACACS: u16 = 49;
127    pub const TP_PORT_DNS: u16 = 53;
128    pub const TP_PORT_DHCP_CLIENT: u16 = 67;
129    pub const TP_PORT_DHCP_SERVER: u16 = 68;
130    pub const TP_PORT_HTTP: u16 = 80;
131
132    pub const TP_PORT_POP3: u16 = 110;
133    pub const TP_PORT_SFTP: u16 = 115;
134    pub const TP_PORT_NTP: u16 = 123;
135
136    pub const TP_PORT_SNMP: u16 = 161;
137    pub const TP_PORT_SNMP_TRAP: u16 = 162;
138
139    pub const TP_PORT_BGP: u16 = 179;
140    pub const TP_PORT_LDAP: u16 = 389;
141    pub const TP_PORT_HTTPS: u16 = 443;
142    pub const TP_PORT_HTTPS_PCSYNC: u16 = 8443;
143    pub const TP_PORT_IKE: u16 = 500;
144    pub const TP_PORT_IPSEC_NAT: u16 = 4500;
145
146    pub const TP_PORT_SYSLOG: u16 = 514;
147    pub const TP_PORT_RIPNG: u16 = 521;
148    pub const TP_PORT_DHCPv6_CLIENT: u16 = 546;
149    pub const TP_PORT_DHCPv6_SERVER: u16 = 547;
150    pub const TP_PORT_RTSP: u16 = 554; //RealTime Streaming Protocol
151    pub const TP_PORT_LDAPS: u16 = 636; //
152    pub const TP_PORT_NETCONF_SSH: u16 = 830; //
153    pub const TP_PORT_NETCONF_HTTPS: u16 = 832; //
154    pub const TP_PORT_TWAMP: u16 = 862; 
155    pub const TP_PORT_FTPS: u16 = 990; // Ftp Over TLS/SSL
156    pub const TP_PORT_OPEN_VPN: u16 = 1194; //
157    pub const TP_PORT_L2TP: u16 = 1701; //
158    pub const TP_PORT_RADIUS: u16 = 1812; //
159    pub const TP_PORT_RADIUS_ACCT: u16 = 1813; //
160
161    pub const TP_PORT_SIP: u16 = 5060;
162    pub const TP_PORT_SIPS: u16 = 5061;
163
164    pub const TP_PORT_BFD_CTRL: u16 = 3784;
165    pub const TP_PORT_BFD_ECHO: u16 = 785;
166    pub const TP_PORT_BFD_LAG: u16 = 6784;
167
168    //私有的WOT隧道
169    pub const TP_PORT_WOT: u16 = 38000;
170}
171
172pub fn default_socket_addr() -> SocketAddr {
173    return SocketAddr::new(IpAddr::from([0, 0, 0, 0]), 0);
174}
175//将一个IP地址转化为一个16字节数组
176pub fn ipaddr_to_array(ip:&IpAddr)->(usize,[u8;IPV6_ADDR_LEN]) {
177    let mut ip_addr:[u8;IPV6_ADDR_LEN]=[0;IPV6_ADDR_LEN];
178    match ip{
179        IpAddr::V4(addr)=> {
180            let a = addr.octets();
181            unsafe {
182            std::ptr::copy(&a[0] as *const u8, &mut ip_addr[0] as *mut u8,IPV4_ADDR_LEN);
183            }
184            (IPV4_ADDR_LEN,ip_addr)
185        }
186        IpAddr::V6(addr)=> {
187            (IPV6_ADDR_LEN, addr.octets())
188        }
189    }
190}
191///copy IpAddr to a specified slice
192pub fn copy_ipaddr_to_slice(src:&IpAddr,buf:&mut[u8])->Result<usize,errcode::RESULT> {
193    match src {
194        IpAddr::V4(ip)=> {
195            if buf.len()<IPV4_ADDR_LEN {
196                return Err(errcode::ERROR_OUTOF_MEM)
197            }
198            unsafe {
199                ptr::copy_nonoverlapping(ip.octets().as_ptr(), buf.as_mut_ptr(), IPV4_ADDR_LEN);
200            }
201            return Ok(IPV4_ADDR_LEN)
202        },
203        IpAddr::V6(ip)=> {
204            if buf.len()<IPV6_ADDR_LEN {
205                return Err(errcode::ERROR_OUTOF_MEM)
206            }
207            unsafe {
208                ptr::copy_nonoverlapping(ip.octets().as_ptr(), buf.as_mut_ptr(), IPV6_ADDR_LEN);
209            }
210            return Ok(IPV6_ADDR_LEN)
211        }
212    }
213}
214//将一个数组转化为IP地址,长度为4转化为IPv4地址,16转化为IPv6地址,其它为0
215pub fn bytes_array_to_ipaddr(ip:&[u8])->IpAddr {
216    let ip_addr =  match ip.len() {
217        IPV4_ADDR_LEN=>{
218            IpAddr::from([ip[0],ip[1],ip[2],ip[3]])
219        },
220        IPV6_ADDR_LEN=>{
221            let mut a:[u8;IPV6_ADDR_LEN]=[0;IPV6_ADDR_LEN];
222            unsafe {
223            std::ptr::copy(&ip[0] as *const u8, &mut a[0] as *mut u8, IPV6_ADDR_LEN);
224            }
225            IpAddr::from(a)
226        },
227        _=>IpAddr::from([0,0,0,0]),
228    };
229    return ip_addr;
230}
231
232pub fn ipv4_to_u32(ipv4: &Ipv4Addr) -> u32 {
233    let u8a = ipv4.octets();
234    return u32::from_be_bytes(u8a);
235}
236
237//将IP地址转化为两个64bit数字
238pub fn ipv6_to_u64(ipv6: &Ipv6Addr) -> (u64, u64) {
239    let u8a = ipv6.octets();
240    let v128 = u128::from_be_bytes(u8a);
241
242    let h64 = (v128 >> 64) as u64;
243    let l64 = (v128 & 0xFFFFFFFFFFFFFFFF) as u64;
244    return (l64, h64);
245}
246
247pub fn get_ip_address_family(ip:&IpAddr)->u16 {
248    if ip.is_ipv6() {
249        AF_INET6
250    } else {
251        AF_INET
252    }
253}
254///calculate ip pool size
255pub fn ip_pool_size(ip_start:&IpAddr,ip_end:&IpAddr)->u128 {
256    match (ip_start,ip_end) {
257        (IpAddr::V4(ip1),IpAddr::V4(ip2))=> {
258            let v1=u32::from_be_bytes(ip1.octets());
259            let v2 = u32::from_be_bytes(ip2.octets());
260            if v1>v2 {
261                0
262            } else {
263                (v2-v1+1) as u128
264            }
265        },
266        (IpAddr::V6(ip1),IpAddr::V6(ip2))=> {
267            let v1=u128::from_be_bytes(ip1.octets());
268            let v2 = u128::from_be_bytes(ip2.octets());
269            if v1>v2 {
270                0
271            } else {
272                v2-v1+1
273            }
274        },
275        _=>return 0,
276    }
277}
278
279#[cfg(unix)]
280#[link(name = "os_linux", kind = "static")]
281extern "C" {
282    pub fn tuntap_setup(fd: c_int, name: *mut u8, mode: c_int, packet_info: c_int) -> c_int;
283}
284#[cfg(unix)]
285pub fn create_tap_if(
286    name: &str,
287    mtu: u16,
288    ip_addrs: &[IpNetwork],
289    pkt_info: bool,
290) -> errcode::RESULT {
291    use std::os::unix::io::{AsRawFd};
292
293    let fd = match OpenOptions::new()
294        .read(true)
295        .write(true)
296        .open("/dev/net/tun")
297    {
298        Err(_) => return errcode::ERROR_OPEN_FILE,
299        Ok(f) => f,
300    };
301
302    // The buffer is larger than needed, but who cares… it is large enough.
303    let mut name_buffer = Vec::new();
304    name_buffer.extend_from_slice(name.as_bytes());
305    name_buffer.extend_from_slice(&[0; 33]);
306    let name_ptr: *mut u8 = name_buffer.as_mut_ptr();
307    let result = unsafe {
308        tuntap_setup(
309            fd.as_raw_fd(),
310            name_ptr,
311            2 as c_int,
312            if pkt_info { 1 } else { 0 },
313        )
314    };
315    if result < 0 {
316        return errcode::ERROR_OS_CALL_FAILED;
317    }
318    //fd.close();
319    if ip_addrs.len() > 0 {
320        let addr_str = format!("{}/{}", ip_addrs[0].ip(), ip_addrs[0].prefix());
321        let _ = Command::new("ifconfig")
322            .args([
323                name,
324                "mtu",
325                format!("{}", mtu).as_str(),
326                "add",
327                addr_str.as_str(),
328                "up",
329            ])
330            .spawn();
331    } else {
332       let _= Command::new("ifconfig")
333            .args([name, "mtu", format!("{}", mtu).as_str(), "up"])
334            .spawn();
335    }
336
337    errcode::RESULT_SUCCESS
338}
339
340pub fn get_pnetif_by_name(name: &String) -> Result<netinterface::NetworkInterface, errcode::RESULT> {
341    return netinterface::NetworkInterface::get_interface_by_name(name);
342}
343
344
345#[cfg(windows)]
346pub fn create_tap_if(
347    name: &str,
348    mtu: u16,
349    ip_addrs: &[ipnetwork::IpNetwork],
350    _pkt_info: bool,
351) -> errcode::RESULT {
352    let mtu_cmd = format!("mtu={}", mtu);
353    if ip_addrs.len() > 0 {
354       match Command::new("netsh")
355            .args([
356                "interface",
357                "ip",
358                "set",
359                "address",
360                name,
361                "static",
362                format!("{}", ip_addrs[0].ip()).as_str(),
363                format!("{}", ip_addrs[0].mask()).as_str(),
364            ])
365            .spawn() {
366                Ok(_)=>(),
367                Err(_)=> {
368                    return errcode::ERROR_OS_CALL_FAILED 
369                },
370            }
371
372        match Command::new("netsh")
373            .args([
374                "interface",
375                "ip",
376                "set",
377                "interface",
378                name,
379                mtu_cmd.as_str(),
380            ])
381            .spawn() {
382                Ok(_)=>(),
383                Err(_)=> return errcode::ERROR_OS_CALL_FAILED,               
384            }
385    } else {
386        match Command::new("netsh")
387            .args([name, "mtu", format!("{}", mtu).as_str(), "up"])
388            .spawn() {
389                Ok(_)=>(),
390                Err(_)=> return errcode::ERROR_OS_CALL_FAILED,
391            }
392    }
393
394    errcode::RESULT_SUCCESS
395}
396