Skip to content

uefi-raw: Add HttpProtocol, Ip4Config2Protocol, and TlsConfigurationProtocol #1021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## Added
- Added `Ipv4Address`, `Ipv6Address`, and `MacAddress` types.
- Added `ServiceBindingProtocol` and `Dhcp4Protocol`.
- Added `ServiceBindingProtocol`, `Dhcp4Protocol`, `HttpProtocol`,
`Ip4Config2Protocol`, `TlsConfigurationProtocol`, and related types.

# uefi-raw - 0.5.0 (2023-11-12)

Expand Down
180 changes: 180 additions & 0 deletions uefi-raw/src/protocol/network/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
use crate::{guid, Char16, Char8, Event, Guid, Ipv4Address, Ipv6Address, Status};
use core::ffi::c_void;
use core::fmt::{self, Debug, Formatter};

#[derive(Debug)]
#[repr(C)]
pub struct HttpConfigData {
pub http_version: HttpVersion,
pub time_out_millisec: u32,
pub local_addr_is_ipv6: bool,
pub access_point: HttpAccessPoint,
}

newtype_enum! {
pub enum HttpVersion: i32 => {
HTTP_VERSION_10 = 0,
HTTP_VERSION_11 = 1,
HTTP_VERSION_UNSUPPORTED = 2,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpV4AccessPoint {
pub use_default_addr: bool,
pub local_address: Ipv4Address,
pub local_subnet: Ipv4Address,
pub local_port: u16,
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpV6AccessPoint {
pub local_address: Ipv6Address,
pub local_port: u16,
}

#[repr(C)]
pub union HttpAccessPoint {
pub ipv4_node: *const HttpV4AccessPoint,
pub ipv6_node: *const HttpV6AccessPoint,
}

impl Debug for HttpAccessPoint {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// This is a union type, so we can't access the internal data.
f.debug_struct("HttpAccessPoint").finish()
}
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpToken {
pub event: Event,
pub status: Status,
pub message: *mut HttpMessage,
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpMessage {
pub data: HttpRequestOrResponse,
pub header_count: usize,
pub header: *mut HttpHeader,
pub body_length: usize,
pub body: *mut c_void,
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpRequestData {
pub method: HttpMethod,
pub url: *const Char16,
}

newtype_enum! {
pub enum HttpMethod: i32 => {
GET = 0,
POST = 1,
PATCH = 2,
OPTIONS = 3,
CONNECT = 4,
HEAD = 5,
PUT = 6,
DELETE = 7,
TRACE = 8,
MAX = 9,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpResponseData {
pub status_code: HttpStatusCode,
}

#[repr(C)]
pub union HttpRequestOrResponse {
pub request: *const HttpRequestData,
pub response: *const HttpResponseData,
}

impl Debug for HttpRequestOrResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// This is a union type, so we can't access the internal data.
f.debug_struct("RequestOrResponse").finish()
}
}

#[derive(Clone, Debug)]
#[repr(C)]
pub struct HttpHeader {
pub field_name: *const Char8,
pub field_value: *const Char8,
}

newtype_enum! {
pub enum HttpStatusCode: i32 => {
STATUS_UNSUPPORTED = 0,
STATUS_100_CONTINUE = 1,
STATUS_101_SWITCHING_PROTOCOLS = 2,
STATUS_200_OK = 3,
STATUS_201_CREATED = 4,
STATUS_202_ACCEPTED = 5,
STATUS_203_NON_AUTHORITATIVE_INFORMATION = 6,
STATUS_204_NO_CONTENT = 7,
STATUS_205_RESET_CONTENT = 8,
STATUS_206_PARTIAL_CONTENT = 9,
STATUS_300_MULTIPLE_CHOICES = 10,
STATUS_301_MOVED_PERMANENTLY = 11,
STATUS_302_FOUND = 12,
STATUS_303_SEE_OTHER = 13,
STATUS_304_NOT_MODIFIED = 14,
STATUS_305_USE_PROXY = 15,
STATUS_307_TEMPORARY_REDIRECT = 16,
STATUS_400_BAD_REQUEST = 17,
STATUS_401_UNAUTHORIZED = 18,
STATUS_402_PAYMENT_REQUIRED = 19,
STATUS_403_FORBIDDEN = 20,
STATUS_404_NOT_FOUND = 21,
STATUS_405_METHOD_NOT_ALLOWED = 22,
STATUS_406_NOT_ACCEPTABLE = 23,
STATUS_407_PROXY_AUTHENTICATION_REQUIRED = 24,
STATUS_408_REQUEST_TIME_OUT = 25,
STATUS_409_CONFLICT = 26,
STATUS_410_GONE = 27,
STATUS_411_LENGTH_REQUIRED = 28,
STATUS_412_PRECONDITION_FAILED = 29,
STATUS_413_REQUEST_ENTITY_TOO_LARGE = 30,
STATUS_414_REQUEST_URI_TOO_LARGE = 31,
STATUS_415_UNSUPPORTED_MEDIA_TYPE = 32,
STATUS_416_REQUESTED_RANGE_NOT_SATISFIED = 33,
STATUS_417_EXPECTATION_FAILED = 34,
STATUS_500_INTERNAL_SERVER_ERROR = 35,
STATUS_501_NOT_IMPLEMENTED = 36,
STATUS_502_BAD_GATEWAY = 37,
STATUS_503_SERVICE_UNAVAILABLE = 38,
STATUS_504_GATEWAY_TIME_OUT = 39,
STATUS_505_VERSION_NOT_SUPPORTED = 40,
STATUS_308_PERMANENT_REDIRECT = 41,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct HttpProtocol {
pub get_mode_data:
unsafe extern "efiapi" fn(this: *const Self, config_data: *mut HttpConfigData) -> Status,
pub configure:
unsafe extern "efiapi" fn(this: *mut Self, config_data: *const HttpConfigData) -> Status,
pub request: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
pub cancel: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
pub response: unsafe extern "efiapi" fn(this: *mut Self, token: *mut HttpToken) -> Status,
pub poll: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
}

impl HttpProtocol {
pub const GUID: Guid = guid!("7a59b29b-910b-4171-8242-a85a0df25b5b");
pub const SERVICE_BINDING_GUID: Guid = guid!("bdc8e6af-d9bc-4379-a72a-e0c4e75dae1c");
}
9 changes: 9 additions & 0 deletions uefi-raw/src/protocol/network/ip4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::Ipv4Address;

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(C)]
pub struct Ip4RouteTable {
pub subnet_addr: Ipv4Address,
pub subnet_mask: Ipv4Address,
pub gateway_addr: Ipv4Address,
}
76 changes: 76 additions & 0 deletions uefi-raw/src/protocol/network/ip4_config2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::protocol::network::ip4::Ip4RouteTable;
use crate::{guid, Char16, Event, Guid, Ipv4Address, MacAddress, Status};
use core::ffi::c_void;

newtype_enum! {
pub enum Ip4Config2DataType: i32 => {
INTERFACE_INFO = 0,
POLICY = 1,
MANUAL_ADDRESS = 2,
GATEWAY = 3,
DNS_SERVER = 4,
MAXIMUM = 5,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct Ip4Config2InterfaceInfo {
pub name: [Char16; 32],
pub if_type: u8,
pub hw_addr_size: u32,
pub hw_addr: MacAddress,
pub station_addr: Ipv4Address,
pub subnet_mask: Ipv4Address,
pub route_table_size: u32,
pub route_table: *mut Ip4RouteTable,
}

newtype_enum! {
pub enum Ip4Config2Policy: i32 => {
STATIC = 0,
DHCP = 1,
MAX = 2,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct Ip4Config2ManualAddress {
pub address: Ipv4Address,
pub subnet_mask: Ipv4Address,
}

#[derive(Debug)]
#[repr(C)]
pub struct Ip4Config2Protocol {
pub set_data: unsafe extern "efiapi" fn(
this: *mut Self,
data_type: Ip4Config2DataType,
data_size: usize,
data: *const c_void,
) -> Status,

pub get_data: unsafe extern "efiapi" fn(
this: *mut Self,
data_type: Ip4Config2DataType,
data_size: *mut usize,
data: *mut c_void,
) -> Status,

pub register_data_notify: unsafe extern "efiapi" fn(
this: *mut Self,
data_type: Ip4Config2DataType,
event: Event,
) -> Status,

pub unregister_data_notify: unsafe extern "efiapi" fn(
this: *mut Self,
data_type: Ip4Config2DataType,
event: Event,
) -> Status,
}

impl Ip4Config2Protocol {
pub const GUID: Guid = guid!("5b446ed1-e30b-4faa-871a-3654eca36080");
}
4 changes: 4 additions & 0 deletions uefi-raw/src/protocol/network/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
pub mod dhcp4;
pub mod http;
pub mod ip4;
pub mod ip4_config2;
pub mod tls;
35 changes: 35 additions & 0 deletions uefi-raw/src/protocol/network/tls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::{guid, Guid, Status};
use core::ffi::c_void;

newtype_enum! {
pub enum TlsConfigDataType: i32 => {
HOST_PUBLIC_CERT = 0,
HOST_PRIVATE_KEY = 1,
CA_CERTIFICATE = 2,
CERT_REVOCATION_LIST = 3,
MAXIMUM = 4,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct TlsConfigurationProtocol {
pub set_data: unsafe extern "efiapi" fn(
this: *mut Self,
typ: TlsConfigDataType,
data: *const c_void,
size: usize,
) -> Status,

pub get_data: unsafe extern "efiapi" fn(
this: *const Self,
typ: TlsConfigDataType,
data: *mut c_void,
size: *mut usize,
) -> Status,
}

impl TlsConfigurationProtocol {
pub const GUID: Guid = guid!("1682fe44-bd7a-4407-b7c7-dca37ca3922d");
pub const SERVICE_BINDING_GUID: Guid = guid!("952cb795-ff36-48cf-a249-4df486d6ab8d");
}