Skip to content

Instantly share code, notes, and snippets.

@kings-way
Created October 14, 2019 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kings-way/955f8d25b1cb56f81cdb638ca7a2fc6d to your computer and use it in GitHub Desktop.
Save kings-way/955f8d25b1cb56f81cdb638ca7a2fc6d to your computer and use it in GitHub Desktop.
[rust] send raw packet with libc ('AF_PACKET' + 'send', not 'sendto')
use std::mem;
use std::io;
extern crate libc;
fn main() {
let interface_name = "lo";
let socket_fd = match get_raw_socket(interface_name){
Ok(fd) => fd,
Err(err) => {
eprintln!("Error, {}", err);
return;
}
};
// 14 bytes at least
let mut buffer: Vec<u8> = "Hello, World!!".as_bytes().to_vec();
match send_raw_data(socket_fd, &mut buffer){
Ok(_) => (),
Err(err) => {
eprintln!("Error, {}", err);
return;
}
}
}
fn send_raw_data(socket_fd: i32, buf: &mut [u8]) -> Result<(), io::Error>{
let buf_ptr = buf.as_mut_ptr() as *mut libc::c_void;
match unsafe {
libc::send(socket_fd, buf_ptr, buf.len() as usize, 0)
} {
-1 => Err(io::Error::last_os_error()),
_ => Ok(())
}
}
fn get_raw_socket(iface:&str) -> Result<i32, io::Error> {
let socket_fd;
let mut iface = iface.to_owned();
let ifname = iface.as_mut_ptr() as *mut libc::c_char;
match unsafe {
socket_fd = libc::socket(libc::PF_PACKET, libc::SOCK_RAW, 3);
socket_fd
} {
-1 => return Err(io::Error::last_os_error()),
_ => ()
};
match unsafe {
let mut sa: libc::sockaddr_ll = mem::zeroed();
sa.sll_family = libc::AF_PACKET as u16;
sa.sll_protocol = libc::ETH_P_ALL as u16;
sa.sll_ifindex = libc::if_nametoindex(ifname) as i32;
let sa_ptr = mem::transmute::<*mut libc::sockaddr_ll, *mut libc::sockaddr>(&mut sa);
libc::bind(socket_fd, sa_ptr, mem::size_of_val(&sa) as u32)
} {
-1 => Err(io::Error::last_os_error()),
_ => Ok(socket_fd)
}
}
@vang1ong7ang
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment