|
| 1 | +//! Network I/O protocols. |
| 2 | +
|
| 3 | +use crate::proto::Protocol; |
| 4 | +use crate::{unsafe_guid, Result, Status}; |
| 5 | + |
| 6 | +/// The SNP protocol. |
| 7 | +#[repr(C)] |
| 8 | +#[unsafe_guid("a19832b9-ac25-11d3-9a2d-0090273fc14d")] |
| 9 | +#[derive(Protocol)] |
| 10 | +pub struct SNP { |
| 11 | + pub revision: u64, |
| 12 | + start : extern "efiapi" fn(this: &SNP) -> Status, |
| 13 | + stop : extern "efiapi" fn(this: &SNP) -> Status, |
| 14 | + initialize : extern "efiapi" fn(this: &SNP, extra_rx_buffer_size: usize, extra_tx_buffer_size: usize) -> Status, |
| 15 | + reset : extern "efiapi" fn(this: &SNP, extended_verification: bool) -> Status, |
| 16 | + shutdown : extern "efiapi" fn(this: &SNP) -> Status, |
| 17 | + receive_filters : extern "efiapi" fn(this: &SNP, enable: u32, disable: u32, reset_mcast_filter: bool, mcast_filter_count: usize, mcast_filter: *const MacAddress) -> Status, |
| 18 | + station_address : extern "efiapi" fn(this: &SNP, reset: bool, new: *const MacAddress) -> Status, |
| 19 | + statistics : extern "efiapi" fn(this: &SNP, reset: bool, statistics_size: *mut usize, statistics_table: *mut NetworkStatistics) -> Status, |
| 20 | + mcast_ip_to_mac : extern "efiapi" fn(this: &SNP, ipv6: bool, ip: *const IpAddress) -> Status, |
| 21 | + nv_data : extern "efiapi" fn(this: &SNP, read_write: bool, offset: usize, buffer_size: usize, buffer: *mut u8) -> Status, |
| 22 | + get_status : extern "efiapi" fn(this: &SNP, interrupt_status: *mut u32, tx_buf: *mut *mut u8) -> Status, |
| 23 | + transmit : extern "efiapi" fn(this: &SNP, header_size: usize, buffer_size: usize, buffer: *const u8, src_addr: *const MacAddress, dest_addr: *const MacAddress, protocol: u16) -> Status, |
| 24 | + receive : extern "efiapi" fn(this: &SNP, header_size: *const usize, buffer_size: *mut usize, buffer: *mut u8, src_addr: *mut MacAddress, dest_addr: *mut MacAddress, protocol: *mut u16) -> Status, |
| 25 | + wait_for_packet : usize, |
| 26 | + mode: *const NetworkMode, |
| 27 | +} |
| 28 | + |
| 29 | +impl SNP { |
| 30 | + |
| 31 | + /// Changes the state of a network interface from “stopped” to “started”. |
| 32 | + /// |
| 33 | + /// # Errors |
| 34 | + /// * `uefi::Status::ALREADY_STARTED` The network interface is already in the started state. |
| 35 | + /// * `uefi::Status::INVALID_PARAMETER` This parameter was NULL or did not point to a valid EFI_SIMPLE_NETWORK_PROTOCOL structure |
| 36 | + /// * `uefi::Status::DEVICE_ERROR` The command could not be sent to the network interface. |
| 37 | + /// * `uefi::Status::DEVICE_ERROR` This function is not supported by the network interface. |
| 38 | + pub fn start(&self) -> Result { |
| 39 | + (self.start)(self).into() |
| 40 | + } |
| 41 | + |
| 42 | + /// Changes the state of a network interface from “started” to “stopped”. |
| 43 | + /// |
| 44 | + /// # Errors |
| 45 | + /// * `uefi::Status::NOT_STARTED` The network interface has not been started. |
| 46 | + /// * `uefi::Status::INVALID_PARAMETER` This parameter was NULL or did not point to a valid EFI_SIMPLE_NETWORK_PROTOCOL structure |
| 47 | + /// * `uefi::Status::DEVICE_ERROR` The command could not be sent to the network interface. |
| 48 | + /// * `uefi::Status::DEVICE_ERROR` This function is not supported by the network interface. |
| 49 | + pub fn stop(&mut self) -> Result { |
| 50 | + (self.stop)(self).into() |
| 51 | + } |
| 52 | + |
| 53 | + /// Resets a network adapter and allocates the transmit and receive buffers. |
| 54 | + /// |
| 55 | + /// # Errors |
| 56 | + /// * `uefi::Status::NOT_STARTED` The network interface has not been started. |
| 57 | + /// * `uefi::Status::EFI_OUT_OF_RESOURCES` There was not enough memory for the transmit and receive buffers |
| 58 | + /// * `uefi::Status::INVALID_PARAMETER` This parameter was NULL or did not point to a valid EFI_SIMPLE_NETWORK_PROTOCOL structure |
| 59 | + /// * `uefi::Status::DEVICE_ERROR` The command could not be sent to the network interface. |
| 60 | + /// * `uefi::Status::UNSUPPORTED` The increased buffer size feature is not supported. |
| 61 | + pub fn initialize(&self, extra_rx_buffer_size: usize, extra_tx_buffer_size: usize) -> Result { |
| 62 | + (self.initialize)(self, extra_rx_buffer_size, extra_tx_buffer_size).into() |
| 63 | + } |
| 64 | + |
| 65 | + /// Resets or collects the statistics on a network interface. |
| 66 | + /// |
| 67 | + /// # Errors |
| 68 | + pub fn statistics(&self, reset: bool, statistics_size: *mut usize, statistics_table: *mut NetworkStatistics) -> Result { |
| 69 | + (self.statistics)(self, reset, statistics_size, statistics_table).into() |
| 70 | + } |
| 71 | + |
| 72 | + /// Places a packet in the transmit queue of a network interface. |
| 73 | + /// |
| 74 | + /// # Errors |
| 75 | + /// * `uefi::Status::NOT_STARTED` The network interface has not been started. |
| 76 | + /// * `uefi::Status::EFI_OUT_OF_RESOURCES` There was not enough memory for the transmit and receive buffers |
| 77 | + /// * `uefi::Status::INVALID_PARAMETER` This parameter was NULL or did not point to a valid EFI_SIMPLE_NETWORK_PROTOCOL structure |
| 78 | + /// * `uefi::Status::DEVICE_ERROR` The command could not be sent to the network interface. |
| 79 | + /// * `uefi::Status::UNSUPPORTED` The increased buffer size feature is not supported. |
| 80 | + pub fn transmit(&self, header_size: usize, buffer: &[u8], src_addr: *const MacAddress, dest_addr: *const MacAddress, protocol: u16) -> Result { |
| 81 | + (self.transmit)(self, header_size, buffer.len(), buffer.as_ptr(), src_addr, dest_addr, protocol).into() |
| 82 | + } |
| 83 | + |
| 84 | + /// Pointer for network mode. |
| 85 | + pub fn mode(&self) -> &NetworkMode { |
| 86 | + unsafe { &*self.mode } |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +/// Network statistics structure |
| 91 | +#[repr(C)] |
| 92 | +#[derive(Debug)] |
| 93 | +pub struct NetworkStatistics { |
| 94 | + rx_total_frames: u64, |
| 95 | + rx_good_frames: u64, |
| 96 | + rx_undersize_frames: u64, |
| 97 | + rx_oversize_frames: u64, |
| 98 | + rx_dropped_frames: u64, |
| 99 | + rx_unicast_frames: u64, |
| 100 | + rx_broadcast_frames: u64, |
| 101 | + rx_multicast_frames: u64, |
| 102 | + rx_crc_error_frames: u64, |
| 103 | + rx_total_bytes: u64, |
| 104 | + tx_total_frames: u64, |
| 105 | + tx_good_frames: u64, |
| 106 | + tx_undersize_frames: u64, |
| 107 | + tx_oversize_frames: u64, |
| 108 | + tx_dropped_frames: u64, |
| 109 | + tx_unicast_frames: u64, |
| 110 | + tx_broadcast_frames: u64, |
| 111 | + tx_multicast_frames: u64, |
| 112 | + tx_crc_error_frames: u64, |
| 113 | + tx_total_bytes: u64, |
| 114 | + collisions: u64, |
| 115 | + unsupported_protocol: u64, |
| 116 | + rx_duplicated_frames: u64, |
| 117 | + rx_decrypt_error_frames: u64, |
| 118 | + tx_error_frames: u64, |
| 119 | + tx_retry_frames: u64, |
| 120 | +} |
| 121 | + |
| 122 | +/// EFI_MAC_ADDRESS |
| 123 | +#[repr(C)] |
| 124 | +#[derive(Debug)] |
| 125 | +pub struct MacAddress { |
| 126 | + pub addr: [u8; 32], |
| 127 | +} |
| 128 | + |
| 129 | +/// EFI_IP_ADDRESS |
| 130 | +#[repr(C)] |
| 131 | +#[derive(Debug)] |
| 132 | +pub struct IpAddress { |
| 133 | + addr: [u8; 4], |
| 134 | +} |
| 135 | + |
| 136 | +/// Network mode structure |
| 137 | +#[repr(C)] |
| 138 | +#[derive(Debug)] |
| 139 | +pub struct NetworkMode { |
| 140 | + state: u32, |
| 141 | + hw_address_size: u32, |
| 142 | + media_header_size: u32, |
| 143 | + max_packet_size: u32, |
| 144 | + nv_ram_size: u32, |
| 145 | + nv_ram_access_size: u32, |
| 146 | + receive_filter_mask: u32, |
| 147 | + receive_filter_setting: u32, |
| 148 | + max_mcast_filter_count: u32, |
| 149 | + mcast_filter_count: u32, |
| 150 | + mcast_filter: [MacAddress; 16], |
| 151 | + current_address: MacAddress, |
| 152 | + broadcast_address: MacAddress, |
| 153 | + permanent_address: MacAddress, |
| 154 | + if_type: u8, |
| 155 | + mac_address_changeable: bool, |
| 156 | + multiple_tx_supported: bool, |
| 157 | + media_present_supported: bool, |
| 158 | + media_present: bool, |
| 159 | +} |
| 160 | + |
| 161 | +impl NetworkMode { |
| 162 | + |
| 163 | + /// |
| 164 | + pub fn current_address(&self) -> &MacAddress { |
| 165 | + &self.current_address |
| 166 | + } |
| 167 | + |
| 168 | + /// |
| 169 | + pub fn if_type(&self) -> u8 { |
| 170 | + self.if_type |
| 171 | + } |
| 172 | +} |
0 commit comments