|  |  |  | @ -15,6 +15,34 @@ const SOCK_RAW: usize = 3; | 
			
		
	
		
			
				
					|  |  |  |  | const IPPROTO_IP: usize = 0; | 
			
		
	
		
			
				
					|  |  |  |  | const IPPROTO_ICMP: usize = 1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn parse_addr(sockaddr_in: &SockaddrIn, dest: &mut Option<IpAddress>, port: &mut u16) { | 
			
		
	
		
			
				
					|  |  |  |  |     if sockaddr_in.sin_family == AF_INET as u16 { | 
			
		
	
		
			
				
					|  |  |  |  |         *port = u16::from_be(sockaddr_in.sin_port); | 
			
		
	
		
			
				
					|  |  |  |  |         let addr = u32::from_be(sockaddr_in.sin_addr); | 
			
		
	
		
			
				
					|  |  |  |  |         *dest = Some(IpAddress::v4( | 
			
		
	
		
			
				
					|  |  |  |  |             (addr >> 24) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             ((addr >> 16) & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             ((addr >> 8) & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             (addr & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |         )); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | fn fill_addr(sockaddr_in: &mut SockaddrIn, dest: IpAddress, port: u16) { | 
			
		
	
		
			
				
					|  |  |  |  |     if let IpAddress::Ipv4(ipv4) = dest { | 
			
		
	
		
			
				
					|  |  |  |  |         sockaddr_in.sin_family = AF_INET as u16; | 
			
		
	
		
			
				
					|  |  |  |  |         sockaddr_in.sin_port = u16::to_be(port); | 
			
		
	
		
			
				
					|  |  |  |  |         sockaddr_in.sin_addr = u32::to_be( | 
			
		
	
		
			
				
					|  |  |  |  |             ((ipv4.0[0] as u32) << 24) | 
			
		
	
		
			
				
					|  |  |  |  |                 | ((ipv4.0[1] as u32) << 16) | 
			
		
	
		
			
				
					|  |  |  |  |                 | ((ipv4.0[2] as u32) << 8) | 
			
		
	
		
			
				
					|  |  |  |  |                 | ipv4.0[3] as u32, | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         unimplemented!("ipv6"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |     info!( | 
			
		
	
		
			
				
					|  |  |  |  |         "socket: domain: {}, socket_type: {}, protocol: {}", | 
			
		
	
	
		
			
				
					|  |  |  | @ -31,7 +59,13 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu | 
			
		
	
		
			
				
					|  |  |  |  |                 let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let tcp_handle = proc.sockets.add(tcp_socket); | 
			
		
	
		
			
				
					|  |  |  |  |                 proc.files.insert(fd, FileLike::Socket(tcp_handle)); | 
			
		
	
		
			
				
					|  |  |  |  |                 proc.files.insert( | 
			
		
	
		
			
				
					|  |  |  |  |                     fd, | 
			
		
	
		
			
				
					|  |  |  |  |                     FileLike::Socket(SocketWrapper { | 
			
		
	
		
			
				
					|  |  |  |  |                         handle: tcp_handle, | 
			
		
	
		
			
				
					|  |  |  |  |                         socket_type: SocketType::Tcp, | 
			
		
	
		
			
				
					|  |  |  |  |                     }), | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 Ok(fd as isize) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  |  | @ -50,7 +84,13 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let raw_handle = proc.sockets.add(raw_socket); | 
			
		
	
		
			
				
					|  |  |  |  |                 proc.files.insert(fd, FileLike::Socket(raw_handle)); | 
			
		
	
		
			
				
					|  |  |  |  |                 proc.files.insert( | 
			
		
	
		
			
				
					|  |  |  |  |                     fd, | 
			
		
	
		
			
				
					|  |  |  |  |                     FileLike::Socket(SocketWrapper { | 
			
		
	
		
			
				
					|  |  |  |  |                         handle: raw_handle, | 
			
		
	
		
			
				
					|  |  |  |  |                         socket_type: SocketType::Raw, | 
			
		
	
		
			
				
					|  |  |  |  |                     }), | 
			
		
	
		
			
				
					|  |  |  |  |                 ); | 
			
		
	
		
			
				
					|  |  |  |  |                 Ok(fd as isize) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             _ => Err(SysError::EINVAL), | 
			
		
	
	
		
			
				
					|  |  |  | @ -83,10 +123,10 @@ struct SockaddrIn { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | impl Process { | 
			
		
	
		
			
				
					|  |  |  |  |     fn get_handle(&mut self, fd: usize) -> Result<SocketHandle, SysError> { | 
			
		
	
		
			
				
					|  |  |  |  |     fn get_socket(&mut self, fd: usize) -> Result<SocketWrapper, SysError> { | 
			
		
	
		
			
				
					|  |  |  |  |         let file = self.files.get_mut(&fd).ok_or(SysError::EBADF)?; | 
			
		
	
		
			
				
					|  |  |  |  |         match file { | 
			
		
	
		
			
				
					|  |  |  |  |             FileLike::Socket(handle) => Ok(handle.clone()), | 
			
		
	
		
			
				
					|  |  |  |  |             FileLike::Socket(wrapper) => Ok(wrapper.clone()), | 
			
		
	
		
			
				
					|  |  |  |  |             _ => Err(SysError::ENOTSOCK), | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -98,18 +138,17 @@ pub fn sys_connect(fd: usize, addr: *const u8, addrlen: usize) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |         fd, addr, addrlen | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let mut proc = process(); | 
			
		
	
		
			
				
					|  |  |  |  |     if !proc.memory_set.check_ptr(addr) { | 
			
		
	
		
			
				
					|  |  |  |  |         return Err(SysError::EFAULT); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let mut dest = None; | 
			
		
	
		
			
				
					|  |  |  |  |     let mut port = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     if addrlen == size_of::<SockaddrIn>() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // FIXME: check size as per sin_family
 | 
			
		
	
		
			
				
					|  |  |  |  |     let sockaddr_in = unsafe { &*(addr as *const SockaddrIn) }; | 
			
		
	
		
			
				
					|  |  |  |  |         port = ((sockaddr_in.sin_port & 0xFF) << 8) | (sockaddr_in.sin_port >> 8); | 
			
		
	
		
			
				
					|  |  |  |  |         dest = Some(IpAddress::v4( | 
			
		
	
		
			
				
					|  |  |  |  |             (sockaddr_in.sin_addr & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             ((sockaddr_in.sin_addr >> 8) & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             ((sockaddr_in.sin_addr >> 16) & 0xFF) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |             (sockaddr_in.sin_addr >> 24) as u8, | 
			
		
	
		
			
				
					|  |  |  |  |         )); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     parse_addr(&sockaddr_in, &mut dest, &mut port); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if dest == None { | 
			
		
	
		
			
				
					|  |  |  |  |         return Err(SysError::EINVAL); | 
			
		
	
	
		
			
				
					|  |  |  | @ -120,9 +159,9 @@ pub fn sys_connect(fd: usize, addr: *const u8, addrlen: usize) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |     let iface = &mut *NET_DRIVERS.lock()[0]; | 
			
		
	
		
			
				
					|  |  |  |  |     iface.poll(&mut proc.sockets); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // TODO: check its type
 | 
			
		
	
		
			
				
					|  |  |  |  |     let tcp_handle = proc.get_handle(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     let mut socket = proc.sockets.get::<TcpSocket>(tcp_handle); | 
			
		
	
		
			
				
					|  |  |  |  |     let wrapper = proc.get_socket(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     if let SocketType::Tcp = wrapper.socket_type { | 
			
		
	
		
			
				
					|  |  |  |  |         let mut socket = proc.sockets.get::<TcpSocket>(wrapper.handle); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // TODO selects non-conflict high port
 | 
			
		
	
		
			
				
					|  |  |  |  |         static mut EPHEMERAL_PORT: u16 = 49152; | 
			
		
	
	
		
			
				
					|  |  |  | @ -139,27 +178,25 @@ pub fn sys_connect(fd: usize, addr: *const u8, addrlen: usize) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |             Ok(()) => Ok(0), | 
			
		
	
		
			
				
					|  |  |  |  |             Err(_) => Err(SysError::EISCONN), | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         unimplemented!("socket type") | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_write_socket( | 
			
		
	
		
			
				
					|  |  |  |  |     proc: &mut Process, | 
			
		
	
		
			
				
					|  |  |  |  |     fd: usize, | 
			
		
	
		
			
				
					|  |  |  |  |     base: *const u8, | 
			
		
	
		
			
				
					|  |  |  |  |     len: usize, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_write_socket(proc: &mut Process, fd: usize, base: *const u8, len: usize) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |     // little hack: kick it forward
 | 
			
		
	
		
			
				
					|  |  |  |  |     let iface = &mut *NET_DRIVERS.lock()[0]; | 
			
		
	
		
			
				
					|  |  |  |  |     iface.poll(&mut proc.sockets); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // TODO: check its type
 | 
			
		
	
		
			
				
					|  |  |  |  |     let tcp_handle = proc.get_handle(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     let mut socket = proc.sockets.get::<TcpSocket>(tcp_handle); | 
			
		
	
		
			
				
					|  |  |  |  |     let wrapper = proc.get_socket(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     if let SocketType::Tcp = wrapper.socket_type { | 
			
		
	
		
			
				
					|  |  |  |  |         let mut socket = proc.sockets.get::<TcpSocket>(wrapper.handle); | 
			
		
	
		
			
				
					|  |  |  |  |         let slice = unsafe { slice::from_raw_parts(base, len) }; | 
			
		
	
		
			
				
					|  |  |  |  |         if socket.is_open() { | 
			
		
	
		
			
				
					|  |  |  |  |             if socket.can_send() { | 
			
		
	
		
			
				
					|  |  |  |  |                 match socket.send_slice(&slice) { | 
			
		
	
		
			
				
					|  |  |  |  |                     Ok(size) => Ok(size as isize), | 
			
		
	
		
			
				
					|  |  |  |  |                 Err(err) =>  Err(SysError::ENOBUFS) | 
			
		
	
		
			
				
					|  |  |  |  |                     Err(err) => Err(SysError::ENOBUFS), | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |  |                 Err(SysError::ENOBUFS) | 
			
		
	
	
		
			
				
					|  |  |  | @ -167,6 +204,9 @@ pub fn sys_write_socket( | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             Err(SysError::ECONNREFUSED) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         unimplemented!("socket type") | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_select( | 
			
		
	
	
		
			
				
					|  |  |  | @ -189,9 +229,60 @@ pub fn sys_sendto( | 
			
		
	
		
			
				
					|  |  |  |  |     addr: *const u8, | 
			
		
	
		
			
				
					|  |  |  |  |     addr_len: usize, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |     info!("sys_sendto: fd: {} buffer: {:?} len: {}", fd, buffer, len); | 
			
		
	
		
			
				
					|  |  |  |  |     warn!("sys_sendto is unimplemented"); | 
			
		
	
		
			
				
					|  |  |  |  |     Err(SysError::EINVAL) | 
			
		
	
		
			
				
					|  |  |  |  |     info!( | 
			
		
	
		
			
				
					|  |  |  |  |         "sys_sendto: fd: {} buffer: {:?} len: {} addr: {:?} addr_len: {}", | 
			
		
	
		
			
				
					|  |  |  |  |         fd, buffer, len, addr, addr_len | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |     let mut proc = process(); | 
			
		
	
		
			
				
					|  |  |  |  |     if !proc.memory_set.check_ptr(addr) { | 
			
		
	
		
			
				
					|  |  |  |  |         return Err(SysError::EFAULT); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if !proc.memory_set.check_array(buffer, len) { | 
			
		
	
		
			
				
					|  |  |  |  |         return Err(SysError::EINVAL); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // little hack: kick it forward
 | 
			
		
	
		
			
				
					|  |  |  |  |     let iface = &mut *NET_DRIVERS.lock()[0]; | 
			
		
	
		
			
				
					|  |  |  |  |     iface.poll(&mut proc.sockets); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let wrapper = proc.get_socket(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     if let SocketType::Raw = wrapper.socket_type { | 
			
		
	
		
			
				
					|  |  |  |  |         let mut socket = proc.sockets.get::<RawSocket>(wrapper.handle); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         let mut dest = None; | 
			
		
	
		
			
				
					|  |  |  |  |         let mut port = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         // FIXME: check size as per sin_family
 | 
			
		
	
		
			
				
					|  |  |  |  |         let sockaddr_in = unsafe { &*(addr as *const SockaddrIn) }; | 
			
		
	
		
			
				
					|  |  |  |  |         parse_addr(&sockaddr_in, &mut dest, &mut port); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         if dest == None { | 
			
		
	
		
			
				
					|  |  |  |  |             return Err(SysError::EINVAL); | 
			
		
	
		
			
				
					|  |  |  |  |         } else if let Some(IpAddress::Ipv4(v4_dest)) = dest { | 
			
		
	
		
			
				
					|  |  |  |  |             let slice = unsafe { slice::from_raw_parts(buffer, len) }; | 
			
		
	
		
			
				
					|  |  |  |  |             // using 20-byte IPv4 header
 | 
			
		
	
		
			
				
					|  |  |  |  |             let mut buffer = vec![0u8; len + 20]; | 
			
		
	
		
			
				
					|  |  |  |  |             let mut packet = Ipv4Packet::new_unchecked(&mut buffer); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_version(4); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_header_len(20); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_total_len((20 + len) as u16); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_protocol(socket.ip_protocol().into()); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_src_addr(iface.ipv4_address().unwrap()); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.set_dst_addr(v4_dest); | 
			
		
	
		
			
				
					|  |  |  |  |             let payload = packet.payload_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |             payload.copy_from_slice(slice); | 
			
		
	
		
			
				
					|  |  |  |  |             packet.fill_checksum(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             socket.send_slice(&buffer).unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             Ok(len as isize) | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             unimplemented!("ip type") | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         unimplemented!("socket type") | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_recvfrom( | 
			
		
	
	
		
			
				
					|  |  |  | @ -199,12 +290,44 @@ pub fn sys_recvfrom( | 
			
		
	
		
			
				
					|  |  |  |  |     buffer: *mut u8, | 
			
		
	
		
			
				
					|  |  |  |  |     len: usize, | 
			
		
	
		
			
				
					|  |  |  |  |     flags: usize, | 
			
		
	
		
			
				
					|  |  |  |  |     addr: *const u8, | 
			
		
	
		
			
				
					|  |  |  |  |     addr_len: usize, | 
			
		
	
		
			
				
					|  |  |  |  |     addr: *mut u8, | 
			
		
	
		
			
				
					|  |  |  |  |     addr_len: *mut usize, | 
			
		
	
		
			
				
					|  |  |  |  | ) -> SysResult { | 
			
		
	
		
			
				
					|  |  |  |  |     info!("sys_recvfrom: fd: {} buffer: {:?} len: {}", fd, buffer, len); | 
			
		
	
		
			
				
					|  |  |  |  |     warn!("sys_recvfrom is unimplemented"); | 
			
		
	
		
			
				
					|  |  |  |  |     Err(SysError::EINVAL) | 
			
		
	
		
			
				
					|  |  |  |  |     info!( | 
			
		
	
		
			
				
					|  |  |  |  |         "sys_recvfrom: fd: {} buffer: {:?} len: {} flags: {} addr: {:?} addr_len: {:?}", | 
			
		
	
		
			
				
					|  |  |  |  |         fd, buffer, len, flags, addr, addr_len | 
			
		
	
		
			
				
					|  |  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  |  |     let mut proc = process(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // little hack: kick it forward
 | 
			
		
	
		
			
				
					|  |  |  |  |     let iface = &mut *NET_DRIVERS.lock()[0]; | 
			
		
	
		
			
				
					|  |  |  |  |     iface.poll(&mut proc.sockets); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     let wrapper = proc.get_socket(fd)?; | 
			
		
	
		
			
				
					|  |  |  |  |     if let SocketType::Raw = wrapper.socket_type { | 
			
		
	
		
			
				
					|  |  |  |  |         let mut socket = proc.sockets.get::<RawSocket>(wrapper.handle); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; | 
			
		
	
		
			
				
					|  |  |  |  |         match socket.recv_slice(&mut slice) { | 
			
		
	
		
			
				
					|  |  |  |  |             Ok(size) => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let mut packet = Ipv4Packet::new_unchecked(&slice); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // FIXME: check size as per sin_family
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let mut sockaddr_in = unsafe { &mut *(addr as *mut SockaddrIn) }; | 
			
		
	
		
			
				
					|  |  |  |  |                 fill_addr(&mut sockaddr_in, IpAddress::Ipv4(packet.src_addr()), 0); | 
			
		
	
		
			
				
					|  |  |  |  |                 unsafe { *addr_len = size_of::<SockaddrIn>() }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 Ok(size as isize) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             Err(err) => { | 
			
		
	
		
			
				
					|  |  |  |  |                 warn!("err {:?}", err); | 
			
		
	
		
			
				
					|  |  |  |  |                 Err(SysError::ENOBUFS) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         unimplemented!("socket type") | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn sys_close_socket(proc: &mut Process, fd: usize, handle: SocketHandle) -> SysResult { | 
			
		
	
	
		
			
				
					|  |  |  | 
 |