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
19 changes: 15 additions & 4 deletions examples/async_icmp_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use nex::net::interface::{get_interfaces, Interface};
use nex_packet::builder::icmp::IcmpPacketBuilder;
use nex_packet::icmp::echo_reply::EchoReplyPacket;
use nex_packet::icmp::{self, IcmpPacket, IcmpType};
use nex_socket::icmp::{AsyncIcmpSocket, IcmpConfig, IcmpKind};
use nex_packet::ipv4::Ipv4Packet;
use nex_packet::packet::Packet;
use nex_socket::icmp::{AsyncIcmpSocket, IcmpConfig, IcmpKind};
use rand::{thread_rng, Rng};
use std::collections::HashMap;
use std::env;
Expand Down Expand Up @@ -55,12 +55,23 @@ async fn main() -> std::io::Result<()> {
if let Ok((n, from)) = socket_clone.recv_from(&mut buf).await {
println!("Received {} bytes from {}", n, from.ip());
if let Some(ipv4_packet) = Ipv4Packet::from_buf(&buf[..n]) {
if ipv4_packet.header.next_level_protocol == nex_packet::ip::IpNextProtocol::Icmp {
if ipv4_packet.header.next_level_protocol
== nex_packet::ip::IpNextProtocol::Icmp
{
if let Some(icmp_packet) = IcmpPacket::from_bytes(ipv4_packet.payload()) {
println!("\t{:?} from: {:?} to {:?}, TTL: {}", icmp_packet.header.icmp_type, ipv4_packet.header.source, ipv4_packet.header.destination, ipv4_packet.header.ttl);
println!(
"\t{:?} from: {:?} to {:?}, TTL: {}",
icmp_packet.header.icmp_type,
ipv4_packet.header.source,
ipv4_packet.header.destination,
ipv4_packet.header.ttl
);
match EchoReplyPacket::try_from(icmp_packet) {
Ok(reply) => {
println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number);
println!(
"\tID: {}, Seq: {}",
reply.identifier, reply.sequence_number
);
}
Err(_) => {
println!("\tReceived non-echo-reply ICMP packet");
Expand Down
23 changes: 18 additions & 5 deletions examples/icmp_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,19 @@ fn main() -> std::io::Result<()> {
if let Some(ipv4_packet) = Ipv4Packet::from_buf(packet) {
if ipv4_packet.header.next_level_protocol == nex_packet::ip::IpNextProtocol::Icmp {
if let Some(icmp_packet) = IcmpPacket::from_bytes(ipv4_packet.payload()) {
println!("\t{:?} from: {:?} to {:?}, TTL: {}", icmp_packet.header.icmp_type, ipv4_packet.header.source, ipv4_packet.header.destination, ipv4_packet.header.ttl);
println!(
"\t{:?} from: {:?} to {:?}, TTL: {}",
icmp_packet.header.icmp_type,
ipv4_packet.header.source,
ipv4_packet.header.destination,
ipv4_packet.header.ttl
);
match icmp::echo_reply::EchoReplyPacket::try_from(icmp_packet) {
Ok(reply) => {
println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number);
println!(
"\tID: {}, Seq: {}",
reply.identifier, reply.sequence_number
);
}
Err(_) => {
println!("\tReceived non-echo-reply ICMP packet");
Expand All @@ -93,12 +102,16 @@ fn main() -> std::io::Result<()> {
}
}
}
},
}
IcmpKind::V6 => {
// Parse ICMPv6
// Parse ICMPv6
// The IPv6 header is automatically cropped off when recvfrom() is used.
if let Some(icmpv6_packet) = Icmpv6Packet::from_buf(packet) {
println!("\t{:?} from: {:?}", icmpv6_packet.header.icmpv6_type, from.ip());
println!(
"\t{:?} from: {:?}",
icmpv6_packet.header.icmpv6_type,
from.ip()
);
match icmpv6::echo_reply::EchoReplyPacket::from_buf(packet) {
Some(reply) => {
println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number);
Expand Down
8 changes: 6 additions & 2 deletions nex-socket/src/tcp/async_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ pub struct AsyncTcpSocket {
impl AsyncTcpSocket {
/// Create a socket from the given configuration without connecting.
pub fn from_config(config: &TcpConfig) -> io::Result<Self> {
let socket = Socket::new(config.socket_family.to_domain(), config.socket_type.to_sock_type(), Some(Protocol::TCP))?;
let socket = Socket::new(
config.socket_family.to_domain(),
config.socket_type.to_sock_type(),
Some(Protocol::TCP),
)?;

socket.set_nonblocking(true)?;

// Set socket options based on configuration
if let Some(flag) = config.reuseaddr {
socket.set_reuse_address(flag)?;
Expand Down
6 changes: 5 additions & 1 deletion nex-socket/src/tcp/sync_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ pub struct TcpSocket {
impl TcpSocket {
/// Build a socket according to `TcpSocketConfig`.
pub fn from_config(config: &TcpConfig) -> io::Result<Self> {
let socket = Socket::new(config.socket_family.to_domain(), config.socket_type.to_sock_type(), Some(Protocol::TCP))?;
let socket = Socket::new(
config.socket_family.to_domain(),
config.socket_type.to_sock_type(),
Some(Protocol::TCP),
)?;

socket.set_nonblocking(config.nonblocking)?;

Expand Down
8 changes: 6 additions & 2 deletions nex-socket/src/udp/async_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ pub struct AsyncUdpSocket {
impl AsyncUdpSocket {
/// Create an asynchronous UDP socket from the given configuration.
pub fn from_config(config: &UdpConfig) -> io::Result<Self> {
let socket = Socket::new(config.socket_family.to_domain(), config.socket_type.to_sock_type(), Some(Protocol::UDP))?;
let socket = Socket::new(
config.socket_family.to_domain(),
config.socket_type.to_sock_type(),
Some(Protocol::UDP),
)?;

socket.set_nonblocking(true)?;

// Set socket options based on configuration
if let Some(flag) = config.reuseaddr {
socket.set_reuse_address(flag)?;
Expand Down
6 changes: 5 additions & 1 deletion nex-socket/src/udp/sync_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ pub struct UdpSocket {
impl UdpSocket {
/// Create a socket from the provided configuration.
pub fn from_config(config: &UdpConfig) -> io::Result<Self> {
let socket = Socket::new(config.socket_family.to_domain(), config.socket_type.to_sock_type(), Some(Protocol::UDP))?;
let socket = Socket::new(
config.socket_family.to_domain(),
config.socket_type.to_sock_type(),
Some(Protocol::UDP),
)?;

socket.set_nonblocking(false)?;

Expand Down
23 changes: 15 additions & 8 deletions nex/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
//! Entry point for the nex crate collection.
//! Cross-platform low-level networking library.
//!
//! This crate re-exports the core modules so applications can simply depend on
//! `nex` and gain access to packet parsing, datalink channels and socket helpers.
//! It is intended to be a convenient facade for the underlying crates.
/// Provides core network types and functionality.
//! `nex` is composed of four core modules (sub-crates), providing a unified interface
//! for packet parsing, manipulation, data link access, and transport layer sockets.
//! By depending on the top-level `nex` crate, applications can access all of these capabilities
//! through a convenient facade.
//!
//! - `net` (`nex-core`): Provides core networking types and utilities.
//! - `datalink` (`nex-datalink`): Interfaces with the data link layer; supports raw packet send/receive.
//! - `packet` (`nex-packet`): Enables parsing and building of packets at multiple protocol layers.
//! - `socket` (`nex-socket`): Provides sockets for working with transport protocols such as TCP, UDP, and ICMP (but L3).

/// Provides core networking types and utilities.
pub mod net {
pub use nex_core::*;
}

/// Provides functionality for interacting with the data link layer, support for sending and receiving packets.
/// Interfaces with the data link layer; supports raw packet send/receive.
pub mod datalink {
pub use nex_datalink::*;
}

/// Support for packet parsing and manipulation. Enables users to work with packets at a granular level.
/// Enables parsing and building of packets at multiple protocol layers.
pub mod packet {
pub use nex_packet::*;
}

/// Support for sending and receiving transport layer packets.
/// Provides sockets for working with transport protocols such as TCP, UDP, and ICMP (but L3).
pub mod socket {
pub use nex_socket::*;
}
Loading