hyperv_ic_protocol/
kvp.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Protocol definitions for the KVP (Key-Value Pair) protocol.
5
6use crate::Version;
7use guid::Guid;
8use open_enum::open_enum;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13
14/// The VMBus KVP channel interface GUID.
15pub const INTERFACE_ID: Guid = guid::guid!("a9a0f4e7-5a45-4d96-b827-8a841e8c03e6");
16/// The VMBus KVP channel instance GUID.
17pub const INSTANCE_ID: Guid = guid::guid!("242ff919-07db-4180-9c2e-b86cb68c8c55");
18
19/// Version 3.0.
20pub const KVP_VERSION_3: Version = Version::new(3, 0);
21/// Version 4.0.
22pub const KVP_VERSION_4: Version = Version::new(4, 0);
23/// Version 5.0.
24pub const KVP_VERSION_5: Version = Version::new(5, 0);
25
26/// The header for KVP messages.
27#[repr(C)]
28#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
29pub struct KvpHeader {
30    /// The operation to perform.
31    pub operation: KvpOperation,
32    /// The pool to use.
33    pub pool: KvpPool,
34}
35
36open_enum! {
37    /// The operation to perform.
38    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
39    pub enum KvpOperation: u8 {
40        /// Get a value.
41        GET = 0,
42        /// Set a value.
43        SET = 1,
44        /// Delete a value.
45        DELETE = 2,
46        /// Enumerate values.
47        ENUMERATE = 3,
48        /// Get IP address information.
49        GET_IP_ADDRESS_INFO = 4,
50        /// Set IP address information.
51        SET_IP_ADDRESS_INFO = 5,
52    }
53}
54
55open_enum! {
56    /// The pool to use for a value.
57    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
58    pub enum KvpPool: u8 {
59        #![allow(missing_docs)] // TODO: figure out what the semantics of these actually are.
60        EXTERNAL = 0,
61        GUEST = 1,
62        AUTO = 2,
63        AUTO_EXTERNAL = 3,
64        // There is an "internal" pool defined in some places, but this is never
65        // exchanged between host and guest.
66    }
67}
68
69/// The maximum key size, in bytes.
70pub const MAX_KEY_BYTES: usize = 512;
71/// The maximum value size, in bytes.
72pub const MAX_VALUE_BYTES: usize = 2048;
73
74/// A value request or response.
75#[repr(C)]
76#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
77pub struct Value {
78    /// The type of the value.
79    pub value_type: ValueType,
80    /// The size of the key, in bytes (including the null terminator).
81    pub key_size: u32,
82    /// The size of the value, in bytes.
83    pub value_size: u32,
84    /// The key, as a null-terminated UTF-16 string.
85    pub key: [u16; MAX_KEY_BYTES / 2],
86    /// The value.
87    pub value: [u8; MAX_VALUE_BYTES],
88}
89
90open_enum! {
91    /// The type of the value.
92    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
93    pub enum ValueType: u32 {
94        /// A UTF-16 string.
95        STRING = 1,         // REG_SZ
96        /// A UTF-16 string, with environment variables expanded.
97        EXPAND_STRING = 2,  // REG_EXPAND_SZ
98        /// A 32-bit integer.
99        DWORD = 4,          // REG_DWORD
100        /// A 64-bit integer.
101        QWORD = 11,         // REG_QWORD
102    }
103}
104
105/// A message to get or set a key-value pair.
106#[repr(C)]
107#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
108pub struct MessageGetSet {
109    /// The value.
110    pub value: Value,
111}
112
113/// A message to delete a key-value pair.
114#[repr(C)]
115#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
116pub struct MessageDelete {
117    /// The size of the key, in bytes (including the null terminator).
118    pub key_size: u32,
119    /// The key, as a null-terminated UTF-16 string.
120    pub key: [u16; MAX_KEY_BYTES / 2],
121}
122
123/// A message to enumerate key-value pairs.
124#[repr(C)]
125#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
126pub struct MessageEnumerate {
127    /// The index of the enumeration.
128    pub index: u32,
129    /// The value.
130    pub value: Value,
131}
132
133/// A get, set, enumerate, or delete message.
134#[repr(C)]
135#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
136pub struct KvpMessage {
137    /// The header.
138    pub header: KvpHeader,
139    /// The body of the message. The actual message may start
140    /// at a different offset, depending on alignment.
141    pub data: [u8; 2578],
142}
143
144/// The message for exchanging IP address information.
145#[repr(C)]
146#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
147pub struct KvpMessage2 {
148    /// The message header.
149    pub header: KvpHeader,
150    /// The body of the message. The actual message may start
151    /// at a different offset, depending on alignment.
152    pub data: [u8; 0x1d02],
153}
154
155/// IP address information, in UTF-16 string form.
156#[repr(C)]
157#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
158pub struct MessageIpAddressInfo {
159    /// The adapter ID, as a null-terminated UTF-16 string.
160    pub adapter_id: [u16; 128],
161    /// The protocols this message applies to.
162    pub address_family: AddressFamily,
163    /// Whether DHCP is enabled for the adapter.
164    pub dhcp_enabled: u8,
165    /// The IP addresses, as a semicolon-delimited, null-terminated UTF-16 string.
166    pub ip_address: [u16; 1024],
167    /// The subnets, as a semicolon-delimited, null-terminated UTF-16 string.
168    pub subnet: [u16; 1024],
169    /// The gateways, as a semicolon-delimited, null-terminated UTF-16 string.
170    pub gateway: [u16; 512],
171    /// The DNS server addresses, as a semicolon-delimited, null-terminated
172    /// UTF-16 string.
173    pub dns_server_addresses: [u16; 1024],
174}
175
176open_enum! {
177    /// The address family of a network protocol, for specifying the scope of a request.
178    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
179    pub enum AddressFamily: u8 {
180        /// No protocol.
181        NONE = 0,
182        /// IPv4.
183        IPV4 = 1,
184        /// IPv6.
185        IPV6 = 2,
186        /// Both IPv4 and IPv6.
187        IPV4V6 = 3,
188    }
189}
190
191/// IP address information, in binary form.
192#[repr(C)]
193#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
194pub struct MessageIpAddressInfoBinary {
195    /// The number of IPv4 addresses.
196    pub ipv4_address_count: u32,
197    /// The number of IPv6 addresses.
198    pub ipv6_address_count: u32,
199    /// The number of IPv4 subnets.
200    pub ipv4_gateway_count: u32,
201    /// The number of IPv6 subnets.
202    pub ipv6_gateway_count: u32,
203    /// The number of IPv4 gateways.
204    pub ipv4_dns_server_count: u32,
205    /// The number of IPv6 gateways.
206    pub ipv6_dns_server_count: u32,
207    /// The adapter ID, as a null-terminated UTF-16 string.
208    pub adapter_id: [u16; 128],
209    /// The protocols this message applies to.
210    pub address_family: AddressFamily,
211    /// Whether DHCP is enabled for the adapter.
212    pub dhcp_enabled: u8,
213    /// Zero padding.
214    pub padding: u16,
215    /// The IPv4 addresses.
216    pub ipv4_addresses: [IpAddressV4; 64],
217    /// The IPv6 addresses.
218    pub ipv6_addresses: [IpAddressV6; 64],
219    /// The IPv4 subnets.
220    pub ipv4_subnets: [IpAddressV4; 64],
221    /// The IPv6 subnets.
222    pub ipv6_subnets: [u32; 64],
223    /// The IPv4 gateways.
224    pub ipv4_gateways: [IpAddressV4; 5],
225    /// The IPv6 gateways.
226    pub ipv6_gateways: [IpAddressV6; 5],
227    /// The IPv4 DNS servers.
228    pub ipv4_dns_servers: [IpAddressV4; 64],
229    /// The IPv6 DNS servers.
230    pub ipv6_dns_servers: [IpAddressV6; 64],
231    /// The IPv4 and IPv6 address origins. This is flattened into a single
232    /// array, without gaps between the IPv4 and IPv6 addresses.
233    pub ip_address_origins: [IpAddressOrigin; 128],
234}
235
236open_enum! {
237    /// The origin of an IP address.
238    #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
239    pub enum IpAddressOrigin: u16 {
240        /// Unknown origin.
241        UNKNOWN = 0,
242        /// Non-static assignment (probably DHCP).
243        OTHER = 1,
244        /// Static assignment.
245        STATIC = 2,
246    }
247}
248
249/// An IPv4 address, encoded as four octets in network byte order.
250#[repr(C)]
251#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
252pub struct IpAddressV4(pub [u8; 4]);
253
254/// An IPv6 address, encoded as sixteen octets in network byte order.
255#[repr(C)]
256#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
257pub struct IpAddressV6(pub [u8; 16]);