1use ::std::{
9 fmt::Debug,
10 net::SocketAddr,
11 time::Duration,
12};
13
14#[derive(Clone, Debug)]
17pub struct Event {
18 pub time: Duration,
19 pub action: Action,
20}
21
22#[derive(Clone, Debug)]
23pub enum Action {
24 SyscallEvent(SyscallEvent),
25 PacketEvent(PacketEvent),
26}
27
28#[derive(Clone, Debug)]
29pub struct SyscallEvent {
30 pub end_time: Option<Duration>,
31 pub syscall: DemikernelSyscall,
32}
33
34#[derive(Clone)]
35#[allow(dead_code)]
36pub enum DemikernelSyscall {
37 Socket(SocketArgs, i32),
38 Bind(BindArgs, i32),
39 Listen(ListenArgs, i32),
40 Accept(AcceptArgs, i32),
41 Connect(ConnectArgs, i32),
42 Push(PushArgs, i32),
43 PushTo(PushToArgs, i32),
44 Pop(PopArgs, i32),
45 Close(CloseArgs, i32),
46 Wait(WaitArgs, i32),
47 Unsupported,
48}
49
50impl Debug for DemikernelSyscall {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self {
53 DemikernelSyscall::Socket(args, _qd) => write!(f, "demi_socket({:?})", args),
54 DemikernelSyscall::Bind(args, _ok) => write!(f, "demi_bind({:?})", args),
55 DemikernelSyscall::Listen(args, _ok) => write!(f, "demi_listen({:?})", args),
56 DemikernelSyscall::Accept(args, _qd) => write!(f, "demi_accept({:?})", args),
57 DemikernelSyscall::Connect(args, _ok) => write!(f, "demi_connect({:?})", args),
58 DemikernelSyscall::Push(args, _ret) => write!(f, "demi_push({:?})", args),
59 DemikernelSyscall::PushTo(args, _ret) => write!(f, "demi_pushto({:?})", args),
60 DemikernelSyscall::Pop(args, _ret) => write!(f, "demi_pop({:?})", args),
61 DemikernelSyscall::Close(args, _ret) => write!(f, "demi_close({:?})", args),
62 DemikernelSyscall::Wait(args, _ret) => write!(f, "demi_wait({:?})", args),
63 DemikernelSyscall::Unsupported => write!(f, "Unsupported"),
64 }
65 }
66}
67
68#[derive(Clone, Debug, PartialEq)]
69#[allow(non_camel_case_types)]
70pub enum SocketDomain {
71 AF_INET,
72}
73
74#[derive(Clone, Debug, PartialEq)]
75#[allow(non_camel_case_types)]
76pub enum SocketType {
77 SOCK_STREAM,
78 SOCK_DGRAM,
79}
80
81#[derive(Clone, Debug, PartialEq)]
82#[allow(non_camel_case_types)]
83pub enum SocketProtocol {
84 IPPROTO_TCP,
85 IPPROTO_UDP,
86}
87
88#[derive(Clone, Debug)]
89pub struct SocketArgs {
90 pub domain: SocketDomain,
91 pub typ: SocketType,
92 pub protocol: SocketProtocol,
93}
94
95#[derive(Clone, Debug)]
96pub struct BindArgs {
97 pub qd: Option<u32>,
98 pub addr: Option<SocketAddr>,
99}
100
101#[derive(Clone, Debug)]
102pub struct ListenArgs {
103 pub qd: Option<u32>,
104 pub backlog: Option<usize>,
105}
106
107#[derive(Clone, Debug)]
108pub struct AcceptArgs {
109 pub qd: Option<u32>,
110}
111
112#[derive(Clone, Debug)]
113pub struct ConnectArgs {
114 pub qd: Option<u32>,
115 pub addr: Option<SocketAddr>,
116}
117
118#[derive(Clone, Debug)]
119pub struct PushArgs {
120 pub qd: Option<u32>,
121 pub buf: Option<Vec<u8>>,
122 pub len: Option<u32>,
123}
124
125#[derive(Clone, Debug)]
126pub struct PushToArgs {
127 pub qd: Option<u32>,
128 pub buf: Option<Vec<u8>>,
129 pub len: Option<u32>,
130 pub addr: Option<SocketAddr>,
131}
132
133#[derive(Clone, Debug)]
134pub struct PopArgs {
135 pub qd: u32,
136 pub len: Option<u32>,
137}
138
139#[derive(Clone, Debug)]
140pub struct WaitArgs {
141 pub qd: Option<u32>,
142 pub timeout: Option<Duration>,
143}
144
145#[derive(Clone, Debug)]
146pub struct CloseArgs {
147 pub qd: u32,
148}
149
150#[derive(Clone, Debug)]
151pub enum PacketEvent {
152 Tcp(PacketDirection, TcpPacket),
153 Udp(PacketDirection, UdpPacket),
154}
155
156#[derive(Clone, Debug, PartialEq)]
157pub enum PacketDirection {
158 Incoming,
159 Outgoing,
160}
161
162#[derive(Clone, Debug)]
163pub struct TcpPacket {
164 pub flags: TcpFlags,
165 pub seqnum: TcpSequenceNumber,
166 pub ack: Option<u32>,
167 pub win: Option<u32>,
168 pub options: Vec<TcpOption>,
169}
170
171#[derive(Clone, Debug)]
172pub struct UdpPacket {
173 pub len: u32,
174}
175
176#[derive(Clone)]
177pub struct TcpFlags {
178 pub syn: bool,
179 pub ack: bool,
180 pub fin: bool,
181 pub rst: bool,
182 pub psh: bool,
183 pub urg: bool,
184 pub ece: bool,
185 pub cwr: bool,
186}
187
188#[derive(Clone, Debug)]
189pub struct TcpSequenceNumber {
190 pub seq: u32,
191 pub win: u32,
192}
193
194#[derive(Clone, Debug)]
195pub enum TcpOption {
196 Noop,
197 Mss(u16),
198 WindowScale(u8),
199 SackOk,
200 Timestamp(u32, u32),
201 EndOfOptions,
202}
203
204impl Debug for TcpFlags {
205 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206 let mut flags = String::new();
207 if self.syn {
208 flags.push_str("SYN ");
209 }
210 if self.ack {
211 flags.push_str("ACK ");
212 }
213 if self.fin {
214 flags.push_str("FIN ");
215 }
216 if self.rst {
217 flags.push_str("RST ");
218 }
219 if self.psh {
220 flags.push_str("PSH ");
221 }
222 if self.urg {
223 flags.push_str("URG ");
224 }
225 if self.ece {
226 flags.push_str("ECE ");
227 }
228 if self.cwr {
229 flags.push_str("CWR ");
230 }
231 write!(f, "{}", flags)
232 }
233}
234
235pub fn parse_int(s: &str) -> Result<u32, ()> {
236 match s.parse::<u32>() {
237 Ok(val) => Ok(val),
238 Err(_) => {
239 eprintln!("{} cannot be represented as a u32", s);
240 Err(())
241 },
242 }
243}
244
245pub fn parse_ret_code(s: &str) -> Result<i32, ()> {
246 if let Ok(val) = s.parse::<i32>() {
247 Ok(val)
248 } else {
249 match s {
251 "EPERM" => Ok(libc::EPERM),
252 "ENOENT" => Ok(libc::ENOENT),
253 "ESRCH" => Ok(libc::ESRCH),
254 "EINTR" => Ok(libc::EINTR),
255 "EIO" => Ok(libc::EIO),
256 "ENXIO" => Ok(libc::ENXIO),
257 "E2BIG" => Ok(libc::E2BIG),
258 "ENOEXEC" => Ok(libc::ENOEXEC),
259 "EBADF" => Ok(libc::EBADF),
260 "ECHILD" => Ok(libc::ECHILD),
261 "EAGAIN" => Ok(libc::EAGAIN),
262 "ENOMEM" => Ok(libc::ENOMEM),
263 "EACCES" => Ok(libc::EACCES),
264 "EFAULT" => Ok(libc::EFAULT),
265 "EBUSY" => Ok(libc::EBUSY),
266 "EEXIST" => Ok(libc::EEXIST),
267 "EXDEV" => Ok(libc::EXDEV),
268 "ENODEV" => Ok(libc::ENODEV),
269 "ENOTDIR" => Ok(libc::ENOTDIR),
270 "EISDIR" => Ok(libc::EISDIR),
271 "EINVAL" => Ok(libc::EINVAL),
272 "ENFILE" => Ok(libc::ENFILE),
273 "EMFILE" => Ok(libc::EMFILE),
274 "ENOTTY" => Ok(libc::ENOTTY),
275 "EFBIG" => Ok(libc::EFBIG),
276 "ENOSPC" => Ok(libc::ENOSPC),
277 "ESPIPE" => Ok(libc::ESPIPE),
278 "EROFS" => Ok(libc::EROFS),
279 "EMLINK" => Ok(libc::EMLINK),
280 "EPIPE" => Ok(libc::EPIPE),
281 "EDOM" => Ok(libc::EDOM),
282 "ERANGE" => Ok(libc::ERANGE),
283 "EDEADLK" => Ok(libc::EDEADLK),
284 "EDEADLOCK" => Ok(libc::EDEADLOCK),
285 "ENAMETOOLONG" => Ok(libc::ENAMETOOLONG),
286 "ENOLCK" => Ok(libc::ENOLCK),
287 "ENOSYS" => Ok(libc::ENOSYS),
288 "ENOTEMPTY" => Ok(libc::ENOTEMPTY),
289 "EILSEQ" => Ok(libc::EILSEQ),
290 "EADDRINUSE" => Ok(libc::EADDRINUSE),
291 "EADDRNOTAVAIL" => Ok(libc::EADDRNOTAVAIL),
292 "EAFNOSUPPORT" => Ok(libc::EAFNOSUPPORT),
293 "EALREADY" => Ok(libc::EALREADY),
294 "EBADMSG" => Ok(libc::EBADMSG),
295 "ECANCELED" => Ok(libc::ECANCELED),
296 "ECONNABORTED" => Ok(libc::ECONNABORTED),
297 "ECONNREFUSED" => Ok(libc::ECONNREFUSED),
298 "ECONNRESET" => Ok(libc::ECONNRESET),
299 "EDESTADDRREQ" => Ok(libc::EDESTADDRREQ),
300 "EHOSTUNREACH" => Ok(libc::EHOSTUNREACH),
301 "EIDRM" => Ok(libc::EIDRM),
302 "EINPROGRESS" => Ok(libc::EINPROGRESS),
303 "EISCONN" => Ok(libc::EISCONN),
304 "ELOOP" => Ok(libc::ELOOP),
305 "EMSGSIZE" => Ok(libc::EMSGSIZE),
306 "ENETDOWN" => Ok(libc::ENETDOWN),
307 "ENETRESET" => Ok(libc::ENETRESET),
308 "ENETUNREACH" => Ok(libc::ENETUNREACH),
309 "ENOBUFS" => Ok(libc::ENOBUFS),
310 "ENODATA" => Ok(libc::ENODATA),
311 "ENOLINK" => Ok(libc::ENOLINK),
312 "ENOMSG" => Ok(libc::ENOMSG),
313 "ENOPROTOOPT" => Ok(libc::ENOPROTOOPT),
314 "ENOSR" => Ok(libc::ENOSR),
315 "ENOSTR" => Ok(libc::ENOSTR),
316 "ENOTCONN" => Ok(libc::ENOTCONN),
317 "ENOTRECOVERABLE" => Ok(libc::ENOTRECOVERABLE),
318 "ENOTSOCK" => Ok(libc::ENOTSOCK),
319 "ENOTSUP" => Ok(libc::ENOTSUP),
320 "EOPNOTSUPP" => Ok(libc::EOPNOTSUPP),
321 "EOVERFLOW" => Ok(libc::EOVERFLOW),
322 "EOWNERDEAD" => Ok(libc::EOWNERDEAD),
323 "EPROTO" => Ok(libc::EPROTO),
324 "EPROTONOSUPPORT" => Ok(libc::EPROTONOSUPPORT),
325 "EPROTOTYPE" => Ok(libc::EPROTOTYPE),
326 "ETIME" => Ok(libc::ETIME),
327 "ETIMEDOUT" => Ok(libc::ETIMEDOUT),
328 "ETXTBSY" => Ok(libc::ETXTBSY),
329 "EWOULDBLOCK" => Ok(libc::EWOULDBLOCK),
330 _ => panic!("Unknown error code"),
331 }
332 }
333}