mirror of
https://github.com/apple/container.git
synced 2026-09-27 10:05:42 +00:00
Move Bindable to ContainerizationExtras, fix binding bugs. (#481)
- Bindable is generally useful, so it makes sense to move it out of the netlink library. Removed Equatable conformance from Bindable as this isn't generally necessary (it's only used for unit tests in netlink). - Fix some offset checks in a couple data binding functions and improve the unit tests.
This commit is contained in:
@@ -18,11 +18,31 @@
|
||||
public struct IPv4Address: Sendable, Hashable, CustomStringConvertible, Equatable, Comparable {
|
||||
public let value: UInt32
|
||||
|
||||
/// Creates an IPv4Address from an unsigned integer.
|
||||
///
|
||||
/// - Parameter string: The integer representation of the address.
|
||||
@inlinable
|
||||
public init(_ value: UInt32) {
|
||||
self.value = value
|
||||
}
|
||||
|
||||
/// Creates an IPv4Address from 4 bytes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - bytes: 4-byte array in network byte order representing the IPv4 address
|
||||
/// - Throws: `AddressError.unableToParse` if the byte array length is not 4
|
||||
@inlinable
|
||||
public init(_ bytes: [UInt8]) throws {
|
||||
guard bytes.count == 4 else {
|
||||
throw AddressError.unableToParse
|
||||
}
|
||||
self.value =
|
||||
(UInt32(bytes[0]) << 24)
|
||||
| (UInt32(bytes[1]) << 16)
|
||||
| (UInt32(bytes[2]) << 16)
|
||||
| UInt32(bytes[3])
|
||||
}
|
||||
|
||||
/// Creates an IPv4Address from a string representation.
|
||||
///
|
||||
/// - Parameter string: The IPv4 address string in dotted decimal notation (e.g., "192.168.1.1")
|
||||
|
||||
@@ -71,12 +71,12 @@ extension IPv6Address {
|
||||
if remainingAddress.isEmpty {
|
||||
// If we have IPv4 suffix, ipBytes already has the IPv4 data, just return
|
||||
if hasIPv4Suffix {
|
||||
return Self(ipBytes, zone: zone)
|
||||
return try Self(ipBytes, zone: zone)
|
||||
}
|
||||
|
||||
// Pure "::" - Return the unspecified address, handling zone identifiers
|
||||
if let zone = zone, !zone.isEmpty {
|
||||
return Self(ipBytes, zone: zone)
|
||||
return try Self(ipBytes, zone: zone)
|
||||
}
|
||||
return .unspecified
|
||||
}
|
||||
|
||||
@@ -33,11 +33,14 @@ public struct IPv6Address: Sendable, Hashable, CustomStringConvertible, Equatabl
|
||||
/// Creates an IPv6Address from 16 bytes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - bytes: 16-byte array representing the IPv6 address
|
||||
/// - bytes: 16-byte array in network byte order representing the IPv6 address
|
||||
/// - zone: Optional zone identifier (e.g., "eth0")
|
||||
/// - Throws: `AddressError.unableToParse` if the byte array length is not 16
|
||||
@inlinable
|
||||
public init(_ bytes: [UInt8], zone: String? = nil) {
|
||||
precondition(bytes.count == 16, "IPv6 address must be exactly 16 bytes")
|
||||
public init(_ bytes: [UInt8], zone: String? = nil) throws {
|
||||
guard bytes.count == 16 else {
|
||||
throw AddressError.unableToParse
|
||||
}
|
||||
|
||||
// Build UInt128 value in chunks to avoid compiler complexity
|
||||
let hh =
|
||||
|
||||
@@ -30,6 +30,25 @@ public struct MACAddress: Sendable, Hashable, CustomStringConvertible, Equatable
|
||||
self.value = value & 0x0000_ffff_ffff_ffff
|
||||
}
|
||||
|
||||
/// Creates an IPv4Address from 6 bytes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - bytes: 6-byte array in network byte order representing the IPv4 address
|
||||
/// - Throws: `AddressError.unableToParse` if the byte array length is not 6
|
||||
@inlinable
|
||||
public init(_ bytes: [UInt8]) throws {
|
||||
guard bytes.count == 6 else {
|
||||
throw AddressError.unableToParse
|
||||
}
|
||||
self.value =
|
||||
(UInt64(bytes[0]) << 40)
|
||||
| (UInt64(bytes[1]) << 32)
|
||||
| (UInt64(bytes[2]) << 24)
|
||||
| (UInt64(bytes[3]) << 16)
|
||||
| (UInt64(bytes[4]) << 8)
|
||||
| UInt64(bytes[5])
|
||||
}
|
||||
|
||||
/// Creates an MACAddress from a string representation.
|
||||
///
|
||||
/// - Parameter string: The MAC address string with colon or dash delimiters.
|
||||
@@ -225,9 +244,9 @@ public struct MACAddress: Sendable, Hashable, CustomStringConvertible, Equatable
|
||||
/// - Parameter network: The IPv6 address to use for the network prefix
|
||||
/// - Returns: The link local IP address for the MAC address
|
||||
@inlinable
|
||||
public func ipv6Address(network: IPv6Address) -> IPv6Address {
|
||||
public func ipv6Address(network: IPv6Address) throws -> IPv6Address {
|
||||
let prefixBytes = network.bytes
|
||||
return IPv6Address([
|
||||
return try IPv6Address([
|
||||
prefixBytes[0], prefixBytes[1], prefixBytes[2], prefixBytes[3],
|
||||
prefixBytes[4], prefixBytes[5], prefixBytes[6], prefixBytes[7],
|
||||
bytes[0] ^ 0x02, bytes[1], bytes[2], 0xff,
|
||||
|
||||
@@ -14,6 +14,28 @@
|
||||
// limitations under the License.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Foundation
|
||||
|
||||
package enum BindError: Error, CustomStringConvertible {
|
||||
case recvMarshalFailure(type: String, field: String)
|
||||
case sendMarshalFailure(type: String, field: String)
|
||||
|
||||
package var description: String {
|
||||
switch self {
|
||||
case .recvMarshalFailure(let type, let field):
|
||||
return "failed to unmarshal \(type).\(field)"
|
||||
case .sendMarshalFailure(let type, let field):
|
||||
return "failed to marshal \(type).\(field)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
package protocol Bindable: Sendable {
|
||||
static var size: Int { get }
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int
|
||||
}
|
||||
|
||||
extension ArraySlice<UInt8> {
|
||||
package func hexEncodedString() -> String {
|
||||
self.map { String(format: "%02hhx", $0) }.joined()
|
||||
@@ -35,7 +57,7 @@ extension [UInt8] {
|
||||
|
||||
package mutating func copyIn<T>(as type: T.Type, value: T, offset: Int = 0, size: Int? = nil) -> Int? {
|
||||
let size = size ?? MemoryLayout<T>.size
|
||||
guard self.count >= size - offset else {
|
||||
guard self.count >= size + offset else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -45,12 +67,12 @@ extension [UInt8] {
|
||||
}
|
||||
}
|
||||
|
||||
package mutating func copyOut<T>(as type: T.Type, offset: Int = 0, size: Int? = nil) -> (Int, T)? {
|
||||
guard self.count >= (size ?? MemoryLayout<T>.size) - offset else {
|
||||
package func copyOut<T>(as type: T.Type, offset: Int = 0, size: Int? = nil) -> (Int, T)? {
|
||||
guard self.count >= (size ?? MemoryLayout<T>.size) + offset else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.withUnsafeMutableBytes {
|
||||
return self.withUnsafeBytes {
|
||||
guard let value = $0.baseAddress?.advanced(by: offset).assumingMemoryBound(to: T.self).pointee else {
|
||||
return nil
|
||||
}
|
||||
@@ -67,7 +89,7 @@ extension [UInt8] {
|
||||
return offset + buffer.count
|
||||
}
|
||||
|
||||
package mutating func copyOut(buffer: inout [UInt8], offset: Int = 0) -> Int? {
|
||||
package func copyOut(buffer: inout [UInt8], offset: Int = 0) -> Int? {
|
||||
guard offset + buffer.count <= self.count else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public struct NetlinkSession {
|
||||
let newRequestOffset =
|
||||
requestBuffer.copyIn(as: UInt32.self, value: m, offset: requestOffset)
|
||||
else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "IFLA_MTU")
|
||||
}
|
||||
requestOffset = newRequestOffset
|
||||
}
|
||||
@@ -162,7 +162,7 @@ public struct NetlinkSession {
|
||||
value: filters,
|
||||
offset: requestOffset)
|
||||
else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "IFLA_EXT_MASK")
|
||||
}
|
||||
|
||||
if let interfaceNameAttr {
|
||||
@@ -170,7 +170,7 @@ public struct NetlinkSession {
|
||||
requestOffset = try interfaceNameAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard let updatedRequestOffset = requestBuffer.copyIn(buffer: interfaceName, offset: requestOffset)
|
||||
else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "IFLA_IFNAME")
|
||||
}
|
||||
requestOffset = updatedRequestOffset
|
||||
}
|
||||
@@ -239,13 +239,13 @@ public struct NetlinkSession {
|
||||
let ipLocalAttr = RTAttribute(len: UInt16(addressAttrSize), type: AddressAttributeType.IFA_LOCAL)
|
||||
requestOffset = try ipLocalAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard var requestOffset = requestBuffer.copyIn(buffer: ipAddressBytes, offset: requestOffset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "IFA_LOCAL")
|
||||
}
|
||||
|
||||
let ipAddressAttr = RTAttribute(len: UInt16(addressAttrSize), type: AddressAttributeType.IFA_ADDRESS)
|
||||
requestOffset = try ipAddressAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard let requestOffset = requestBuffer.copyIn(buffer: ipAddressBytes, offset: requestOffset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "IFA_ADDRESS")
|
||||
}
|
||||
|
||||
guard requestOffset == requestSize else {
|
||||
@@ -305,13 +305,13 @@ public struct NetlinkSession {
|
||||
let dstAddrAttr = RTAttribute(len: UInt16(dstAddrAttrSize), type: RouteAttributeType.DST)
|
||||
requestOffset = try dstAddrAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard var requestOffset = requestBuffer.copyIn(buffer: dstAddrBytes, offset: requestOffset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_DST")
|
||||
}
|
||||
|
||||
let srcAddrAttr = RTAttribute(len: UInt16(dstAddrAttrSize), type: RouteAttributeType.PREFSRC)
|
||||
requestOffset = try srcAddrAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard var requestOffset = requestBuffer.copyIn(buffer: srcAddrBytes, offset: requestOffset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_PREFSRC")
|
||||
}
|
||||
|
||||
let interfaceAttr = RTAttribute(len: UInt16(interfaceAttrSize), type: RouteAttributeType.OIF)
|
||||
@@ -322,7 +322,7 @@ public struct NetlinkSession {
|
||||
value: UInt32(interfaceIndex),
|
||||
offset: requestOffset)
|
||||
else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_OIF")
|
||||
}
|
||||
|
||||
guard requestOffset == requestSize else {
|
||||
@@ -378,7 +378,7 @@ public struct NetlinkSession {
|
||||
let dstAddrAttr = RTAttribute(len: UInt16(dstAddrAttrSize), type: RouteAttributeType.GATEWAY)
|
||||
requestOffset = try dstAddrAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
guard var requestOffset = requestBuffer.copyIn(buffer: dstAddrBytes, offset: requestOffset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_GATEWAY")
|
||||
}
|
||||
let interfaceAttr = RTAttribute(len: UInt16(interfaceAttrSize), type: RouteAttributeType.OIF)
|
||||
requestOffset = try interfaceAttr.appendBuffer(&requestBuffer, offset: requestOffset)
|
||||
@@ -388,7 +388,7 @@ public struct NetlinkSession {
|
||||
value: UInt32(interfaceIndex),
|
||||
offset: requestOffset)
|
||||
else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_OIF")
|
||||
}
|
||||
|
||||
guard requestOffset == requestSize else {
|
||||
@@ -404,7 +404,7 @@ public struct NetlinkSession {
|
||||
|
||||
private func getInterfaceName(_ interface: String) throws -> [UInt8] {
|
||||
guard let interfaceNameData = interface.data(using: .utf8) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "String", field: "interface")
|
||||
}
|
||||
|
||||
var interfaceName = [UInt8](interfaceNameData)
|
||||
@@ -503,7 +503,7 @@ public struct NetlinkSession {
|
||||
|
||||
private func parseErrorCode(buffer: inout [UInt8], offset: Int) throws -> (Int32, Int) {
|
||||
guard let errorPtr = buffer.bind(as: Int32.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkErrorMessage", field: "error")
|
||||
}
|
||||
|
||||
let rc = errorPtr.pointee
|
||||
|
||||
@@ -135,17 +135,11 @@ struct RouteAttributeType {
|
||||
static let PREFSRC: UInt16 = 7
|
||||
}
|
||||
|
||||
protocol Bindable: Equatable {
|
||||
static var size: Int { get }
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int
|
||||
}
|
||||
|
||||
struct SockaddrNetlink: Bindable {
|
||||
struct SockaddrNetlink: Bindable, Equatable {
|
||||
static let size = 12
|
||||
|
||||
var family: UInt16
|
||||
var pad: UInt16 = 0
|
||||
var _pad: UInt16 = 0
|
||||
var pid: UInt32
|
||||
var groups: UInt32
|
||||
|
||||
@@ -157,13 +151,16 @@ struct SockaddrNetlink: Bindable {
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: family, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "SockaddrNetlink", field: "family")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: 0, offset: offset) else {
|
||||
throw BindError.sendMarshalFailure(type: "SockaddrNetlink", field: "_pad")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: pid, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "SockaddrNetlink", field: "pid")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: groups, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "SockaddrNetlink", field: "groups")
|
||||
}
|
||||
|
||||
return offset
|
||||
@@ -171,25 +168,30 @@ struct SockaddrNetlink: Bindable {
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "SockaddrNetlink", field: "family")
|
||||
}
|
||||
family = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw BindError.recvMarshalFailure(type: "SockaddrNetlink", field: "_pad")
|
||||
}
|
||||
_pad = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "SockaddrNetlink", field: "pid")
|
||||
}
|
||||
pid = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "SockaddrNetlink", field: "groups")
|
||||
}
|
||||
groups = value
|
||||
|
||||
return offset + Self.size
|
||||
return offset
|
||||
}
|
||||
}
|
||||
|
||||
struct NetlinkMessageHeader: Bindable {
|
||||
struct NetlinkMessageHeader: Bindable, Equatable {
|
||||
static let size = 16
|
||||
|
||||
var len: UInt32
|
||||
@@ -208,19 +210,19 @@ struct NetlinkMessageHeader: Bindable {
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: len, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "NetlinkMessageHeader", field: "len")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: type, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "NetlinkMessageHeader", field: "type")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: flags, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "NetlinkMessageHeader", field: "flags")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: seq, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "NetlinkMessageHeader", field: "seq")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: pid, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "NetlinkMessageHeader", field: "pid")
|
||||
}
|
||||
|
||||
return offset
|
||||
@@ -228,27 +230,27 @@ struct NetlinkMessageHeader: Bindable {
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkMessageHeader", field: "len")
|
||||
}
|
||||
len = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkMessageHeader", field: "type")
|
||||
}
|
||||
type = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkMessageHeader", field: "flags")
|
||||
}
|
||||
flags = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkMessageHeader", field: "seq")
|
||||
}
|
||||
seq = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "NetlinkMessageHeader", field: "pid")
|
||||
}
|
||||
pid = value
|
||||
|
||||
@@ -262,7 +264,7 @@ struct NetlinkMessageHeader: Bindable {
|
||||
}
|
||||
}
|
||||
|
||||
struct InterfaceInfo: Bindable {
|
||||
struct InterfaceInfo: Bindable, Equatable {
|
||||
static let size = 16
|
||||
|
||||
var family: UInt8
|
||||
@@ -285,22 +287,22 @@ struct InterfaceInfo: Bindable {
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: family, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "family")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: _pad, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "_pad")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: type, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "type")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: Int32.self, value: index, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "index")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: flags, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "flags")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: change, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "InterfaceInfo", field: "change")
|
||||
}
|
||||
|
||||
return offset
|
||||
@@ -308,32 +310,32 @@ struct InterfaceInfo: Bindable {
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "family")
|
||||
}
|
||||
family = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "_pad")
|
||||
}
|
||||
_pad = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "type")
|
||||
}
|
||||
type = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: Int32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "index")
|
||||
}
|
||||
index = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "flags")
|
||||
}
|
||||
flags = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "InterfaceInfo", field: "change")
|
||||
}
|
||||
change = value
|
||||
|
||||
@@ -341,7 +343,7 @@ struct InterfaceInfo: Bindable {
|
||||
}
|
||||
}
|
||||
|
||||
struct AddressInfo: Bindable {
|
||||
struct AddressInfo: Bindable, Equatable {
|
||||
static let size = 8
|
||||
|
||||
var family: UInt8
|
||||
@@ -363,19 +365,19 @@ struct AddressInfo: Bindable {
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: family, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "AddressInfo", field: "family")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: prefixLength, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "AddressInfo", field: "prefixLength")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: flags, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "AddressInfo", field: "flags")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: scope, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "AddressInfo", field: "scope")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: index, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "AddressInfo", field: "index")
|
||||
}
|
||||
|
||||
return offset
|
||||
@@ -383,27 +385,27 @@ struct AddressInfo: Bindable {
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "AddressInfo", field: "family")
|
||||
}
|
||||
family = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "AddressInfo", field: "prefixLength")
|
||||
}
|
||||
prefixLength = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "AddressInfo", field: "flags")
|
||||
}
|
||||
flags = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "AddressInfo", field: "scope")
|
||||
}
|
||||
scope = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "AddressInfo", field: "index")
|
||||
}
|
||||
index = value
|
||||
|
||||
@@ -411,7 +413,7 @@ struct AddressInfo: Bindable {
|
||||
}
|
||||
}
|
||||
|
||||
struct RouteInfo: Bindable {
|
||||
struct RouteInfo: Bindable, Equatable {
|
||||
static let size = 12
|
||||
|
||||
var family: UInt8
|
||||
@@ -448,31 +450,31 @@ struct RouteInfo: Bindable {
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: family, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "family")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: dstLen, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "dstLen")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: srcLen, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "srcLen")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: tos, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "tos")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: table, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "table")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: proto, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "proto")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: scope, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "scope")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: type, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "type")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: flags, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RouteInfo", field: "flags")
|
||||
}
|
||||
|
||||
return offset
|
||||
@@ -480,47 +482,47 @@ struct RouteInfo: Bindable {
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "family")
|
||||
}
|
||||
family = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "dstLen")
|
||||
}
|
||||
dstLen = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "srcLen")
|
||||
}
|
||||
srcLen = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "tos")
|
||||
}
|
||||
tos = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "table")
|
||||
}
|
||||
table = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "proto")
|
||||
}
|
||||
proto = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "scope")
|
||||
}
|
||||
scope = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "type")
|
||||
}
|
||||
type = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RouteInfo", field: "flags")
|
||||
}
|
||||
flags = value
|
||||
|
||||
@@ -529,8 +531,8 @@ struct RouteInfo: Bindable {
|
||||
}
|
||||
|
||||
/// A route information.
|
||||
public struct RTAttribute: Bindable {
|
||||
static let size = 4
|
||||
public struct RTAttribute: Bindable, Equatable {
|
||||
package static let size = 4
|
||||
|
||||
public var len: UInt16
|
||||
public var type: UInt16
|
||||
@@ -541,25 +543,25 @@ public struct RTAttribute: Bindable {
|
||||
self.type = type
|
||||
}
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
package func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: len, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "len")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: type, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "type")
|
||||
}
|
||||
|
||||
return offset
|
||||
}
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
package mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RTAttribute", field: "len")
|
||||
}
|
||||
len = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "RTAttribute", field: "type")
|
||||
}
|
||||
type = value
|
||||
|
||||
@@ -612,8 +614,8 @@ public struct LinkResponse {
|
||||
}
|
||||
|
||||
/// Network interface statistics (64-bit version)
|
||||
public struct LinkStatistics64: Bindable {
|
||||
static let size = 23 * 8
|
||||
public struct LinkStatistics64: Bindable, Equatable {
|
||||
package static let size = 23 * 8
|
||||
|
||||
public var rxPackets: UInt64
|
||||
public var txPackets: UInt64
|
||||
@@ -665,193 +667,193 @@ public struct LinkStatistics64: Bindable {
|
||||
self.txCompressed = 0
|
||||
}
|
||||
|
||||
func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
package func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxPackets, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxPackets")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txPackets, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txPackets")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxBytes, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxBytes")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txBytes, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txBytes")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxDropped, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxDropped")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txDropped, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txDropped")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: multicast, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "multicast")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: collisions, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "collisions")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxLengthErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxLengthErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxOverErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxOverErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxCrcErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxCrcErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxFrameErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxFrameErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxFifoErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxFifoErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxMissedErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxMissedErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txAbortedErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txAbortedErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txCarrierErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txCarrierErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txFifoErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txFifoErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txHeartbeatErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txHeartbeatErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txWindowErrors, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txWindowErrors")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: rxCompressed, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "rxCompressed")
|
||||
}
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: txCompressed, offset: offset) else {
|
||||
throw NetlinkDataError.sendMarshalFailure
|
||||
throw BindError.sendMarshalFailure(type: "LinkStatistics64", field: "txCompressed")
|
||||
}
|
||||
|
||||
return offset
|
||||
}
|
||||
|
||||
mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
package mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int {
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxPackets")
|
||||
}
|
||||
rxPackets = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txPackets")
|
||||
}
|
||||
txPackets = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxBytes")
|
||||
}
|
||||
rxBytes = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txBytes")
|
||||
}
|
||||
txBytes = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxErrors")
|
||||
}
|
||||
rxErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txErrors")
|
||||
}
|
||||
txErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxDropped")
|
||||
}
|
||||
rxDropped = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txDropped")
|
||||
}
|
||||
txDropped = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "multicast")
|
||||
}
|
||||
multicast = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "collisions")
|
||||
}
|
||||
collisions = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxLengthErrors")
|
||||
}
|
||||
rxLengthErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxOverErrors")
|
||||
}
|
||||
rxOverErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxCrcErrors")
|
||||
}
|
||||
rxCrcErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxFrameErrors")
|
||||
}
|
||||
rxFrameErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxFifoErrors")
|
||||
}
|
||||
rxFifoErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxMissedErrors")
|
||||
}
|
||||
rxMissedErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txAbortedErrors")
|
||||
}
|
||||
txAbortedErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txCarrierErrors")
|
||||
}
|
||||
txCarrierErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txFifoErrors")
|
||||
}
|
||||
txFifoErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txHeartbeatErrors")
|
||||
}
|
||||
txHeartbeatErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txWindowErrors")
|
||||
}
|
||||
txWindowErrors = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "rxCompressed")
|
||||
}
|
||||
rxCompressed = value
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: offset) else {
|
||||
throw NetlinkDataError.recvUnmarshalFailure
|
||||
throw BindError.recvMarshalFailure(type: "LinkStatistics64", field: "txCompressed")
|
||||
}
|
||||
txCompressed = value
|
||||
|
||||
@@ -861,18 +863,12 @@ public struct LinkStatistics64: Bindable {
|
||||
|
||||
/// Errors thrown when parsing netlink data.
|
||||
public enum NetlinkDataError: Swift.Error, CustomStringConvertible, Equatable {
|
||||
case sendMarshalFailure
|
||||
case recvUnmarshalFailure
|
||||
case responseError(rc: Int32)
|
||||
case unsupportedPlatform
|
||||
|
||||
/// The description of the errors.
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .sendMarshalFailure:
|
||||
return "could not marshal netlink packet"
|
||||
case .recvUnmarshalFailure:
|
||||
return "could not unmarshal netlink packet"
|
||||
case .responseError(let rc):
|
||||
return "netlink response indicates error, rc = \(rc)"
|
||||
case .unsupportedPlatform:
|
||||
|
||||
@@ -182,10 +182,11 @@ struct MACAddressTests {
|
||||
(0x5e3b_68d7_e510, 0xfd97_7b15_d62e_75ac_5c3b_68ff_fed7_e510),
|
||||
]
|
||||
)
|
||||
func testLinkLocalAddress(mac: UInt64, ipv6: UInt128) {
|
||||
func testLinkLocalAddress(mac: UInt64, ipv6: UInt128) throws {
|
||||
let mac = MACAddress(mac)
|
||||
let ipv6Prefix = IPv6Address(ipv6 & 0xffff_ffff_ffff_ffff_0000_0000_0000_0000)
|
||||
#expect(mac.ipv6Address(network: ipv6Prefix) == IPv6Address(ipv6))
|
||||
let ipv6Address = try mac.ipv6Address(network: ipv6Prefix)
|
||||
#expect(ipv6Address == IPv6Address(ipv6))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,51 @@
|
||||
|
||||
import Testing
|
||||
|
||||
@testable import ContainerizationExtras
|
||||
|
||||
struct BufferTest {
|
||||
// MARK: - hexEncodedString Tests
|
||||
|
||||
@Test func testArrayHexEncodedStringEmpty() {
|
||||
let buffer: [UInt8] = []
|
||||
#expect(buffer.hexEncodedString() == "")
|
||||
}
|
||||
|
||||
@Test func testArrayHexEncodedStringSingleByte() {
|
||||
let buffer: [UInt8] = [0xFF]
|
||||
#expect(buffer.hexEncodedString() == "ff")
|
||||
}
|
||||
|
||||
@Test func testArrayHexEncodedStringMultipleBytes() {
|
||||
let buffer: [UInt8] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]
|
||||
#expect(buffer.hexEncodedString() == "0123456789abcdef")
|
||||
}
|
||||
|
||||
@Test func testArrayHexEncodedStringZeroes() {
|
||||
let buffer: [UInt8] = [0x00, 0x00, 0x00]
|
||||
#expect(buffer.hexEncodedString() == "000000")
|
||||
}
|
||||
|
||||
@Test func testArraySliceHexEncodedStringEmpty() {
|
||||
let buffer: [UInt8] = [0x01, 0x02, 0x03]
|
||||
let slice = buffer[0..<0]
|
||||
#expect(slice.hexEncodedString() == "")
|
||||
}
|
||||
|
||||
@Test func testArraySliceHexEncodedStringSingleByte() {
|
||||
let buffer: [UInt8] = [0x01, 0x02, 0x03]
|
||||
let slice = buffer[1..<2]
|
||||
#expect(slice.hexEncodedString() == "02")
|
||||
}
|
||||
|
||||
@Test func testArraySliceHexEncodedStringMultipleBytes() {
|
||||
let buffer: [UInt8] = [0x00, 0xAA, 0xBB, 0xCC, 0x00]
|
||||
let slice = buffer[1..<4]
|
||||
#expect(slice.hexEncodedString() == "aabbcc")
|
||||
}
|
||||
|
||||
// MARK: - bind<T> Tests
|
||||
|
||||
@Test func testBufferBind() throws {
|
||||
let expectedValue: UInt64 = 0x0102_0304_0506_0708
|
||||
let expectedBuffer: [UInt8] = [
|
||||
@@ -26,11 +70,6 @@ struct BufferTest {
|
||||
]
|
||||
var buffer = [UInt8](repeating: 0, count: 3 * MemoryLayout<UInt64>.size)
|
||||
guard let ptr = buffer.bind(as: UInt64.self, offset: 2 * MemoryLayout<UInt64>.size) else {
|
||||
// NOTE: This does not work:
|
||||
// let ptr: UnsafeMutablePointer<UInt64> = #require(buffer.bind(as: UInt64.self, offset: MemoryLayout<UInt64>.size), "could not bind value to buffer")
|
||||
// it fails with the error:
|
||||
// cannot use mutating member on immutable value: '$0' is immutable
|
||||
// $0.bind(as: $1, offset: $2)
|
||||
#expect(Bool(false), "could not bind value to buffer")
|
||||
return
|
||||
}
|
||||
@@ -39,11 +78,257 @@ struct BufferTest {
|
||||
#expect(buffer == expectedBuffer)
|
||||
}
|
||||
|
||||
@Test func testBufferBindZeroOffset() {
|
||||
let expectedValue: UInt32 = 0x1234_5678
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
guard let ptr = buffer.bind(as: UInt32.self, offset: 0) else {
|
||||
#expect(Bool(false), "could not bind value to buffer at offset 0")
|
||||
return
|
||||
}
|
||||
|
||||
ptr.pointee = expectedValue
|
||||
#expect(buffer[0] == 0x78)
|
||||
#expect(buffer[1] == 0x56)
|
||||
#expect(buffer[2] == 0x34)
|
||||
#expect(buffer[3] == 0x12)
|
||||
}
|
||||
|
||||
@Test func testBufferBindRangeError() throws {
|
||||
var buffer = [UInt8](repeating: 0, count: 3 * MemoryLayout<UInt64>.size)
|
||||
#expect(buffer.bind(as: UInt64.self, offset: 2 * MemoryLayout<UInt64>.size + 1) == nil)
|
||||
}
|
||||
|
||||
@Test func testBufferBindRangeErrorExactBoundary() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
// Trying to bind UInt64 at offset 1 requires 9 bytes total
|
||||
#expect(buffer.bind(as: UInt64.self, offset: 1) == nil)
|
||||
}
|
||||
|
||||
@Test func testBufferBindWithCustomSize() {
|
||||
var buffer = [UInt8](repeating: 0, count: 16)
|
||||
// Request a size larger than the type
|
||||
guard let ptr = buffer.bind(as: UInt32.self, offset: 4, size: 8) else {
|
||||
#expect(Bool(false), "could not bind with custom size")
|
||||
return
|
||||
}
|
||||
|
||||
ptr.pointee = 0xAABB_CCDD
|
||||
#expect(buffer[4] == 0xDD)
|
||||
#expect(buffer[5] == 0xCC)
|
||||
#expect(buffer[6] == 0xBB)
|
||||
#expect(buffer[7] == 0xAA)
|
||||
}
|
||||
|
||||
@Test func testBufferBindWithCustomSizeRangeError() {
|
||||
var buffer = [UInt8](repeating: 0, count: 10)
|
||||
// Request size 8 at offset 4 would require 12 bytes total
|
||||
#expect(buffer.bind(as: UInt32.self, offset: 4, size: 8) == nil)
|
||||
}
|
||||
|
||||
// MARK: - copyIn<T> Tests
|
||||
|
||||
@Test func testCopyInUInt8() {
|
||||
var buffer = [UInt8](repeating: 0, count: 4)
|
||||
let value: UInt8 = 0x42
|
||||
|
||||
guard let offset = buffer.copyIn(as: UInt8.self, value: value, offset: 2) else {
|
||||
#expect(Bool(false), "could not copy UInt8 to buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 3)
|
||||
#expect(buffer[2] == 0x42)
|
||||
}
|
||||
|
||||
@Test func testCopyInUInt16() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
let value: UInt16 = 0x1234
|
||||
|
||||
guard let offset = buffer.copyIn(as: UInt16.self, value: value, offset: 3) else {
|
||||
#expect(Bool(false), "could not copy UInt16 to buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 5)
|
||||
#expect(buffer[3] == 0x34)
|
||||
#expect(buffer[4] == 0x12)
|
||||
}
|
||||
|
||||
@Test func testCopyInUInt32() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
let value: UInt32 = 0x1234_5678
|
||||
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: value, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy UInt32 to buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 4)
|
||||
#expect(buffer[0] == 0x78)
|
||||
#expect(buffer[1] == 0x56)
|
||||
#expect(buffer[2] == 0x34)
|
||||
#expect(buffer[3] == 0x12)
|
||||
}
|
||||
|
||||
@Test func testCopyInUInt64() {
|
||||
var buffer = [UInt8](repeating: 0, count: 16)
|
||||
let value: UInt64 = 0x0102_0304_0506_0708
|
||||
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: value, offset: 4) else {
|
||||
#expect(Bool(false), "could not copy UInt64 to buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 12)
|
||||
#expect(buffer[4] == 0x08)
|
||||
#expect(buffer[5] == 0x07)
|
||||
#expect(buffer[6] == 0x06)
|
||||
#expect(buffer[7] == 0x05)
|
||||
#expect(buffer[8] == 0x04)
|
||||
#expect(buffer[9] == 0x03)
|
||||
#expect(buffer[10] == 0x02)
|
||||
#expect(buffer[11] == 0x01)
|
||||
}
|
||||
|
||||
@Test func testCopyInRangeError() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
let value: UInt64 = 0x1234_5678_90AB_CDEF
|
||||
|
||||
// Offset 4 + size 8 = 12, but buffer only has 8 bytes
|
||||
#expect(buffer.copyIn(as: UInt64.self, value: value, offset: 4) == nil)
|
||||
}
|
||||
|
||||
@Test func testCopyInExactBoundary() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
let value: UInt64 = 0xFEDC_BA98_7654_3210
|
||||
|
||||
guard let offset = buffer.copyIn(as: UInt64.self, value: value, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy UInt64 at exact boundary")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 8)
|
||||
}
|
||||
|
||||
@Test func testCopyInWithCustomSize() {
|
||||
var buffer = [UInt8](repeating: 0, count: 16)
|
||||
let value: UInt32 = 0xAABB_CCDD
|
||||
|
||||
// Copy with custom size of 8 (larger than UInt32's 4 bytes)
|
||||
guard let offset = buffer.copyIn(as: UInt32.self, value: value, offset: 2, size: 8) else {
|
||||
#expect(Bool(false), "could not copy with custom size")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 6) // offset + MemoryLayout<UInt32>.size
|
||||
#expect(buffer[2] == 0xDD)
|
||||
#expect(buffer[3] == 0xCC)
|
||||
#expect(buffer[4] == 0xBB)
|
||||
#expect(buffer[5] == 0xAA)
|
||||
}
|
||||
|
||||
@Test func testCopyInWithCustomSizeRangeError() {
|
||||
var buffer = [UInt8](repeating: 0, count: 8)
|
||||
let value: UInt32 = 0x1234_5678
|
||||
|
||||
// Request size 8 at offset 2 would require 10 bytes total
|
||||
#expect(buffer.copyIn(as: UInt32.self, value: value, offset: 2, size: 8) == nil)
|
||||
}
|
||||
|
||||
// MARK: - copyOut<T> Tests
|
||||
|
||||
@Test func testCopyOutUInt8() {
|
||||
let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt8.self, offset: 2) else {
|
||||
#expect(Bool(false), "could not copy out UInt8")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 3)
|
||||
#expect(value == 0x22)
|
||||
}
|
||||
|
||||
@Test func testCopyOutUInt16() {
|
||||
let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt16.self, offset: 2) else {
|
||||
#expect(Bool(false), "could not copy out UInt16")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 4)
|
||||
#expect(value == 0x3322)
|
||||
}
|
||||
|
||||
@Test func testCopyOutUInt32() {
|
||||
let buffer: [UInt8] = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy out UInt32")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 4)
|
||||
#expect(value == 0x7856_3412)
|
||||
}
|
||||
|
||||
@Test func testCopyOutUInt64() {
|
||||
let buffer: [UInt8] = [
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0xFF, 0xFF,
|
||||
]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: 4) else {
|
||||
#expect(Bool(false), "could not copy out UInt64")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 12)
|
||||
#expect(value == 0x8877_6655_4433_2211)
|
||||
}
|
||||
|
||||
@Test func testCopyOutRangeError() {
|
||||
let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33]
|
||||
|
||||
// Trying to read UInt64 from offset 0 with only 4 bytes
|
||||
#expect(buffer.copyOut(as: UInt64.self, offset: 0) == nil)
|
||||
}
|
||||
|
||||
@Test func testCopyOutExactBoundary() {
|
||||
let buffer: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt64.self, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy out at exact boundary")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 8)
|
||||
#expect(value == 0x0807_0605_0403_0201)
|
||||
}
|
||||
|
||||
@Test func testCopyOutWithCustomSize() {
|
||||
let buffer: [UInt8] = [0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0xFF, 0xFF, 0xFF, 0xFF]
|
||||
|
||||
guard let (offset, value) = buffer.copyOut(as: UInt32.self, offset: 2, size: 8) else {
|
||||
#expect(Bool(false), "could not copy out with custom size")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 6) // offset + MemoryLayout<UInt32>.size
|
||||
#expect(value == 0x4433_2211)
|
||||
}
|
||||
|
||||
@Test func testCopyOutWithCustomSizeRangeError() {
|
||||
let buffer: [UInt8] = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55]
|
||||
|
||||
// Request size 8 at offset 2 would require 10 bytes total, but buffer only has 6
|
||||
#expect(buffer.copyOut(as: UInt32.self, offset: 2, size: 8) == nil)
|
||||
}
|
||||
|
||||
// MARK: - copyIn(buffer:) and copyOut(buffer:) Tests
|
||||
|
||||
@Test func testBufferCopy() throws {
|
||||
let inputBuffer: [UInt8] = [0x01, 0x02, 0x03]
|
||||
var buffer = [UInt8](repeating: 0, count: 9)
|
||||
@@ -78,6 +363,45 @@ struct BufferTest {
|
||||
#expect(expectedOutputBuffer == outputBuffer)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyZeroOffset() {
|
||||
let inputBuffer: [UInt8] = [0xAA, 0xBB, 0xCC]
|
||||
var buffer = [UInt8](repeating: 0, count: 5)
|
||||
|
||||
guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy to buffer at offset 0")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 3)
|
||||
#expect(buffer[0] == 0xAA)
|
||||
#expect(buffer[1] == 0xBB)
|
||||
#expect(buffer[2] == 0xCC)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyEmptyBuffer() {
|
||||
let inputBuffer: [UInt8] = []
|
||||
var buffer = [UInt8](repeating: 0, count: 5)
|
||||
|
||||
guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 2) else {
|
||||
#expect(Bool(false), "could not copy empty buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 2)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyExactFit() {
|
||||
let inputBuffer: [UInt8] = [0x01, 0x02, 0x03]
|
||||
var buffer = [UInt8](repeating: 0, count: 6)
|
||||
|
||||
guard let offset = buffer.copyIn(buffer: inputBuffer, offset: 3) else {
|
||||
#expect(Bool(false), "could not copy to exact fit")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 6)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyRangeError() throws {
|
||||
let inputBuffer: [UInt8] = [0x01, 0x02, 0x03]
|
||||
var buffer = [UInt8](repeating: 0, count: 9)
|
||||
@@ -87,4 +411,46 @@ struct BufferTest {
|
||||
var outputBuffer = [UInt8](repeating: 0, count: 3)
|
||||
#expect(buffer.copyOut(buffer: &outputBuffer, offset: 7) == nil)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyOutZeroOffset() {
|
||||
let buffer: [UInt8] = [0x11, 0x22, 0x33, 0x44, 0x55]
|
||||
var outputBuffer = [UInt8](repeating: 0, count: 3)
|
||||
|
||||
guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 0) else {
|
||||
#expect(Bool(false), "could not copy out at offset 0")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 3)
|
||||
#expect(outputBuffer[0] == 0x11)
|
||||
#expect(outputBuffer[1] == 0x22)
|
||||
#expect(outputBuffer[2] == 0x33)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyOutEmptyBuffer() {
|
||||
let buffer: [UInt8] = [0x11, 0x22, 0x33]
|
||||
var outputBuffer: [UInt8] = []
|
||||
|
||||
guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 1) else {
|
||||
#expect(Bool(false), "could not copy out to empty buffer")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 1)
|
||||
}
|
||||
|
||||
@Test func testBufferCopyOutExactFit() {
|
||||
let buffer: [UInt8] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]
|
||||
var outputBuffer = [UInt8](repeating: 0, count: 3)
|
||||
|
||||
guard let offset = buffer.copyOut(buffer: &outputBuffer, offset: 3) else {
|
||||
#expect(Bool(false), "could not copy out exact fit")
|
||||
return
|
||||
}
|
||||
|
||||
#expect(offset == 6)
|
||||
#expect(outputBuffer[0] == 0xDD)
|
||||
#expect(outputBuffer[1] == 0xEE)
|
||||
#expect(outputBuffer[2] == 0xFF)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,4 +108,114 @@ struct TypesTest {
|
||||
#expect(offset == RTAttribute.size)
|
||||
#expect(expectedValue == value)
|
||||
}
|
||||
|
||||
@Test func testSockaddrNetlink() throws {
|
||||
let expectedValue = SockaddrNetlink(family: 16, pid: 0x1234_5678, groups: 0x9abc_def0)
|
||||
let expectedBuffer: [UInt8] = [
|
||||
0x10, 0x00, 0x00, 0x00,
|
||||
0x78, 0x56, 0x34, 0x12,
|
||||
0xf0, 0xde, 0xbc, 0x9a,
|
||||
]
|
||||
var buffer = [UInt8](repeating: 0, count: SockaddrNetlink.size)
|
||||
let offset = try expectedValue.appendBuffer(&buffer, offset: 0)
|
||||
#expect(SockaddrNetlink.size == offset)
|
||||
#expect(expectedBuffer == buffer)
|
||||
|
||||
var unmarshaledValue = SockaddrNetlink()
|
||||
let bindOffset = try unmarshaledValue.bindBuffer(&buffer, offset: 0)
|
||||
#expect(bindOffset == SockaddrNetlink.size)
|
||||
#expect(expectedValue == unmarshaledValue)
|
||||
}
|
||||
|
||||
@Test func testRouteInfo() throws {
|
||||
let expectedValue = RouteInfo(
|
||||
family: UInt8(AddressFamily.AF_INET),
|
||||
dstLen: 24,
|
||||
srcLen: 0,
|
||||
tos: 0,
|
||||
table: RouteTable.MAIN,
|
||||
proto: RouteProtocol.KERNEL,
|
||||
scope: RouteScope.LINK,
|
||||
type: RouteType.UNICAST,
|
||||
flags: 0xdead_beef
|
||||
)
|
||||
let expectedBuffer: [UInt8] = [
|
||||
0x02, 0x18, 0x00, 0x00,
|
||||
0xfe, 0x02, 0xfd, 0x01,
|
||||
0xef, 0xbe, 0xad, 0xde,
|
||||
]
|
||||
var buffer = [UInt8](repeating: 0, count: RouteInfo.size)
|
||||
let offset = try expectedValue.appendBuffer(&buffer, offset: 0)
|
||||
#expect(RouteInfo.size == offset)
|
||||
#expect(expectedBuffer == buffer)
|
||||
|
||||
var unmarshaledValue = RouteInfo(
|
||||
dstLen: 0, srcLen: 0, tos: 0, table: 0, proto: 0, scope: 0, type: 0, flags: 0)
|
||||
let bindOffset = try unmarshaledValue.bindBuffer(&buffer, offset: 0)
|
||||
#expect(bindOffset == RouteInfo.size)
|
||||
#expect(expectedValue == unmarshaledValue)
|
||||
}
|
||||
|
||||
@Test func testLinkStatistics64() throws {
|
||||
var expectedValue = LinkStatistics64()
|
||||
expectedValue.rxPackets = 0x0102_0304_0506_0708
|
||||
expectedValue.txPackets = 0x090a_0b0c_0d0e_0f10
|
||||
expectedValue.rxBytes = 0x1112_1314_1516_1718
|
||||
expectedValue.txBytes = 0x191a_1b1c_1d1e_1f20
|
||||
expectedValue.rxErrors = 0x2122_2324_2526_2728
|
||||
expectedValue.txErrors = 0x292a_2b2c_2d2e_2f30
|
||||
expectedValue.rxDropped = 0x3132_3334_3536_3738
|
||||
expectedValue.txDropped = 0x393a_3b3c_3d3e_3f40
|
||||
expectedValue.multicast = 0x4142_4344_4546_4748
|
||||
expectedValue.collisions = 0x494a_4b4c_4d4e_4f50
|
||||
expectedValue.rxLengthErrors = 0x5152_5354_5556_5758
|
||||
expectedValue.rxOverErrors = 0x595a_5b5c_5d5e_5f60
|
||||
expectedValue.rxCrcErrors = 0x6162_6364_6566_6768
|
||||
expectedValue.rxFrameErrors = 0x696a_6b6c_6d6e_6f70
|
||||
expectedValue.rxFifoErrors = 0x7172_7374_7576_7778
|
||||
expectedValue.rxMissedErrors = 0x797a_7b7c_7d7e_7f80
|
||||
expectedValue.txAbortedErrors = 0x8182_8384_8586_8788
|
||||
expectedValue.txCarrierErrors = 0x898a_8b8c_8d8e_8f90
|
||||
expectedValue.txFifoErrors = 0x9192_9394_9596_9798
|
||||
expectedValue.txHeartbeatErrors = 0x999a_9b9c_9d9e_9fa0
|
||||
expectedValue.txWindowErrors = 0xa1a2_a3a4_a5a6_a7a8
|
||||
expectedValue.rxCompressed = 0xa9aa_abac_adae_afb0
|
||||
expectedValue.txCompressed = 0xb1b2_b3b4_b5b6_b7b8
|
||||
|
||||
let expectedBuffer: [UInt8] = [
|
||||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09,
|
||||
0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
|
||||
0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
|
||||
0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21,
|
||||
0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29,
|
||||
0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
|
||||
0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39,
|
||||
0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
|
||||
0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49,
|
||||
0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51,
|
||||
0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59,
|
||||
0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61,
|
||||
0x70, 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
|
||||
0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71,
|
||||
0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79,
|
||||
0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81,
|
||||
0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89,
|
||||
0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91,
|
||||
0xa0, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99,
|
||||
0xa8, 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1,
|
||||
0xb0, 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
|
||||
0xb8, 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1,
|
||||
]
|
||||
|
||||
var buffer = [UInt8](repeating: 0, count: LinkStatistics64.size)
|
||||
let offset = try expectedValue.appendBuffer(&buffer, offset: 0)
|
||||
#expect(LinkStatistics64.size == offset)
|
||||
#expect(expectedBuffer == buffer)
|
||||
|
||||
var unmarshaledValue = LinkStatistics64()
|
||||
let bindOffset = try unmarshaledValue.bindBuffer(&buffer, offset: 0)
|
||||
#expect(bindOffset == LinkStatistics64.size)
|
||||
#expect(expectedValue == unmarshaledValue)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user