1pub mod port_table;
2pub mod socket;
3pub mod tcp;
4pub mod udp;
5
6pub use lose_net_stack::IPv4;
7
8use alloc::{sync::Arc, vec};
9use lose_net_stack::{LoseStack, MacAddress, TcpFlags, results::Packet};
10
11use crate::{
12 drivers::NET_DEVICE,
13 net::socket::{get_socket, push_data},
14 sync::UPIntrFreeCell,
15};
16
17use self::{port_table::check_accept, socket::set_s_a_by_index};
18
19pub struct NetStack(UPIntrFreeCell<LoseStack>);
20
21impl NetStack {
22 pub fn new() -> Self {
23 unsafe {
24 NetStack(UPIntrFreeCell::new(LoseStack::new(
25 IPv4::new(10, 0, 2, 15),
26 MacAddress::new([0x52, 0x54, 0x00, 0x12, 0x34, 0x56]),
27 )))
28 }
29 }
30}
31
32lazy_static::lazy_static! {
33 static ref LOSE_NET_STACK: Arc<NetStack> = Arc::new(NetStack::new());
34}
35
36pub fn net_interrupt_handler() {
37 let mut recv_buf = vec![0u8; 1024];
38
39 let len = NET_DEVICE.receive(&mut recv_buf);
40
41 let packet = LOSE_NET_STACK
42 .0
43 .exclusive_access()
44 .analysis(&recv_buf[..len]);
45
46 match packet {
50 Packet::ARP(arp_packet) => {
51 let lose_stack = LOSE_NET_STACK.0.exclusive_access();
52 let reply_packet = arp_packet
53 .reply_packet(lose_stack.ip, lose_stack.mac)
54 .expect("can't build reply");
55 let reply_data = reply_packet.build_data();
56 NET_DEVICE.transmit(&reply_data)
57 }
58
59 Packet::UDP(udp_packet) => {
60 let target = udp_packet.source_ip;
61 let lport = udp_packet.dest_port;
62 let rport = udp_packet.source_port;
63
64 if let Some(socket_index) = get_socket(target, lport, rport) {
65 push_data(socket_index, udp_packet.data.to_vec());
66 }
67 }
68
69 Packet::TCP(tcp_packet) => {
70 let target = tcp_packet.source_ip;
71 let lport = tcp_packet.dest_port;
72 let rport = tcp_packet.source_port;
73 let flags = tcp_packet.flags;
74
75 if flags.contains(TcpFlags::S) {
76 if check_accept(lport, &tcp_packet).is_some() {
78 let mut reply_packet = tcp_packet.ack();
79 reply_packet.flags = TcpFlags::S | TcpFlags::A;
80 NET_DEVICE.transmit(&reply_packet.build_data());
81 }
82 return;
83 } else if tcp_packet.flags.contains(TcpFlags::F) {
84 let reply_packet = tcp_packet.ack();
86 NET_DEVICE.transmit(&reply_packet.build_data());
87
88 let mut end_packet = reply_packet.ack();
89 end_packet.flags |= TcpFlags::F;
90 NET_DEVICE.transmit(&end_packet.build_data());
91 } else if tcp_packet.flags.contains(TcpFlags::A) && tcp_packet.data_len == 0 {
92 return;
93 }
94
95 if let Some(socket_index) = get_socket(target, lport, rport) {
96 push_data(socket_index, tcp_packet.data.to_vec());
97 set_s_a_by_index(socket_index, tcp_packet.seq, tcp_packet.ack);
98 }
99 }
100 _ => {}
101 }
102}
103
104#[allow(unused)]
105pub fn hexdump(data: &[u8]) {
106 const PRELAND_WIDTH: usize = 70;
107 println!("[kernel] {:-^1$}", " hexdump ", PRELAND_WIDTH);
108 for offset in (0..data.len()).step_by(16) {
109 print!("[kernel] ");
110 for i in 0..16 {
111 if offset + i < data.len() {
112 print!("{:02x} ", data[offset + i]);
113 } else {
114 print!("{:02} ", "");
115 }
116 }
117
118 print!("{:>6}", ' ');
119
120 for i in 0..16 {
121 if offset + i < data.len() {
122 let c = data[offset + i];
123 if c >= 0x20 && c <= 0x7e {
124 print!("{}", c as char);
125 } else {
126 print!(".");
127 }
128 } else {
129 print!("{:02} ", "");
130 }
131 }
132
133 println!("");
134 }
135 println!("[kernel] {:-^1$}", " hexdump end ", PRELAND_WIDTH);
136}