| 1 | const std = @import("std"); |
| 2 | const uefi = std.os.uefi; |
| 3 | const Guid = uefi.Guid; |
| 4 | const Event = uefi.Event; |
| 5 | const Status = uefi.Status; |
| 6 | const cc = uefi.cc; |
| 7 | const MacAddress = uefi.MacAddress; |
| 8 | const Ip6 = uefi.protocol.Ip6; |
| 9 | |
| 10 | pub const Ip6Config = extern struct { |
| 11 | _set_data: *const fn (*const Ip6Config, DataType, usize, *const anyopaque) callconv(cc) Status, |
| 12 | _get_data: *const fn (*const Ip6Config, DataType, *usize, ?*const anyopaque) callconv(cc) Status, |
| 13 | _register_data_notify: *const fn (*const Ip6Config, DataType, Event) callconv(cc) Status, |
| 14 | _unregister_data_notify: *const fn (*const Ip6Config, DataType, Event) callconv(cc) Status, |
| 15 | |
| 16 | pub const SetDataError = uefi.UnexpectedError || error{ |
| 17 | InvalidParameter, |
| 18 | WriteProtected, |
| 19 | AccessDenied, |
| 20 | NotReady, |
| 21 | BadBufferSize, |
| 22 | Unsupported, |
| 23 | OutOfResources, |
| 24 | DeviceError, |
| 25 | }; |
| 26 | pub const GetDataError = uefi.UnexpectedError || error{ |
| 27 | InvalidParameter, |
| 28 | BufferTooSmall, |
| 29 | NotReady, |
| 30 | NotFound, |
| 31 | }; |
| 32 | pub const RegisterDataNotifyError = uefi.UnexpectedError || error{ |
| 33 | InvalidParameter, |
| 34 | Unsupported, |
| 35 | OutOfResources, |
| 36 | AccessDenied, |
| 37 | }; |
| 38 | pub const UnregisterDataNotifyError = uefi.UnexpectedError || error{ |
| 39 | InvalidParameter, |
| 40 | NotFound, |
| 41 | }; |
| 42 | |
| 43 | pub fn setData( |
| 44 | self: *const Ip6Config, |
| 45 | comptime data_type: std.meta.Tag(DataType), |
| 46 | payload: *const @FieldType(DataType, @tagName(data_type)), |
| 47 | ) SetDataError!void { |
| 48 | const data_size = @sizeOf(@TypeOf(payload)); |
| 49 | switch (self._set_data(self, data_type, data_size, @ptrCast(payload))) { |
| 50 | .success => {}, |
| 51 | .invalid_parameter => return error.InvalidParameter, |
| 52 | .write_protected => return error.WriteProtected, |
| 53 | .access_denied => return error.AccessDenied, |
| 54 | .not_ready => return error.NotReady, |
| 55 | .bad_buffer_size => return error.BadBufferSize, |
| 56 | .unsupported => return error.Unsupported, |
| 57 | .out_of_resources => return error.OutOfResources, |
| 58 | .device_error => return error.DeviceError, |
| 59 | else => |status| return uefi.unexpectedStatus(status), |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | pub fn getData( |
| 64 | self: *const Ip6Config, |
| 65 | comptime data_type: std.meta.Tag(DataType), |
| 66 | ) GetDataError!@FieldType(DataType, @tagName(data_type)) { |
| 67 | const DataPayload = @FieldType(DataType, @tagName(data_type)); |
| 68 | |
| 69 | var payload: DataPayload = undefined; |
| 70 | var payload_size: usize = @sizeOf(DataPayload); |
| 71 | |
| 72 | switch (self._get_data(self, data_type, &payload_size, @ptrCast(&payload))) { |
| 73 | .success => return payload, |
| 74 | .invalid_parameter => return error.InvalidParameter, |
| 75 | .buffer_too_small => return error.BufferTooSmall, |
| 76 | .not_ready => return error.NotReady, |
| 77 | .not_found => return error.NotFound, |
| 78 | else => |status| return uefi.unexpectedStatus(status), |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | pub fn registerDataNotify( |
| 83 | self: *const Ip6Config, |
| 84 | data_type: DataType, |
| 85 | event: Event, |
| 86 | ) RegisterDataNotifyError!void { |
| 87 | switch (self._register_data_notify(self, data_type, event)) { |
| 88 | .success => {}, |
| 89 | .invalid_parameter => return error.InvalidParameter, |
| 90 | .unsupported => return error.Unsupported, |
| 91 | .out_of_resources => return error.OutOfResources, |
| 92 | .access_denied => return error.AccessDenied, |
| 93 | else => |status| return uefi.unexpectedStatus(status), |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | pub fn unregisterDataNotify( |
| 98 | self: *const Ip6Config, |
| 99 | data_type: DataType, |
| 100 | event: Event, |
| 101 | ) UnregisterDataNotifyError!void { |
| 102 | switch (self._unregister_data_notify(self, data_type, event)) { |
| 103 | .success => {}, |
| 104 | .invalid_parameter => return error.InvalidParameter, |
| 105 | .not_found => return error.NotFound, |
| 106 | else => |status| return uefi.unexpectedStatus(status), |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | pub const guid align(8) = Guid{ |
| 111 | .time_low = 0x937fe521, |
| 112 | .time_mid = 0x95ae, |
| 113 | .time_high_and_version = 0x4d1a, |
| 114 | .clock_seq_high_and_reserved = 0x89, |
| 115 | .clock_seq_low = 0x29, |
| 116 | .node = [_]u8{ 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a }, |
| 117 | }; |
| 118 | |
| 119 | pub const DataType = union(enum(u32)) { |
| 120 | interface_info: InterfaceInfo, |
| 121 | alt_interface_id: InterfaceId, |
| 122 | policy: Policy, |
| 123 | dup_addr_detect_transmits: DupAddrDetectTransmits, |
| 124 | manual_address: [*]ManualAddress, |
| 125 | gateway: [*]Ip6.Address, |
| 126 | dns_server: [*]Ip6.Address, |
| 127 | }; |
| 128 | |
| 129 | pub const InterfaceInfo = extern struct { |
| 130 | name: [32]u16, |
| 131 | if_type: u8, |
| 132 | hw_address_size: u32, |
| 133 | hw_address: MacAddress, |
| 134 | address_info_count: u32, |
| 135 | address_info: [*]Ip6.AddressInfo, |
| 136 | route_count: u32, |
| 137 | route_table: Ip6.RouteTable, |
| 138 | }; |
| 139 | |
| 140 | pub const InterfaceId = extern struct { |
| 141 | id: [8]u8, |
| 142 | }; |
| 143 | |
| 144 | pub const Policy = enum(u32) { |
| 145 | manual, |
| 146 | automatic, |
| 147 | }; |
| 148 | |
| 149 | pub const DupAddrDetectTransmits = extern struct { |
| 150 | dup_addr_detect_transmits: u32, |
| 151 | }; |
| 152 | |
| 153 | pub const ManualAddress = extern struct { |
| 154 | address: Ip6.Address, |
| 155 | is_anycast: bool, |
| 156 | prefix_length: u8, |
| 157 | }; |
| 158 | }; |