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