@@ -11,10 +11,9 @@ use crate::{
1111 runtime:: fail:: Fail ,
1212} ;
1313use :: std:: { mem, mem:: MaybeUninit } ;
14- use libc:: sockaddr;
1514
1615//======================================================================================================================
17- // Constants & Structures
16+ // Structures
1817//======================================================================================================================
1918
2019pub struct RawSocket ( libc:: c_int ) ;
@@ -25,27 +24,24 @@ pub struct RawSocket(libc::c_int);
2524
2625impl RawSocket {
2726 pub fn new ( ) -> Result < Self , Fail > {
28- let domain: i32 = libc:: AF_PACKET ; // Do not parse any headers.
29- let ty: i32 = libc:: SOCK_RAW | libc:: SOCK_NONBLOCK ; // Non-blocking, raw socket.
30- let protocol: i32 = libc:: ETH_P_ALL ; // Accept packet from all protocols.
31- let sockfd: i32 = unsafe { libc:: socket ( domain, ty, protocol) } ;
27+ let domain = libc:: AF_PACKET ; // raw packet socket, no header parsing
28+ let ty = libc:: SOCK_RAW | libc:: SOCK_NONBLOCK ; // raw, non-blocking socket
29+ let protocol = libc:: ETH_P_ALL ; // all protocols
3230
33- // Check if we failed to create the underlying raw socket.
34- if sockfd == -1 {
31+ let fd = unsafe { libc :: socket ( domain , ty , protocol ) } ;
32+ if fd == -1 {
3533 return Err ( Fail :: new ( libc:: EAGAIN , "failed to create raw socket" ) ) ;
3634 }
37- trace ! ( "Creating raw socket with fd={:?}" , sockfd) ;
38- Ok ( RawSocket ( sockfd) )
35+
36+ trace ! ( "created raw socket with fd={:?}" , fd) ;
37+ Ok ( RawSocket ( fd) )
3938 }
4039
41- // Binds a socket to a raw address.
40+ // Binds the socket to a raw address.
4241 pub fn bind ( & self , addr : & RawSocketAddr ) -> Result < ( ) , Fail > {
43- let ret: i32 = unsafe {
44- let ( sockaddr_ptr, address_len) : ( * const sockaddr , Socklen ) = addr. as_sockaddr_ptr ( ) ;
45- libc:: bind ( self . 0 , sockaddr_ptr, address_len)
46- } ;
42+ let ( ptr, len) = addr. as_sockaddr_ptr ( ) ;
4743
48- // Check if we failed to bind the underlying raw socket.
44+ let ret = unsafe { libc :: bind ( self . 0 , ptr , len ) } ;
4945 if ret == -1 {
5046 return Err ( Fail :: new ( libc:: EAGAIN , "failed to bind raw socket" ) ) ;
5147 }
@@ -54,63 +50,65 @@ impl RawSocket {
5450 }
5551
5652 /// Sends data through a raw socket.
57- pub fn sendto ( & self , buf : & [ u8 ] , rawaddr : & RawSocketAddr ) -> Result < usize , Fail > {
58- let buf_len: usize = buf. len ( ) ;
59- let buf_ptr: * const libc:: c_void = buf. as_ptr ( ) as * const libc:: c_void ;
60- let ( addr_ptr, addrlen) : ( * const sockaddr , Socklen ) = rawaddr. as_sockaddr_ptr ( ) ;
61-
62- let nbytes: i32 =
63- unsafe { libc:: sendto ( self . 0 , buf_ptr, buf_len, libc:: MSG_DONTWAIT , addr_ptr, addrlen) as i32 } ;
53+ pub fn sendto ( & self , data : & [ u8 ] , rawaddr : & RawSocketAddr ) -> Result < usize , Fail > {
54+ let ( addr_ptr, addr_len) = rawaddr. as_sockaddr_ptr ( ) ;
55+ let ret = unsafe {
56+ libc:: sendto (
57+ self . 0 ,
58+ data. as_ptr ( ) as * const libc:: c_void ,
59+ data. len ( ) ,
60+ libc:: MSG_DONTWAIT ,
61+ addr_ptr,
62+ addr_len,
63+ )
64+ } ;
6465
65- // Check if we failed to send data through raw socket.
66- if nbytes == -1 {
66+ if ret == -1 {
6767 return Err ( Fail :: new ( libc:: EAGAIN , "failed to send data through raw socket" ) ) ;
6868 }
6969
70- Ok ( nbytes as usize )
70+ Ok ( ret as usize )
7171 }
7272
73- /// Receives data from a raw socket.
74- pub fn recvfrom ( & self , buf : & [ MaybeUninit < u8 > ] ) -> Result < ( usize , RawSocketAddr ) , Fail > {
75- let buf_ptr: * mut libc:: c_void = buf. as_ptr ( ) as * mut libc:: c_void ;
76- let buf_len: usize = buf. len ( ) ;
77- let mut addrlen: Socklen = mem:: size_of :: < SockAddrIn > ( ) as u32 ;
78- let mut rawaddr: RawSocketAddr = RawSocketAddr :: default ( ) ;
79- let addrlen_ptr: * mut Socklen = & mut addrlen as * mut Socklen ;
80- let ( addr_ptr, _) : ( * mut sockaddr , Socklen ) = rawaddr. as_sockaddr_mut_ptr ( ) ;
73+ /// Receive data from a raw socket.
74+ pub fn recvfrom ( & self , recv_buffer : & [ MaybeUninit < u8 > ] ) -> Result < ( usize , RawSocketAddr ) , Fail > {
75+ let ptr = recv_buffer. as_ptr ( ) as * mut libc:: c_void ;
76+ let mut addrlen = mem:: size_of :: < SockAddrIn > ( ) as u32 ;
77+ let mut rawaddr = RawSocketAddr :: default ( ) ;
78+ let ( addr_ptr, _) = rawaddr. as_sockaddr_ptr_mut ( ) ;
79+ let addrlen_ptr = & mut addrlen as * mut Socklen ;
8180
82- let nbytes : i32 = unsafe {
81+ let ret = unsafe {
8382 libc:: recvfrom (
8483 self . 0 ,
85- buf_ptr ,
86- buf_len ,
84+ ptr ,
85+ recv_buffer . len ( ) ,
8786 libc:: MSG_DONTWAIT ,
8887 addr_ptr,
8988 addrlen_ptr as * mut u32 ,
9089 ) as i32
9190 } ;
9291
93- // Check if we failed to receive data from raw socket.
94- if nbytes == -1 {
92+ if ret == -1 {
9593 return Err ( Fail :: new ( libc:: EAGAIN , "failed to receive data from raw socket" ) ) ;
9694 }
9795
98- Ok ( ( nbytes as usize , rawaddr) )
96+ Ok ( ( ret as usize , rawaddr) )
9997 }
10098}
10199
102100//======================================================================================================================
103101// Trait Implementations
104102//======================================================================================================================
105103
106- /// Closes the raw socket.
107104impl Drop for RawSocket {
108105 fn drop ( & mut self ) {
109- if unsafe { libc:: close ( self . 0 ) } < 0 {
110- let errno: libc:: c_int = unsafe { * libc:: __errno_location ( ) } ;
111- warn ! ( "could not close raw socket (fd={:?}): {:?}" , self . 0 , errno) ;
106+ let ret = unsafe { libc:: close ( self . 0 ) } ;
107+ if ret < 0 {
108+ let errno = unsafe { * libc:: __errno_location ( ) } ;
109+ warn ! ( "failed to close raw socket (fd={}): {}" , self . 0 , errno) ;
112110 } else {
113- trace ! ( "Closing raw socket fd={:? }" , self . 0 )
111+ trace ! ( "closed raw socket fd={}" , self . 0 )
114112 }
115113 }
116114}
0 commit comments