1 use crate::{guid, Char8, Event, Guid, Ipv4Address, MacAddress, Status}; 2 use core::ffi::c_void; 3 4 newtype_enum! { 5 pub enum Dhcp4Event: i32 => { 6 SEND_DISCOVER = 0x01, 7 RCVD_OFFER = 0x02, 8 SELECT_OFFER = 0x03, 9 SEND_REQUEST = 0x04, 10 RCVD_ACK = 0x05, 11 RCVD_NAK = 0x06, 12 SEND_DECLINE = 0x07, 13 BOUND_COMPLETED = 0x08, 14 ENTER_RENEWING = 0x09, 15 ENTER_REBINDING = 0x0a, 16 ADDRESS_LOST = 0x0b, 17 FAIL = 0x0c, 18 } 19 } 20 21 newtype_enum! { 22 pub enum Dhcp4State: i32 => { 23 STOPPED = 0x0, 24 INIT = 0x1, 25 SELECTING = 0x2, 26 REQUESTING = 0x3, 27 BOUND = 0x4, 28 RENEWING = 0x5, 29 REBINDING = 0x6, 30 INIT_REBOOT = 0x7, 31 REBOOTING = 0x8, 32 } 33 } 34 35 #[derive(Debug)] 36 #[repr(C, packed)] 37 pub struct Dhcp4Packet { 38 pub size: u32, 39 pub length: u32, 40 pub header: Dhcp4Header, 41 pub magik: u32, 42 43 /// Start of the DHCP packed option data. 44 /// 45 /// Note that this field is actually a variable-length array. 46 pub option: [u8; 0], 47 } 48 49 #[derive(Clone, Copy, Debug)] 50 #[repr(C, packed)] 51 pub struct Dhcp4Header { 52 pub op_code: u8, 53 pub hw_type: u8, 54 pub hw_addr_len: u8, 55 pub hops: u8, 56 pub xid: u32, 57 pub seconds: u16, 58 pub reserved: u16, 59 pub client_addr: Ipv4Address, 60 pub your_addr: Ipv4Address, 61 pub server_addr: Ipv4Address, 62 pub gateway_addr: Ipv4Address, 63 pub client_hw_addr: [u8; 16], 64 pub server_name: [Char8; 64], 65 pub boot_file_name: [Char8; 128], 66 } 67 68 #[derive(Debug)] 69 #[repr(C, packed)] 70 pub struct Dhcp4PacketOption { 71 pub op_code: u8, 72 pub length: u8, 73 74 /// Start of the DHCP option data. 75 /// 76 /// Note that this field is actually a variable-length array. 77 pub data: [u8; 0], 78 } 79 80 #[derive(Debug)] 81 #[repr(C)] 82 pub struct Dhcp4ConfigData { 83 pub discover_try_count: u32, 84 pub discover_timeout: *mut u32, 85 pub request_try_count: u32, 86 pub request_timeout: *mut u32, 87 pub client_address: Ipv4Address, 88 pub callback: Option< 89 unsafe extern "efiapi" fn( 90 this: *mut Dhcp4Protocol, 91 context: *const c_void, 92 current_state: Dhcp4State, 93 dhcp4_event: Dhcp4Event, 94 packet: *const Dhcp4Packet, 95 new_packet: *mut *const Dhcp4Packet, 96 ) -> Status, 97 >, 98 pub callback_context: *mut c_void, 99 pub option_count: u32, 100 pub option_list: *mut *const Dhcp4PacketOption, 101 } 102 103 #[derive(Debug)] 104 #[repr(C)] 105 pub struct Dhcp4ModeData { 106 pub state: Dhcp4State, 107 pub config_data: Dhcp4ConfigData, 108 pub client_address: Ipv4Address, 109 pub client_mac_address: MacAddress, 110 pub server_address: Ipv4Address, 111 pub router_address: Ipv4Address, 112 pub subnet_mask: Ipv4Address, 113 pub lease_time: u32, 114 pub reply_packet: *const Dhcp4Packet, 115 } 116 117 #[derive(Debug)] 118 #[repr(C)] 119 pub struct Dhcp4ListenPoint { 120 pub listen_address: Ipv4Address, 121 pub subnet_mask: Ipv4Address, 122 pub listen_port: u16, 123 } 124 125 #[derive(Debug)] 126 #[repr(C)] 127 pub struct Dhcp4TransmitReceiveToken { 128 pub status: Status, 129 pub completion_event: Event, 130 pub remote_address: Ipv4Address, 131 pub remote_port: u16, 132 pub gateway_address: Ipv4Address, 133 pub listen_point_count: u32, 134 pub listen_points: *mut Dhcp4ListenPoint, 135 pub timeout_value: u32, 136 pub packet: *mut Dhcp4Packet, 137 pub response_count: u32, 138 pub response_list: *mut Dhcp4Packet, 139 } 140 141 #[derive(Debug)] 142 #[repr(C)] 143 pub struct Dhcp4Protocol { 144 pub get_mode_data: 145 unsafe extern "efiapi" fn(this: *const Self, mode_data: *mut Dhcp4ModeData) -> Status, 146 pub configure: 147 unsafe extern "efiapi" fn(this: *mut Self, cfg_data: *const Dhcp4ConfigData) -> Status, 148 pub start: unsafe extern "efiapi" fn(this: *mut Self, completion_event: Event) -> Status, 149 pub renew_rebind: unsafe extern "efiapi" fn( 150 this: *mut Self, 151 rebind_request: bool, 152 completion_event: Event, 153 ) -> Status, 154 pub release: unsafe extern "efiapi" fn(this: *mut Self) -> Status, 155 pub stop: unsafe extern "efiapi" fn(this: *mut Self) -> Status, 156 pub build: unsafe extern "efiapi" fn( 157 this: *mut Self, 158 seed_packet: *mut Dhcp4Packet, 159 delete_count: u32, 160 delete_list: *mut u8, 161 append_count: u32, 162 append_list: *const *const Dhcp4PacketOption, 163 new_packet: *mut *mut Dhcp4Packet, 164 ) -> Status, 165 pub transmit_receive: 166 unsafe extern "efiapi" fn(this: *mut Self, token: *mut Dhcp4TransmitReceiveToken) -> Status, 167 pub parse: unsafe extern "efiapi" fn( 168 this: *mut Self, 169 packet: *mut Dhcp4Packet, 170 option_count: *mut u32, 171 packet_option_list: *mut *mut Dhcp4PacketOption, 172 ) -> Status, 173 } 174 175 impl Dhcp4Protocol { 176 pub const GUID: Guid = guid!("8a219718-4ef5-4761-91c8-c0f04bda9e56"); 177 pub const SERVICE_BINDING_GUID: Guid = guid!("9d9a39d8-bd42-4a73-a4d5-8ee94be11380"); 178 } 179