Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors on android #664

Open
Kofituo opened this issue Dec 10, 2023 · 4 comments
Open

Errors on android #664

Kofituo opened this issue Dec 10, 2023 · 4 comments

Comments

@Kofituo
Copy link

Kofituo commented Dec 10, 2023

Hi there,
I'm trying out this crate on an android device but I'm facing this error

log_panics: thread '<unnamed>' panicked at 'Error happened Permission denied (os error 13)': src/lib.rs:78

This is the code surrounding line 78

fn get_mac_through_arp(interface: NetworkInterface, target_ip: Ipv4Addr) -> MacAddr {
    let source_ip = interface
        .ips
        .iter()
        .find(|ip| ip.is_ipv4())
        .map(|ip| match ip.ip() {
            IpAddr::V4(ip) => ip,
            _ => unreachable!(),
        })
        .unwrap();

    let (mut sender, mut receiver) = match pnet::datalink::channel(&interface, Default::default()) {
        Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
        Ok(_) => panic!("Unknown channel type"),
        Err(e) => panic!("Error happened {}", e), // line 78
    };

    let mut ethernet_buffer = [0u8; 42];
    let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();

    ethernet_packet.set_destination(MacAddr::broadcast());
    ethernet_packet.set_source(interface.mac.unwrap());
    ethernet_packet.set_ethertype(EtherTypes::Arp);

    let mut arp_buffer = [0u8; 28];
    let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap();

    arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet);
    arp_packet.set_protocol_type(EtherTypes::Ipv4);
    arp_packet.set_hw_addr_len(6);
    arp_packet.set_proto_addr_len(4);
    arp_packet.set_operation(ArpOperations::Request);
    arp_packet.set_sender_hw_addr(interface.mac.unwrap());
    arp_packet.set_sender_proto_addr(source_ip);
    arp_packet.set_target_hw_addr(MacAddr::zero());
    arp_packet.set_target_proto_addr(target_ip);

    ethernet_packet.set_payload(arp_packet.packet_mut());

    sender
        .send_to(ethernet_packet.packet(), None)
        .unwrap()
        .unwrap();

    println!("Sent ARP request");

    loop {
        let buf = receiver.next().unwrap();
        let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();
        if arp.get_sender_proto_addr() == target_ip
            && arp.get_target_hw_addr() == interface.mac.unwrap()
        {
            println!("Received reply");
            return arp.get_sender_hw_addr();
        }
    }
    // unreachable
}

The code is from the examples folder (arp_packet.rs)

@Kofituo
Copy link
Author

Kofituo commented Dec 10, 2023

On further debugging, the error originates here:
linux.rs lines 101-109

let (typ, proto) = match config.channel_type {
        super::ChannelType::Layer2 => (libc::SOCK_RAW, eth_p_all),
        super::ChannelType::Layer3(proto) => (libc::SOCK_DGRAM, proto),
    };
    let socket = unsafe { libc::socket(libc::AF_PACKET, typ, proto.to_be() as i32) };
    if socket == -1 {
        return Err(io::Error::last_os_error()); // here
    }

@Martichou
Copy link
Contributor

Afaik, you can't create a socket with eth_p_all if you're non-root. Solution would be to give your app root access or to switch to using a VPN-like API from Android to do that (but that's outside the scope of this project).

@Kofituo
Copy link
Author

Kofituo commented Jan 16, 2024

@Martichou Is there an alternative this library can use to it works on all android?

@Martichou
Copy link
Contributor

The goal of this (I suppose you use datalink), is to get all packets. And afaik there's not other way (at least, not without root permission).

Raw sockets provide unrestricted access to the underlying protocols, which can be a security risks if misused. So the vast majority of OSes restrict it to superuser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants