master
1const std = @import("std");
2const uefi = std.os.uefi;
3const Guid = uefi.Guid;
4const Event = uefi.Event;
5const Status = uefi.Status;
6const MacAddress = uefi.MacAddress;
7const ManagedNetworkConfigData = uefi.protocol.ManagedNetwork.Config;
8const SimpleNetwork = uefi.protocol.SimpleNetwork;
9const cc = uefi.cc;
10const Error = Status.Error;
11
12pub const Ip6 = extern struct {
13 _get_mode_data: *const fn (*const Ip6, ?*Mode, ?*ManagedNetworkConfigData, ?*SimpleNetwork) callconv(cc) Status,
14 _configure: *const fn (*Ip6, ?*const Config) callconv(cc) Status,
15 _groups: *const fn (*Ip6, bool, ?*const Address) callconv(cc) Status,
16 _routes: *const fn (*Ip6, bool, ?*const Address, u8, ?*const Address) callconv(cc) Status,
17 _neighbors: *const fn (*Ip6, bool, *const Address, ?*const MacAddress, u32, bool) callconv(cc) Status,
18 _transmit: *const fn (*Ip6, *CompletionToken) callconv(cc) Status,
19 _receive: *const fn (*Ip6, *CompletionToken) callconv(cc) Status,
20 _cancel: *const fn (*Ip6, ?*CompletionToken) callconv(cc) Status,
21 _poll: *const fn (*Ip6) callconv(cc) Status,
22
23 pub const GetModeDataError = uefi.UnexpectedError || error{
24 InvalidParameter,
25 OutOfResources,
26 };
27 pub const ConfigureError = uefi.UnexpectedError || error{
28 InvalidParameter,
29 OutOfResources,
30 NoMapping,
31 AlreadyStarted,
32 DeviceError,
33 Unsupported,
34 };
35 pub const GroupsError = uefi.UnexpectedError || error{
36 InvalidParameter,
37 NotStarted,
38 OutOfResources,
39 Unsupported,
40 AlreadyStarted,
41 NotFound,
42 DeviceError,
43 };
44 pub const RoutesError = uefi.UnexpectedError || error{
45 NotStarted,
46 InvalidParameter,
47 OutOfResources,
48 NotFound,
49 AccessDenied,
50 };
51 pub const NeighborsError = uefi.UnexpectedError || error{
52 NotStarted,
53 InvalidParameter,
54 OutOfResources,
55 NotFound,
56 AccessDenied,
57 };
58 pub const TransmitError = uefi.UnexpectedError || error{
59 NotStarted,
60 NoMapping,
61 InvalidParameter,
62 AccessDenied,
63 NotReady,
64 NotFound,
65 OutOfResources,
66 BufferTooSmall,
67 BadBufferSize,
68 DeviceError,
69 NoMedia,
70 };
71 pub const ReceiveError = uefi.UnexpectedError || error{
72 NotStarted,
73 NoMapping,
74 InvalidParameter,
75 OutOfResources,
76 DeviceError,
77 AccessDenied,
78 NotReady,
79 NoMedia,
80 };
81 pub const CancelError = uefi.UnexpectedError || error{
82 InvalidParameter,
83 NotStarted,
84 NotFound,
85 DeviceError,
86 };
87 pub const PollError = uefi.UnexpectedError || error{
88 NotStarted,
89 InvalidParameter,
90 DeviceError,
91 Timeout,
92 };
93
94 pub const ModeData = struct {
95 ip6_mode: Mode,
96 mnp_config: ManagedNetworkConfigData,
97 snp_mode: SimpleNetwork,
98 };
99
100 /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
101 pub fn getModeData(self: *const Ip6) GetModeDataError!ModeData {
102 var data: ModeData = undefined;
103 switch (self._get_mode_data(self, &data.ip6_mode, &data.mnp_config, &data.snp_mode)) {
104 .success => return data,
105 .invalid_parameter => return Error.InvalidParameter,
106 .out_of_resources => return Error.OutOfResources,
107 else => |status| return uefi.unexpectedStatus(status),
108 }
109 }
110
111 /// Assign IPv6 address and other configuration parameter to this EFI IPv6 Protocol driver instance.
112 ///
113 /// To reset the configuration, use `disable` instead.
114 pub fn configure(self: *Ip6, ip6_config_data: *const Config) ConfigureError!void {
115 switch (self._configure(self, ip6_config_data)) {
116 .success => {},
117 .invalid_parameter => return Error.InvalidParameter,
118 .out_of_resources => return Error.OutOfResources,
119 .no_mapping => return Error.NoMapping,
120 .already_started => return Error.AlreadyStarted,
121 .device_error => return Error.DeviceError,
122 .unsupported => return Error.Unsupported,
123 else => |status| return uefi.unexpectedStatus(status),
124 }
125 }
126
127 pub fn disable(self: *Ip6) ConfigureError!void {
128 switch (self._configure(self, null)) {
129 .success => {},
130 .invalid_parameter => return Error.InvalidParameter,
131 .out_of_resources => return Error.OutOfResources,
132 .no_mapping => return Error.NoMapping,
133 .already_started => return Error.AlreadyStarted,
134 .device_error => return Error.DeviceError,
135 .unsupported => return Error.Unsupported,
136 else => |status| return uefi.unexpectedStatus(status),
137 }
138 }
139
140 pub fn leaveAllGroups(self: *Ip6) GroupsError!void {
141 switch (self._groups(self, false, null)) {
142 .success => {},
143 .invalid_parameter => return Error.InvalidParameter,
144 .not_started => return Error.NotStarted,
145 .out_of_resources => return Error.OutOfResources,
146 .unsupported => return Error.Unsupported,
147 .already_started => return Error.AlreadyStarted,
148 .not_found => return Error.NotFound,
149 .device_error => return Error.DeviceError,
150 else => |status| return uefi.unexpectedStatus(status),
151 }
152 }
153
154 /// Joins and leaves multicast groups.
155 ///
156 /// To leave all groups, use `leaveAllGroups` instead.
157 pub fn groups(
158 self: *Ip6,
159 join_flag: JoinFlag,
160 group_address: *const Address,
161 ) GroupsError!void {
162 switch (self._groups(
163 self,
164 // set to TRUE to join the multicast group session and FALSE to leave
165 join_flag == .join,
166 group_address,
167 )) {
168 .success => {},
169 .invalid_parameter => return Error.InvalidParameter,
170 .not_started => return Error.NotStarted,
171 .out_of_resources => return Error.OutOfResources,
172 .unsupported => return Error.Unsupported,
173 .already_started => return Error.AlreadyStarted,
174 .not_found => return Error.NotFound,
175 .device_error => return Error.DeviceError,
176 else => |status| return uefi.unexpectedStatus(status),
177 }
178 }
179
180 /// Adds and deletes routing table entries.
181 pub fn routes(
182 self: *Ip6,
183 delete_route: DeleteFlag,
184 destination: ?*const Address,
185 prefix_length: u8,
186 gateway_address: ?*const Address,
187 ) RoutesError!void {
188 switch (self._routes(
189 self,
190 delete_route == .delete,
191 destination,
192 prefix_length,
193 gateway_address,
194 )) {
195 .success => {},
196 .not_started => return Error.NotStarted,
197 .invalid_parameter => return Error.InvalidParameter,
198 .out_of_resources => return Error.OutOfResources,
199 .not_found => return Error.NotFound,
200 .access_denied => return Error.AccessDenied,
201 else => |status| return uefi.unexpectedStatus(status),
202 }
203 }
204
205 /// Add or delete Neighbor cache entries.
206 pub fn neighbors(
207 self: *Ip6,
208 delete_flag: DeleteFlag,
209 target_ip6_address: *const Address,
210 target_link_address: ?*const MacAddress,
211 timeout: u32,
212 override: bool,
213 ) NeighborsError!void {
214 switch (self._neighbors(
215 self,
216 // set to TRUE to delete this route from the routing table.
217 // set to FALSE to add this route to the routing table.
218 delete_flag == .delete,
219 target_ip6_address,
220 target_link_address,
221 timeout,
222 override,
223 )) {
224 .success => {},
225 .not_started => return Error.NotStarted,
226 .invalid_parameter => return Error.InvalidParameter,
227 .out_of_resources => return Error.OutOfResources,
228 .not_found => return Error.NotFound,
229 .access_denied => return Error.AccessDenied,
230 else => |status| return uefi.unexpectedStatus(status),
231 }
232 }
233
234 /// Places outgoing data packets into the transmit queue.
235 pub fn transmit(self: *Ip6, token: *CompletionToken) TransmitError!void {
236 switch (self._transmit(self, token)) {
237 .success => {},
238 .not_started => return Error.NotStarted,
239 .no_mapping => return Error.NoMapping,
240 .invalid_parameter => return Error.InvalidParameter,
241 .access_denied => return Error.AccessDenied,
242 .not_ready => return Error.NotReady,
243 .not_found => return Error.NotFound,
244 .out_of_resources => return Error.OutOfResources,
245 .buffer_too_small => return Error.BufferTooSmall,
246 .bad_buffer_size => return Error.BadBufferSize,
247 .device_error => return Error.DeviceError,
248 .no_media => return Error.NoMedia,
249 else => |status| return uefi.unexpectedStatus(status),
250 }
251 }
252
253 /// Places a receiving request into the receiving queue.
254 pub fn receive(self: *Ip6, token: *CompletionToken) ReceiveError!void {
255 switch (self._receive(self, token)) {
256 .success => {},
257 .not_started => return Error.NotStarted,
258 .no_mapping => return Error.NoMapping,
259 .invalid_parameter => return Error.InvalidParameter,
260 .out_of_resources => return Error.OutOfResources,
261 .device_error => return Error.DeviceError,
262 .access_denied => return Error.AccessDenied,
263 .not_ready => return Error.NotReady,
264 .no_media => return Error.NoMedia,
265 else => |status| return uefi.unexpectedStatus(status),
266 }
267 }
268
269 /// Abort an asynchronous transmits or receive request.
270 pub fn cancel(self: *Ip6, token: ?*CompletionToken) CancelError!void {
271 switch (self._cancel(self, token)) {
272 .success => {},
273 .invalid_parameter => return Error.InvalidParameter,
274 .not_started => return Error.NotStarted,
275 .not_found => return Error.NotFound,
276 .device_error => return Error.DeviceError,
277 else => |status| return uefi.unexpectedStatus(status),
278 }
279 }
280
281 /// Polls for incoming data packets and processes outgoing data packets.
282 ///
283 /// Returns true if a packet was received or processed.
284 pub fn poll(self: *Ip6) PollError!bool {
285 switch (self._poll(self)) {
286 .success => return true,
287 .not_ready => return false,
288 .not_started => return Error.NotStarted,
289 .invalid_parameter => return Error.InvalidParameter,
290 .device_error => return Error.DeviceError,
291 .timeout => return Error.Timeout,
292 else => |status| return uefi.unexpectedStatus(status),
293 }
294 }
295
296 pub const guid align(8) = Guid{
297 .time_low = 0x2c8759d5,
298 .time_mid = 0x5c2d,
299 .time_high_and_version = 0x66ef,
300 .clock_seq_high_and_reserved = 0x92,
301 .clock_seq_low = 0x5f,
302 .node = [_]u8{ 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 },
303 };
304
305 pub const DeleteFlag = enum {
306 delete,
307 add,
308 };
309
310 pub const JoinFlag = enum {
311 join,
312 leave,
313 };
314
315 pub const Mode = extern struct {
316 is_started: bool,
317 max_packet_size: u32,
318 config_data: Config,
319 is_configured: bool,
320 address_count: u32,
321 address_list: [*]AddressInfo,
322 group_count: u32,
323 group_table: [*]Address,
324 route_count: u32,
325 route_table: [*]RouteTable,
326 neighbor_count: u32,
327 neighbor_cache: [*]NeighborCache,
328 prefix_count: u32,
329 prefix_table: [*]AddressInfo,
330 icmp_type_count: u32,
331 icmp_type_list: [*]IcmpType,
332 };
333
334 pub const Config = extern struct {
335 default_protocol: u8,
336 accept_any_protocol: bool,
337 accept_icmp_errors: bool,
338 accept_promiscuous: bool,
339 destination_address: Address,
340 station_address: Address,
341 traffic_class: u8,
342 hop_limit: u8,
343 flow_label: u32,
344 receive_timeout: u32,
345 transmit_timeout: u32,
346 };
347
348 pub const Address = [16]u8;
349
350 pub const AddressInfo = extern struct {
351 address: Address,
352 prefix_length: u8,
353 };
354
355 pub const RouteTable = extern struct {
356 gateway: Address,
357 destination: Address,
358 prefix_length: u8,
359 };
360
361 pub const NeighborState = enum(u32) {
362 incomplete,
363 reachable,
364 stale,
365 delay,
366 probe,
367 };
368
369 pub const NeighborCache = extern struct {
370 neighbor: Address,
371 link_address: MacAddress,
372 state: NeighborState,
373 };
374
375 pub const IcmpType = extern struct {
376 type: u8,
377 code: u8,
378 };
379
380 pub const CompletionToken = extern struct {
381 event: Event,
382 status: Status,
383 packet: *anyopaque, // union TODO
384 };
385};