1use crate::{Boolean, Char8, Guid, IpAddress, MacAddress, Status, guid, newtype_enum};
4use bitflags::bitflags;
5use core::ffi::c_void;
6use core::fmt::{self, Debug, Formatter};
7
8#[derive(Debug)]
9#[repr(C)]
10pub struct PxeBaseCodeProtocol {
11 pub revision: u64,
12 pub start: unsafe extern "efiapi" fn(this: *mut Self, use_ipv6: Boolean) -> Status,
13 pub stop: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
14 pub dhcp: unsafe extern "efiapi" fn(this: *mut Self, sort_offers: Boolean) -> Status,
15 pub discover: unsafe extern "efiapi" fn(
16 this: *mut Self,
17 ty: PxeBaseCodeBootType,
18 layer: *mut u16,
19 use_bis: Boolean,
20 info: *const PxeBaseCodeDiscoverInfo,
21 ) -> Status,
22 pub mtftp: unsafe extern "efiapi" fn(
23 this: *mut Self,
24 operation: PxeBaseCodeTftpOpcode,
25 buffer: *mut c_void,
26 overwrite: Boolean,
27 buffer_size: *mut u64,
28 block_size: *const usize,
29 server_ip: *const IpAddress,
30 filename: *const Char8,
31 info: *const PxeBaseCodeMtftpInfo,
32 dont_use_buffer: Boolean,
33 ) -> Status,
34 pub udp_write: unsafe extern "efiapi" fn(
35 this: *mut Self,
36 op_flags: PxeBaseCodeUdpOpFlags,
37 dest_ip: *const IpAddress,
38 dest_port: *const PxeBaseCodeUdpPort,
39 gateway_ip: *const IpAddress,
40 src_ip: *const IpAddress,
41 src_port: *mut PxeBaseCodeUdpPort,
42 header_size: *const usize,
43 header_ptr: *const c_void,
44 buffer_size: *const usize,
45 buffer_ptr: *const c_void,
46 ) -> Status,
47 pub udp_read: unsafe extern "efiapi" fn(
48 this: *mut Self,
49 op_flags: PxeBaseCodeUdpOpFlags,
50 dest_ip: *mut IpAddress,
51 dest_port: *mut PxeBaseCodeUdpPort,
52 src_ip: *mut IpAddress,
53 src_port: *mut PxeBaseCodeUdpPort,
54 header_size: *const usize,
55 header_ptr: *mut c_void,
56 buffer_size: *mut usize,
57 buffer_ptr: *mut c_void,
58 ) -> Status,
59 pub set_ip_filter: unsafe extern "efiapi" fn(
60 this: *mut Self,
61 new_filter: *const PxeBaseCodeIpFilter,
62 ) -> Status,
63 pub arp: unsafe extern "efiapi" fn(
64 this: *mut Self,
65 ip_addr: *const IpAddress,
66 mac_addr: *mut MacAddress,
67 ) -> Status,
68 pub set_parameters: unsafe extern "efiapi" fn(
69 this: *mut Self,
70 new_auto_arp: *const Boolean,
71 new_send_guid: *const Boolean,
72 new_ttl: *const u8,
73 new_tos: *const u8,
74 new_make_callback: *const Boolean,
75 ) -> Status,
76 pub set_station_ip: unsafe extern "efiapi" fn(
77 this: *mut Self,
78 new_station_ip: *const IpAddress,
79 new_subnet_mask: *const IpAddress,
80 ) -> Status,
81 pub set_packets: unsafe extern "efiapi" fn(
82 this: *mut Self,
83 new_dhcp_discover_valid: *const Boolean,
84 new_dhcp_ack_received: *const Boolean,
85 new_proxy_offer_received: *const Boolean,
86 new_pxe_discover_valid: *const Boolean,
87 new_pxe_reply_received: *const Boolean,
88 new_pxe_bis_reply_received: *const Boolean,
89 new_dhcp_discover: *const PxeBaseCodePacket,
90 new_dhcp_ack: *const PxeBaseCodePacket,
91 new_proxy_offer: *const PxeBaseCodePacket,
92 new_pxe_discover: *const PxeBaseCodePacket,
93 new_pxe_reply: *const PxeBaseCodePacket,
94 new_pxe_bis_reply: *const PxeBaseCodePacket,
95 ) -> Status,
96 pub mode: *const PxeBaseCodeMode,
97}
98
99impl PxeBaseCodeProtocol {
100 pub const GUID: Guid = guid!("03c4e603-ac28-11d3-9a2d-0090273fc14d");
101}
102
103newtype_enum! {
104 pub enum PxeBaseCodeBootType: u16 => {
105 BOOTSTRAP = 0,
106 MS_WINNT_RIS = 1,
107 INTEL_LCM = 2,
108 DOS_UNDI = 3,
109 NEC_ESMPRO = 4,
110 IBM_WSOD = 5,
111 IBM_LCCM = 6,
112 CA_UNICENTER_TNG = 7,
113 HP_OPENVIEW = 8,
114 ALTIRIS_9 = 9,
115 ALTIRIS_10 = 10,
116 ALTIRIS_11 = 11,
117 NOT_USED_12 = 12,
118 REDHAT_INSTALL = 13,
119 REDHAT_BOOT = 14,
120 REMBO = 15,
121 BEOBOOT = 16,
122 PXETEST = 65535,
126 }
127}
128
129newtype_enum! {
130 pub enum PxeBaseCodeTftpOpcode: i32 => {
131 TFTP_FIRST = 0,
132 TFTP_GET_FILE_SIZE = 1,
133 TFTP_READ_FILE = 2,
134 TFTP_WRITE_FILE = 3,
135 TFTP_READ_DIRECTORY = 4,
136 MTFTP_GET_FILE_SIZE = 5,
137 MTFTP_READ_FILE = 6,
138 MTFTP_READ_DIRECTORY = 7,
139 MTFTP_LAST = 8,
140 }
141}
142
143#[derive(Debug)]
144#[repr(C)]
145pub struct PxeBaseCodeDiscoverInfo {
146 pub use_m_cast: Boolean,
147 pub use_b_cast: Boolean,
148 pub use_u_cast: Boolean,
149 pub must_use_list: Boolean,
150 pub server_m_cast_ip: IpAddress,
151 pub ip_cnt: u16,
152
153 pub srv_list: [PxeBaseCodeSrvlist; 0],
155}
156
157#[derive(Clone, Copy, Debug)]
158#[repr(C)]
159pub struct PxeBaseCodeSrvlist {
160 pub server_type: u16,
161 pub accept_any_response: Boolean,
162 pub reserved: u8,
163 pub ip_addr: IpAddress,
164}
165
166pub type PxeBaseCodeUdpPort = u16;
167
168#[derive(Clone, Copy, Debug)]
169#[repr(C)]
170pub struct PxeBaseCodeMtftpInfo {
171 pub m_cast_ip: IpAddress,
172 pub c_port: PxeBaseCodeUdpPort,
173 pub s_port: PxeBaseCodeUdpPort,
174 pub listen_timeout: u16,
175 pub transmit_timeout: u16,
176}
177
178bitflags! {
179 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
181 #[repr(transparent)]
182 pub struct PxeBaseCodeUdpOpFlags: u16 {
183 const ANY_SRC_IP = 0x0001;
185
186 const ANY_SRC_PORT = 0x0002;
190
191 const ANY_DEST_IP = 0x0004;
193
194 const ANY_DEST_PORT = 0x0008;
196
197 const USE_FILTER = 0x0010;
199
200 const MAY_FRAGMENT = 0x0020;
202 }
203}
204
205#[derive(Clone, Debug)]
206#[repr(C)]
207pub struct PxeBaseCodeMode {
208 pub started: Boolean,
209 pub ipv6_available: Boolean,
210 pub ipv6_supported: Boolean,
211 pub using_ipv6: Boolean,
212 pub bis_supported: Boolean,
213 pub bis_detected: Boolean,
214 pub auto_arp: Boolean,
215 pub send_guid: Boolean,
216 pub dhcp_discover_valid: Boolean,
217 pub dhcp_ack_received: Boolean,
218 pub proxy_offer_received: Boolean,
219 pub pxe_discover_valid: Boolean,
220 pub pxe_reply_received: Boolean,
221 pub pxe_bis_reply_received: Boolean,
222 pub icmp_error_received: Boolean,
223 pub tftp_error_received: Boolean,
224 pub make_callbacks: Boolean,
225 pub ttl: u8,
226 pub tos: u8,
227 pub station_ip: IpAddress,
228 pub subnet_mask: IpAddress,
229 pub dhcp_discover: PxeBaseCodePacket,
230 pub dhcp_ack: PxeBaseCodePacket,
231 pub proxy_offer: PxeBaseCodePacket,
232 pub pxe_discover: PxeBaseCodePacket,
233 pub pxe_reply: PxeBaseCodePacket,
234 pub pxe_bis_reply: PxeBaseCodePacket,
235 pub ip_filter: PxeBaseCodeIpFilter,
236 pub arp_cache_entries: u32,
237 pub arp_cache: [PxeBaseCodeArpEntry; 8],
238 pub route_table_entries: u32,
239 pub route_table: [PxeBaseCodeRouteEntry; 8],
240 pub icmp_error: PxeBaseCodeIcmpError,
241 pub tftp_error: PxeBaseCodeTftpError,
242}
243
244#[derive(Clone, Copy)]
245#[repr(C)]
246pub union PxeBaseCodePacket {
247 pub raw: [u8; 1472],
248 pub dhcpv4: PxeBaseCodeDhcpV4Packet,
249 pub dhcpv6: PxeBaseCodeDhcpV6Packet,
250}
251
252impl Debug for PxeBaseCodePacket {
253 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
254 f.debug_struct("PxeBaseCodePacket").finish()
255 }
256}
257
258#[derive(Clone, Copy, Debug)]
259#[repr(C)]
260pub struct PxeBaseCodeDhcpV4Packet {
261 pub bootp_opcode: u8,
262 pub bootp_hw_type: u8,
263 pub bootp_hw_addr_len: u8,
264 pub bootp_gate_hops: u8,
265 pub bootp_ident: u32,
266 pub bootp_seconds: u16,
267 pub bootp_flags: u16,
268 pub bootp_ci_addr: [u8; 4],
269 pub bootp_yi_addr: [u8; 4],
270 pub bootp_si_addr: [u8; 4],
271 pub bootp_gi_addr: [u8; 4],
272 pub bootp_hw_addr: [u8; 16],
273 pub bootp_srv_name: [u8; 64],
274 pub bootp_boot_file: [u8; 128],
275 pub dhcp_magik: u32,
276 pub dhcp_options: [u8; 56],
277}
278
279#[derive(Clone, Copy, Debug)]
280#[repr(C)]
281pub struct PxeBaseCodeDhcpV6Packet {
282 pub message_type: u8,
283 pub transaction_id: [u8; 3],
284 pub dhcp_options: [u8; 1024],
285}
286
287#[derive(Clone, Copy, Debug)]
288#[repr(C)]
289pub struct PxeBaseCodeIpFilter {
290 pub filters: PxeBaseCodeIpFilterFlags,
291 pub ip_cnt: u8,
292 pub reserved: u16,
293 pub ip_list: [IpAddress; 8],
294}
295
296bitflags! {
297 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
299 #[repr(transparent)]
300 pub struct PxeBaseCodeIpFilterFlags: u8 {
301 const STATION_IP = 0x01;
303
304 const BROADCAST = 0x02;
306
307 const PROMISCUOUS = 0x04;
309
310 const PROMISCUOUS_MULTICAST = 0x08;
312 }
313}
314
315#[derive(Clone, Copy, Debug)]
316#[repr(C)]
317pub struct PxeBaseCodeArpEntry {
318 pub ip_addr: IpAddress,
319 pub mac_addr: MacAddress,
320}
321
322#[derive(Clone, Copy, Debug)]
323#[repr(C)]
324pub struct PxeBaseCodeRouteEntry {
325 pub ip_addr: IpAddress,
326 pub subnet_mask: IpAddress,
327 pub gw_addr: IpAddress,
328}
329
330#[derive(Clone, Debug)]
331#[repr(C)]
332pub struct PxeBaseCodeIcmpError {
333 pub ty: u8,
334 pub code: u8,
335 pub checksum: u16,
336 pub u: PxeBaseCodeIcmpErrorUnion,
337 pub data: [u8; 494],
338}
339
340#[derive(Clone, Copy)]
343#[repr(C)]
344pub union PxeBaseCodeIcmpErrorUnion {
345 pub reserved: u32,
346 pub mtu: u32,
347 pub pointer: u32,
348 pub echo: PxeBaseCodeIcmpErrorEcho,
349}
350
351impl Debug for PxeBaseCodeIcmpErrorUnion {
352 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
353 f.debug_struct("PxeBaseCodeIcmpErrorUnion").finish()
354 }
355}
356
357#[derive(Clone, Copy, Debug)]
360#[repr(C)]
361pub struct PxeBaseCodeIcmpErrorEcho {
362 pub identifier: u16,
363 pub sequence: u16,
364}
365
366#[derive(Clone, Debug)]
367#[repr(C)]
368pub struct PxeBaseCodeTftpError {
369 pub error_code: u8,
370 pub error_string: [Char8; 127],
371}