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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions uefi-test-runner/src/proto/network/pxe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

use uefi::proto::network::IpAddress;
use uefi::proto::network::EfiIpAddr;
use uefi::proto::network::pxe::{BaseCode, DhcpV4Packet, IpFilter, IpFilters, UdpOpFlags};
use uefi::{CStr8, boot};

Expand Down Expand Up @@ -30,7 +30,7 @@ pub fn test() {
info!("DHCP: Server IP: {:?}", dhcp_ack.bootp_si_addr);
info!("DHCP: Client IP: {:?}", dhcp_ack.bootp_yi_addr);

let server_ip = IpAddress::new_v4(dhcp_ack.bootp_si_addr);
let server_ip = EfiIpAddr::new_v4(dhcp_ack.bootp_si_addr);

const EXAMPLE_FILE_NAME: &[u8] = b"example-file.txt\0";
const EXAMPLE_FILE_CONTENT: &[u8] = b"Hello world!";
Expand Down
6 changes: 3 additions & 3 deletions uefi-test-runner/src/proto/network/snp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use smoltcp::wire::{
ETHERNET_HEADER_LEN, EthernetFrame, IPV4_HEADER_LEN, Ipv4Packet, UDP_HEADER_LEN, UdpPacket,
};
use uefi::boot::ScopedProtocol;
use uefi::proto::network::MacAddress;
use uefi::proto::network::EfiMacAddr;
use uefi::proto::network::snp::{InterruptStatus, ReceiveFlags, SimpleNetwork};
use uefi::{Status, boot};
use uefi_raw::protocol::network::snp::NetworkState;
Expand Down Expand Up @@ -53,8 +53,8 @@ fn receive(simple_network: &mut SimpleNetwork, buffer: &mut [u8]) -> uefi::Resul
// Wait for a bit to ensure that the previous packet has been processed.
boot::stall(Duration::from_millis(500));

let mut recv_src_mac = MacAddress([0; 32]);
let mut recv_dst_mac = MacAddress([0; 32]);
let mut recv_src_mac = EfiMacAddr([0; 32]);
let mut recv_dst_mac = EfiMacAddr([0; 32]);
let mut recv_ethernet_protocol = 0;

let res = simple_network.receive(
Expand Down
9 changes: 9 additions & 0 deletions uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@
defaults to the recommended value of `MemoryType::LOADER_DATA`.
- **Breaking:** Removed duplication in `DevicePathHeader`. Instead of public fields,
there is now a public constructor combined with public getters.
- **Breaking:** All public APIs related to networking now use
`core::net::{IpAddr, Ipv4Addr, Ipv6Addr}`, i.e., the types from the standard
library.
- **Breaking:** Removed type `IpAddress`. Instead, a new alias `EfiIpAddr` is
exported which forwards to the new `IpAddress` type in `uefi-raw`. That type
is tightly integrated with `core::net::{IpAddr, Ipv4Addr, Ipv6Addr}` via
various `From/Into` implementations. This simplifies working with IP addresses
significantly.
- **Breaking:** For consistency, `MacAddress` was renamed to `EfiMacAddr`.
- `boot::memory_map()` will never return `Status::BUFFER_TOO_SMALL` from now on,
as this is considered a hard internal error where users can't do anything
about it anyway. It will panic instead.
Expand Down
2 changes: 1 addition & 1 deletion uefi/src/proto/device_path/device_path_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ use crate::polyfill::maybe_uninit_slice_as_mut_ptr;
use crate::proto::device_path::{
self, DevicePathHeader, DevicePathNode, DeviceSubType, DeviceType, NodeConversionError,
};
use crate::proto::network::IpAddress;
use crate::{Guid, guid};
use bitflags::bitflags;
use core::ptr::addr_of;
use core::{fmt, slice};
use ptr_meta::Pointee;
use uefi_raw::IpAddress;
/// Device path nodes for [`DeviceType::END`].
pub mod end {
use super::*;
Expand Down
22 changes: 6 additions & 16 deletions uefi/src/proto/network/ip4config2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
use alloc::vec;
use alloc::vec::Vec;
use core::ffi::c_void;
use core::net::Ipv4Addr;
use core::time::Duration;

use uefi::boot::ScopedProtocol;
use uefi::prelude::*;
use uefi::proto::unsafe_protocol;
use uefi::{print, println};
use uefi_raw::Ipv4Address;
use uefi_raw::protocol::network::ip4_config2::{
Ip4Config2DataType, Ip4Config2InterfaceInfo, Ip4Config2Policy, Ip4Config2Protocol,
};
Expand Down Expand Up @@ -102,29 +102,19 @@ impl Ip4Config2 {
})
}

fn print_info(info: &Ip4Config2InterfaceInfo) {
println!(
"addr v4: {}.{}.{}.{}",
info.station_addr.0[0],
info.station_addr.0[1],
info.station_addr.0[2],
info.station_addr.0[3],
);
}

/// Bring up network interface. Does nothing in case the network
/// is already set up. Otherwise turns on DHCP and waits until an
/// IPv4 address has been assigned. Reports progress on the
/// console if verbose is set to true. Returns TIMEOUT error in
/// case DHCP configuration does not finish within 30 seconds.
pub fn ifup(&mut self, verbose: bool) -> uefi::Result<()> {
let no_address = Ipv4Address::default();
let no_address = Ipv4Addr::from_bits(0);

let info = self.get_interface_info()?;
if info.station_addr != no_address {
if info.station_addr != no_address.into() {
if verbose {
print!("Network is already up: ");
Self::print_info(&info);
println!("addr v4: {}", info.station_addr);
}
return Ok(());
}
Expand All @@ -140,10 +130,10 @@ impl Ip4Config2 {
}
boot::stall(Duration::from_secs(1));
let info = self.get_interface_info()?;
if info.station_addr != no_address {
if info.station_addr != no_address.into() {
if verbose {
print!(" OK: ");
Self::print_info(&info);
println!("addr v4: {}", info.station_addr);
}
return Ok(());
}
Expand Down
98 changes: 6 additions & 92 deletions uefi/src/proto/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,101 +3,15 @@
//! Network access protocols.
//!
//! These protocols can be used to interact with network resources.
//!
//! To work with Mac and IP addresses, `uefi` uses with the types:
//! - [`EfiIpAddr`] that is tightly integrated with the [`core::net::IpAddr`]
//! type,
//! - [`EfiMacAddr`]

pub mod http;
pub mod ip4config2;
pub mod pxe;
pub mod snp;

pub use uefi_raw::MacAddress;

/// Represents an IPv4/v6 address.
///
/// Corresponds to the `EFI_IP_ADDRESS` type in the C API.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(C, align(4))]
pub struct IpAddress(pub [u8; 16]);

impl IpAddress {
/// Construct a new IPv4 address.
#[must_use]
pub const fn new_v4(ip_addr: [u8; 4]) -> Self {
let mut buffer = [0; 16];
buffer[0] = ip_addr[0];
buffer[1] = ip_addr[1];
buffer[2] = ip_addr[2];
buffer[3] = ip_addr[3];
Self(buffer)
}

/// Construct a new IPv6 address.
#[must_use]
pub const fn new_v6(ip_addr: [u8; 16]) -> Self {
Self(ip_addr)
}

/// Construct from a `uefi_raw::IpAddress` union.
///
/// # Safety
///
/// `is_ipv6` must accurately reflect how the union was initialized.
#[must_use]
const unsafe fn from_raw(ip_addr: uefi_raw::IpAddress, is_ipv6: bool) -> Self {
if is_ipv6 {
Self::new_v6(unsafe { ip_addr.v6.0 })
} else {
Self::new_v4(unsafe { ip_addr.v4.0 })
}
}

#[must_use]
const fn as_raw_ptr(&self) -> *const uefi_raw::IpAddress {
// The uefi-raw type is defined differently, but the layout is
// compatible.
self.0.as_ptr().cast()
}

#[must_use]
const fn as_raw_ptr_mut(&mut self) -> *mut uefi_raw::IpAddress {
// The uefi-raw type is defined differently, but the layout is
// compatible.
self.0.as_mut_ptr().cast()
}
}

impl From<core::net::Ipv4Addr> for IpAddress {
fn from(t: core::net::Ipv4Addr) -> Self {
Self::new_v4(t.octets())
}
}

impl From<IpAddress> for core::net::Ipv4Addr {
fn from(IpAddress(o): IpAddress) -> Self {
Self::from([o[0], o[1], o[2], o[3]])
}
}

impl From<core::net::Ipv6Addr> for IpAddress {
fn from(t: core::net::Ipv6Addr) -> Self {
Self::new_v6(t.octets())
}
}

impl From<IpAddress> for core::net::Ipv6Addr {
fn from(value: IpAddress) -> Self {
Self::from(value.0)
}
}

impl From<core::net::IpAddr> for IpAddress {
fn from(t: core::net::IpAddr) -> Self {
match t {
core::net::IpAddr::V4(a) => a.into(),
core::net::IpAddr::V6(a) => a.into(),
}
}
}

// NOTE: We cannot impl From<IpAddress> for core::net::IpAddr
// because IpAddress is a raw union, with nothing indicating
// whether it should be considered v4 or v6.
pub use uefi_raw::{IpAddress as EfiIpAddr, MacAddress as EfiMacAddr};
Loading