usb_vsock/
lib.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
5//! A transport-agnostic library for implementing a vsock bridge over a usb bulk device.
6
7mod connection;
8mod packet;
9
10pub use connection::*;
11pub use packet::*;
12
13/// Magic sent in the sync packet of the USB protocol.
14///
15/// The 0 indicates protocol version 0, and we expect the reply sync packet to
16/// have the exact same contents. As we version the protocol this may increment.
17///
18/// To document the semantics, let's say this header were "vsock:3". The device
19/// could reply with a lower number, say "vsock:1". This is the device
20/// requesting a downgrade, and if we accept we send the final sync with
21/// "vsock:1". Otherwise we hang up.
22pub const VSOCK_MAGIC: &[u8; 7] = b"vsock:0";
23
24/// A placeholder CID indicating "any" CID is acceptable.
25pub const CID_ANY: u32 = u32::MAX;
26
27/// CID of the host.
28pub const CID_HOST: u32 = 2;
29
30/// The loopback CID.
31pub const CID_LOOPBACK: u32 = 1;
32
33/// An address for a vsock packet transmitted over USB. Since this library does not implement
34/// policy decisions, it includes all four components of a vsock address pair even though some
35/// may not be appropriate for some situations.
36#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
37pub struct Address {
38    /// For Connect, Reset, Accept, and Data packets this represents the device side's address.
39    /// Usually this will be a special value representing either that it is simply "the device",
40    /// or zero along with the rest of the cid and port fields to indicate that it's a control stream
41    /// packet. Must be zero for any other packet type.
42    pub device_cid: u32,
43    /// For Connect, Reset, Accept, and Data packets this represents the host side's address.
44    /// Usually this will be a special value representing either that it is simply "the host",
45    /// or zero along with the rest of the cid and port fields to indicate that it's a control stream
46    /// packet. Must be zero for any other packet type.
47    pub host_cid: u32,
48    /// For Connect, Reset, Accept, and Data packets this represents the device side's port.
49    /// This must be a valid positive value for any of those packet types, unless all of the cid and
50    /// port fields are also zero, in which case it is a control stream packet. Must be zero for any
51    /// other packet type.
52    pub device_port: u32,
53    /// For Connect, Reset, Accept, and Data packets this represents the host side's port.
54    /// This must be a valid positive value for any of those packet types, unless all of the cid and
55    /// port fields are also zero, in which case it is a control stream packet. Must be zero for any
56    /// other packet type.
57    pub host_port: u32,
58}
59
60impl Address {
61    /// Returns true if all the fields of this address are zero (which usually means it's a control
62    /// packet of some sort).
63    pub fn is_zeros(&self) -> bool {
64        *self == Self::default()
65    }
66}
67
68impl From<&Header> for Address {
69    fn from(header: &Header) -> Self {
70        Self {
71            device_cid: header.device_cid.get(),
72            host_cid: header.host_cid.get(),
73            device_port: header.device_port.get(),
74            host_port: header.host_port.get(),
75        }
76    }
77}