原始套接字是否有安全接口?

时间:2015-11-14 22:23:52

标签: linux sockets network-programming rust

Here据说唯一的方法是使用libc:

extern crate libc;
extern crate native;
use libc::{c_int, c_void, socket, AF_INET, sockaddr_storage};
use native::io::net::sockaddr_to_addr;
use std::io::net::ip::SocketAddr;
static SOCK_RAW: c_int = 3;
static IPPROTO_ICMP: c_int = 1;

fn recvfrom<'buf>(sock: c_int, buf: &'buf mut [u8]) -> (&'buf mut [u8], SocketAddr) {
  let mut storage: sockaddr_storage = unsafe { std::mem::init() };
  let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
  let mut addrlen = std::mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;

  let bytes = unsafe { libc::recvfrom(sock,
                 buf.as_mut_ptr() as *mut c_void,
                 buf.len() as u64, 
                 0, storagep, &mut addrlen) };

  (buf.mut_slice_to(bytes as uint),
   sockaddr_to_addr(&storage, addrlen as uint).unwrap())
}

fn main() {
  let handle = unsafe { socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) };
  println!("{}", handle);
  let mut bufferator = [0, ..2048];
  loop {
    let (buf, from) = recvfrom(handle, bufferator.as_mut_slice());
    println!("from {}, data:\n{}", from, buf);
  }
}

但这是一年前写的,所以事情可能已经改变了?

1 个答案:

答案 0 :(得分:1)

一般情况下,任意C代码都没有安全的接口,因为不能保证C代码不会执行Rust不允许的安全操作。虽然只是惯例,Rust土地上的许多东西在名称中都说“原始”有不安全的语义。

您可以做的是使用Rust代码包装原始C代码,以确保C代码永远不会进入违反程序安全的状态。这就是构建TcpStreamUdpSocket等项目的方式。据我所知,ICMP套接字没有包装器。