Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions examples/arp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use nex::datalink;
use nex::datalink::Channel::Ethernet;
use nex::net::interface::{get_interfaces, Interface};
use nex::net::mac::MacAddr;
use nex::packet::builder::ethernet::EthernetPacketBuilder;
use nex::packet::ethernet::EtherType;
use nex::packet::frame::{Frame, ParseOption};
use nex::packet::builder::ethernet::EthernetPacketBuilder;
use nex_packet::arp::ArpOperation;
use nex_packet::builder::arp::ArpPacketBuilder;
use nex_packet::packet::Packet;
Expand Down Expand Up @@ -47,7 +47,10 @@ fn main() {
None => Interface::default().expect("Failed to get default interface"),
};

let src_mac = interface.mac_addr.clone().expect("No MAC address on interface");
let src_mac = interface
.mac_addr
.clone()
.expect("No MAC address on interface");
let src_ip = interface.ipv4.get(0).expect("No IPv4 address").addr();

let (mut tx, mut rx) = match datalink::channel(&interface, Default::default()) {
Expand All @@ -63,9 +66,7 @@ fn main() {

let arp_builder = ArpPacketBuilder::new(src_mac, src_ip, target_ip);

let packet = eth_builder
.payload(arp_builder.build().to_bytes())
.build();
let packet = eth_builder.payload(arp_builder.build().to_bytes()).build();

match tx.send(&packet.to_bytes()) {
Some(_) => println!("ARP Request sent to {}", target_ip),
Expand All @@ -83,7 +84,9 @@ fn main() {
match &frame.datalink {
Some(dlink) => {
if let Some(arp) = &dlink.arp {
if arp.operation == ArpOperation::Reply && arp.sender_proto_addr == target_ip {
if arp.operation == ArpOperation::Reply
&& arp.sender_proto_addr == target_ip
{
println!("Received ARP Reply from {}", arp.sender_proto_addr);
println!("MAC address: {}", arp.sender_hw_addr);
println!(
Expand Down
11 changes: 7 additions & 4 deletions examples/async_icmp_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
//! Example: async_icmp_socket 192.168.1

use bytes::Bytes;
use nex_socket::icmp::{AsyncIcmpSocket, IcmpConfig, IcmpKind};
use nex::net::interface::{get_interfaces, Interface};
use nex_packet::builder::icmp::IcmpPacketBuilder;
use nex_packet::icmp::{self, IcmpType};
use nex_socket::icmp::{AsyncIcmpSocket, IcmpConfig, IcmpKind};
use rand::{thread_rng, Rng};
use std::collections::HashMap;
use std::env;
use nex::net::interface::{Interface, get_interfaces};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::Arc;
use std::time::Duration;
use rand::{Rng, thread_rng};
use tokio::sync::Mutex;
use tokio::time;

Expand All @@ -24,7 +24,10 @@ async fn main() -> std::io::Result<()> {
assert!(parts.len() == 3, "prefix must be a.b.c");

let interface = match env::args().nth(2) {
Some(name) => get_interfaces().into_iter().find(|i| i.name == name).expect("interface not found"),
Some(name) => get_interfaces()
.into_iter()
.find(|i| i.name == name)
.expect("interface not found"),
None => Interface::default().expect("default interface"),
};

Expand Down
6 changes: 5 additions & 1 deletion examples/async_tcp_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ async fn main() -> std::io::Result<()> {
for port in ports {
let addr = SocketAddr::new(ip, port);
handles.push(tokio::spawn(async move {
let cfg = if ip.is_ipv4() { TcpConfig::v4_stream() } else { TcpConfig::v6_stream() };
let cfg = if ip.is_ipv4() {
TcpConfig::v4_stream()
} else {
TcpConfig::v6_stream()
};
let sock = AsyncTcpSocket::from_config(&cfg).unwrap();
match sock.connect_timeout(addr, Duration::from_millis(500)).await {
Ok(_) => println!("Port {} is open", port),
Expand Down
36 changes: 36 additions & 0 deletions examples/async_udp_socket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! UDP echo using AsyncUdpSocket
//!
//! This example starts a small UDP echo server and client using nex-socket and Tokio.
//!
//! It will send a single UDP datagram to the server and print the echoed reply.

use nex_socket::udp::{AsyncUdpSocket, UdpConfig};
use tokio::task;

#[tokio::main]
async fn main() -> std::io::Result<()> {
let server_cfg = UdpConfig {
bind_addr: Some("127.0.0.1:0".parse().unwrap()),
..Default::default()
};
let server = AsyncUdpSocket::from_config(&server_cfg)?;
let server_addr = server.local_addr()?;

let handle = task::spawn(async move {
let mut buf = [0u8; 512];
let (n, peer) = server.recv_from(&mut buf).await?;
println!("Server received: {}", String::from_utf8_lossy(&buf[..n]));
server.send_to(&buf[..n], peer).await?;
Ok::<(), std::io::Error>(())
});

let client = AsyncUdpSocket::v4_dgram()?;
let msg = b"hello via async udp";
client.send_to(msg, server_addr).await?;
let mut buf = [0u8; 512];
let (n, _) = client.recv_from(&mut buf).await?;
println!("Client received: {}", String::from_utf8_lossy(&buf[..n]));

handle.await??;
Ok(())
}
45 changes: 36 additions & 9 deletions examples/dns_dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use nex_core::mac::MacAddr;
use nex_packet::ethernet::EthernetHeader;
use nex_packet::packet::Packet;
use std::env;
use std::net::{IpAddr};
use std::net::IpAddr;

fn main() {
let interface: Interface = match env::args().nth(1) {
Expand Down Expand Up @@ -50,7 +50,8 @@ fn main() {
);

let eth_packet = if interface.is_tun()
|| (cfg!(any(target_os = "macos", target_os = "ios")) && interface.is_loopback())
|| (cfg!(any(target_os = "macos", target_os = "ios"))
&& interface.is_loopback())
{
let offset = if interface.is_loopback() { 14 } else { 0 };
let payload = Bytes::copy_from_slice(&packet[offset..]);
Expand All @@ -59,7 +60,11 @@ fn main() {
header: EthernetHeader {
destination: MacAddr::zero(),
source: MacAddr::zero(),
ethertype: if version == 4 { EtherType::Ipv4 } else { EtherType::Ipv6 },
ethertype: if version == 4 {
EtherType::Ipv4
} else {
EtherType::Ipv6
},
},
payload,
}
Expand All @@ -69,11 +74,19 @@ fn main() {

if let EtherType::Ipv4 = eth_packet.header.ethertype {
if let Some(ipv4) = Ipv4Packet::from_bytes(eth_packet.payload.clone()) {
handle_udp(ipv4.payload, IpAddr::V4(ipv4.header.source), IpAddr::V4(ipv4.header.destination));
handle_udp(
ipv4.payload,
IpAddr::V4(ipv4.header.source),
IpAddr::V4(ipv4.header.destination),
);
}
} else if let EtherType::Ipv6 = eth_packet.header.ethertype {
if let Some(ipv6) = Ipv6Packet::from_bytes(eth_packet.payload.clone()) {
handle_udp(ipv6.payload, IpAddr::V6(ipv6.header.source), IpAddr::V6(ipv6.header.destination));
handle_udp(
ipv6.payload,
IpAddr::V6(ipv6.header.source),
IpAddr::V6(ipv6.header.destination),
);
}
}
}
Expand All @@ -86,24 +99,38 @@ fn handle_udp(packet: Bytes, src: IpAddr, dst: IpAddr) {
if let Some(udp) = UdpPacket::from_bytes(packet.clone()) {
if udp.payload.len() > 0 {
if let Some(dns) = DnsPacket::from_bytes(udp.payload.clone()) {
println!("DNS Packet: {}:{} > {}:{}", src, udp.header.source, dst, udp.header.destination);
println!(
"DNS Packet: {}:{} > {}:{}",
src, udp.header.source, dst, udp.header.destination
);

for query in &dns.queries {
println!(" Query: {:?} (type: {:?}, class: {:?})", query.get_qname_parsed(), query.qtype, query.qclass);
println!(
" Query: {:?} (type: {:?}, class: {:?})",
query.get_qname_parsed(),
query.qtype,
query.qclass
);
}

for response in &dns.responses {
match response.rtype {
DnsType::A | DnsType::AAAA => {
if let Some(ip) = response.get_ip() {
println!(" Response: {} (type: {:?}, ttl: {})", ip, response.rtype, response.ttl);
println!(
" Response: {} (type: {:?}, ttl: {})",
ip, response.rtype, response.ttl
);
} else {
println!(" Invalid IP data for type: {:?}", response.rtype);
}
}
DnsType::CNAME | DnsType::NS | DnsType::PTR => {
if let Some(name) = response.get_name() {
println!(" Response: {} (type: {:?}, ttl: {})", name, response.rtype, response.ttl);
println!(
" Response: {} (type: {:?}, ttl: {})",
name, response.rtype, response.ttl
);
} else {
println!(" Invalid name data for type: {:?}", response.rtype);
}
Expand Down
48 changes: 27 additions & 21 deletions examples/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use nex::packet::icmpv6::Icmpv6Packet;
use nex::packet::ip::IpNextProtocol;
use nex::packet::ipv4::Ipv4Packet;
use nex::packet::ipv6::Ipv6Packet;
use nex::packet::packet::Packet;
use nex::packet::tcp::TcpPacket;
use nex::packet::udp::UdpPacket;
use nex::packet::packet::Packet;
use nex_packet::ethernet::EthernetHeader;
use nex_packet::{icmp, icmpv6};
use std::env;
Expand Down Expand Up @@ -61,7 +61,7 @@ fn main() {
capture_no,
packet.len()
);

if interface.is_tun()
|| (cfg!(any(target_os = "macos", target_os = "ios"))
&& interface.is_loopback())
Expand All @@ -74,14 +74,16 @@ fn main() {
}
let payload = Bytes::copy_from_slice(&packet[payload_offset..]);
if packet.len() > payload_offset {
let version = Ipv4Packet::from_buf(packet)
.unwrap()
.header.version;
let version = Ipv4Packet::from_buf(packet).unwrap().header.version;
let fake_eth = EthernetPacket {
header: EthernetHeader {
destination: MacAddr::zero(),
source: MacAddr::zero(),
ethertype: if version == 4 { EtherType::Ipv4 } else { EtherType::Ipv6 },
ethertype: if version == 4 {
EtherType::Ipv4
} else {
EtherType::Ipv6
},
},
payload,
};
Expand Down Expand Up @@ -220,7 +222,8 @@ fn handle_icmp_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
let total_len = icmp_packet.total_len();
match icmp_packet.header.icmp_type {
IcmpType::EchoRequest => {
let echo_request_packet = icmp::echo_request::EchoRequestPacket::try_from(icmp_packet).unwrap();
let echo_request_packet =
icmp::echo_request::EchoRequestPacket::try_from(icmp_packet).unwrap();
println!(
"ICMP echo request {} -> {} (seq={:?}, id={:?}), length: {}",
source,
Expand All @@ -231,7 +234,8 @@ fn handle_icmp_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
);
}
IcmpType::EchoReply => {
let echo_reply_packet = icmp::echo_reply::EchoReplyPacket::try_from(icmp_packet).unwrap();
let echo_reply_packet =
icmp::echo_reply::EchoReplyPacket::try_from(icmp_packet).unwrap();
println!(
"ICMP echo reply {} -> {} (seq={:?}, id={:?}), length: {}",
source,
Expand All @@ -242,7 +246,11 @@ fn handle_icmp_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
);
}
IcmpType::DestinationUnreachable => {
let unreachable_packet = icmp::destination_unreachable::DestinationUnreachablePacket::try_from(icmp_packet).unwrap();
let unreachable_packet =
icmp::destination_unreachable::DestinationUnreachablePacket::try_from(
icmp_packet,
)
.unwrap();
println!(
"ICMP destination unreachable {} -> {} (code={:?}), next_hop_mtu={}, length: {}",
source,
Expand All @@ -253,22 +261,17 @@ fn handle_icmp_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
);
}
IcmpType::TimeExceeded => {
let time_exceeded_packet = icmp::time_exceeded::TimeExceededPacket::try_from(icmp_packet).unwrap();
let time_exceeded_packet =
icmp::time_exceeded::TimeExceededPacket::try_from(icmp_packet).unwrap();
println!(
"ICMP time exceeded {} -> {} (code={:?}), length: {}",
source,
destination,
time_exceeded_packet.header.icmp_code,
total_len
source, destination, time_exceeded_packet.header.icmp_code, total_len
);
}
_ => {
println!(
"ICMP packet {} -> {} (type={:?}), length: {}",
source,
destination,
icmp_packet.header.icmp_type,
total_len
source, destination, icmp_packet.header.icmp_type, total_len
)
}
}
Expand All @@ -282,7 +285,8 @@ fn handle_icmpv6_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
if let Some(icmpv6_packet) = icmpv6_packet {
match icmpv6_packet.header.icmpv6_type {
nex::packet::icmpv6::Icmpv6Type::EchoRequest => {
let echo_request_packet = icmpv6::echo_request::EchoRequestPacket::try_from(icmpv6_packet).unwrap();
let echo_request_packet =
icmpv6::echo_request::EchoRequestPacket::try_from(icmpv6_packet).unwrap();
println!(
"ICMPv6 echo request {} -> {} (type={:?}), length: {}",
source,
Expand All @@ -292,7 +296,8 @@ fn handle_icmpv6_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
);
}
nex::packet::icmpv6::Icmpv6Type::EchoReply => {
let echo_reply_packet = icmpv6::echo_reply::EchoReplyPacket::try_from(icmpv6_packet).unwrap();
let echo_reply_packet =
icmpv6::echo_reply::EchoReplyPacket::try_from(icmpv6_packet).unwrap();
println!(
"ICMPv6 echo reply {} -> {} (type={:?}), length: {}",
source,
Expand All @@ -302,7 +307,8 @@ fn handle_icmpv6_packet(source: IpAddr, destination: IpAddr, packet: Bytes) {
);
}
nex::packet::icmpv6::Icmpv6Type::NeighborSolicitation => {
let ns_packet = icmpv6::ndp::NeighborSolicitPacket::try_from(icmpv6_packet).unwrap();
let ns_packet =
icmpv6::ndp::NeighborSolicitPacket::try_from(icmpv6_packet).unwrap();
println!(
"ICMPv6 neighbor solicitation {} -> {} (type={:?}), length: {}",
source,
Expand Down
12 changes: 6 additions & 6 deletions examples/icmp_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ use nex::datalink;
use nex::datalink::Channel::Ethernet;
use nex::net::interface::Interface;
use nex::net::mac::MacAddr;
use nex::packet::ethernet::EtherType;
use nex::packet::frame::{Frame, ParseOption};
use nex::packet::builder::ethernet::EthernetPacketBuilder;
use nex::packet::builder::icmp::IcmpPacketBuilder;
use nex::packet::builder::icmpv6::Icmpv6PacketBuilder;
use nex::packet::icmp::IcmpType;
use nex::packet::icmpv6::Icmpv6Type;
use nex::packet::builder::ethernet::EthernetPacketBuilder;
use nex::packet::builder::ipv4::Ipv4PacketBuilder;
use nex::packet::builder::ipv6::Ipv6PacketBuilder;
use nex_packet::{icmp, icmpv6};
use nex::packet::ethernet::EtherType;
use nex::packet::frame::{Frame, ParseOption};
use nex::packet::icmp::IcmpType;
use nex::packet::icmpv6::Icmpv6Type;
use nex_packet::ip::IpNextProtocol;
use nex_packet::ipv4::Ipv4Flags;
use nex_packet::packet::Packet;
use nex_packet::{icmp, icmpv6};
use std::env;
use std::net::IpAddr;

Expand Down
Loading