Serenity Operating System
at portability 628 lines 26 kB view raw
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}