Downgrade pnet to 0.26

main
shellrow 3 years ago
parent c5ba7d16d8
commit 89c67b24c9
  1. 2
      Cargo.toml
  2. 5
      examples/default_gateway.rs
  3. 202
      src/lib.rs

@ -10,4 +10,4 @@ categories = ["network-programming"]
license = "MIT"
[dependencies]
pnet = "0.27"
pnet = "0.26"

@ -1,5 +1,8 @@
use default_net;
fn main(){
default_net::get_default_gateway();
match default_net::get_default_gateway() {
Ok(default_gateway) => {println!("Default Gateway: {}",default_gateway)},
Err(e) => {println!("{}",e)},
}
}

@ -6,8 +6,11 @@ use std::time::{Duration, Instant};
use std::net::IpAddr;
//use pnet::packet::Packet;
use pnet::transport::icmp_packet_iter;
use pnet::packet::Packet;
use pnet::datalink;
pub fn get_default_gateway(){
pub fn get_default_gateway() -> Result<String,String> {
/*
let buf = [0u8; 0];
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
@ -16,22 +19,41 @@ pub fn get_default_gateway(){
let dest: &str = "192.168.11.1:80";
socket.set_ttl(1).unwrap();
socket.send_to(&buf, dest).unwrap();
*/
send_udp_packet();
/*
let protocol = Layer4(Ipv4(pnet::packet::ip::IpNextHeaderProtocols::Icmp));
let (mut _tx, mut rx) = match pnet::transport::transport_channel(4096, protocol) {
Ok((tx, rx)) => (tx, rx),
Err(e) => panic!("Error happened {}", e),
};
let timeout = Duration::from_millis(3000);
let router_ip = receive_icmp_packets(&mut rx, pnet::packet::icmp::IcmpTypes::TimeExceeded, &timeout);
match router_ip {
Ok(ip) => {println!("{}", ip)},
Err(e) => {println!("{}", e)},
}
*/
let timeout = Duration::from_millis(3000);
//let r = receive_icmp_packets(&mut rx, pnet::packet::icmp::IcmpTypes::TimeExceeded, &timeout);
let r = receive_icmp_packets(pnet::packet::icmp::IcmpTypes::TimeExceeded, &timeout);
return r;
}
pub fn send_udp_packet(){
let buf = [0u8; 0];
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
Err(_) => panic!("error!"),
};
let dest: &str = "192.168.11.1:80";
socket.set_ttl(1).unwrap();
socket.send_to(&buf, dest).unwrap();
}
#[cfg(any(unix, macos))]
pub fn receive_icmp_packets(rx: &mut pnet::transport::TransportReceiver, icmp_type: pnet::packet::icmp::IcmpType, timeout: &Duration) -> Result<String, String>{
let mut iter = icmp_packet_iter(rx);
pub fn receive_icmp_packets(icmp_type: pnet::packet::icmp::IcmpType, timeout: &Duration) -> Result<String, String>{
let protocol = Layer4(Ipv4(pnet::packet::ip::IpNextHeaderProtocols::Icmp));
let (mut _tx, mut rx) = match pnet::transport::transport_channel(4096, protocol) {
Ok((tx, rx)) => (tx, rx),
Err(e) => panic!("Error happened {}", e),
};
let mut iter = icmp_packet_iter(&mut rx);
let start_time = Instant::now();
loop {
match iter.next_with_timeout(*timeout) {
@ -53,19 +75,21 @@ pub fn receive_icmp_packets(rx: &mut pnet::transport::TransportReceiver, icmp_ty
}
if Instant::now().duration_since(start_time) > *timeout {
return Err(String::from("timeout"));
}else{
send_udp_packet();
}
}
}
/*
#[cfg(target_os = "windows")]
fn send_icmp_packet(){
}
*/
#[cfg(target_os = "windows")]
fn receive_icmp_packets(rx: &mut pnet::transport::TransportReceiver, icmp_type: pnet::packet::icmp::IcmpType, timeout: &Duration) -> Result<String, String>{
let mut iter = icmp_packet_iter(rx);
fn receive_icmp_packets(icmp_type: pnet::packet::icmp::IcmpType, timeout: &Duration) -> Result<String, String>{
/*
let protocol = Layer4(Ipv4(pnet::packet::ip::IpNextHeaderProtocols::Icmp));
let (mut _tx, mut rx) = match pnet::transport::transport_channel(4096, protocol) {
Ok((tx, rx)) => (tx, rx),
Err(e) => panic!("Error happened {}", e),
};
let mut iter = icmp_packet_iter(&mut rx);
let start_time = Instant::now();
loop {
match iter.next() {
@ -83,7 +107,153 @@ fn receive_icmp_packets(rx: &mut pnet::transport::TransportReceiver, icmp_type:
}
if Instant::now().duration_since(start_time) > *timeout {
return Err(String::from("timeout"));
}else{
send_udp_packet();
}
}
*/
let default_idx = get_default_interface_index().unwrap();
let interfaces = pnet::datalink::interfaces();
let interface = interfaces.into_iter().filter(|interface: &pnet::datalink::NetworkInterface| interface.index == default_idx).next().expect("Failed to get Interface");
let (mut _sender, mut receiver) = match datalink::channel(&interface, Default::default()) {
Ok(pnet::datalink::Channel::Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unknown channel type"),
Err(e) => panic!("Error happened {}", e),
};
receive_packets(&mut receiver, timeout)
}
#[cfg(target_os = "windows")]
fn receive_packets(rx: &mut Box<dyn pnet::datalink::DataLinkReceiver>, timeout: &Duration) -> Result<String, String>{
let start_time = Instant::now();
loop {
match rx.next() {
Ok(frame) => {
let frame = pnet::packet::ethernet::EthernetPacket::new(frame).unwrap();
match frame.get_ethertype() {
pnet::packet::ethernet::EtherTypes::Ipv4 => {
if let Some(ip_addr) = ipv4_handler(&frame){
return Ok(ip_addr);
}
},
pnet::packet::ethernet::EtherTypes::Ipv6 => {
if let Some(ip_addr) = ipv6_handler(&frame){
return Ok(ip_addr);
}
},
_ => {
//println!("Not a ipv4 or ipv6");
}
}
},
Err(e) => {
return Err(format!("An error occurred while reading: {}", e));
}
}
if Instant::now().duration_since(start_time) > *timeout {
return Err(String::from("timeout"));
}else{
send_udp_packet();
}
}
}
fn ipv4_handler(ethernet: &pnet::packet::ethernet::EthernetPacket) -> Option<String> {
if let Some(packet) = pnet::packet::ipv4::Ipv4Packet::new(ethernet.payload()){
match packet.get_next_level_protocol() {
pnet::packet::ip::IpNextHeaderProtocols::Icmp => {
return icmp_handler(&packet);
},
_ => {
None
}
}
}else{
None
}
}
fn ipv6_handler(ethernet: &pnet::packet::ethernet::EthernetPacket) -> Option<String> {
if let Some(packet) = pnet::packet::ipv6::Ipv6Packet::new(ethernet.payload()){
match packet.get_next_header() {
pnet::packet::ip::IpNextHeaderProtocols::Icmpv6 => {
return icmpv6_handler(&packet);
},
_ => {
None
}
}
}else{
None
}
}
fn icmp_handler(ip_packet: &pnet::packet::ipv4::Ipv4Packet) -> Option<String> {
if let Some(packet) = pnet::packet::icmp::IcmpPacket::new(ip_packet.payload()){
if packet.get_icmp_type() == pnet::packet::icmp::IcmpTypes::TimeExceeded {
let ipv4_addr = ip_packet.get_source();
return Some(ipv4_addr.to_string())
}else{
None
}
}else{
None
}
}
fn icmpv6_handler(ip_packet: &pnet::packet::ipv6::Ipv6Packet) -> Option<String> {
if let Some(packet) = pnet::packet::icmp::IcmpPacket::new(ip_packet.payload()){
if packet.get_icmp_type() == pnet::packet::icmp::IcmpTypes::TimeExceeded {
let ipv6_addr = ip_packet.get_source();
return Some(ipv6_addr.to_string())
}else{
None
}
}else{
None
}
}
pub fn get_local_ipaddr() -> Option<String> {
let socket = match UdpSocket::bind("0.0.0.0:0") {
Ok(s) => s,
Err(_) => return None,
};
match socket.connect("8.8.8.8:80") {
Ok(()) => (),
Err(_) => return None,
};
match socket.local_addr() {
Ok(addr) => return Some(addr.ip().to_string()),
Err(_) => return None,
};
}
pub fn get_default_interface_index() -> Option<u32> {
let local_ip = get_local_ipaddr();
let all_interfaces = datalink::interfaces();
if let Some(local_ip) = local_ip {
for iface in all_interfaces{
for ip in iface.ips{
match ip.ip() {
IpAddr::V4(ipv4) => {
if local_ip == ipv4.to_string() {
return Some(iface.index)
}
},
IpAddr::V6(ipv6) => {
if local_ip == ipv6.to_string() {
return Some(iface.index)
}
},
}
}
}
return None;
}else{
return None;
}
}

Loading…
Cancel
Save