55use super :: { IpAddress , MacAddress } ;
66use crate :: polyfill:: maybe_uninit_slice_as_mut_ptr;
77use crate :: proto:: unsafe_protocol;
8- use crate :: util:: ptr_write_unaligned_and_add;
8+ use crate :: util:: { ptr_write_unaligned_and_add, usize_from_u32 } ;
99use crate :: { CStr8 , Result , Status , StatusExt } ;
1010use bitflags:: bitflags;
1111use core:: fmt:: { self , Debug , Display , Formatter } ;
1212use core:: iter:: from_fn;
1313use core:: mem:: MaybeUninit ;
1414use core:: ptr:: { self , null, null_mut} ;
15+ use core:: slice;
1516use ptr_meta:: Pointee ;
1617use uefi_raw:: protocol:: network:: pxe:: {
17- PxeBaseCodeDiscoverInfo , PxeBaseCodeIpFilter , PxeBaseCodeMtftpInfo , PxeBaseCodePacket ,
18- PxeBaseCodeProtocol , PxeBaseCodeTftpOpcode ,
18+ PxeBaseCodeDiscoverInfo , PxeBaseCodeIpFilter , PxeBaseCodeMode , PxeBaseCodeMtftpInfo ,
19+ PxeBaseCodePacket , PxeBaseCodeProtocol , PxeBaseCodeTftpOpcode ,
1920} ;
2021use uefi_raw:: { Boolean , Char8 } ;
2122
@@ -814,6 +815,13 @@ pub union Packet {
814815 dhcpv6 : DhcpV6Packet ,
815816}
816817
818+ impl Packet {
819+ fn from_raw ( packet : & PxeBaseCodePacket ) -> & Self {
820+ // Safety: `Packet` has the same layout as `PxeBaseCodePacket`.
821+ unsafe { & * ptr:: from_ref ( packet) . cast ( ) }
822+ }
823+ }
824+
817825impl Debug for Packet {
818826 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
819827 write ! ( f, "<binary data>" )
@@ -942,91 +950,150 @@ impl DhcpV6Packet {
942950/// [`BaseCode`].
943951///
944952/// Corresponds to the `EFI_PXE_BASE_CODE_MODE` type in the C API.
945- #[ repr( C ) ]
953+ #[ repr( transparent ) ]
946954#[ derive( Debug ) ]
947- pub struct Mode {
955+ pub struct Mode ( PxeBaseCodeMode ) ;
956+
957+ impl Mode {
948958 /// `true` if this device has been started by calling [`BaseCode::start`].
949959 /// This field is set to `true` by [`BaseCode::start`] and to `false` by
950960 /// the [`BaseCode::stop`] function.
951- pub started : bool ,
961+ pub fn started ( & self ) -> bool {
962+ self . 0 . started . into ( )
963+ }
964+
952965 /// `true` if the UNDI protocol supports IPv6
953- pub ipv6_available : bool ,
966+ pub fn ipv6_available ( & self ) -> bool {
967+ self . 0 . ipv6_available . into ( )
968+ }
969+
954970 /// `true` if this PXE Base Code Protocol implementation supports IPv6.
955- pub ipv6_supported : bool ,
971+ pub fn ipv6_supported ( & self ) -> bool {
972+ self . 0 . ipv6_supported . into ( )
973+ }
974+
956975 /// `true` if this device is currently using IPv6. This field is set by
957976 /// [`BaseCode::start`].
958- pub using_ipv6 : bool ,
977+ pub fn using_ipv6 ( & self ) -> bool {
978+ self . 0 . using_ipv6 . into ( )
979+ }
980+
959981 /// `true` if this PXE Base Code implementation supports Boot Integrity
960982 /// Services (BIS). This field is set by [`BaseCode::start`].
961- pub bis_supported : bool ,
983+ pub fn bis_supported ( & self ) -> bool {
984+ self . 0 . bis_supported . into ( )
985+ }
986+
962987 /// `true` if this device and the platform support Boot Integrity Services
963988 /// (BIS). This field is set by [`BaseCode::start`].
964- pub bis_detected : bool ,
989+ pub fn bis_detected ( & self ) -> bool {
990+ self . 0 . bis_detected . into ( )
991+ }
992+
965993 /// `true` for automatic ARP packet generation, `false` otherwise. This
966994 /// field is initialized to `true` by [`BaseCode::start`] and can be
967995 /// modified with [`BaseCode::set_parameters`].
968- pub auto_arp : bool ,
996+ pub fn auto_arp ( & self ) -> bool {
997+ self . 0 . auto_arp . into ( )
998+ }
999+
9691000 /// This field is used to change the Client Hardware Address (chaddr) field
9701001 /// in the DHCP and Discovery packets. Set to `true` to send the SystemGuid
9711002 /// (if one is available). Set to `false` to send the client NIC MAC
9721003 /// address. This field is initialized to `false` by [`BaseCode::start`]
9731004 /// and can be modified with [`BaseCode::set_parameters`].
974- pub send_guid : bool ,
1005+ pub fn send_guid ( & self ) -> bool {
1006+ self . 0 . send_guid . into ( )
1007+ }
1008+
9751009 /// This field is initialized to `false` by [`BaseCode::start`] and set to
9761010 /// `true` when [`BaseCode::dhcp`] completes successfully. When `true`,
9771011 /// [`Self::dhcp_discover`] is valid. This field can also be changed by
9781012 /// [`BaseCode::set_packets`].
979- pub dhcp_discover_valid : bool ,
1013+ pub fn dhcp_discover_valid ( & self ) -> bool {
1014+ self . 0 . dhcp_discover_valid . into ( )
1015+ }
1016+
9801017 /// This field is initialized to `false` by [`BaseCode::start`] and set to
9811018 /// `true` when [`BaseCode::dhcp`] completes successfully. When `true`,
9821019 /// [`Self::dhcp_ack`] is valid. This field can also be changed by
9831020 /// [`BaseCode::set_packets`].
984- pub dhcp_ack_received : bool ,
1021+ pub fn dhcp_ack_received ( & self ) -> bool {
1022+ self . 0 . dhcp_ack_received . into ( )
1023+ }
1024+
9851025 /// This field is initialized to `false` by [`BaseCode::start`] and set to
9861026 /// `true` when [`BaseCode::dhcp`] completes successfully and a proxy DHCP
9871027 /// offer packet was received. When `true`, [`Self::proxy_offer`] is valid.
9881028 /// This field can also be changed by [`BaseCode::set_packets`].
989- pub proxy_offer_received : bool ,
1029+ pub fn proxy_offer_received ( & self ) -> bool {
1030+ self . 0 . proxy_offer_received . into ( )
1031+ }
1032+
9901033 /// When `true`, [`Self::pxe_discover`] is valid. This field is set to
9911034 /// `false` by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set
9921035 /// to `true` or `false` by [`BaseCode::discover`] and
9931036 /// [`BaseCode::set_packets`].
994- pub pxe_discover_valid : bool ,
1037+ pub fn pxe_discover_valid ( & self ) -> bool {
1038+ self . 0 . pxe_discover_valid . into ( )
1039+ }
1040+
9951041 /// When `true`, [`Self::pxe_reply`] is valid. This field is set to `false`
9961042 /// by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set to `true`
9971043 /// or `false` by [`BaseCode::discover`] and [`BaseCode::set_packets`].
998- pub pxe_reply_received : bool ,
1044+ pub fn pxe_reply_received ( & self ) -> bool {
1045+ self . 0 . pxe_reply_received . into ( )
1046+ }
1047+
9991048 /// When `true`, [`Self::pxe_bis_reply`] is valid. This field is set to
10001049 /// `false` by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set
10011050 /// to `true` or `false` by the [`BaseCode::discover`] and
10021051 /// [`BaseCode::set_packets`].
1003- pub pxe_bis_reply_received : bool ,
1052+ pub fn pxe_bis_reply_received ( & self ) -> bool {
1053+ self . 0 . pxe_bis_reply_received . into ( )
1054+ }
1055+
10041056 /// Indicates whether [`Self::icmp_error`] has been updated. This field is
10051057 /// reset to `false` by [`BaseCode::start`], [`BaseCode::dhcp`],
10061058 /// [`BaseCode::discover`],[`BaseCode::udp_read`], [`BaseCode::udp_write`],
10071059 /// [`BaseCode::arp`] and any of the TFTP/MTFTP operations. If an ICMP
10081060 /// error is received, this field will be set to `true` after
10091061 /// [`Self::icmp_error`] is updated.
1010- pub icmp_error_received : bool ,
1062+ pub fn icmp_error_received ( & self ) -> bool {
1063+ self . 0 . icmp_error_received . into ( )
1064+ }
1065+
10111066 /// Indicates whether [`Self::tftp_error`] has been updated. This field is
10121067 /// reset to `false` by [`BaseCode::start`] and any of the TFTP/MTFTP
10131068 /// operations. If a TFTP error is received, this field will be set to
10141069 /// `true` after [`Self::tftp_error`] is updated.
1015- pub tftp_error_received : bool ,
1070+ pub fn tftp_error_received ( & self ) -> bool {
1071+ self . 0 . tftp_error_received . into ( )
1072+ }
1073+
10161074 /// When `false`, callbacks will not be made. When `true`, make callbacks
10171075 /// to the PXE Base Code Callback Protocol. This field is reset to `false`
10181076 /// by [`BaseCode::start`] if the PXE Base Code Callback Protocol is not
10191077 /// available. It is reset to `true` by [`BaseCode::start`] if the PXE Base
10201078 /// Code Callback Protocol is available.
1021- pub make_callbacks : bool ,
1079+ pub fn make_callbacks ( & self ) -> bool {
1080+ self . 0 . make_callbacks . into ( )
1081+ }
1082+
10221083 /// The "time to live" field of the IP header. This field is initialized to
10231084 /// `16` by [`BaseCode::start`] and can be modified by
10241085 /// [`BaseCode::set_parameters`].
1025- pub ttl : u8 ,
1086+ pub fn ttl ( & self ) -> u8 {
1087+ self . 0 . ttl
1088+ }
1089+
10261090 /// The type of service field of the IP header. This field is initialized
10271091 /// to `0` by [`BaseCode::start`], and can be modified with
10281092 /// [`BaseCode::set_parameters`].
1029- pub tos : u8 ,
1093+ pub fn tos ( & self ) -> u8 {
1094+ self . 0 . tos
1095+ }
1096+
10301097 /// The device’s current IP address. This field is initialized to a zero
10311098 /// address by Start(). This field is set when [`BaseCode::dhcp`] completes
10321099 /// successfully. This field can also be set by
@@ -1035,7 +1102,10 @@ pub struct Mode {
10351102 /// before [`BaseCode::discover`], [`BaseCode::udp_read`],
10361103 /// [`BaseCode::udp_write`], [`BaseCode::arp`] and any of the TFTP/MTFTP
10371104 /// operations are called.
1038- pub station_ip : IpAddress ,
1105+ pub fn station_ip ( & self ) -> IpAddress {
1106+ unsafe { IpAddress :: from_raw ( self . 0 . station_ip , self . using_ipv6 ( ) ) }
1107+ }
1108+
10391109 /// The device's current subnet mask. This field is initialized to a zero
10401110 /// address by [`BaseCode::start`]. This field is set when
10411111 /// [`BaseCode::dhcp`] completes successfully. This field can also be set
@@ -1044,58 +1114,103 @@ pub struct Mode {
10441114 /// [`BaseCode::set_station_ip`] before [`BaseCode::discover`],
10451115 /// [`BaseCode::udp_read`], [`BaseCode::udp_write`],
10461116 /// [`BaseCode::arp`] or any of the TFTP/MTFTP operations are called.
1047- pub subnet_mask : IpAddress ,
1117+ pub fn subnet_mask ( & self ) -> IpAddress {
1118+ unsafe { IpAddress :: from_raw ( self . 0 . subnet_mask , self . using_ipv6 ( ) ) }
1119+ }
1120+
10481121 /// Cached DHCP Discover packet. This field is zero-filled by the
10491122 /// [`BaseCode::start`] function, and is set when [`BaseCode::dhcp`]
10501123 /// completes successfully. The contents of this field can replaced by
10511124 /// [`BaseCode::set_packets`].
1052- pub dhcp_discover : Packet ,
1125+ pub fn dhcp_discover ( & self ) -> & Packet {
1126+ Packet :: from_raw ( & self . 0 . dhcp_discover )
1127+ }
1128+
10531129 /// Cached DHCP Ack packet. This field is zero-filled by
10541130 /// [`BaseCode::start`], and is set when [`BaseCode::dhcp`] completes
10551131 /// successfully. The contents of this field can be replaced by
10561132 /// [`BaseCode::set_packets`].
1057- pub dhcp_ack : Packet ,
1133+ pub fn dhcp_ack ( & self ) -> & Packet {
1134+ Packet :: from_raw ( & self . 0 . dhcp_ack )
1135+ }
1136+
10581137 /// Cached Proxy Offer packet. This field is zero-filled by
10591138 /// [`BaseCode::start`], and is set when [`BaseCode::dhcp`] completes
10601139 /// successfully. The contents of this field can be replaced by
10611140 /// [`BaseCode::set_packets`].
1062- pub proxy_offer : Packet ,
1141+ pub fn proxy_offer ( & self ) -> & Packet {
1142+ Packet :: from_raw ( & self . 0 . proxy_offer )
1143+ }
1144+
10631145 /// Cached PXE Discover packet. This field is zero-filled by
10641146 /// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
10651147 /// successfully. The contents of this field can be replaced by
10661148 /// [`BaseCode::set_packets`].
1067- pub pxe_discover : Packet ,
1149+ pub fn pxe_discover ( & self ) -> & Packet {
1150+ Packet :: from_raw ( & self . 0 . pxe_discover )
1151+ }
1152+
10681153 /// Cached PXE Reply packet. This field is zero-filled by
10691154 /// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
10701155 /// successfully. The contents of this field can be replaced by the
10711156 /// [`BaseCode::set_packets`] function.
1072- pub pxe_reply : Packet ,
1157+ pub fn pxe_reply ( & self ) -> & Packet {
1158+ Packet :: from_raw ( & self . 0 . pxe_reply )
1159+ }
1160+
10731161 /// Cached PXE BIS Reply packet. This field is zero-filled by
10741162 /// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
10751163 /// successfully. This field can be replaced by [`BaseCode::set_packets`].
1076- pub pxe_bis_reply : Packet ,
1164+ pub fn pxe_bis_reply ( & self ) -> & Packet {
1165+ Packet :: from_raw ( & self . 0 . pxe_bis_reply )
1166+ }
1167+
10771168 /// The current IP receive filter settings. The receive filter is disabled
10781169 /// and the number of IP receive filters is set to zero by
10791170 /// [`BaseCode::start`], and is set by [`BaseCode::set_ip_filter`].
1080- pub ip_filter : IpFilter ,
1081- /// The number of valid entries in the ARP cache. This field is reset to
1082- /// zero by [`BaseCode::start`].
1083- pub arp_cache_entries : u32 ,
1084- /// Array of cached ARP entries.
1085- pub arp_cache : [ ArpEntry ; 8 ] ,
1171+ pub fn ip_filter ( & self ) -> & IpFilter {
1172+ // Safety: `IpFilter` has the same layout as `PxeBaseCodeIpFilter`.
1173+ unsafe { & * ptr:: from_ref ( & self . 0 . ip_filter ) . cast ( ) }
1174+ }
1175+
1176+ /// Cached ARP entries.
1177+ pub fn arp_cache ( & self ) -> & [ ArpEntry ] {
1178+ let len = usize_from_u32 ( self . 0 . arp_cache_entries ) ;
1179+ // Safety: `ArpEntry` has the same layout as `PxeBaseCodeArpEntry`.
1180+ unsafe { slice:: from_raw_parts ( ptr:: from_ref ( & self . 0 . arp_cache ) . cast :: < ArpEntry > ( ) , len) }
1181+ }
1182+
10861183 /// The number of valid entries in the current route table. This field is
10871184 /// reset to zero by [`BaseCode::start`].
1088- pub route_table_entries : u32 ,
1185+ pub fn route_table_entries ( & self ) -> u32 {
1186+ self . 0 . route_table_entries
1187+ }
1188+
10891189 /// Array of route table entries.
1090- pub route_table : [ RouteEntry ; 8 ] ,
1190+ pub fn route_table ( & self ) -> & [ RouteEntry ] {
1191+ let len = usize_from_u32 ( self . 0 . route_table_entries ) ;
1192+
1193+ // Safety: `RouteEntry` has the same layout as `PxeBaseCodeRouteEntry`.
1194+ unsafe {
1195+ slice:: from_raw_parts ( ptr:: from_ref ( & self . 0 . route_table ) . cast :: < RouteEntry > ( ) , len)
1196+ }
1197+ }
1198+
10911199 /// ICMP error packet. This field is updated when an ICMP error is received
10921200 /// and is undefined until the first ICMP error is received. This field is
10931201 /// zero-filled by [`BaseCode::start`].
1094- pub icmp_error : IcmpError ,
1202+ pub fn icmp_error ( & self ) -> & IcmpError {
1203+ // Safety: `IcmpError` has the same layout as `PxeBaseCodeIcmpError`.
1204+ unsafe { & * ptr:: from_ref ( & self . 0 . icmp_error ) . cast ( ) }
1205+ }
1206+
10951207 /// TFTP error packet. This field is updated when a TFTP error is received
10961208 /// and is undefined until the first TFTP error is received. This field is
10971209 /// zero-filled by the [`BaseCode::start`] function.
1098- pub tftp_error : TftpError ,
1210+ pub fn tftp_error ( & self ) -> & TftpError {
1211+ // Safety: `TftpError` has the same layout as `PxeBaseCodeTftpError`.
1212+ unsafe { & * ptr:: from_ref ( & self . 0 . tftp_error ) . cast ( ) }
1213+ }
10991214}
11001215
11011216/// An entry for the ARP cache found in [`Mode::arp_cache`]
0 commit comments