5
5
use super :: { IpAddress , MacAddress } ;
6
6
use crate :: polyfill:: maybe_uninit_slice_as_mut_ptr;
7
7
use 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 } ;
9
9
use crate :: { CStr8 , Result , Status , StatusExt } ;
10
10
use bitflags:: bitflags;
11
11
use core:: fmt:: { self , Debug , Display , Formatter } ;
12
12
use core:: iter:: from_fn;
13
13
use core:: mem:: MaybeUninit ;
14
14
use core:: ptr:: { self , null, null_mut} ;
15
+ use core:: slice;
15
16
use ptr_meta:: Pointee ;
16
17
use uefi_raw:: protocol:: network:: pxe:: {
17
- PxeBaseCodeDiscoverInfo , PxeBaseCodeIpFilter , PxeBaseCodeMtftpInfo , PxeBaseCodePacket ,
18
- PxeBaseCodeProtocol , PxeBaseCodeTftpOpcode ,
18
+ PxeBaseCodeDiscoverInfo , PxeBaseCodeIpFilter , PxeBaseCodeMode , PxeBaseCodeMtftpInfo ,
19
+ PxeBaseCodePacket , PxeBaseCodeProtocol , PxeBaseCodeTftpOpcode ,
19
20
} ;
20
21
use uefi_raw:: { Boolean , Char8 } ;
21
22
@@ -814,6 +815,13 @@ pub union Packet {
814
815
dhcpv6 : DhcpV6Packet ,
815
816
}
816
817
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
+
817
825
impl Debug for Packet {
818
826
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
819
827
write ! ( f, "<binary data>" )
@@ -942,91 +950,150 @@ impl DhcpV6Packet {
942
950
/// [`BaseCode`].
943
951
///
944
952
/// Corresponds to the `EFI_PXE_BASE_CODE_MODE` type in the C API.
945
- #[ repr( C ) ]
953
+ #[ repr( transparent ) ]
946
954
#[ derive( Debug ) ]
947
- pub struct Mode {
955
+ pub struct Mode ( PxeBaseCodeMode ) ;
956
+
957
+ impl Mode {
948
958
/// `true` if this device has been started by calling [`BaseCode::start`].
949
959
/// This field is set to `true` by [`BaseCode::start`] and to `false` by
950
960
/// the [`BaseCode::stop`] function.
951
- pub started : bool ,
961
+ pub fn started ( & self ) -> bool {
962
+ self . 0 . started . into ( )
963
+ }
964
+
952
965
/// `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
+
954
970
/// `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
+
956
975
/// `true` if this device is currently using IPv6. This field is set by
957
976
/// [`BaseCode::start`].
958
- pub using_ipv6 : bool ,
977
+ pub fn using_ipv6 ( & self ) -> bool {
978
+ self . 0 . using_ipv6 . into ( )
979
+ }
980
+
959
981
/// `true` if this PXE Base Code implementation supports Boot Integrity
960
982
/// 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
+
962
987
/// `true` if this device and the platform support Boot Integrity Services
963
988
/// (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
+
965
993
/// `true` for automatic ARP packet generation, `false` otherwise. This
966
994
/// field is initialized to `true` by [`BaseCode::start`] and can be
967
995
/// 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
+
969
1000
/// This field is used to change the Client Hardware Address (chaddr) field
970
1001
/// in the DHCP and Discovery packets. Set to `true` to send the SystemGuid
971
1002
/// (if one is available). Set to `false` to send the client NIC MAC
972
1003
/// address. This field is initialized to `false` by [`BaseCode::start`]
973
1004
/// 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
+
975
1009
/// This field is initialized to `false` by [`BaseCode::start`] and set to
976
1010
/// `true` when [`BaseCode::dhcp`] completes successfully. When `true`,
977
1011
/// [`Self::dhcp_discover`] is valid. This field can also be changed by
978
1012
/// [`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
+
980
1017
/// This field is initialized to `false` by [`BaseCode::start`] and set to
981
1018
/// `true` when [`BaseCode::dhcp`] completes successfully. When `true`,
982
1019
/// [`Self::dhcp_ack`] is valid. This field can also be changed by
983
1020
/// [`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
+
985
1025
/// This field is initialized to `false` by [`BaseCode::start`] and set to
986
1026
/// `true` when [`BaseCode::dhcp`] completes successfully and a proxy DHCP
987
1027
/// offer packet was received. When `true`, [`Self::proxy_offer`] is valid.
988
1028
/// 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
+
990
1033
/// When `true`, [`Self::pxe_discover`] is valid. This field is set to
991
1034
/// `false` by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set
992
1035
/// to `true` or `false` by [`BaseCode::discover`] and
993
1036
/// [`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
+
995
1041
/// When `true`, [`Self::pxe_reply`] is valid. This field is set to `false`
996
1042
/// by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set to `true`
997
1043
/// 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
+
999
1048
/// When `true`, [`Self::pxe_bis_reply`] is valid. This field is set to
1000
1049
/// `false` by [`BaseCode::start`] and [`BaseCode::dhcp`], and can be set
1001
1050
/// to `true` or `false` by the [`BaseCode::discover`] and
1002
1051
/// [`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
+
1004
1056
/// Indicates whether [`Self::icmp_error`] has been updated. This field is
1005
1057
/// reset to `false` by [`BaseCode::start`], [`BaseCode::dhcp`],
1006
1058
/// [`BaseCode::discover`],[`BaseCode::udp_read`], [`BaseCode::udp_write`],
1007
1059
/// [`BaseCode::arp`] and any of the TFTP/MTFTP operations. If an ICMP
1008
1060
/// error is received, this field will be set to `true` after
1009
1061
/// [`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
+
1011
1066
/// Indicates whether [`Self::tftp_error`] has been updated. This field is
1012
1067
/// reset to `false` by [`BaseCode::start`] and any of the TFTP/MTFTP
1013
1068
/// operations. If a TFTP error is received, this field will be set to
1014
1069
/// `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
+
1016
1074
/// When `false`, callbacks will not be made. When `true`, make callbacks
1017
1075
/// to the PXE Base Code Callback Protocol. This field is reset to `false`
1018
1076
/// by [`BaseCode::start`] if the PXE Base Code Callback Protocol is not
1019
1077
/// available. It is reset to `true` by [`BaseCode::start`] if the PXE Base
1020
1078
/// 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
+
1022
1083
/// The "time to live" field of the IP header. This field is initialized to
1023
1084
/// `16` by [`BaseCode::start`] and can be modified by
1024
1085
/// [`BaseCode::set_parameters`].
1025
- pub ttl : u8 ,
1086
+ pub fn ttl ( & self ) -> u8 {
1087
+ self . 0 . ttl
1088
+ }
1089
+
1026
1090
/// The type of service field of the IP header. This field is initialized
1027
1091
/// to `0` by [`BaseCode::start`], and can be modified with
1028
1092
/// [`BaseCode::set_parameters`].
1029
- pub tos : u8 ,
1093
+ pub fn tos ( & self ) -> u8 {
1094
+ self . 0 . tos
1095
+ }
1096
+
1030
1097
/// The device’s current IP address. This field is initialized to a zero
1031
1098
/// address by Start(). This field is set when [`BaseCode::dhcp`] completes
1032
1099
/// successfully. This field can also be set by
@@ -1035,7 +1102,10 @@ pub struct Mode {
1035
1102
/// before [`BaseCode::discover`], [`BaseCode::udp_read`],
1036
1103
/// [`BaseCode::udp_write`], [`BaseCode::arp`] and any of the TFTP/MTFTP
1037
1104
/// 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
+
1039
1109
/// The device's current subnet mask. This field is initialized to a zero
1040
1110
/// address by [`BaseCode::start`]. This field is set when
1041
1111
/// [`BaseCode::dhcp`] completes successfully. This field can also be set
@@ -1044,58 +1114,103 @@ pub struct Mode {
1044
1114
/// [`BaseCode::set_station_ip`] before [`BaseCode::discover`],
1045
1115
/// [`BaseCode::udp_read`], [`BaseCode::udp_write`],
1046
1116
/// [`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
+
1048
1121
/// Cached DHCP Discover packet. This field is zero-filled by the
1049
1122
/// [`BaseCode::start`] function, and is set when [`BaseCode::dhcp`]
1050
1123
/// completes successfully. The contents of this field can replaced by
1051
1124
/// [`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
+
1053
1129
/// Cached DHCP Ack packet. This field is zero-filled by
1054
1130
/// [`BaseCode::start`], and is set when [`BaseCode::dhcp`] completes
1055
1131
/// successfully. The contents of this field can be replaced by
1056
1132
/// [`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
+
1058
1137
/// Cached Proxy Offer packet. This field is zero-filled by
1059
1138
/// [`BaseCode::start`], and is set when [`BaseCode::dhcp`] completes
1060
1139
/// successfully. The contents of this field can be replaced by
1061
1140
/// [`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
+
1063
1145
/// Cached PXE Discover packet. This field is zero-filled by
1064
1146
/// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
1065
1147
/// successfully. The contents of this field can be replaced by
1066
1148
/// [`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
+
1068
1153
/// Cached PXE Reply packet. This field is zero-filled by
1069
1154
/// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
1070
1155
/// successfully. The contents of this field can be replaced by the
1071
1156
/// [`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
+
1073
1161
/// Cached PXE BIS Reply packet. This field is zero-filled by
1074
1162
/// [`BaseCode::start`], and is set when [`BaseCode::discover`] completes
1075
1163
/// 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
+
1077
1168
/// The current IP receive filter settings. The receive filter is disabled
1078
1169
/// and the number of IP receive filters is set to zero by
1079
1170
/// [`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
+
1086
1183
/// The number of valid entries in the current route table. This field is
1087
1184
/// 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
+
1089
1189
/// 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
+
1091
1199
/// ICMP error packet. This field is updated when an ICMP error is received
1092
1200
/// and is undefined until the first ICMP error is received. This field is
1093
1201
/// 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
+
1095
1207
/// TFTP error packet. This field is updated when a TFTP error is received
1096
1208
/// and is undefined until the first TFTP error is received. This field is
1097
1209
/// 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
+ }
1099
1214
}
1100
1215
1101
1216
/// An entry for the ARP cache found in [`Mode::arp_cache`]
0 commit comments