1#![allow(missing_docs)]
6
7use std::convert::From;
8use std::net::Ipv4Addr;
9use std::num::NonZeroUsize;
10use std::str::FromStr;
11use std::sync::{Arc, Mutex};
12
13use utils::time::timestamp_cycles;
14
15use crate::dumbo::pdu::Incomplete;
16use crate::dumbo::pdu::arp::{
17 ArpError as ArpFrameError, ETH_IPV4_FRAME_LEN, EthIPv4ArpFrame, test_speculative_tpa,
18};
19use crate::dumbo::pdu::ethernet::{
20 ETHERTYPE_ARP, ETHERTYPE_IPV4, EthernetError as EthernetFrameError, EthernetFrame,
21};
22use crate::dumbo::pdu::ipv4::{
23 IPv4Packet, Ipv4Error as IPv4PacketError, PROTOCOL_TCP, test_speculative_dst_addr,
24};
25use crate::dumbo::pdu::tcp::TcpError as TcpSegmentError;
26use crate::dumbo::tcp::NextSegmentStatus;
27use crate::dumbo::tcp::handler::{RecvEvent, TcpIPv4Handler, WriteEvent, WriteNextError};
28use crate::logger::{IncMetric, METRICS};
29use crate::mmds::data_store::Mmds;
30use crate::utils::net::mac::MacAddr;
31
32const DEFAULT_MAC_ADDR: &str = "06:01:23:45:67:01";
33const DEFAULT_IPV4_ADDR: [u8; 4] = [169, 254, 169, 254];
34const DEFAULT_TCP_PORT: u16 = 80;
35const DEFAULT_MAX_CONNECTIONS: usize = 30;
36const DEFAULT_MAX_PENDING_RESETS: usize = 100;
37
38#[derive(Debug, PartialEq, thiserror::Error, displaydoc::Display)]
39enum WriteArpFrameError {
40 NoPendingArpReply,
42 Arp(#[from] ArpFrameError),
44 Ethernet(#[from] EthernetFrameError),
46}
47
48#[derive(Debug, PartialEq, thiserror::Error, displaydoc::Display)]
49enum WritePacketError {
50 IPv4Packet(#[from] IPv4PacketError),
52 Ethernet(#[from] EthernetFrameError),
54 TcpSegment(#[from] TcpSegmentError),
56 WriteNext(#[from] WriteNextError),
58}
59
60#[derive(Debug)]
61pub struct MmdsNetworkStack {
62 remote_mac_addr: MacAddr,
64 pub(crate) mac_addr: MacAddr,
66 pub ipv4_addr: Ipv4Addr,
68 pending_arp_reply_dest: Option<Ipv4Addr>,
72 pub(crate) tcp_handler: TcpIPv4Handler,
74 pub mmds: Arc<Mutex<Mmds>>,
76}
77
78impl MmdsNetworkStack {
79 pub fn new(
80 mac_addr: MacAddr,
81 ipv4_addr: Ipv4Addr,
82 tcp_port: u16,
83 mmds: Arc<Mutex<Mmds>>,
84 ) -> Self {
85 MmdsNetworkStack {
86 remote_mac_addr: mac_addr,
87 mac_addr,
88 ipv4_addr,
89 pending_arp_reply_dest: None,
90 tcp_handler: TcpIPv4Handler::new(
91 ipv4_addr,
92 tcp_port,
93 NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
94 NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
95 ),
96 mmds,
97 }
98 }
99
100 pub fn new_with_defaults(mmds_ipv4_addr: Option<Ipv4Addr>, mmds: Arc<Mutex<Mmds>>) -> Self {
101 let mac_addr = MacAddr::from_str(DEFAULT_MAC_ADDR).unwrap();
102 let ipv4_addr = mmds_ipv4_addr.unwrap_or_else(|| Ipv4Addr::from(DEFAULT_IPV4_ADDR));
103
104 Self::new(mac_addr, ipv4_addr, DEFAULT_TCP_PORT, mmds)
106 }
107
108 pub fn set_ipv4_addr(&mut self, ipv4_addr: Ipv4Addr) {
109 self.ipv4_addr = ipv4_addr;
110 self.tcp_handler.set_local_ipv4_addr(ipv4_addr);
111 }
112
113 pub fn ipv4_addr(&self) -> Ipv4Addr {
114 self.ipv4_addr
115 }
116
117 pub fn default_ipv4_addr() -> Ipv4Addr {
118 Ipv4Addr::from(DEFAULT_IPV4_ADDR)
119 }
120
121 pub fn is_mmds_frame(&self, src: &[u8]) -> bool {
126 if let Ok(eth) = EthernetFrame::from_bytes(src) {
127 match eth.ethertype() {
128 ETHERTYPE_ARP => test_speculative_tpa(src, self.ipv4_addr),
129 ETHERTYPE_IPV4 => test_speculative_dst_addr(src, self.ipv4_addr),
130 _ => false,
131 }
132 } else {
133 false
134 }
135 }
136
137 pub fn detour_frame(&mut self, src: &[u8]) -> bool {
146 if let Ok(eth) = EthernetFrame::from_bytes(src) {
147 match eth.ethertype() {
148 ETHERTYPE_ARP => return self.detour_arp(eth),
149 ETHERTYPE_IPV4 => return self.detour_ipv4(eth),
150 _ => (),
151 }
152 } else {
153 METRICS.mmds.rx_bad_eth.inc();
154 }
155
156 false
157 }
158
159 fn detour_arp(&mut self, eth: EthernetFrame<&[u8]>) -> bool {
160 if let Ok(arp) = EthIPv4ArpFrame::request_from_bytes(eth.payload()) {
161 self.remote_mac_addr = arp.sha();
162 self.pending_arp_reply_dest = Some(arp.spa());
163 return true;
164 }
165
166 false
167 }
168
169 fn detour_ipv4(&mut self, eth: EthernetFrame<&[u8]>) -> bool {
170 if let Ok(ip) = IPv4Packet::from_bytes(eth.payload(), false) {
174 if ip.protocol() == PROTOCOL_TCP {
175 self.remote_mac_addr = eth.src_mac();
180 let mmds_instance = self.mmds.clone();
181 match &mut self.tcp_handler.receive_packet(&ip, move |request| {
182 super::convert_to_response(mmds_instance, request)
183 }) {
184 Ok(event) => {
185 METRICS.mmds.rx_count.inc();
186 match event {
187 RecvEvent::NewConnectionSuccessful => {
188 METRICS.mmds.connections_created.inc()
189 }
190 RecvEvent::NewConnectionReplacing => {
191 METRICS.mmds.connections_created.inc();
192 METRICS.mmds.connections_destroyed.inc();
193 }
194 RecvEvent::EndpointDone => {
195 METRICS.mmds.connections_destroyed.inc();
196 }
197 _ => (),
198 }
199 }
200 Err(_) => METRICS.mmds.rx_accepted_err.inc(),
201 }
202 } else {
203 METRICS.mmds.rx_accepted_unusual.inc();
205 }
206 return true;
207 }
208
209 false
210 }
211
212 pub fn write_next_frame(&mut self, buf: &mut [u8]) -> Option<NonZeroUsize> {
217 if self.pending_arp_reply_dest.is_some() {
219 return match self.write_arp_reply(buf) {
220 Ok(something) => {
221 METRICS.mmds.tx_count.inc();
222 self.pending_arp_reply_dest = None;
223 something
224 }
225 Err(_) => {
226 METRICS.mmds.tx_errors.inc();
227 None
228 }
229 };
230 } else {
231 let call_write = match self.tcp_handler.next_segment_status() {
232 NextSegmentStatus::Available => true,
233 NextSegmentStatus::Timeout(value) => timestamp_cycles() >= value,
234 NextSegmentStatus::Nothing => false,
235 };
236
237 if call_write {
238 return match self.write_packet(buf) {
239 Ok(something) => {
240 METRICS.mmds.tx_count.inc();
241 something
242 }
243 Err(_) => {
244 METRICS.mmds.tx_errors.inc();
245 None
246 }
247 };
248 }
249 }
250 None
251 }
252
253 fn prepare_eth_unsized<'a>(
254 &self,
255 buf: &'a mut [u8],
256 ethertype: u16,
257 ) -> Result<Incomplete<EthernetFrame<'a, &'a mut [u8]>>, EthernetFrameError> {
258 EthernetFrame::write_incomplete(buf, self.remote_mac_addr, self.mac_addr, ethertype)
259 }
260
261 fn write_arp_reply(&self, buf: &mut [u8]) -> Result<Option<NonZeroUsize>, WriteArpFrameError> {
262 let arp_reply_dest = self
263 .pending_arp_reply_dest
264 .ok_or(WriteArpFrameError::NoPendingArpReply)?;
265
266 let mut eth_unsized = self.prepare_eth_unsized(buf, ETHERTYPE_ARP)?;
267
268 let arp_len = EthIPv4ArpFrame::write_reply(
269 eth_unsized
270 .inner_mut()
271 .payload_mut()
272 .split_at_mut(ETH_IPV4_FRAME_LEN)
273 .0,
274 self.mac_addr,
275 self.ipv4_addr,
276 self.remote_mac_addr,
277 arp_reply_dest,
278 )?
279 .len();
280
281 Ok(Some(
282 NonZeroUsize::new(eth_unsized.with_payload_len_unchecked(arp_len).len()).unwrap(),
284 ))
285 }
286
287 fn write_packet(&mut self, buf: &mut [u8]) -> Result<Option<NonZeroUsize>, WritePacketError> {
288 let mut eth_unsized = self.prepare_eth_unsized(buf, ETHERTYPE_IPV4)?;
289
290 let (maybe_len, event) = self
291 .tcp_handler
292 .write_next_packet(eth_unsized.inner_mut().payload_mut())?;
293
294 if let WriteEvent::EndpointDone = event {
295 METRICS.mmds.connections_destroyed.inc()
296 }
297
298 if let Some(packet_len) = maybe_len {
299 return Ok(Some(
300 NonZeroUsize::new(
302 eth_unsized
303 .with_payload_len_unchecked(packet_len.get())
304 .len(),
305 )
306 .unwrap(),
307 ));
308 }
309
310 Ok(None)
311 }
312}
313
314#[cfg(test)]
315mod tests {
316 use std::str::FromStr;
317
318 use super::*;
319 use crate::dumbo::pdu::tcp::{Flags as TcpFlags, TcpSegment};
320
321 const REMOTE_ADDR: Ipv4Addr = Ipv4Addr::LOCALHOST;
324 const REMOTE_MAC_STR: &str = "11:11:11:22:22:22";
325 const MMDS_PORT: u16 = 80;
326 const REMOTE_PORT: u16 = 1235;
327 const SEQ_NUMBER: u32 = 123;
328
329 impl MmdsNetworkStack {
331 fn write_arp_request(&mut self, buf: &mut [u8], for_mmds: bool) -> usize {
332 self.pending_arp_reply_dest = Some(REMOTE_ADDR);
334 let len = self.write_arp_reply(buf).unwrap().unwrap().get();
335 self.pending_arp_reply_dest = None;
336
337 let mut eth = EthernetFrame::from_bytes_unchecked(&mut buf[..len]);
338 let mut arp = EthIPv4ArpFrame::from_bytes_unchecked(eth.payload_mut());
339
340 arp.set_operation(1);
342 arp.set_sha(MacAddr::from_str(REMOTE_MAC_STR).unwrap());
343 arp.set_spa(REMOTE_ADDR);
344
345 if for_mmds {
347 arp.set_tpa(self.ipv4_addr);
348 }
349 len
350 }
351
352 fn write_incoming_tcp_segment(
353 &self,
354 buf: &mut [u8],
355 addr: Ipv4Addr,
356 flags: TcpFlags,
357 ) -> usize {
358 let mut eth_unsized = self.prepare_eth_unsized(buf, ETHERTYPE_IPV4).unwrap();
359 let packet_len = {
360 let mut packet = IPv4Packet::write_header(
361 eth_unsized.inner_mut().payload_mut(),
362 PROTOCOL_TCP,
363 REMOTE_ADDR,
364 addr,
365 )
366 .unwrap();
367
368 let segment_len = TcpSegment::write_incomplete_segment::<[u8]>(
369 packet.inner_mut().payload_mut(),
370 SEQ_NUMBER,
371 1234,
372 flags,
373 10000,
374 None,
375 0,
376 None,
377 )
378 .unwrap()
379 .finalize(REMOTE_PORT, MMDS_PORT, Some((REMOTE_ADDR, addr)))
380 .len();
381
382 packet.with_payload_len_unchecked(segment_len, true).len()
383 };
384
385 eth_unsized.with_payload_len_unchecked(packet_len).len()
386 }
387
388 fn next_frame_as_ipv4_packet<'a>(&mut self, buf: &'a mut [u8]) -> IPv4Packet<'_, &'a [u8]> {
389 let len = self.write_next_frame(buf).unwrap().get();
390 let eth = EthernetFrame::from_bytes(&buf[..len]).unwrap();
391 IPv4Packet::from_bytes(&buf[eth.payload_offset()..len], true).unwrap()
392 }
393 }
394
395 #[test]
396 fn test_ns_new_with_defaults() {
397 let ns = MmdsNetworkStack::new_with_defaults(None, Arc::new(Mutex::new(Mmds::default())));
398 assert_eq!(ns.mac_addr, MacAddr::from_str(DEFAULT_MAC_ADDR).unwrap());
399 assert_eq!(ns.ipv4_addr, Ipv4Addr::from(DEFAULT_IPV4_ADDR));
400
401 let ns = MmdsNetworkStack::new_with_defaults(
402 Some(Ipv4Addr::LOCALHOST),
403 Arc::new(Mutex::new(Mmds::default())),
404 );
405 assert_eq!(ns.mac_addr, MacAddr::from_str(DEFAULT_MAC_ADDR).unwrap());
406 assert_eq!(ns.ipv4_addr, Ipv4Addr::LOCALHOST);
407 }
408
409 #[test]
410 #[allow(clippy::cognitive_complexity)]
411 fn test_ns() {
412 let mut ns =
413 MmdsNetworkStack::new_with_defaults(None, Arc::new(Mutex::new(Mmds::default())));
414 let mut buf = [0u8; 2000];
415 let mut bad_buf = [0u8; 1];
416
417 let remote_mac = MacAddr::from_str(REMOTE_MAC_STR).unwrap();
418 let mmds_addr = ns.ipv4_addr;
419 let bad_mmds_addr = Ipv4Addr::from_str("1.2.3.4").unwrap();
420
421 assert!(!ns.is_mmds_frame(&bad_buf));
423 assert!(!ns.detour_frame(bad_buf.as_ref()));
424
425 assert!(ns.write_next_frame(buf.as_mut()).is_none());
427
428 {
429 let len = ns.write_arp_request(buf.as_mut(), false);
430 assert!(!ns.is_mmds_frame(&buf[..len]));
432 assert!(ns.write_next_frame(buf.as_mut()).is_none());
434 }
435
436 {
437 let len = ns.write_arp_request(buf.as_mut(), true);
438
439 assert!(ns.detour_frame(&buf[..len]));
441 assert_eq!(ns.remote_mac_addr, remote_mac);
442 }
443
444 {
446 assert!(ns.write_next_frame(bad_buf.as_mut()).is_none());
448 let curr_tx_count = METRICS.mmds.tx_count.count();
449 let len = ns.write_next_frame(buf.as_mut()).unwrap().get();
450 assert_eq!(curr_tx_count + 1, METRICS.mmds.tx_count.count());
451 let eth = EthernetFrame::from_bytes(&buf[..len]).unwrap();
452 let arp_reply = EthIPv4ArpFrame::from_bytes_unchecked(eth.payload());
453
454 assert_eq!(arp_reply.operation(), 2);
456 assert_eq!(arp_reply.sha(), ns.mac_addr);
457 assert_eq!(arp_reply.spa(), ns.ipv4_addr);
458 assert_eq!(arp_reply.tha(), ns.remote_mac_addr);
459 assert_eq!(arp_reply.tpa(), REMOTE_ADDR);
460 }
461
462 assert!(ns.write_next_frame(buf.as_mut()).is_none());
464
465 {
468 let len = ns.write_incoming_tcp_segment(buf.as_mut(), bad_mmds_addr, TcpFlags::ACK);
469 assert!(!ns.is_mmds_frame(&buf[..len]));
470
471 assert!(ns.write_next_frame(buf.as_mut()).is_none());
473 }
474
475 {
477 let len = ns.write_incoming_tcp_segment(buf.as_mut(), mmds_addr, TcpFlags::ACK);
478 let curr_rx_count = METRICS.mmds.rx_count.count();
479 assert!(ns.detour_frame(&buf[..len]));
480 assert_eq!(curr_rx_count + 1, METRICS.mmds.rx_count.count());
481 }
482
483 {
485 assert!(ns.write_next_frame(bad_buf.as_mut()).is_none());
486
487 let ip = ns.next_frame_as_ipv4_packet(buf.as_mut());
488 assert_eq!(ip.source_address(), mmds_addr);
489 assert_eq!(ip.destination_address(), REMOTE_ADDR);
490
491 let s = TcpSegment::from_bytes(
492 ip.payload(),
493 Some((ip.source_address(), ip.destination_address())),
494 )
495 .unwrap();
496 assert_eq!(s.flags_after_ns(), TcpFlags::RST);
497 assert_eq!(s.source_port(), MMDS_PORT);
498 assert_eq!(s.destination_port(), REMOTE_PORT);
499 }
500
501 assert!(ns.write_next_frame(buf.as_mut()).is_none());
503
504 {
506 let len = ns.write_incoming_tcp_segment(buf.as_mut(), mmds_addr, TcpFlags::SYN);
507 assert!(ns.detour_frame(&buf[..len]));
508 }
509
510 {
512 let ip = ns.next_frame_as_ipv4_packet(buf.as_mut());
513 assert_eq!(ip.source_address(), mmds_addr);
514 assert_eq!(ip.destination_address(), REMOTE_ADDR);
515
516 let s = TcpSegment::from_bytes(
517 ip.payload(),
518 Some((ip.source_address(), ip.destination_address())),
519 )
520 .unwrap();
521 assert_eq!(s.flags_after_ns(), TcpFlags::SYN | TcpFlags::ACK);
522 assert_eq!(s.source_port(), MMDS_PORT);
523 assert_eq!(s.destination_port(), REMOTE_PORT);
524 assert_eq!(s.ack_number(), SEQ_NUMBER.wrapping_add(1));
525 }
526
527 assert!(ns.write_next_frame(buf.as_mut()).is_none());
529 }
530
531 #[test]
532 fn test_set_ipv4_addr() {
533 let mut ns =
534 MmdsNetworkStack::new_with_defaults(None, Arc::new(Mutex::new(Mmds::default())));
535 assert_ne!(ns.ipv4_addr, Ipv4Addr::LOCALHOST);
536 assert_ne!(ns.tcp_handler.local_ipv4_addr(), Ipv4Addr::LOCALHOST);
537 ns.set_ipv4_addr(Ipv4Addr::LOCALHOST);
538 assert_eq!(ns.ipv4_addr, Ipv4Addr::LOCALHOST);
539 assert_eq!(ns.tcp_handler.local_ipv4_addr(), Ipv4Addr::LOCALHOST);
540 }
541
542 #[test]
543 fn test_default_ipv4_addr() {
544 let actual = MmdsNetworkStack::default_ipv4_addr();
545 let expected = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
546 assert_eq!(actual, expected);
547 }
548
549 #[test]
550 fn test_break_speculative_check_detour_arp() {
551 let mut buf = [0u8; 2000];
552 let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
553 let other_ip = Ipv4Addr::new(5, 6, 7, 8);
554 let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
555 let mut ns =
556 MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
557
558 let mut eth =
559 EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_ARP).unwrap();
560 let mut arp = EthIPv4ArpFrame::from_bytes_unchecked(eth.inner_mut().payload_mut());
561 arp.set_tpa(other_ip);
562 let len = ns.write_arp_request(buf.as_mut(), false);
563
564 eth = EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_ARP).unwrap();
565 IPv4Packet::from_bytes_unchecked(eth.inner_mut().payload_mut()).set_destination_address(ip);
566
567 assert!(!ns.is_mmds_frame(&buf[..len]));
568 }
569
570 #[test]
571 fn test_break_speculative_check_detour_ipv4() {
572 let mut buf = [0u8; 2000];
573 let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
574 let other_ip = Ipv4Addr::new(5, 6, 7, 8);
575 let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
576 let ns =
577 MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
578
579 let mut eth =
580 EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_IPV4).unwrap();
581 IPv4Packet::from_bytes_unchecked(eth.inner_mut().payload_mut())
582 .set_destination_address(other_ip);
583 let len = ns.write_incoming_tcp_segment(buf.as_mut(), other_ip, TcpFlags::SYN);
584 eth = EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_IPV4).unwrap();
585 let mut arp = EthIPv4ArpFrame::from_bytes_unchecked(eth.inner_mut().payload_mut());
586 arp.set_tpa(ip);
587 assert!(!ns.is_mmds_frame(&buf[..len]));
588 }
589
590 #[test]
591 fn test_wrong_ethertype() {
592 let mut buf = [0u8; 2000];
593 let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
594 let other_ip = Ipv4Addr::new(5, 6, 7, 8);
595 let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
596 let mut ns =
597 MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
598
599 let mut eth =
601 EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_IPV4).unwrap();
602 IPv4Packet::from_bytes_unchecked(eth.inner_mut().payload_mut())
603 .set_destination_address(other_ip);
604 let len = ns.write_incoming_tcp_segment(buf.as_mut(), other_ip, TcpFlags::SYN);
605
606 eth = EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_IPV4).unwrap();
607 let mut arp = EthIPv4ArpFrame::from_bytes_unchecked(eth.inner_mut().payload_mut());
608 arp.set_tpa(ip);
609
610 assert!(ns.detour_ipv4(EthernetFrame::from_bytes(&buf[..len]).unwrap()));
611 assert!(!ns.detour_arp(EthernetFrame::from_bytes(&buf[..len]).unwrap()));
612
613 let mut eth =
615 EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_ARP).unwrap();
616 let mut arp = EthIPv4ArpFrame::from_bytes_unchecked(eth.inner_mut().payload_mut());
617 arp.set_tpa(other_ip);
618 let len = ns.write_arp_request(buf.as_mut(), false);
619
620 eth = EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_ARP).unwrap();
621 IPv4Packet::from_bytes_unchecked(eth.inner_mut().payload_mut()).set_destination_address(ip);
622
623 assert!(ns.detour_arp(EthernetFrame::from_bytes(&buf[..len]).unwrap()));
624 assert!(!ns.detour_ipv4(EthernetFrame::from_bytes(&buf[..len]).unwrap()));
625 }
626}