Skip to content

Commit

Permalink
Add SockProtocol variants for ICMP{,v6}
Browse files Browse the repository at this point in the history
  • Loading branch information
gnaaman-dn committed Aug 29, 2023
1 parent 996db47 commit de9361a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased] - ReleaseDate

### Added
- Added `Icmp` and `IcmpV6` to `SockProtocol`.
(#[2103](https://github.com/nix-rust/nix/pull/2103))

## [0.27.1] - 2023-08-28

### Fixed
Expand Down
24 changes: 16 additions & 8 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ pub enum SockProtocol {
Udp = libc::IPPROTO_UDP,
/// Raw sockets ([raw(7)](https://man7.org/linux/man-pages/man7/raw.7.html))
Raw = libc::IPPROTO_RAW,
/// Allows applications and other KEXTs to be notified when certain kernel events occur
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
#[cfg(any(target_os = "ios", target_os = "macos"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
KextEvent = libc::SYSPROTO_EVENT,
/// Allows applications to configure and control a KEXT
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
#[cfg(any(target_os = "ios", target_os = "macos"))]
Expand Down Expand Up @@ -231,20 +226,33 @@ pub enum SockProtocol {
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
EthAll = (libc::ETH_P_ALL as u16).to_be() as i32,
/// ICMP protocol ([icmp(7)](https://man7.org/linux/man-pages/man7/icmp.7.html))
Icmp = libc::IPPROTO_ICMP,
/// ICMPv6 protocol (ICMP over IPv6)
IcmpV6 = libc::IPPROTO_ICMPV6,
}

impl SockProtocol {
/// The Controller Area Network raw socket protocol
/// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan))
#[cfg(target_os = "linux")]
#[cfg_attr(docsrs, doc(cfg(all())))]
CanRaw = libc::CAN_RAW,
}
#[allow(non_upper_case_globals)]
pub const CanRaw: SockProtocol = SockProtocol::Icmp; // Matches libc::CAN_RAW

impl SockProtocol {
/// The Controller Area Network broadcast manager protocol
/// ([ref](https://docs.kernel.org/networking/can.html#how-to-use-socketcan))
#[cfg(target_os = "linux")]
#[cfg_attr(docsrs, doc(cfg(all())))]
#[allow(non_upper_case_globals)]
pub const CanBcm: SockProtocol = SockProtocol::NetlinkUserSock; // Matches libc::CAN_BCM

/// Allows applications and other KEXTs to be notified when certain kernel events occur
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
#[cfg(any(target_os = "ios", target_os = "macos"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
#[allow(non_upper_case_globals)]
pub const KextEvent: SockProtocol = SockProtocol::Icmp; // Matches libc::SYSPROTO_EVENT
}
#[cfg(any(target_os = "android", target_os = "linux"))]
libc_bitflags! {
Expand Down
33 changes: 33 additions & 0 deletions test/sys/test_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2685,3 +2685,36 @@ pub fn test_txtime() {
recvmsg::<()>(rsock.as_raw_fd(), &mut iov2, None, MsgFlags::empty())
.unwrap();
}

// cfg needed for capability check.
#[cfg(any(target_os = "android", target_os = "linux"))]
#[test]
fn test_icmp_protocol() {
use nix::sys::socket::{
sendto, socket, AddressFamily, MsgFlags, SockFlag, SockProtocol,
SockType, SockaddrIn,
};

require_capability!("test_icmp_protocol", CAP_NET_RAW);

let owned_fd = socket(
AddressFamily::Inet,
SockType::Raw,
SockFlag::empty(),
SockProtocol::Icmp,
)
.unwrap();

// Send a minimal ICMP packet with no payload.
let packet = [
0x08, // Type
0x00, // Code
0x84, 0x85, // Checksum
0x73, 0x8a, // ID
0x00, 0x00, // Sequence Number
];

let dest_addr = SockaddrIn::new(127, 0, 0, 1, 0);
sendto(owned_fd.as_raw_fd(), &packet, &dest_addr, MsgFlags::empty())
.unwrap();
}

0 comments on commit de9361a

Please sign in to comment.