1#![allow(dead_code)]
8
9use alloc::{collections::BTreeMap, string::String, vec::Vec};
10
11use crate::net::Ipv4Address;
12
13const DEFAULT_MTU: u16 = 1500;
17
18const MAX_NAME_LEN: usize = 16;
20
21const MAX_QUEUE_DEPTH: usize = 256;
23
24const MAX_TUNNELS: usize = 64;
26
27const MAX_ROUTES: usize = 128;
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
34pub enum TunnelType {
35 #[default]
37 Tun,
38 Tap,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
44pub enum TunnelState {
45 #[default]
47 Down,
48 Up,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
54pub enum EncapProtocol {
55 #[default]
57 Udp,
58 Tcp,
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum TunnelError {
65 AlreadyExists,
67 NotFound,
69 NotUp,
71 AlreadyUp,
73 PacketTooLarge,
75 QueueFull,
77 QueueEmpty,
79 TooManyTunnels,
81 TooManyRoutes,
83 RouteExists,
85 RouteNotFound,
87 InvalidName,
89 InvalidMtu,
91}
92
93#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
97pub struct TunnelStats {
98 pub tx_packets: u64,
100 pub rx_packets: u64,
102 pub tx_bytes: u64,
104 pub rx_bytes: u64,
106 pub tx_errors: u64,
108 pub rx_errors: u64,
110}
111
112#[derive(Debug, Clone, PartialEq)]
116pub struct TunnelConfig {
117 pub name: String,
119 pub tunnel_type: TunnelType,
121 pub mtu: u16,
123 pub local_address: Ipv4Address,
125 pub peer_address: Ipv4Address,
127 pub subnet_mask: Ipv4Address,
129}
130
131impl TunnelConfig {
132 pub fn new(
134 name: &str,
135 tunnel_type: TunnelType,
136 local_address: Ipv4Address,
137 peer_address: Ipv4Address,
138 subnet_mask: Ipv4Address,
139 ) -> Self {
140 Self {
141 name: String::from(name),
142 tunnel_type,
143 mtu: DEFAULT_MTU,
144 local_address,
145 peer_address,
146 subnet_mask,
147 }
148 }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq)]
155pub struct EncapsulationHeader {
156 pub src_ip: Ipv4Address,
158 pub dst_ip: Ipv4Address,
160 pub protocol: EncapProtocol,
162 pub src_port: u16,
164 pub dst_port: u16,
166}
167
168impl EncapsulationHeader {
169 pub fn new(
171 src_ip: Ipv4Address,
172 dst_ip: Ipv4Address,
173 protocol: EncapProtocol,
174 src_port: u16,
175 dst_port: u16,
176 ) -> Self {
177 Self {
178 src_ip,
179 dst_ip,
180 protocol,
181 src_port,
182 dst_port,
183 }
184 }
185
186 pub fn to_bytes(&self) -> [u8; 20] {
188 let mut buf = [0u8; 20];
189 buf[0..4].copy_from_slice(&self.src_ip.0);
190 buf[4..8].copy_from_slice(&self.dst_ip.0);
191 buf[8] = match self.protocol {
192 EncapProtocol::Udp => 17,
193 EncapProtocol::Tcp => 6,
194 };
195 buf[9] = 0; buf[10..12].copy_from_slice(&self.src_port.to_be_bytes());
197 buf[12..14].copy_from_slice(&self.dst_port.to_be_bytes());
198 buf
200 }
201
202 pub fn overhead(&self) -> u16 {
204 match self.protocol {
206 EncapProtocol::Udp => 28,
207 EncapProtocol::Tcp => 40,
208 }
209 }
210}
211
212#[derive(Debug, PartialEq)]
216pub struct TunnelInterface {
217 config: TunnelConfig,
219 state: TunnelState,
221 tx_queue: Vec<Vec<u8>>,
223 rx_queue: Vec<Vec<u8>>,
225 stats: TunnelStats,
227 encap: Option<EncapsulationHeader>,
229}
230
231impl TunnelInterface {
232 pub fn create(config: TunnelConfig) -> Result<Self, TunnelError> {
234 if config.name.is_empty() || config.name.len() > MAX_NAME_LEN {
235 return Err(TunnelError::InvalidName);
236 }
237 if config.mtu == 0 {
238 return Err(TunnelError::InvalidMtu);
239 }
240
241 Ok(Self {
242 config,
243 state: TunnelState::Down,
244 tx_queue: Vec::new(),
245 rx_queue: Vec::new(),
246 stats: TunnelStats::default(),
247 encap: None,
248 })
249 }
250
251 pub fn bring_up(&mut self) -> Result<(), TunnelError> {
253 if self.state == TunnelState::Up {
254 return Err(TunnelError::AlreadyUp);
255 }
256 self.state = TunnelState::Up;
257 Ok(())
258 }
259
260 pub fn bring_down(&mut self) {
262 self.state = TunnelState::Down;
263 self.tx_queue.clear();
264 self.rx_queue.clear();
265 }
266
267 pub fn send_packet(&mut self, data: &[u8]) -> Result<(), TunnelError> {
269 if self.state != TunnelState::Up {
270 return Err(TunnelError::NotUp);
271 }
272 if data.len() > self.config.mtu as usize {
273 self.stats.tx_errors += 1;
274 return Err(TunnelError::PacketTooLarge);
275 }
276 if self.tx_queue.len() >= MAX_QUEUE_DEPTH {
277 self.stats.tx_errors += 1;
278 return Err(TunnelError::QueueFull);
279 }
280
281 self.stats.tx_packets += 1;
282 self.stats.tx_bytes += data.len() as u64;
283 self.tx_queue.push(data.to_vec());
284 Ok(())
285 }
286
287 pub fn receive_packet(&mut self) -> Result<Vec<u8>, TunnelError> {
289 if self.state != TunnelState::Up {
290 return Err(TunnelError::NotUp);
291 }
292 if self.rx_queue.is_empty() {
293 return Err(TunnelError::QueueEmpty);
294 }
295
296 let pkt = self.rx_queue.remove(0);
297 self.stats.rx_packets += 1;
298 self.stats.rx_bytes += pkt.len() as u64;
299 Ok(pkt)
300 }
301
302 pub fn inject_rx(&mut self, data: Vec<u8>) -> Result<(), TunnelError> {
305 if self.rx_queue.len() >= MAX_QUEUE_DEPTH {
306 self.stats.rx_errors += 1;
307 return Err(TunnelError::QueueFull);
308 }
309 self.rx_queue.push(data);
310 Ok(())
311 }
312
313 pub fn drain_tx(&mut self) -> Option<Vec<u8>> {
316 if self.tx_queue.is_empty() {
317 None
318 } else {
319 Some(self.tx_queue.remove(0))
320 }
321 }
322
323 pub fn set_mtu(&mut self, mtu: u16) -> Result<(), TunnelError> {
325 if mtu == 0 {
326 return Err(TunnelError::InvalidMtu);
327 }
328 self.config.mtu = mtu;
329 Ok(())
330 }
331
332 pub fn get_mtu(&self) -> u16 {
334 self.config.mtu
335 }
336
337 pub fn get_stats(&self) -> TunnelStats {
339 self.stats
340 }
341
342 pub fn name(&self) -> &str {
344 &self.config.name
345 }
346
347 pub fn tunnel_type(&self) -> TunnelType {
349 self.config.tunnel_type
350 }
351
352 pub fn state(&self) -> TunnelState {
354 self.state
355 }
356
357 pub fn config(&self) -> &TunnelConfig {
359 &self.config
360 }
361
362 pub fn set_encap(&mut self, encap: EncapsulationHeader) {
364 self.encap = Some(encap);
365 }
366
367 pub fn encap(&self) -> Option<&EncapsulationHeader> {
369 self.encap.as_ref()
370 }
371}
372
373#[derive(Debug, Clone, PartialEq, Eq)]
377pub struct TunnelRoute {
378 pub destination: Ipv4Address,
380 pub prefix_len: u8,
382 pub tunnel_name: String,
384 pub metric: u32,
386}
387
388pub struct RouteInjection {
390 routes: Vec<TunnelRoute>,
392}
393
394impl Default for RouteInjection {
395 fn default() -> Self {
396 Self::new()
397 }
398}
399
400impl RouteInjection {
401 pub fn new() -> Self {
403 Self { routes: Vec::new() }
404 }
405
406 pub fn add_route(
408 &mut self,
409 destination: Ipv4Address,
410 prefix_len: u8,
411 tunnel_name: &str,
412 metric: u32,
413 ) -> Result<(), TunnelError> {
414 for r in &self.routes {
416 if r.destination == destination
417 && r.prefix_len == prefix_len
418 && r.tunnel_name == tunnel_name
419 {
420 return Err(TunnelError::RouteExists);
421 }
422 }
423
424 if self.routes.len() >= MAX_ROUTES {
425 return Err(TunnelError::TooManyRoutes);
426 }
427
428 self.routes.push(TunnelRoute {
429 destination,
430 prefix_len,
431 tunnel_name: String::from(tunnel_name),
432 metric,
433 });
434 Ok(())
435 }
436
437 pub fn remove_route(
439 &mut self,
440 destination: Ipv4Address,
441 prefix_len: u8,
442 tunnel_name: &str,
443 ) -> Result<(), TunnelError> {
444 let idx = self
445 .routes
446 .iter()
447 .position(|r| {
448 r.destination == destination
449 && r.prefix_len == prefix_len
450 && r.tunnel_name == tunnel_name
451 })
452 .ok_or(TunnelError::RouteNotFound)?;
453
454 self.routes.remove(idx);
455 Ok(())
456 }
457
458 pub fn get_routes(&self) -> &[TunnelRoute] {
460 &self.routes
461 }
462
463 pub fn lookup(&self, dst: &Ipv4Address) -> Option<&TunnelRoute> {
465 let mut best: Option<&TunnelRoute> = None;
466 let dst_u32 = dst.to_u32();
467
468 for route in &self.routes {
469 let mask = if route.prefix_len == 0 {
470 0u32
471 } else {
472 u32::MAX << (32 - route.prefix_len)
473 };
474 let net = route.destination.to_u32() & mask;
475 if (dst_u32 & mask) == net {
476 match best {
477 None => best = Some(route),
478 Some(b) => {
479 if route.prefix_len > b.prefix_len
481 || (route.prefix_len == b.prefix_len && route.metric < b.metric)
482 {
483 best = Some(route);
484 }
485 }
486 }
487 }
488 }
489
490 best
491 }
492}
493
494pub struct TunnelManager {
498 tunnels: BTreeMap<String, TunnelInterface>,
500 routes: RouteInjection,
502}
503
504impl Default for TunnelManager {
505 fn default() -> Self {
506 Self::new()
507 }
508}
509
510impl TunnelManager {
511 pub fn new() -> Self {
513 Self {
514 tunnels: BTreeMap::new(),
515 routes: RouteInjection::new(),
516 }
517 }
518
519 pub fn create_tunnel(&mut self, config: TunnelConfig) -> Result<(), TunnelError> {
521 if self.tunnels.len() >= MAX_TUNNELS {
522 return Err(TunnelError::TooManyTunnels);
523 }
524 if self.tunnels.contains_key(&config.name) {
525 return Err(TunnelError::AlreadyExists);
526 }
527
528 let name = config.name.clone();
529 let iface = TunnelInterface::create(config)?;
530 self.tunnels.insert(name, iface);
531 Ok(())
532 }
533
534 pub fn destroy_tunnel(&mut self, name: &str) -> Result<(), TunnelError> {
536 self.tunnels
537 .remove(name)
538 .map(|_| ())
539 .ok_or(TunnelError::NotFound)
540 }
541
542 pub fn get_tunnel(&self, name: &str) -> Option<&TunnelInterface> {
544 self.tunnels.get(name)
545 }
546
547 pub fn get_tunnel_mut(&mut self, name: &str) -> Option<&mut TunnelInterface> {
549 self.tunnels.get_mut(name)
550 }
551
552 pub fn list_tunnels(&self) -> Vec<&str> {
554 self.tunnels.keys().map(|k| k.as_str()).collect()
555 }
556
557 pub fn tunnel_count(&self) -> usize {
559 self.tunnels.len()
560 }
561
562 pub fn routes(&self) -> &RouteInjection {
564 &self.routes
565 }
566
567 pub fn routes_mut(&mut self) -> &mut RouteInjection {
569 &mut self.routes
570 }
571}
572
573#[cfg(test)]
576mod tests {
577 use super::*;
578
579 fn test_config(name: &str) -> TunnelConfig {
580 TunnelConfig::new(
581 name,
582 TunnelType::Tun,
583 Ipv4Address::new(10, 0, 0, 1),
584 Ipv4Address::new(10, 0, 0, 2),
585 Ipv4Address::new(255, 255, 255, 0),
586 )
587 }
588
589 #[test]
590 fn test_tunnel_create() {
591 let config = test_config("tun0");
592 let iface = TunnelInterface::create(config).unwrap();
593 assert_eq!(iface.name(), "tun0");
594 assert_eq!(iface.tunnel_type(), TunnelType::Tun);
595 assert_eq!(iface.state(), TunnelState::Down);
596 assert_eq!(iface.get_mtu(), DEFAULT_MTU);
597 }
598
599 #[test]
600 fn test_tunnel_create_invalid_name() {
601 let mut config = test_config("tun0");
602 config.name = String::new();
603 assert_eq!(
604 TunnelInterface::create(config),
605 Err(TunnelError::InvalidName)
606 );
607 }
608
609 #[test]
610 fn test_tunnel_bring_up_down() {
611 let config = test_config("tun0");
612 let mut iface = TunnelInterface::create(config).unwrap();
613
614 assert!(iface.bring_up().is_ok());
615 assert_eq!(iface.state(), TunnelState::Up);
616
617 assert_eq!(iface.bring_up(), Err(TunnelError::AlreadyUp));
619
620 iface.bring_down();
621 assert_eq!(iface.state(), TunnelState::Down);
622 }
623
624 #[test]
625 fn test_tunnel_send_requires_up() {
626 let config = test_config("tun0");
627 let mut iface = TunnelInterface::create(config).unwrap();
628
629 assert_eq!(iface.send_packet(&[1, 2, 3]), Err(TunnelError::NotUp));
630 }
631
632 #[test]
633 fn test_tunnel_send_receive() {
634 let config = test_config("tun0");
635 let mut iface = TunnelInterface::create(config).unwrap();
636 iface.bring_up().unwrap();
637
638 let data = [0xAA; 100];
639 assert!(iface.send_packet(&data).is_ok());
640
641 let pkt = iface.drain_tx().unwrap();
643 assert_eq!(pkt.len(), 100);
644 assert!(iface.drain_tx().is_none());
645
646 iface.inject_rx(pkt).unwrap();
648 let received = iface.receive_packet().unwrap();
649 assert_eq!(received.len(), 100);
650 assert_eq!(received[0], 0xAA);
651 }
652
653 #[test]
654 fn test_tunnel_mtu_enforcement() {
655 let mut config = test_config("tun0");
656 config.mtu = 64;
657 let mut iface = TunnelInterface::create(config).unwrap();
658 iface.bring_up().unwrap();
659
660 assert!(iface.send_packet(&[0u8; 64]).is_ok());
662
663 assert_eq!(
665 iface.send_packet(&[0u8; 65]),
666 Err(TunnelError::PacketTooLarge)
667 );
668
669 let stats = iface.get_stats();
670 assert_eq!(stats.tx_packets, 1);
671 assert_eq!(stats.tx_errors, 1);
672 }
673
674 #[test]
675 fn test_tunnel_set_mtu() {
676 let config = test_config("tun0");
677 let mut iface = TunnelInterface::create(config).unwrap();
678
679 assert!(iface.set_mtu(9000).is_ok());
680 assert_eq!(iface.get_mtu(), 9000);
681
682 assert_eq!(iface.set_mtu(0), Err(TunnelError::InvalidMtu));
683 }
684
685 #[test]
686 fn test_tunnel_stats() {
687 let config = test_config("tun0");
688 let mut iface = TunnelInterface::create(config).unwrap();
689 iface.bring_up().unwrap();
690
691 iface.send_packet(&[1u8; 50]).unwrap();
692 iface.send_packet(&[2u8; 100]).unwrap();
693 iface.inject_rx(alloc::vec![3u8; 75]).unwrap();
694 iface.receive_packet().unwrap();
695
696 let stats = iface.get_stats();
697 assert_eq!(stats.tx_packets, 2);
698 assert_eq!(stats.tx_bytes, 150);
699 assert_eq!(stats.rx_packets, 1);
700 assert_eq!(stats.rx_bytes, 75);
701 assert_eq!(stats.tx_errors, 0);
702 assert_eq!(stats.rx_errors, 0);
703 }
704
705 #[test]
706 fn test_tunnel_manager_create_destroy() {
707 let mut mgr = TunnelManager::new();
708
709 mgr.create_tunnel(test_config("tun0")).unwrap();
710 mgr.create_tunnel(test_config("tun1")).unwrap();
711 assert_eq!(mgr.tunnel_count(), 2);
712
713 assert_eq!(
715 mgr.create_tunnel(test_config("tun0")),
716 Err(TunnelError::AlreadyExists)
717 );
718
719 mgr.destroy_tunnel("tun0").unwrap();
720 assert_eq!(mgr.tunnel_count(), 1);
721
722 assert_eq!(mgr.destroy_tunnel("tun0"), Err(TunnelError::NotFound));
724 }
725
726 #[test]
727 fn test_tunnel_manager_list() {
728 let mut mgr = TunnelManager::new();
729 mgr.create_tunnel(test_config("tun0")).unwrap();
730 mgr.create_tunnel(test_config("tun1")).unwrap();
731
732 let names = mgr.list_tunnels();
733 assert_eq!(names.len(), 2);
734 assert!(names.contains(&"tun0"));
735 assert!(names.contains(&"tun1"));
736 }
737
738 #[test]
739 fn test_route_injection_add_remove() {
740 let mut routes = RouteInjection::new();
741
742 routes
743 .add_route(Ipv4Address::new(10, 0, 0, 0), 24, "tun0", 100)
744 .unwrap();
745 assert_eq!(routes.get_routes().len(), 1);
746
747 assert_eq!(
749 routes.add_route(Ipv4Address::new(10, 0, 0, 0), 24, "tun0", 100),
750 Err(TunnelError::RouteExists)
751 );
752
753 routes
754 .remove_route(Ipv4Address::new(10, 0, 0, 0), 24, "tun0")
755 .unwrap();
756 assert_eq!(routes.get_routes().len(), 0);
757
758 assert_eq!(
759 routes.remove_route(Ipv4Address::new(10, 0, 0, 0), 24, "tun0"),
760 Err(TunnelError::RouteNotFound)
761 );
762 }
763
764 #[test]
765 fn test_route_lookup_longest_prefix() {
766 let mut routes = RouteInjection::new();
767
768 routes
770 .add_route(Ipv4Address::new(0, 0, 0, 0), 0, "tun0", 100)
771 .unwrap();
772 routes
774 .add_route(Ipv4Address::new(10, 0, 0, 0), 24, "tun1", 100)
775 .unwrap();
776
777 let route = routes.lookup(&Ipv4Address::new(10, 0, 0, 5)).unwrap();
779 assert_eq!(route.tunnel_name, "tun1");
780
781 let route = routes.lookup(&Ipv4Address::new(192, 168, 1, 1)).unwrap();
783 assert_eq!(route.tunnel_name, "tun0");
784 }
785
786 #[test]
787 fn test_encap_header() {
788 let hdr = EncapsulationHeader::new(
789 Ipv4Address::new(192, 168, 1, 1),
790 Ipv4Address::new(203, 0, 113, 1),
791 EncapProtocol::Udp,
792 12345,
793 1194,
794 );
795
796 assert_eq!(hdr.overhead(), 28);
797
798 let bytes = hdr.to_bytes();
799 assert_eq!(&bytes[0..4], &[192, 168, 1, 1]);
800 assert_eq!(&bytes[4..8], &[203, 0, 113, 1]);
801 assert_eq!(bytes[8], 17); let tcp_hdr = EncapsulationHeader::new(
804 Ipv4Address::new(10, 0, 0, 1),
805 Ipv4Address::new(10, 0, 0, 2),
806 EncapProtocol::Tcp,
807 443,
808 443,
809 );
810 assert_eq!(tcp_hdr.overhead(), 40);
811 assert_eq!(tcp_hdr.to_bytes()[8], 6); }
813}