1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4#![allow(unused_variables)]
5#![allow(dead_code)]
6
7use super::super::*;
8use libc;
9use std::os::raw::{c_int,c_void};
10use std::net::{UdpSocket,SocketAddr,SocketAddrV6,SocketAddrV4};
11use mio::net::UdpSocket as mio_udpsocket;
12#[cfg(unix)]
13use std::os::unix::io::{AsRawFd,RawFd};
14use std::io::{self,Error, IoSliceMut,IoSlice};
15use std::mem;
16
17#[repr(C)]
18#[derive(Clone,Copy)]
19pub union sockaddr_t {
20 pub v4: libc::sockaddr_in,
21 pub v6: libc::sockaddr_in6,
22}
23
24impl sockaddr_t {
25 pub fn as_ptr(&self) -> *const libc::sockaddr {
26 self as *const _ as *const libc::sockaddr
27 }
28
29 pub fn from_socket_addr(addr:&SocketAddr)->(Self,libc::socklen_t){
30 match addr {
31 SocketAddr::V4(ipv4)=> {
32 let sin_addr = libc::in_addr {
33 s_addr: u32::from_ne_bytes(ipv4.ip().octets()),
34 };
35 let sockaddr = libc::sockaddr_in{
36 sin_family:libc::AF_INET as libc::sa_family_t,
37 sin_port:ipv4.port().to_be(),
38 sin_addr:sin_addr,
39 sin_zero:[0;8],
40 };
41 return (Self{v4:sockaddr},mem::size_of::<libc::sockaddr_in>() as libc::socklen_t)
42 },
43 SocketAddr::V6(ipv6)=> {
44 let sockaddr = libc::sockaddr_in6 {
45 sin6_family:libc::AF_INET6 as libc::sa_family_t,
46 sin6_port:ipv6.port().to_be(),
47 sin6_flowinfo:ipv6.flowinfo(),
48 sin6_addr:libc::in6_addr {
49 s6_addr: ipv6.ip().octets(),
50 },
51 sin6_scope_id:ipv6.scope_id(),
52 };
53 return (Self{v6:sockaddr},mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t)
54 },
55 }
56
57 }
58}
59
60pub unsafe fn to_socket_addr(
61 sock_addr: *const sockaddr_t,
62) -> io::Result<SocketAddr> {
63 if sock_addr==std::ptr::null() {
64 return Err(io::ErrorKind::InvalidInput.into())
65 }
66 match (*sock_addr).v4.sin_family as libc::c_int {
67 libc::AF_INET => {
68 let addr: &libc::sockaddr_in = &*(sock_addr as *const libc::sockaddr_in);
70 let ip = Ipv4Addr::from(addr.sin_addr.s_addr.to_ne_bytes());
71 let port = u16::from_be(addr.sin_port);
72 Ok(SocketAddr::V4(SocketAddrV4::new(ip, port)))
73 }
74 libc::AF_INET6 => {
75 let addr: &libc::sockaddr_in6 = &*(sock_addr as *const libc::sockaddr_in6);
77 let ip = Ipv6Addr::from(addr.sin6_addr.s6_addr);
78 let port = u16::from_be(addr.sin6_port);
79 Ok(SocketAddr::V6(SocketAddrV6::new(
80 ip,
81 port,
82 addr.sin6_flowinfo,
83 addr.sin6_scope_id,
84 )))
85 }
86 _ => Err(io::ErrorKind::InvalidInput.into()),
87 }
88}
89
90pub fn set_socket_recvbuf(socket:RawFdType,buf_size:i32)->i32 {
92 return unsafe {
93 libc::setsockopt(socket as c_int, libc::SOL_SOCKET,
94 libc::SO_RCVBUF,&(buf_size as c_int) as *const _ as *const c_void,std::mem::size_of::<i32>() as libc::socklen_t)
95 };
96}
97
98pub fn set_socket_sendbuf(socket:RawFdType,buf_size:i32)->i32 {
100 return unsafe {
101 libc::setsockopt(socket as c_int, libc::SOL_SOCKET,
102 libc::SO_SNDBUF,&(buf_size as c_int) as *const _ as *const c_void,std::mem::size_of::<i32>() as libc::socklen_t)
103 };
104}
105
106pub fn set_socket_reuse_addr(socket:RawFdType,is_reuse:i32)->i32 {
108 return unsafe {
109 libc::setsockopt(socket as c_int, libc::SOL_SOCKET,
110 libc::SO_REUSEADDR,&(is_reuse as c_int) as *const _ as *const c_void,std::mem::size_of::<i32>() as libc::socklen_t)
111 };
112}
113
114pub fn set_socket_reuse_port(socket:RawFdType,is_reuse:i32)->i32 {
116 return unsafe {
117 libc::setsockopt(socket as c_int, libc::SOL_SOCKET,
118 libc::SO_REUSEPORT,&(is_reuse as c_int) as *const _ as *const c_void,std::mem::size_of::<i32>() as libc::socklen_t)
119 };
120}
121pub fn get_raw_socket(socket:&mio_udpsocket)->RawFdType {
123 return socket.as_raw_fd();
124}
125
126pub fn send_udp_msg(fd:RawFdType,buf:&[u8],addr:&SocketAddr)->io::Result<usize> {
128
129 unsafe {
130 let (sockaddr,len) = sockaddr_t::from_socket_addr(addr);
131 let res= libc::sendto(fd as libc::c_int,buf.as_ptr() as *const c_void,buf.len() as libc::size_t,0,
132 sockaddr.as_ptr(),len) as usize;
133
134 if res>0 {
135 return Ok(res as usize)
136 } else {
137 return Err(Error::last_os_error())
138 }
139 }
140}
141
142pub fn wait_for_single_fd_read(fd:RawFdType,timeout_msec:i32)->Result<(),errcode::RESULT> {
145 let mut fds = libc::pollfd{
146 fd:fd as libc::c_int,
147 events:libc::POLLIN,
148 revents:0,
149 };
150 match unsafe { libc::poll(&mut fds as *mut libc::pollfd,1 as libc::nfds_t,timeout_msec as libc::c_int) } {
151 0=>Err(errcode::ERROR_TIME_OUT),
152 1=>Ok(()),
153 _=>Err(errcode::ERROR_OS_CALL_FAILED),
154 }
155}
156
157pub fn create_rawsocket(is_l2_socket:bool)->RawFdType {
160 let sock_type=if is_l2_socket {libc::SOCK_RAW} else {libc::SOCK_DGRAM};
161
162 return unsafe { libc::socket(libc::AF_PACKET, sock_type, i32::from((libc::ETH_P_ALL as u16).to_be())) }
163}
164
165pub fn get_netif_index_by_name(name: &str) -> Result<i32,errcode::RESULT> {
167 if name.len() > libc::IFNAMSIZ {
168 return Err(errcode::ERROR_INVALID_PARAM);
169 }
170 let mut buf = [0u8; libc::IFNAMSIZ];
171 buf[..name.len()].copy_from_slice(name.as_bytes());
172 let idx = unsafe { libc::if_nametoindex(buf.as_ptr() as *const libc::c_char) };
173 if idx == 0 {
174 return Err(errcode::ERROR_NOT_FOUND);
175 }
176
177 Ok(idx as i32)
178}
179
180pub fn bind_by_index(fd:RawFdType,ifindex: i32) -> errcode::RESULT {
182 unsafe {
183 let mut ss: libc::sockaddr_storage = std::mem::zeroed();
184 let sll: *mut libc::sockaddr_ll = &mut ss as *mut libc::sockaddr_storage as *mut libc::sockaddr_ll;
185 (*sll).sll_family = libc::AF_PACKET as u16;
186 (*sll).sll_protocol = (libc::ETH_P_ALL as u16).to_be();
187 (*sll).sll_ifindex = ifindex;
188
189 let sa = (&ss as *const libc::sockaddr_storage) as *const libc::sockaddr;
190 let res = libc::bind(fd, sa, std::mem::size_of::<libc::sockaddr_ll>() as u32);
191 if res == -1 {
192 return errcode::ERROR_BIND_SOCKET;
193 }
194 let ignore_pkt:i32 = 1;
195 const PACKET_IGNORE_OUTGOING:i32=23;
196 libc::setsockopt(fd,libc::SOL_PACKET,PACKET_IGNORE_OUTGOING,
197 &ignore_pkt as *const i32 as *const libc::c_void,std::mem::size_of::<i32>().try_into().unwrap());
198 }
199
200 errcode::RESULT_SUCCESS
201}
202
203pub fn bind(fd:RawFdType,addr:&SocketAddr)->errcode::RESULT {
204 let (os_addr,len)=sockaddr_t::from_socket_addr(addr);
205
206 let res = unsafe { libc::bind(fd,std::ptr::addr_of!(os_addr) as *const libc::sockaddr, len) };
207 if res!=0 {
208 println!("bind socket addr={},os_err={}",addr,std::io::Error::last_os_error());
209 return errcode::ERROR_BIND_SOCKET
210 }
211 return errcode::RESULT_SUCCESS
212
213}
214pub fn listen(fd:RawFdType,back_log:i32)->errcode::RESULT {
215
216 let res = unsafe { libc::listen(fd,back_log) };
217 if res!=0 {
218 return errcode::ERROR_BIND_SOCKET
219 }
220 return errcode::RESULT_SUCCESS
221
222}
223
224pub fn accept(fd:RawFdType)->Result<(RawFdType,SocketAddr),errcode::RESULT> {
225 let mut sock_addr = unsafe { mem::zeroed::<sockaddr_t>() };
226 let mut len=std::mem::size_of::<sockaddr_t>() as u32;
227 let res = unsafe { libc::accept(fd,std::ptr::addr_of_mut!(sock_addr) as *mut libc::sockaddr,&mut len as * mut u32) };
228 if res<0 {
229 println!("[rawsocket]accept connection error,ret={},os_err={}",res,std::io::Error::last_os_error());
230 return Err(errcode::ERROR_OS_CALL_FAILED)
231 }
232 let addr=match unsafe { to_socket_addr(std::ptr::addr_of!(sock_addr)) } {
233 Err(_)=>return Err(errcode::ERROR_INVALID_IPADDR),
234 Ok(a)=>a,
235 };
236 return Ok((res as RawFdType,addr))
237
238}
239
240pub fn connect(fd:RawFdType,dst:&SocketAddr)->errcode::RESULT {
241 let (addr,len)=sockaddr_t::from_socket_addr(dst);
242 let ret = unsafe {
243 libc::connect(fd, std::ptr::addr_of!(addr) as *const libc::sockaddr, len)
244 };
245
246 if ret==0 {
247 return errcode::RESULT_SUCCESS
248 }
249 return errcode::ERROR_OS_CALL_FAILED
250}
251
252pub fn set_promisc_mode(fd:RawFdType,if_idx: i32, state: bool) ->errcode::RESULT {
254 let packet_membership = if state {
255 libc::PACKET_ADD_MEMBERSHIP
256 } else {
257 libc::PACKET_DROP_MEMBERSHIP
258 };
259
260 unsafe {
261 let mut mreq: libc::packet_mreq = std::mem::zeroed();
262
263 mreq.mr_ifindex = if_idx;
264 mreq.mr_type = libc::PACKET_MR_PROMISC as u16;
265
266 let res = libc::setsockopt(fd, libc::SOL_PACKET, packet_membership,
267 (&mreq as *const libc::packet_mreq) as *const libc::c_void, std::mem::size_of::<libc::packet_mreq>() as u32);
268 if res == -1 {
269 return errcode::ERROR_OS_CALL_FAILED;
270 }
271 }
272
273 errcode::RESULT_SUCCESS
274}
275
276pub fn read_fd(fd: RawFd, buf: &mut [u8],flags:i32) -> Result<usize,errcode::RESULT> {
278 let rv = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut libc::c_void, buf.len()) };
279 if rv < 0 {
280 return Err(errcode::ERROR_RECV_MSG);
281 }
282
283 Ok(rv as usize)
284}
285
286pub fn write_fd(fd: RawFd, buf: &[u8],flags:i32) -> Result<usize,errcode::RESULT> {
288 let rv = unsafe { libc::write(fd, buf.as_ptr() as *const libc::c_void, buf.len().try_into().unwrap()) };
289 if rv < 0 {
290 return Err(errcode::ERROR_RECV_MSG);
292 }
293
294 Ok(rv as usize)
295}
296
297pub fn send_to(fd: RawFdType, buf: &[u8],flags:i32,dst:&SocketAddr) -> Result<usize,errcode::RESULT> {
298 let (addr,len)=sockaddr_t::from_socket_addr(dst);
299 let rv = unsafe {
300 libc::sendto(fd, buf.as_ptr() as *const libc::c_void, buf.len(), flags,
301 std::ptr::addr_of!(addr) as *const libc::sockaddr, len)
302 };
303 if rv < 0 {
304 return Err(errcode::ERROR_SEND_MSG);
305 }
306
307 Ok(rv as usize)
308}
309
310#[cfg(unix)]
312pub fn read_fd_vector(fd: RawFd, bufs: &mut [IoSliceMut]) -> io::Result<usize> {
313 let rv = unsafe { libc::readv(fd, bufs.as_mut_ptr() as *const libc::iovec, bufs.len() as i32) };
314 if rv < 0 {
315 return Err(Error::last_os_error());
316 }
317
318 Ok(rv as usize)
319}
320
321pub fn write_fd_vertor(fd: RawFd, bufs: &[IoSlice]) -> io::Result<usize> {
323 let rv = unsafe { libc::writev(fd, bufs.as_ptr() as *const libc::iovec, bufs.len() as i32) };
324 if rv < 0 {
325 return Err(Error::last_os_error());
326 }
327
328 Ok(rv as usize)
329}
330
331 pub fn set_non_blocking(fd:RawFd) -> io::Result<()> {
333 unsafe {
334 let mut res = libc::fcntl(fd, libc::F_GETFL);
335 if res != -1 {
336 res = libc::fcntl(fd, libc::F_SETFL, res | libc::O_NONBLOCK);
337 }
338 if res == -1 {
339 return Err(Error::last_os_error());
340 }
341 }
342 Ok(())
343 }
344
345
346pub fn close_fd(fd:RawFdType) {
348 unsafe {
349 libc::close(fd);
350 }
351}
352
353pub fn recv_from(fd: RawFd, buf: &mut [u8]) -> io::Result<(usize,SocketAddr)> {
355 unsafe {
357 let mut addr=mem::zeroed::<sockaddr_t>();
358 let mut addr_len = mem::size_of::<sockaddr_t>() as u32;
359 let rv =
360 libc::recvfrom(fd, buf.as_mut_ptr() as *mut libc::c_void,
361 buf.len(),0,&mut addr as *mut _ as *mut libc::sockaddr, &mut addr_len as *mut u32);
362
363 if rv < 0 {
364 let err = Error::last_os_error();
365 return Err(err);
367 }
368 let sockaddr = match to_socket_addr(&addr as *const sockaddr_t) {
369 Ok(a)=>a,
370 Err(_)=>return Err(Error::last_os_error()),
371 };
372 Ok((rv as usize,sockaddr))
373}
374}
375
376
377#[repr(C)]
380#[derive(Copy,Clone)]
381pub struct iovec {
382 pub iov_base: *mut u8,
383 pub iov_len: usize,
384}
385impl iovec {
386 pub fn from_raw_parts(buf_ptr:*mut u8,len:usize)->iovec {
387 return Self{
388 iov_base:buf_ptr,
389 iov_len:len,
390 }
391 }
392
393 pub fn from_slice(buf:&mut[u8])->iovec {
394 return Self{
395 iov_base:buf.as_mut_ptr(),
396 iov_len:buf.len(),
397 }
398 }
399 pub fn to_slice(&mut self)->&[u8] {
400 let p = unsafe { std::slice::from_raw_parts_mut(self.iov_base, self.iov_len) };
401 return p
402 }
403}
404
405#[derive(Debug)]
408#[repr(C)]
409pub struct msg_hdr_t {
410 pub msg_name: *mut sockaddr_t,
411 pub msg_namelen: u32,
412 pub msg_iov: *mut iovec,
413 pub msg_iovlen: usize,
414 pub msg_control: *mut u8,
415 pub msg_control_len: usize,
416 pub msg_flags: i32,
417}
418#[derive(Debug)]
419#[repr(C)]
420pub struct mmsg_hdr_t {
421 pub msg_hdr: msg_hdr_t,
422 pub msg_len: u32,
423}
424
425impl mmsg_hdr_t {
426 pub fn new(capacity:usize, buffs:&mut [iovec],addr:&mut sockaddr_t)->Self {
430
431 return mmsg_hdr_t{
433 msg_hdr:msg_hdr_t {
434 msg_name: addr as * mut sockaddr_t,
435 msg_namelen: std::mem::size_of::<sockaddr_t>() as u32,
436 msg_iov: buffs.as_mut_ptr(),
437 msg_iovlen:capacity,
438 msg_control:std::ptr::null_mut(),
439 msg_control_len:0,
440 msg_flags:0
441 },
442 msg_len:0,
443 }
444 }
445
446 pub fn get_nth_buf_len(&self,idx:usize)->usize {
447 if idx>=self.msg_hdr.msg_iovlen {
448 return 0;
449 }
450 let buf= unsafe {
451 &*((self.msg_hdr.msg_iov as usize + mem::size_of::<iovec>()*idx) as *const iovec)
452 };
453 return buf.iov_len;
454
455 }
456
457 pub fn to_string(&self)->String {
458 unsafe {
459 let mut content = Vec::with_capacity(64);
460 std::ptr::copy((*self.msg_hdr.msg_iov).iov_base, content.as_mut_ptr(), 32);
461 content.set_len(32);
462 format!("msg_len={},msg_name={:?},msg_namelen={},msg_iov={:?},msg_iov_len={},msg_control:{:?},msg_control_len={},
463 content={:?}",
464 self.msg_len,self.msg_hdr.msg_name,self.msg_hdr.msg_namelen,self.msg_hdr.msg_iov,
465 self.msg_hdr.msg_iovlen,self.msg_hdr.msg_control,self.msg_hdr.msg_control_len,
466 content.as_slice())
467 }
468 }
469}
470
471pub fn recv_from_mmsg(fd: RawFd, bufs: &mut [mmsg_hdr_t],bufs_count:u32) -> io::Result<usize> {
473 let rv = unsafe {
475 libc::recvmmsg(fd, bufs.as_mut_ptr() as *mut mmsg_hdr_t as *mut u8 as *mut libc::mmsghdr,
476 bufs_count,0,std::ptr::null_mut() as *mut libc::timespec)
477 };
478 if rv < 0 {
479 let err = Error::last_os_error();
480 return Err(err);
482 }
483
484 Ok(rv as usize)
485}
486
487pub fn send_mmsg(fd: RawFd, bufs: &mut mmsg_hdr_t,bufs_count:u32) -> io::Result<usize> {
489 let rv = unsafe { libc::sendmmsg(fd, bufs as *mut mmsg_hdr_t as *mut u8 as *mut libc::mmsghdr,
490 bufs_count,0) };
491 if rv < 0 {
492 return Err(Error::last_os_error());
493 }
494
495 Ok(rv as usize)
496}