1const std = @import("std");
2const uefi = std.os.uefi;
3const Guid = uefi.Guid;
4const Event = uefi.Event;
5const Status = uefi.Status;
6const cc = uefi.cc;
7const MacAddress = uefi.MacAddress;
8const Ip6 = uefi.protocol.Ip6;
9
10pub 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};