vmi_utils/bridge/
mod.rs

1//! Bridge utilities.
2
3mod packet;
4mod response;
5
6use vmi_core::{VmiContext, VmiDriver, VmiOs};
7
8pub use self::{packet::BridgePacket, response::BridgeResponse};
9
10/// A bridge dispatcher.
11pub trait BridgeDispatch<Driver, Os, T = ()>
12where
13    Driver: VmiDriver,
14    Os: VmiOs<Driver>,
15{
16    /// Dispatch the request.
17    fn dispatch(
18        &mut self,
19        vmi: &VmiContext<'_, Driver, Os>,
20        packet: BridgePacket,
21    ) -> Option<BridgeResponse<T>>;
22}
23
24/// A bridge handler.
25pub trait BridgeHandler<Driver, Os, T = ()>: BridgeDispatch<Driver, Os, T>
26where
27    Driver: VmiDriver,
28    Os: VmiOs<Driver>,
29{
30    /// Marker for an empty handler.
31    ///
32    /// Set to `true` in the implementation for the `()` type.
33    const EMPTY: bool = false;
34
35    /// The magic number.
36    const MAGIC: u32;
37
38    /// The request code.
39    const REQUEST: u16;
40
41    /// The first verification value.
42    ///
43    /// # Architecture-specific
44    ///
45    /// - **AMD64**: `RAX`
46    const VERIFY_VALUE1: Option<u64> = None;
47
48    /// The second verification value.
49    ///
50    /// # Architecture-specific
51    ///
52    /// - **AMD64**: `RBX`
53    const VERIFY_VALUE2: Option<u64> = None;
54
55    /// The third verification value.
56    ///
57    /// # Architecture-specific
58    ///
59    /// - **AMD64**: `RCX`
60    const VERIFY_VALUE3: Option<u64> = None;
61
62    /// The fourth verification value.
63    ///
64    /// # Architecture-specific
65    ///
66    /// - **AMD64**: `RDX`
67    const VERIFY_VALUE4: Option<u64> = None;
68}
69
70macro_rules! impl_bridge_dispatch {
71    ($($ty:ident),*) => {
72        #[allow(non_snake_case)]
73        impl<Driver, Os, T, $($ty),*> BridgeDispatch<Driver, Os, T> for ($($ty),+,)
74        where
75            Driver: VmiDriver,
76            Os: VmiOs<Driver>,
77            $($ty: BridgeHandler<Driver, Os, T>,)+
78        {
79            fn dispatch(&mut self, vmi: &VmiContext<'_, Driver, Os>, packet: BridgePacket) -> Option<BridgeResponse<T>> {
80                let ($($ty,)+) = self;
81
82                $(
83                    if packet.request() == <$ty as BridgeHandler<Driver, Os, T>>::REQUEST {
84                        return $ty.dispatch(vmi, packet);
85                    }
86                )*
87
88                None
89            }
90        }
91    };
92}
93
94impl<Driver, Os, T> BridgeDispatch<Driver, Os, T> for ()
95where
96    Driver: VmiDriver,
97    Os: VmiOs<Driver>,
98{
99    fn dispatch(
100        &mut self,
101        _vmi: &VmiContext<'_, Driver, Os>,
102        _packet: BridgePacket,
103    ) -> Option<BridgeResponse<T>> {
104        None
105    }
106}
107
108impl<Driver, Os, T> BridgeHandler<Driver, Os, T> for ()
109where
110    Driver: VmiDriver,
111    Os: VmiOs<Driver>,
112{
113    const EMPTY: bool = true;
114    const MAGIC: u32 = 0;
115    const REQUEST: u16 = 0;
116}
117
118impl_bridge_dispatch!(B1);
119impl_bridge_dispatch!(B1, B2);
120impl_bridge_dispatch!(B1, B2, B3);
121impl_bridge_dispatch!(B1, B2, B3, B4);
122impl_bridge_dispatch!(B1, B2, B3, B4, B5);
123impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6);
124impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7);
125impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8);
126impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9);
127impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10);
128impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11);
129impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12);
130impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13);
131impl_bridge_dispatch!(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14);
132impl_bridge_dispatch!(
133    B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15
134);
135impl_bridge_dispatch!(
136    B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16
137);
138
139/// A bridge.
140pub struct Bridge<Driver, Os, B, T = ()>
141where
142    Driver: VmiDriver,
143    Os: VmiOs<Driver>,
144    B: BridgeDispatch<Driver, Os, T>,
145{
146    handlers: B,
147    _phantom: std::marker::PhantomData<(Driver, Os, T)>,
148}
149
150impl<Driver, Os, B, T> Bridge<Driver, Os, B, T>
151where
152    Driver: VmiDriver,
153    Os: VmiOs<Driver>,
154    B: BridgeDispatch<Driver, Os, T>,
155{
156    /// Creates a new bridge.
157    pub fn new(handlers: B) -> Self {
158        Self {
159            handlers,
160            _phantom: std::marker::PhantomData,
161        }
162    }
163}
164
165impl<Driver, Os, B, T> BridgeDispatch<Driver, Os, T> for Bridge<Driver, Os, B, T>
166where
167    Driver: VmiDriver,
168    Os: VmiOs<Driver>,
169    B: BridgeDispatch<Driver, Os, T>,
170{
171    fn dispatch(
172        &mut self,
173        vmi: &VmiContext<'_, Driver, Os>,
174        packet: BridgePacket,
175    ) -> Option<BridgeResponse<T>> {
176        self.handlers.dispatch(vmi, packet)
177    }
178}