Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <Kernel/Lock.h>
28#include <Kernel/Net/ARP.h>
29#include <Kernel/Net/EtherType.h>
30#include <Kernel/Net/EthernetFrameHeader.h>
31#include <Kernel/Net/ICMP.h>
32#include <Kernel/Net/IPv4.h>
33#include <Kernel/Net/IPv4Socket.h>
34#include <Kernel/Net/LoopbackAdapter.h>
35#include <Kernel/Net/Routing.h>
36#include <Kernel/Net/TCP.h>
37#include <Kernel/Net/TCPSocket.h>
38#include <Kernel/Net/UDP.h>
39#include <Kernel/Net/UDPSocket.h>
40#include <Kernel/Process.h>
41
42//#define NETWORK_TASK_DEBUG
43//#define ETHERNET_DEBUG
44//#define ETHERNET_VERY_DEBUG
45//#define ARP_DEBUG
46//#define IPV4_DEBUG
47//#define ICMP_DEBUG
48//#define UDP_DEBUG
49//#define TCP_DEBUG
50
51namespace Kernel {
52
53static void handle_arp(const EthernetFrameHeader&, size_t frame_size);
54static void handle_ipv4(const EthernetFrameHeader&, size_t frame_size);
55static void handle_icmp(const EthernetFrameHeader&, const IPv4Packet&);
56static void handle_udp(const IPv4Packet&);
57static void handle_tcp(const IPv4Packet&);
58
59void NetworkTask_main()
60{
61 WaitQueue packet_wait_queue;
62 u8 octet = 15;
63 int pending_packets = 0;
64 NetworkAdapter::for_each([&](auto& adapter) {
65 if (String(adapter.class_name()) == "LoopbackAdapter") {
66 adapter.set_ipv4_address({ 127, 0, 0, 1 });
67 adapter.set_ipv4_netmask({ 255, 0, 0, 0 });
68 adapter.set_ipv4_gateway({ 0, 0, 0, 0 });
69 } else {
70 adapter.set_ipv4_address({ 10, 0, 2, octet++ });
71 adapter.set_ipv4_netmask({ 255, 255, 255, 0 });
72 adapter.set_ipv4_gateway({ 10, 0, 2, 2 });
73 }
74
75 kprintf("NetworkTask: %s network adapter found: hw=%s address=%s netmask=%s gateway=%s\n",
76 adapter.class_name(),
77 adapter.mac_address().to_string().characters(),
78 adapter.ipv4_address().to_string().characters(),
79 adapter.ipv4_netmask().to_string().characters(),
80 adapter.ipv4_gateway().to_string().characters());
81
82 adapter.on_receive = [&]() {
83 pending_packets++;
84 packet_wait_queue.wake_all();
85 };
86 });
87
88 auto dequeue_packet = [&pending_packets](u8* buffer, size_t buffer_size) -> size_t {
89 if (pending_packets == 0)
90 return 0;
91 size_t packet_size = 0;
92 NetworkAdapter::for_each([&](auto& adapter) {
93 if (packet_size || !adapter.has_queued_packets())
94 return;
95 packet_size = adapter.dequeue_packet(buffer, buffer_size);
96 pending_packets--;
97#ifdef NETWORK_TASK_DEBUG
98 kprintf("NetworkTask: Dequeued packet from %s (%d bytes)\n", adapter.name().characters(), packet_size);
99#endif
100 });
101 return packet_size;
102 };
103
104 size_t buffer_size = 64 * KB;
105 auto buffer_region = MM.allocate_kernel_region(buffer_size, "Kernel Packet Buffer", Region::Access::Read | Region::Access::Write, false, true);
106 auto buffer = (u8*)buffer_region->vaddr().get();
107
108 kprintf("NetworkTask: Enter main loop.\n");
109 for (;;) {
110 size_t packet_size = dequeue_packet(buffer, buffer_size);
111 if (!packet_size) {
112 Thread::current->wait_on(packet_wait_queue);
113 continue;
114 }
115 if (packet_size < sizeof(EthernetFrameHeader)) {
116 kprintf("NetworkTask: Packet is too small to be an Ethernet packet! (%zu)\n", packet_size);
117 continue;
118 }
119 auto& eth = *(const EthernetFrameHeader*)buffer;
120#ifdef ETHERNET_DEBUG
121 kprintf("NetworkTask: From %s to %s, ether_type=%w, packet_length=%u\n",
122 eth.source().to_string().characters(),
123 eth.destination().to_string().characters(),
124 eth.ether_type(),
125 packet_size);
126#endif
127
128#ifdef ETHERNET_VERY_DEBUG
129 for (size_t i = 0; i < packet_size; i++) {
130 kprintf("%b", buffer[i]);
131
132 switch (i % 16) {
133 case 7:
134 kprintf(" ");
135 break;
136 case 15:
137 kprintf("\n");
138 break;
139 default:
140 kprintf(" ");
141 break;
142 }
143 }
144
145 kprintf("\n");
146#endif
147
148 switch (eth.ether_type()) {
149 case EtherType::ARP:
150 handle_arp(eth, packet_size);
151 break;
152 case EtherType::IPv4:
153 handle_ipv4(eth, packet_size);
154 break;
155 case EtherType::IPv6:
156 // ignore
157 break;
158 default:
159 kprintf("NetworkTask: Unknown ethernet type %#04x\n", eth.ether_type());
160 }
161 }
162}
163
164void handle_arp(const EthernetFrameHeader& eth, size_t frame_size)
165{
166 constexpr size_t minimum_arp_frame_size = sizeof(EthernetFrameHeader) + sizeof(ARPPacket);
167 if (frame_size < minimum_arp_frame_size) {
168 kprintf("handle_arp: Frame too small (%d, need %d)\n", frame_size, minimum_arp_frame_size);
169 return;
170 }
171 auto& packet = *static_cast<const ARPPacket*>(eth.payload());
172 if (packet.hardware_type() != 1 || packet.hardware_address_length() != sizeof(MACAddress)) {
173 kprintf("handle_arp: Hardware type not ethernet (%w, len=%u)\n",
174 packet.hardware_type(),
175 packet.hardware_address_length());
176 return;
177 }
178 if (packet.protocol_type() != EtherType::IPv4 || packet.protocol_address_length() != sizeof(IPv4Address)) {
179 kprintf("handle_arp: Protocol type not IPv4 (%w, len=%u)\n",
180 packet.hardware_type(),
181 packet.protocol_address_length());
182 return;
183 }
184
185#ifdef ARP_DEBUG
186 kprintf("handle_arp: operation=%w, sender=%s/%s, target=%s/%s\n",
187 packet.operation(),
188 packet.sender_hardware_address().to_string().characters(),
189 packet.sender_protocol_address().to_string().characters(),
190 packet.target_hardware_address().to_string().characters(),
191 packet.target_protocol_address().to_string().characters());
192#endif
193
194 if (!packet.sender_hardware_address().is_zero() && !packet.sender_protocol_address().is_zero()) {
195 // Someone has this IPv4 address. I guess we can try to remember that.
196 // FIXME: Protect against ARP spamming.
197 // FIXME: Support static ARP table entries.
198 LOCKER(arp_table().lock());
199 arp_table().resource().set(packet.sender_protocol_address(), packet.sender_hardware_address());
200
201 kprintf("ARP table (%d entries):\n", arp_table().resource().size());
202 for (auto& it : arp_table().resource()) {
203 kprintf("%s :: %s\n", it.value.to_string().characters(), it.key.to_string().characters());
204 }
205 }
206
207 if (packet.operation() == ARPOperation::Request) {
208 // Who has this IP address?
209 if (auto adapter = NetworkAdapter::from_ipv4_address(packet.target_protocol_address())) {
210 // We do!
211 kprintf("handle_arp: Responding to ARP request for my IPv4 address (%s)\n",
212 adapter->ipv4_address().to_string().characters());
213 ARPPacket response;
214 response.set_operation(ARPOperation::Response);
215 response.set_target_hardware_address(packet.sender_hardware_address());
216 response.set_target_protocol_address(packet.sender_protocol_address());
217 response.set_sender_hardware_address(adapter->mac_address());
218 response.set_sender_protocol_address(adapter->ipv4_address());
219
220 adapter->send(packet.sender_hardware_address(), response);
221 }
222 return;
223 }
224}
225
226void handle_ipv4(const EthernetFrameHeader& eth, size_t frame_size)
227{
228 constexpr size_t minimum_ipv4_frame_size = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet);
229 if (frame_size < minimum_ipv4_frame_size) {
230 kprintf("handle_ipv4: Frame too small (%d, need %d)\n", frame_size, minimum_ipv4_frame_size);
231 return;
232 }
233 auto& packet = *static_cast<const IPv4Packet*>(eth.payload());
234
235 if (packet.length() < sizeof(IPv4Packet)) {
236 kprintf("handle_ipv4: IPv4 packet too short (%u, need %u)\n", packet.length(), sizeof(IPv4Packet));
237 return;
238 }
239
240 size_t actual_ipv4_packet_length = frame_size - sizeof(EthernetFrameHeader);
241 if (packet.length() > actual_ipv4_packet_length) {
242 kprintf("handle_ipv4: IPv4 packet claims to be longer than it is (%u, actually %zu)\n", packet.length(), actual_ipv4_packet_length);
243 return;
244 }
245
246#ifdef IPV4_DEBUG
247 kprintf("handle_ipv4: source=%s, target=%s\n",
248 packet.source().to_string().characters(),
249 packet.destination().to_string().characters());
250#endif
251
252 switch ((IPv4Protocol)packet.protocol()) {
253 case IPv4Protocol::ICMP:
254 return handle_icmp(eth, packet);
255 case IPv4Protocol::UDP:
256 return handle_udp(packet);
257 case IPv4Protocol::TCP:
258 return handle_tcp(packet);
259 default:
260 kprintf("handle_ipv4: Unhandled protocol %u\n", packet.protocol());
261 break;
262 }
263}
264
265void handle_icmp(const EthernetFrameHeader& eth, const IPv4Packet& ipv4_packet)
266{
267 auto& icmp_header = *static_cast<const ICMPHeader*>(ipv4_packet.payload());
268#ifdef ICMP_DEBUG
269 kprintf("handle_icmp: source=%s, destination=%s, type=%b, code=%b\n",
270 ipv4_packet.source().to_string().characters(),
271 ipv4_packet.destination().to_string().characters(),
272 icmp_header.type(),
273 icmp_header.code());
274#endif
275
276 {
277 LOCKER(IPv4Socket::all_sockets().lock());
278 for (RefPtr<IPv4Socket> socket : IPv4Socket::all_sockets().resource()) {
279 LOCKER(socket->lock());
280 if (socket->protocol() != (unsigned)IPv4Protocol::ICMP)
281 continue;
282 socket->did_receive(ipv4_packet.source(), 0, KBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
283 }
284 }
285
286 auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
287 if (!adapter)
288 return;
289
290 if (icmp_header.type() == ICMPType::EchoRequest) {
291 auto& request = reinterpret_cast<const ICMPEchoPacket&>(icmp_header);
292 kprintf("handle_icmp: EchoRequest from %s: id=%u, seq=%u\n",
293 ipv4_packet.source().to_string().characters(),
294 (u16)request.identifier,
295 (u16)request.sequence_number);
296 size_t icmp_packet_size = ipv4_packet.payload_size();
297 auto buffer = ByteBuffer::create_zeroed(icmp_packet_size);
298 auto& response = *(ICMPEchoPacket*)buffer.data();
299 response.header.set_type(ICMPType::EchoReply);
300 response.header.set_code(0);
301 response.identifier = request.identifier;
302 response.sequence_number = request.sequence_number;
303 if (size_t icmp_payload_size = icmp_packet_size - sizeof(ICMPEchoPacket))
304 memcpy(response.payload(), request.payload(), icmp_payload_size);
305 response.header.set_checksum(internet_checksum(&response, icmp_packet_size));
306 // FIXME: What is the right TTL value here? Is 64 ok? Should we use the same TTL as the echo request?
307 adapter->send_ipv4(eth.source(), ipv4_packet.source(), IPv4Protocol::ICMP, buffer.data(), buffer.size(), 64);
308 }
309}
310
311void handle_udp(const IPv4Packet& ipv4_packet)
312{
313 if (ipv4_packet.payload_size() < sizeof(UDPPacket)) {
314 kprintf("handle_udp: Packet too small (%u, need %zu)\n", ipv4_packet.payload_size());
315 return;
316 }
317
318 auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
319 if (!adapter) {
320 kprintf("handle_udp: this packet is not for me, it's for %s\n", ipv4_packet.destination().to_string().characters());
321 return;
322 }
323
324 auto& udp_packet = *static_cast<const UDPPacket*>(ipv4_packet.payload());
325#ifdef UDP_DEBUG
326 kprintf("handle_udp: source=%s:%u, destination=%s:%u length=%u\n",
327 ipv4_packet.source().to_string().characters(),
328 udp_packet.source_port(),
329 ipv4_packet.destination().to_string().characters(),
330 udp_packet.destination_port(),
331 udp_packet.length());
332#endif
333
334 auto socket = UDPSocket::from_port(udp_packet.destination_port());
335 if (!socket) {
336 kprintf("handle_udp: No UDP socket for port %u\n", udp_packet.destination_port());
337 return;
338 }
339
340 ASSERT(socket->type() == SOCK_DGRAM);
341 ASSERT(socket->local_port() == udp_packet.destination_port());
342 socket->did_receive(ipv4_packet.source(), udp_packet.source_port(), KBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
343}
344
345void handle_tcp(const IPv4Packet& ipv4_packet)
346{
347 if (ipv4_packet.payload_size() < sizeof(TCPPacket)) {
348 kprintf("handle_tcp: IPv4 payload is too small to be a TCP packet (%u, need %zu)\n", ipv4_packet.payload_size(), sizeof(TCPPacket));
349 return;
350 }
351
352 auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
353
354 size_t minimum_tcp_header_size = 5 * sizeof(u32);
355 size_t maximum_tcp_header_size = 15 * sizeof(u32);
356 if (tcp_packet.header_size() < minimum_tcp_header_size || tcp_packet.header_size() > maximum_tcp_header_size) {
357 kprintf("handle_tcp: TCP packet header has invalid size %zu\n", tcp_packet.header_size());
358 }
359
360 if (ipv4_packet.payload_size() < tcp_packet.header_size()) {
361 kprintf("handle_tcp: IPv4 payload is smaller than TCP header claims (%u, supposedly %u)\n", ipv4_packet.payload_size(), tcp_packet.header_size());
362 return;
363 }
364
365 size_t payload_size = ipv4_packet.payload_size() - tcp_packet.header_size();
366
367#ifdef TCP_DEBUG
368 kprintf("handle_tcp: source=%s:%u, destination=%s:%u seq_no=%u, ack_no=%u, flags=%w (%s%s%s%s), window_size=%u, payload_size=%u\n",
369 ipv4_packet.source().to_string().characters(),
370 tcp_packet.source_port(),
371 ipv4_packet.destination().to_string().characters(),
372 tcp_packet.destination_port(),
373 tcp_packet.sequence_number(),
374 tcp_packet.ack_number(),
375 tcp_packet.flags(),
376 tcp_packet.has_syn() ? "SYN " : "",
377 tcp_packet.has_ack() ? "ACK " : "",
378 tcp_packet.has_fin() ? "FIN " : "",
379 tcp_packet.has_rst() ? "RST " : "",
380 tcp_packet.window_size(),
381 payload_size);
382#endif
383
384 auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
385 if (!adapter) {
386 kprintf("handle_tcp: this packet is not for me, it's for %s\n", ipv4_packet.destination().to_string().characters());
387 return;
388 }
389
390 IPv4SocketTuple tuple(ipv4_packet.destination(), tcp_packet.destination_port(), ipv4_packet.source(), tcp_packet.source_port());
391
392#ifdef TCP_DEBUG
393 kprintf("handle_tcp: looking for socket; tuple=%s\n", tuple.to_string().characters());
394#endif
395
396 auto socket = TCPSocket::from_tuple(tuple);
397 if (!socket) {
398 kprintf("handle_tcp: No TCP socket for tuple %s\n", tuple.to_string().characters());
399 kprintf("handle_tcp: source=%s:%u, destination=%s:%u seq_no=%u, ack_no=%u, flags=%w (%s%s%s%s), window_size=%u, payload_size=%u\n",
400 ipv4_packet.source().to_string().characters(),
401 tcp_packet.source_port(),
402 ipv4_packet.destination().to_string().characters(),
403 tcp_packet.destination_port(),
404 tcp_packet.sequence_number(),
405 tcp_packet.ack_number(),
406 tcp_packet.flags(),
407 tcp_packet.has_syn() ? "SYN " : "",
408 tcp_packet.has_ack() ? "ACK " : "",
409 tcp_packet.has_fin() ? "FIN " : "",
410 tcp_packet.has_rst() ? "RST " : "",
411 tcp_packet.window_size(),
412 payload_size);
413 return;
414 }
415
416 ASSERT(socket->type() == SOCK_STREAM);
417 ASSERT(socket->local_port() == tcp_packet.destination_port());
418
419#ifdef TCP_DEBUG
420 kprintf("handle_tcp: got socket; state=%s\n", socket->tuple().to_string().characters(), TCPSocket::to_string(socket->state()));
421#endif
422
423 socket->receive_tcp_packet(tcp_packet, ipv4_packet.payload_size());
424
425 switch (socket->state()) {
426 case TCPSocket::State::Closed:
427 kprintf("handle_tcp: unexpected flags in Closed state\n");
428 // TODO: we may want to send an RST here, maybe as a configurable option
429 return;
430 case TCPSocket::State::TimeWait:
431 kprintf("handle_tcp: unexpected flags in TimeWait state\n");
432 socket->send_tcp_packet(TCPFlags::RST);
433 socket->set_state(TCPSocket::State::Closed);
434 return;
435 case TCPSocket::State::Listen:
436 switch (tcp_packet.flags()) {
437 case TCPFlags::SYN: {
438#ifdef TCP_DEBUG
439 kprintf("handle_tcp: incoming connection\n");
440#endif
441 auto& local_address = ipv4_packet.destination();
442 auto& peer_address = ipv4_packet.source();
443 auto client = socket->create_client(local_address, tcp_packet.destination_port(), peer_address, tcp_packet.source_port());
444 if (!client) {
445 kprintf("handle_tcp: couldn't create client socket\n");
446 return;
447 }
448#ifdef TCP_DEBUG
449 kprintf("handle_tcp: created new client socket with tuple %s\n", client->tuple().to_string().characters());
450#endif
451 client->set_sequence_number(1000);
452 client->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
453 client->send_tcp_packet(TCPFlags::SYN | TCPFlags::ACK);
454 client->set_state(TCPSocket::State::SynReceived);
455 return;
456 }
457 default:
458 kprintf("handle_tcp: unexpected flags in Listen state\n");
459 // socket->send_tcp_packet(TCPFlags::RST);
460 return;
461 }
462 case TCPSocket::State::SynSent:
463 switch (tcp_packet.flags()) {
464 case TCPFlags::SYN:
465 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
466 socket->send_tcp_packet(TCPFlags::ACK);
467 socket->set_state(TCPSocket::State::SynReceived);
468 return;
469 case TCPFlags::ACK | TCPFlags::SYN:
470 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
471 socket->send_tcp_packet(TCPFlags::ACK);
472 socket->set_state(TCPSocket::State::Established);
473 socket->set_setup_state(Socket::SetupState::Completed);
474 socket->set_connected(true);
475 return;
476 case TCPFlags::ACK | TCPFlags::FIN:
477 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
478 socket->send_tcp_packet(TCPFlags::ACK);
479 socket->set_state(TCPSocket::State::Closed);
480 socket->set_error(TCPSocket::Error::FINDuringConnect);
481 socket->set_setup_state(Socket::SetupState::Completed);
482 return;
483 case TCPFlags::ACK | TCPFlags::RST:
484 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
485 socket->send_tcp_packet(TCPFlags::ACK);
486 socket->set_state(TCPSocket::State::Closed);
487 socket->set_error(TCPSocket::Error::RSTDuringConnect);
488 socket->set_setup_state(Socket::SetupState::Completed);
489 return;
490 default:
491 kprintf("handle_tcp: unexpected flags in SynSent state\n");
492 socket->send_tcp_packet(TCPFlags::RST);
493 socket->set_state(TCPSocket::State::Closed);
494 socket->set_error(TCPSocket::Error::UnexpectedFlagsDuringConnect);
495 socket->set_setup_state(Socket::SetupState::Completed);
496 return;
497 }
498 case TCPSocket::State::SynReceived:
499 switch (tcp_packet.flags()) {
500 case TCPFlags::ACK:
501 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
502
503 switch (socket->direction()) {
504 case TCPSocket::Direction::Incoming:
505 if (!socket->has_originator()) {
506 kprintf("handle_tcp: connection doesn't have an originating socket; maybe it went away?\n");
507 socket->send_tcp_packet(TCPFlags::RST);
508 socket->set_state(TCPSocket::State::Closed);
509 return;
510 }
511
512 socket->set_state(TCPSocket::State::Established);
513 socket->set_setup_state(Socket::SetupState::Completed);
514 socket->release_to_originator();
515 return;
516 case TCPSocket::Direction::Outgoing:
517 socket->set_state(TCPSocket::State::Established);
518 socket->set_setup_state(Socket::SetupState::Completed);
519 socket->set_connected(true);
520 return;
521 default:
522 kprintf("handle_tcp: got ACK in SynReceived state but direction is invalid (%s)\n", TCPSocket::to_string(socket->direction()));
523 socket->send_tcp_packet(TCPFlags::RST);
524 socket->set_state(TCPSocket::State::Closed);
525 return;
526 }
527
528 return;
529 default:
530 kprintf("handle_tcp: unexpected flags in SynReceived state\n");
531 socket->send_tcp_packet(TCPFlags::RST);
532 socket->set_state(TCPSocket::State::Closed);
533 return;
534 }
535 case TCPSocket::State::CloseWait:
536 switch (tcp_packet.flags()) {
537 default:
538 kprintf("handle_tcp: unexpected flags in CloseWait state\n");
539 socket->send_tcp_packet(TCPFlags::RST);
540 socket->set_state(TCPSocket::State::Closed);
541 return;
542 }
543 case TCPSocket::State::LastAck:
544 switch (tcp_packet.flags()) {
545 case TCPFlags::ACK:
546 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
547 socket->set_state(TCPSocket::State::Closed);
548 return;
549 default:
550 kprintf("handle_tcp: unexpected flags in LastAck state\n");
551 socket->send_tcp_packet(TCPFlags::RST);
552 socket->set_state(TCPSocket::State::Closed);
553 return;
554 }
555 case TCPSocket::State::FinWait1:
556 switch (tcp_packet.flags()) {
557 case TCPFlags::ACK:
558 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
559 socket->set_state(TCPSocket::State::FinWait2);
560 return;
561 case TCPFlags::FIN:
562 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
563 socket->set_state(TCPSocket::State::Closing);
564 return;
565 default:
566 kprintf("handle_tcp: unexpected flags in FinWait1 state\n");
567 socket->send_tcp_packet(TCPFlags::RST);
568 socket->set_state(TCPSocket::State::Closed);
569 return;
570 }
571 case TCPSocket::State::FinWait2:
572 switch (tcp_packet.flags()) {
573 case TCPFlags::FIN:
574 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
575 socket->set_state(TCPSocket::State::TimeWait);
576 return;
577 case TCPFlags::ACK | TCPFlags::RST:
578 socket->set_state(TCPSocket::State::Closed);
579 return;
580 default:
581 kprintf("handle_tcp: unexpected flags in FinWait2 state\n");
582 socket->send_tcp_packet(TCPFlags::RST);
583 socket->set_state(TCPSocket::State::Closed);
584 return;
585 }
586 case TCPSocket::State::Closing:
587 switch (tcp_packet.flags()) {
588 case TCPFlags::ACK:
589 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
590 socket->set_state(TCPSocket::State::TimeWait);
591 return;
592 default:
593 kprintf("handle_tcp: unexpected flags in Closing state\n");
594 socket->send_tcp_packet(TCPFlags::RST);
595 socket->set_state(TCPSocket::State::Closed);
596 return;
597 }
598 case TCPSocket::State::Established:
599 if (tcp_packet.has_fin()) {
600 if (payload_size != 0)
601 socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), KBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
602
603 socket->set_ack_number(tcp_packet.sequence_number() + payload_size + 1);
604 socket->send_tcp_packet(TCPFlags::ACK);
605 socket->set_state(TCPSocket::State::CloseWait);
606 socket->set_connected(false);
607 return;
608 }
609
610 socket->set_ack_number(tcp_packet.sequence_number() + payload_size);
611
612#ifdef TCP_DEBUG
613 kprintf("Got packet with ack_no=%u, seq_no=%u, payload_size=%u, acking it with new ack_no=%u, seq_no=%u\n",
614 tcp_packet.ack_number(),
615 tcp_packet.sequence_number(),
616 payload_size,
617 socket->ack_number(),
618 socket->sequence_number());
619#endif
620
621 if (payload_size) {
622 if (socket->did_receive(ipv4_packet.source(), tcp_packet.source_port(), KBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size())))
623 socket->send_tcp_packet(TCPFlags::ACK);
624 }
625 }
626}
627
628}