@@ -206,7 +206,7 @@ impl AddressFamily {
206
206
/// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from
207
207
/// the `sa_family` field of a `sockaddr`.
208
208
///
209
- /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink
209
+ /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link
210
210
/// and System. Returns None for unsupported or unknown address families.
211
211
pub fn from_i32 ( family : i32 ) -> Option < AddressFamily > {
212
212
match family {
@@ -798,52 +798,22 @@ impl SockAddr {
798
798
#[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ]
799
799
Some ( AddressFamily :: System ) => Some ( SockAddr :: SysControl (
800
800
SysControlAddr ( * ( addr as * const sys_control:: sockaddr_ctl ) ) ) ) ,
801
- // FIXME: android is same ?
802
- // #[cfg(any(target_os = "android", target_os = "linux"))]
803
- #[ cfg( target_os = "linux" ) ]
804
- Some ( AddressFamily :: Packet ) => {
805
- let sll: * const libc:: sockaddr_ll = mem:: transmute ( addr) ;
806
- let mac = EtherAddr ( ( * sll) . sll_addr [ 0 ] ,
807
- ( * sll) . sll_addr [ 1 ] ,
808
- ( * sll) . sll_addr [ 2 ] ,
809
- ( * sll) . sll_addr [ 3 ] ,
810
- ( * sll) . sll_addr [ 4 ] ,
811
- ( * sll) . sll_addr [ 5 ] ) ;
812
- Some ( SockAddr :: Ether ( mac) )
801
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
802
+ Some ( AddressFamily :: Packet ) => match EtherAddr :: from_libc_sockaddr_ll (
803
+ addr as * const libc:: sockaddr_ll ) {
804
+ Some ( mac_addr) => Some ( SockAddr :: Ether ( mac_addr) ) ,
805
+ None => None
813
806
} ,
814
807
#[ cfg( any( target_os = "dragonfly" ,
815
- target_os = "freebsd" ,
816
- target_os = "ios" ,
817
- target_os = "macos" ,
818
- target_os = "netbsd" ,
819
- target_os = "openbsd" ) ) ]
820
- Some ( AddressFamily :: Link ) => {
821
- let sdl: * const libc:: sockaddr_dl = mem:: transmute ( addr) ;
822
- let nlen = ( * sdl) . sdl_nlen as usize ;
823
- let max_nlen: usize = if cfg ! ( target_os = "macos" ) {
824
- 12
825
- } else if cfg ! ( target_os = "freebsd" ) {
826
- 46
827
- } else if cfg ! ( target_os = "dragonfly" ) {
828
- 12
829
- } else if cfg ! ( target_os = "netbsd" ) {
830
- 12
831
- } else if cfg ! ( target_os = "openbsd" ) {
832
- 24
833
- } else {
834
- return None ;
835
- } ;
836
- if nlen + 5 >= max_nlen {
837
- return None ;
838
- }
839
- let mac = EtherAddr ( ( * sdl) . sdl_data [ nlen] as u8 ,
840
- ( * sdl) . sdl_data [ nlen + 1 ] as u8 ,
841
- ( * sdl) . sdl_data [ nlen + 2 ] as u8 ,
842
- ( * sdl) . sdl_data [ nlen + 3 ] as u8 ,
843
- ( * sdl) . sdl_data [ nlen + 4 ] as u8 ,
844
- ( * sdl) . sdl_data [ nlen + 5 ] as u8 ) ;
845
-
846
- Some ( SockAddr :: Ether ( mac) )
808
+ target_os = "freebsd" ,
809
+ target_os = "ios" ,
810
+ target_os = "macos" ,
811
+ target_os = "netbsd" ,
812
+ target_os = "openbsd" ) ) ]
813
+ Some ( AddressFamily :: Link ) => match EtherAddr :: from_libc_sockaddr_dl (
814
+ addr as * const libc:: sockaddr_dl ) {
815
+ Some ( mac_addr) => Some ( SockAddr :: Ether ( mac_addr) ) ,
816
+ None => None
847
817
} ,
848
818
// Other address families are currently not supported and simply yield a None
849
819
// entry instead of a proper conversion to a `SockAddr`.
@@ -1091,23 +1061,83 @@ pub mod sys_control {
1091
1061
}
1092
1062
1093
1063
#[ derive( Clone , Copy , Eq , Hash , PartialEq ) ]
1094
- pub struct EtherAddr ( pub u8 , pub u8 , pub u8 , pub u8 , pub u8 , pub u8 ) ;
1064
+ pub struct EtherAddr {
1065
+ pub a : u8 ,
1066
+ pub b : u8 ,
1067
+ pub c : u8 ,
1068
+ pub d : u8 ,
1069
+ pub e : u8 ,
1070
+ pub f : u8 ,
1071
+ }
1095
1072
1096
1073
impl EtherAddr {
1097
1074
pub fn new ( a : u8 , b : u8 , c : u8 , d : u8 , e : u8 , f : u8 ) -> EtherAddr {
1098
- EtherAddr ( a, b, c, d, e, f)
1075
+ EtherAddr {
1076
+ a : a,
1077
+ b : b,
1078
+ c : c,
1079
+ d : d,
1080
+ e : e,
1081
+ f : f,
1082
+ }
1083
+ }
1084
+
1085
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1086
+ pub unsafe fn from_libc_sockaddr_ll ( sll : * const libc:: sockaddr_ll ) -> Option < EtherAddr > {
1087
+ let mac = EtherAddr :: new (
1088
+ ( * sll) . sll_addr [ 0 ] ,
1089
+ ( * sll) . sll_addr [ 1 ] ,
1090
+ ( * sll) . sll_addr [ 2 ] ,
1091
+ ( * sll) . sll_addr [ 3 ] ,
1092
+ ( * sll) . sll_addr [ 4 ] ,
1093
+ ( * sll) . sll_addr [ 5 ] ) ;
1094
+ Some ( mac)
1095
+ }
1096
+
1097
+ #[ cfg( any( target_os = "dragonfly" ,
1098
+ target_os = "freebsd" ,
1099
+ target_os = "ios" ,
1100
+ target_os = "macos" ,
1101
+ target_os = "netbsd" ,
1102
+ target_os = "openbsd" ) ) ]
1103
+ pub unsafe fn from_libc_sockaddr_dl ( sdl : * const libc:: sockaddr_dl ) -> Option < EtherAddr > {
1104
+ let nlen = ( * sdl) . sdl_nlen as usize ;
1105
+ let max_nlen: usize = if cfg ! ( target_os = "macos" ) || cfg ! ( target_os = "ios" ) {
1106
+ 12
1107
+ } else if cfg ! ( target_os = "freebsd" ) {
1108
+ 46
1109
+ } else if cfg ! ( target_os = "dragonfly" ) {
1110
+ 12
1111
+ } else if cfg ! ( target_os = "netbsd" ) {
1112
+ 12
1113
+ } else if cfg ! ( target_os = "openbsd" ) {
1114
+ 24
1115
+ } else {
1116
+ unreachable ! ( ) ;
1117
+ } ;
1118
+ if nlen + 5 >= max_nlen {
1119
+ return None ;
1120
+ }
1121
+ let mac = EtherAddr :: new (
1122
+ ( * sdl) . sdl_data [ nlen ] as u8 ,
1123
+ ( * sdl) . sdl_data [ nlen + 1 ] as u8 ,
1124
+ ( * sdl) . sdl_data [ nlen + 2 ] as u8 ,
1125
+ ( * sdl) . sdl_data [ nlen + 3 ] as u8 ,
1126
+ ( * sdl) . sdl_data [ nlen + 4 ] as u8 ,
1127
+ ( * sdl) . sdl_data [ nlen + 5 ] as u8 ) ;
1128
+ Some ( mac)
1099
1129
}
1100
1130
}
1101
1131
1102
1132
impl fmt:: Display for EtherAddr {
1103
1133
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1104
1134
write ! ( f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}" ,
1105
- self . 0 ,
1106
- self . 1 ,
1107
- self . 2 ,
1108
- self . 3 ,
1109
- self . 4 ,
1110
- self . 5 )
1135
+ self . a ,
1136
+ self . b ,
1137
+ self . c ,
1138
+ self . d ,
1139
+ self . e ,
1140
+ self . f )
1111
1141
}
1112
1142
}
1113
1143
0 commit comments