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]);