Serenity Operating System
at master 854 lines 31 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Singleton.h> 8#include <AK/StringBuilder.h> 9#include <Kernel/API/Ioctl.h> 10#include <Kernel/API/POSIX/errno.h> 11#include <Kernel/Debug.h> 12#include <Kernel/FileSystem/OpenFileDescription.h> 13#include <Kernel/Net/ARP.h> 14#include <Kernel/Net/ICMP.h> 15#include <Kernel/Net/IPv4.h> 16#include <Kernel/Net/IPv4Socket.h> 17#include <Kernel/Net/NetworkAdapter.h> 18#include <Kernel/Net/NetworkingManagement.h> 19#include <Kernel/Net/Routing.h> 20#include <Kernel/Net/TCP.h> 21#include <Kernel/Net/TCPSocket.h> 22#include <Kernel/Net/UDP.h> 23#include <Kernel/Net/UDPSocket.h> 24#include <Kernel/Process.h> 25#include <Kernel/UnixTypes.h> 26 27namespace Kernel { 28 29static Singleton<MutexProtected<IPv4Socket::List>> s_all_sockets; 30 31using BlockFlags = Thread::OpenFileDescriptionBlocker::BlockFlags; 32 33MutexProtected<IPv4Socket::List>& IPv4Socket::all_sockets() 34{ 35 return *s_all_sockets; 36} 37 38ErrorOr<NonnullOwnPtr<DoubleBuffer>> IPv4Socket::try_create_receive_buffer() 39{ 40 return DoubleBuffer::try_create("IPv4Socket: Receive buffer"sv, 256 * KiB); 41} 42 43ErrorOr<NonnullRefPtr<Socket>> IPv4Socket::create(int type, int protocol) 44{ 45 auto receive_buffer = TRY(IPv4Socket::try_create_receive_buffer()); 46 47 if (type == SOCK_STREAM) 48 return TRY(TCPSocket::try_create(protocol, move(receive_buffer))); 49 if (type == SOCK_DGRAM) 50 return TRY(UDPSocket::try_create(protocol, move(receive_buffer))); 51 if (type == SOCK_RAW) { 52 auto raw_socket = adopt_ref_if_nonnull(new (nothrow) IPv4Socket(type, protocol, move(receive_buffer), {})); 53 if (raw_socket) 54 return raw_socket.release_nonnull(); 55 return ENOMEM; 56 } 57 return EINVAL; 58} 59 60IPv4Socket::IPv4Socket(int type, int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer, OwnPtr<KBuffer> optional_scratch_buffer) 61 : Socket(AF_INET, type, protocol) 62 , m_receive_buffer(move(receive_buffer)) 63 , m_scratch_buffer(move(optional_scratch_buffer)) 64{ 65 dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}) created with type={}, protocol={}", this, type, protocol); 66 m_buffer_mode = type == SOCK_STREAM ? BufferMode::Bytes : BufferMode::Packets; 67 if (m_buffer_mode == BufferMode::Bytes) { 68 VERIFY(m_scratch_buffer); 69 } 70 71 all_sockets().with_exclusive([&](auto& table) { 72 table.append(*this); 73 }); 74} 75 76IPv4Socket::~IPv4Socket() 77{ 78 all_sockets().with_exclusive([&](auto& table) { 79 table.remove(*this); 80 }); 81} 82 83void IPv4Socket::get_local_address(sockaddr* address, socklen_t* address_size) 84{ 85 sockaddr_in local_address = { AF_INET, htons(m_local_port), { m_local_address.to_in_addr_t() }, { 0 } }; 86 memcpy(address, &local_address, min(static_cast<size_t>(*address_size), sizeof(sockaddr_in))); 87 *address_size = sizeof(sockaddr_in); 88} 89 90void IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size) 91{ 92 sockaddr_in peer_address = { AF_INET, htons(m_peer_port), { m_peer_address.to_in_addr_t() }, { 0 } }; 93 memcpy(address, &peer_address, min(static_cast<size_t>(*address_size), sizeof(sockaddr_in))); 94 *address_size = sizeof(sockaddr_in); 95} 96 97ErrorOr<void> IPv4Socket::bind(Credentials const& credentials, Userspace<sockaddr const*> user_address, socklen_t address_size) 98{ 99 VERIFY(setup_state() == SetupState::Unstarted); 100 if (address_size != sizeof(sockaddr_in)) 101 return set_so_error(EINVAL); 102 103 sockaddr_in address {}; 104 SOCKET_TRY(copy_from_user(&address, user_address, sizeof(sockaddr_in))); 105 106 if (address.sin_family != AF_INET) 107 return set_so_error(EINVAL); 108 109 auto requested_local_port = ntohs(address.sin_port); 110 if (!credentials.is_superuser()) { 111 if (requested_local_port > 0 && requested_local_port < 1024) { 112 dbgln("UID {} attempted to bind {} to port {}", credentials.uid(), class_name(), requested_local_port); 113 return set_so_error(EACCES); 114 } 115 } 116 117 m_local_address = IPv4Address((u8 const*)&address.sin_addr.s_addr); 118 m_local_port = requested_local_port; 119 120 dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket::bind {}({}) to {}:{}", class_name(), this, m_local_address, m_local_port); 121 122 return protocol_bind(); 123} 124 125ErrorOr<void> IPv4Socket::listen(size_t backlog) 126{ 127 MutexLocker locker(mutex()); 128 auto result = allocate_local_port_if_needed(); 129 if (result.error_or_port.is_error() && result.error_or_port.error().code() != ENOPROTOOPT) 130 return result.error_or_port.release_error(); 131 132 set_backlog(backlog); 133 set_role(Role::Listener); 134 evaluate_block_conditions(); 135 136 dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}) listening with backlog={}", this, backlog); 137 138 return protocol_listen(result.did_allocate); 139} 140 141ErrorOr<void> IPv4Socket::connect(Credentials const&, OpenFileDescription& description, Userspace<sockaddr const*> address, socklen_t address_size) 142{ 143 if (address_size != sizeof(sockaddr_in)) 144 return set_so_error(EINVAL); 145 u16 sa_family_copy; 146 auto* user_address = reinterpret_cast<sockaddr const*>(address.unsafe_userspace_ptr()); 147 SOCKET_TRY(copy_from_user(&sa_family_copy, &user_address->sa_family, sizeof(u16))); 148 if (sa_family_copy != AF_INET) 149 return set_so_error(EINVAL); 150 if (m_role == Role::Connected) 151 return set_so_error(EISCONN); 152 153 sockaddr_in safe_address {}; 154 SOCKET_TRY(copy_from_user(&safe_address, (sockaddr_in const*)user_address, sizeof(sockaddr_in))); 155 156 m_peer_address = IPv4Address((u8 const*)&safe_address.sin_addr.s_addr); 157 if (m_peer_address == IPv4Address { 0, 0, 0, 0 }) 158 m_peer_address = IPv4Address { 127, 0, 0, 1 }; 159 m_peer_port = ntohs(safe_address.sin_port); 160 161 return protocol_connect(description); 162} 163 164bool IPv4Socket::can_read(OpenFileDescription const&, u64) const 165{ 166 if (m_role == Role::Listener) 167 return can_accept(); 168 if (protocol_is_disconnected()) 169 return true; 170 return m_can_read; 171} 172 173bool IPv4Socket::can_write(OpenFileDescription const&, u64) const 174{ 175 return true; 176} 177 178PortAllocationResult IPv4Socket::allocate_local_port_if_needed() 179{ 180 MutexLocker locker(mutex()); 181 if (m_local_port) 182 return { m_local_port, false }; 183 auto port_or_error = protocol_allocate_local_port(); 184 if (port_or_error.is_error()) 185 return { port_or_error.release_error(), false }; 186 m_local_port = port_or_error.release_value(); 187 return { m_local_port, true }; 188} 189 190ErrorOr<size_t> IPv4Socket::sendto(OpenFileDescription&, UserOrKernelBuffer const& data, size_t data_length, [[maybe_unused]] int flags, Userspace<sockaddr const*> addr, socklen_t addr_length) 191{ 192 MutexLocker locker(mutex()); 193 194 if (addr && addr_length != sizeof(sockaddr_in)) 195 return set_so_error(EINVAL); 196 197 if (addr) { 198 sockaddr_in ia {}; 199 SOCKET_TRY(copy_from_user(&ia, Userspace<sockaddr_in const*>(addr.ptr()))); 200 201 if (ia.sin_family != AF_INET) { 202 dmesgln("sendto: Bad address family: {} is not AF_INET", ia.sin_family); 203 return set_so_error(EAFNOSUPPORT); 204 } 205 206 m_peer_address = IPv4Address((u8 const*)&ia.sin_addr.s_addr); 207 m_peer_port = ntohs(ia.sin_port); 208 } 209 210 if (!is_connected() && m_peer_address.is_zero()) 211 return set_so_error(EPIPE); 212 213 auto allow_using_gateway = ((flags & MSG_DONTROUTE) || m_routing_disabled) ? AllowUsingGateway::No : AllowUsingGateway::Yes; 214 auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface(), allow_using_gateway); 215 if (routing_decision.is_zero()) 216 return set_so_error(EHOSTUNREACH); 217 218 if (m_local_address.to_u32() == 0) 219 m_local_address = routing_decision.adapter->ipv4_address(); 220 221 if (auto result = allocate_local_port_if_needed(); result.error_or_port.is_error() && result.error_or_port.error().code() != ENOPROTOOPT) 222 return result.error_or_port.release_error(); 223 224 dbgln_if(IPV4_SOCKET_DEBUG, "sendto: destination={}:{}", m_peer_address, m_peer_port); 225 226 if (type() == SOCK_RAW) { 227 auto ipv4_payload_offset = routing_decision.adapter->ipv4_payload_offset(); 228 data_length = min(data_length, routing_decision.adapter->mtu() - ipv4_payload_offset); 229 auto packet = routing_decision.adapter->acquire_packet_buffer(ipv4_payload_offset + data_length); 230 if (!packet) 231 return set_so_error(ENOMEM); 232 routing_decision.adapter->fill_in_ipv4_header(*packet, local_address(), routing_decision.next_hop, 233 m_peer_address, (IPv4Protocol)protocol(), data_length, m_type_of_service, m_ttl); 234 if (auto result = data.read(packet->buffer->data() + ipv4_payload_offset, data_length); result.is_error()) { 235 routing_decision.adapter->release_packet_buffer(*packet); 236 return set_so_error(result.release_error()); 237 } 238 routing_decision.adapter->send_packet(packet->bytes()); 239 routing_decision.adapter->release_packet_buffer(*packet); 240 return data_length; 241 } 242 243 auto nsent_or_error = protocol_send(data, data_length); 244 if (!nsent_or_error.is_error()) 245 Thread::current()->did_ipv4_socket_write(nsent_or_error.value()); 246 return nsent_or_error; 247} 248 249ErrorOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, bool blocking) 250{ 251 MutexLocker locker(mutex()); 252 253 VERIFY(m_receive_buffer); 254 255 if (m_receive_buffer->is_empty()) { 256 if (protocol_is_disconnected()) 257 return 0; 258 if (!blocking) 259 return set_so_error(EAGAIN); 260 261 locker.unlock(); 262 auto unblocked_flags = BlockFlags::None; 263 auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags); 264 locker.lock(); 265 266 if (!has_flag(unblocked_flags, BlockFlags::Read)) { 267 if (res.was_interrupted()) 268 return set_so_error(EINTR); 269 270 // Unblocked due to timeout. 271 return set_so_error(EAGAIN); 272 } 273 } 274 275 ErrorOr<size_t> nreceived_or_error { 0 }; 276 if (flags & MSG_PEEK) 277 nreceived_or_error = m_receive_buffer->peek(buffer, buffer_length); 278 else 279 nreceived_or_error = m_receive_buffer->read(buffer, buffer_length); 280 281 if (!nreceived_or_error.is_error() && nreceived_or_error.value() > 0 && !(flags & MSG_PEEK)) 282 Thread::current()->did_ipv4_socket_read(nreceived_or_error.value()); 283 284 set_can_read(!m_receive_buffer->is_empty()); 285 return nreceived_or_error; 286} 287 288ErrorOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Time& packet_timestamp, bool blocking) 289{ 290 MutexLocker locker(mutex()); 291 ReceivedPacket taken_packet; 292 ReceivedPacket* packet { nullptr }; 293 { 294 if (m_receive_queue.is_empty()) { 295 // FIXME: Shouldn't this return ENOTCONN instead of EOF? 296 // But if so, we still need to deliver at least one EOF read to userspace.. right? 297 if (protocol_is_disconnected()) 298 return 0; 299 if (!blocking) 300 return set_so_error(EAGAIN); 301 } 302 303 if (!m_receive_queue.is_empty()) { 304 if (flags & MSG_PEEK) { 305 packet = &m_receive_queue.first(); 306 } else { 307 taken_packet = m_receive_queue.take_first(); 308 packet = &taken_packet; 309 } 310 311 set_can_read(!m_receive_queue.is_empty()); 312 313 dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}", 314 this, 315 packet->data->size(), 316 m_receive_queue.size()); 317 } 318 } 319 320 if (!packet) { 321 if (protocol_is_disconnected()) { 322 dbgln("IPv4Socket({}) is protocol-disconnected, returning 0 in recvfrom!", this); 323 return 0; 324 } 325 326 locker.unlock(); 327 auto unblocked_flags = BlockFlags::None; 328 auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags); 329 locker.lock(); 330 331 if (!has_flag(unblocked_flags, BlockFlags::Read)) { 332 if (res.was_interrupted()) 333 return set_so_error(EINTR); 334 335 // Unblocked due to timeout. 336 return set_so_error(EAGAIN); 337 } 338 VERIFY(m_can_read); 339 VERIFY(!m_receive_queue.is_empty()); 340 341 if (flags & MSG_PEEK) { 342 packet = &m_receive_queue.first(); 343 } else { 344 taken_packet = m_receive_queue.take_first(); 345 packet = &taken_packet; 346 } 347 348 set_can_read(!m_receive_queue.is_empty()); 349 350 dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}", 351 this, 352 packet->data->size(), 353 m_receive_queue.size()); 354 } 355 VERIFY(packet->data); 356 357 packet_timestamp = packet->timestamp; 358 359 if (addr) { 360 dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet->peer_address, packet->peer_port); 361 362 sockaddr_in out_addr {}; 363 memcpy(&out_addr.sin_addr, &packet->peer_address, sizeof(IPv4Address)); 364 out_addr.sin_port = htons(packet->peer_port); 365 out_addr.sin_family = AF_INET; 366 Userspace<sockaddr_in*> dest_addr = addr.ptr(); 367 SOCKET_TRY(copy_to_user(dest_addr, &out_addr)); 368 369 socklen_t out_length = sizeof(sockaddr_in); 370 VERIFY(addr_length); 371 SOCKET_TRY(copy_to_user(addr_length, &out_length)); 372 } 373 374 if (type() == SOCK_RAW) { 375 size_t bytes_written = min(packet->data->size(), buffer_length); 376 SOCKET_TRY(buffer.write(packet->data->data(), bytes_written)); 377 return bytes_written; 378 } 379 380 return protocol_receive(packet->data->bytes(), buffer, buffer_length, flags); 381} 382 383ErrorOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Time& packet_timestamp, bool blocking) 384{ 385 if (user_addr_length) { 386 socklen_t addr_length; 387 SOCKET_TRY(copy_from_user(&addr_length, user_addr_length.unsafe_userspace_ptr())); 388 if (addr_length < sizeof(sockaddr_in)) 389 return set_so_error(EINVAL); 390 } 391 392 dbgln_if(IPV4_SOCKET_DEBUG, "recvfrom: type={}, local_port={}", type(), local_port()); 393 394 ErrorOr<size_t> total_nreceived = 0; 395 do { 396 auto offset_buffer = buffer.offset(total_nreceived.value()); 397 auto offset_buffer_length = buffer_length - total_nreceived.value(); 398 399 ErrorOr<size_t> nreceived = 0; 400 if (buffer_mode() == BufferMode::Bytes) 401 nreceived = receive_byte_buffered(description, offset_buffer, offset_buffer_length, flags, user_addr, user_addr_length, blocking); 402 else 403 nreceived = receive_packet_buffered(description, offset_buffer, offset_buffer_length, flags, user_addr, user_addr_length, packet_timestamp, blocking); 404 405 if (nreceived.is_error()) 406 total_nreceived = move(nreceived); 407 else 408 total_nreceived.value() += nreceived.value(); 409 } while ((flags & MSG_WAITALL) && !total_nreceived.is_error() && total_nreceived.value() < buffer_length); 410 411 if (!total_nreceived.is_error()) 412 Thread::current()->did_ipv4_socket_read(total_nreceived.value()); 413 return total_nreceived; 414} 415 416bool IPv4Socket::did_receive(IPv4Address const& source_address, u16 source_port, ReadonlyBytes packet, Time const& packet_timestamp) 417{ 418 MutexLocker locker(mutex()); 419 420 if (is_shut_down_for_reading()) 421 return false; 422 423 auto packet_size = packet.size(); 424 425 if (buffer_mode() == BufferMode::Bytes) { 426 VERIFY(m_receive_buffer); 427 428 size_t space_in_receive_buffer = m_receive_buffer->space_for_writing(); 429 if (packet_size > space_in_receive_buffer) { 430 dbgln("IPv4Socket({}): did_receive refusing packet since buffer is full.", this); 431 VERIFY(m_can_read); 432 return false; 433 } 434 auto scratch_buffer = UserOrKernelBuffer::for_kernel_buffer(m_scratch_buffer->data()); 435 auto nreceived_or_error = protocol_receive(packet, scratch_buffer, m_scratch_buffer->size(), 0); 436 if (nreceived_or_error.is_error()) 437 return false; 438 auto nwritten_or_error = m_receive_buffer->write(scratch_buffer, nreceived_or_error.value()); 439 if (nwritten_or_error.is_error()) 440 return false; 441 set_can_read(!m_receive_buffer->is_empty()); 442 } else { 443 if (m_receive_queue.size() > 2000) { 444 dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this); 445 return false; 446 } 447 auto data_or_error = KBuffer::try_create_with_bytes("IPv4Socket: Packet buffer"sv, packet); 448 if (data_or_error.is_error()) { 449 dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet."); 450 return false; 451 } 452 auto result = m_receive_queue.try_append({ source_address, source_port, packet_timestamp, data_or_error.release_value() }); 453 if (result.is_error()) { 454 dbgln("IPv4Socket: Dropped incoming packet because appending to the receive queue failed."); 455 return false; 456 } 457 set_can_read(true); 458 } 459 m_bytes_received += packet_size; 460 461 if constexpr (IPV4_SOCKET_DEBUG) { 462 if (buffer_mode() == BufferMode::Bytes) 463 dbgln("IPv4Socket({}): did_receive {} bytes, total_received={}", this, packet_size, m_bytes_received); 464 else 465 dbgln("IPv4Socket({}): did_receive {} bytes, total_received={}, packets in queue: {}", 466 this, 467 packet_size, 468 m_bytes_received, 469 m_receive_queue.size()); 470 } 471 472 return true; 473} 474 475ErrorOr<NonnullOwnPtr<KString>> IPv4Socket::pseudo_path(OpenFileDescription const&) const 476{ 477 if (m_role == Role::None) 478 return KString::try_create("socket"sv); 479 480 StringBuilder builder; 481 TRY(builder.try_append("socket:"sv)); 482 483 TRY(builder.try_appendff("{}:{}", TRY(m_local_address.to_string()), m_local_port)); 484 if (m_role == Role::Accepted || m_role == Role::Connected) 485 TRY(builder.try_appendff(" / {}:{}", TRY(m_peer_address.to_string()), m_peer_port)); 486 487 switch (m_role) { 488 case Role::Listener: 489 TRY(builder.try_append(" (listening)"sv)); 490 break; 491 case Role::Accepted: 492 TRY(builder.try_append(" (accepted)"sv)); 493 break; 494 case Role::Connected: 495 TRY(builder.try_append(" (connected)"sv)); 496 break; 497 case Role::Connecting: 498 TRY(builder.try_append(" (connecting)"sv)); 499 break; 500 default: 501 VERIFY_NOT_REACHED(); 502 } 503 504 return KString::try_create(builder.string_view()); 505} 506 507ErrorOr<void> IPv4Socket::setsockopt(int level, int option, Userspace<void const*> user_value, socklen_t user_value_size) 508{ 509 if (level != IPPROTO_IP) 510 return Socket::setsockopt(level, option, user_value, user_value_size); 511 512 MutexLocker locker(mutex()); 513 514 switch (option) { 515 case IP_TTL: { 516 if (user_value_size < sizeof(int)) 517 return EINVAL; 518 int value; 519 TRY(copy_from_user(&value, static_ptr_cast<int const*>(user_value))); 520 if (value < 0 || value > 255) 521 return EINVAL; 522 m_ttl = value; 523 return {}; 524 } 525 case IP_TOS: { 526 if (user_value_size < sizeof(int)) 527 return EINVAL; 528 int value; 529 TRY(copy_from_user(&value, static_ptr_cast<int const*>(user_value))); 530 if (value < 0 || value > 255) 531 return EINVAL; 532 m_type_of_service = value; 533 return {}; 534 } 535 case IP_MULTICAST_LOOP: { 536 if (user_value_size != 1) 537 return EINVAL; 538 u8 value; 539 TRY(copy_from_user(&value, static_ptr_cast<u8 const*>(user_value))); 540 if (value != 0 && value != 1) 541 return EINVAL; 542 m_multicast_loop = value; 543 return {}; 544 } 545 case IP_ADD_MEMBERSHIP: { 546 if (user_value_size != sizeof(ip_mreq)) 547 return EINVAL; 548 ip_mreq mreq; 549 TRY(copy_from_user(&mreq, static_ptr_cast<ip_mreq const*>(user_value))); 550 if (mreq.imr_interface.s_addr != INADDR_ANY) 551 return ENOTSUP; 552 IPv4Address address { (u8 const*)&mreq.imr_multiaddr.s_addr }; 553 if (!m_multicast_memberships.contains_slow(address)) 554 m_multicast_memberships.append(address); 555 return {}; 556 } 557 case IP_DROP_MEMBERSHIP: { 558 if (user_value_size != sizeof(ip_mreq)) 559 return EINVAL; 560 ip_mreq mreq; 561 TRY(copy_from_user(&mreq, static_ptr_cast<ip_mreq const*>(user_value))); 562 if (mreq.imr_interface.s_addr != INADDR_ANY) 563 return ENOTSUP; 564 IPv4Address address { (u8 const*)&mreq.imr_multiaddr.s_addr }; 565 m_multicast_memberships.remove_first_matching([&address](auto& a) { return a == address; }); 566 return {}; 567 } 568 default: 569 return ENOPROTOOPT; 570 } 571} 572 573ErrorOr<void> IPv4Socket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size) 574{ 575 if (level != IPPROTO_IP) 576 return Socket::getsockopt(description, level, option, value, value_size); 577 578 MutexLocker locker(mutex()); 579 580 socklen_t size; 581 TRY(copy_from_user(&size, value_size.unsafe_userspace_ptr())); 582 583 switch (option) { 584 case IP_TTL: { 585 if (size < sizeof(int)) 586 return EINVAL; 587 int ttl = m_ttl; 588 TRY(copy_to_user(static_ptr_cast<int*>(value), (int*)&ttl)); 589 size = sizeof(int); 590 return copy_to_user(value_size, &size); 591 } 592 case IP_TOS: { 593 if (size < sizeof(int)) 594 return EINVAL; 595 int type_of_service = m_type_of_service; 596 TRY(copy_to_user(static_ptr_cast<int*>(value), (int*)&type_of_service)); 597 size = sizeof(int); 598 return copy_to_user(value_size, &size); 599 } 600 case IP_MULTICAST_LOOP: { 601 if (size < 1) 602 return EINVAL; 603 TRY(copy_to_user(static_ptr_cast<u8*>(value), (u8 const*)&m_multicast_loop)); 604 size = 1; 605 return copy_to_user(value_size, &size); 606 } 607 default: 608 return ENOPROTOOPT; 609 } 610} 611 612ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) 613{ 614 TRY(Process::current().require_promise(Pledge::inet)); 615 616 MutexLocker locker(mutex()); 617 618 auto ioctl_route = [request, arg]() -> ErrorOr<void> { 619 auto user_route = static_ptr_cast<rtentry*>(arg); 620 rtentry route; 621 TRY(copy_from_user(&route, user_route)); 622 623 Userspace<const char*> user_rt_dev((FlatPtr)route.rt_dev); 624 auto ifname = TRY(try_copy_kstring_from_user(user_rt_dev, IFNAMSIZ)); 625 626 auto adapter = NetworkingManagement::the().lookup_by_name(ifname->view()); 627 if (!adapter) 628 return ENODEV; 629 630 switch (request) { 631 case SIOCADDRT: { 632 auto current_process_credentials = Process::current().credentials(); 633 if (!current_process_credentials->is_superuser()) 634 return EPERM; 635 if (route.rt_gateway.sa_family != AF_INET) 636 return EAFNOSUPPORT; 637 if (!(route.rt_flags & RTF_UP)) 638 return EINVAL; // FIXME: Find the correct value to return 639 640 auto destination = IPv4Address(((sockaddr_in&)route.rt_dst).sin_addr.s_addr); 641 auto gateway = IPv4Address(((sockaddr_in&)route.rt_gateway).sin_addr.s_addr); 642 auto genmask = IPv4Address(((sockaddr_in&)route.rt_genmask).sin_addr.s_addr); 643 644 return update_routing_table(destination, gateway, genmask, route.rt_flags, adapter, UpdateTable::Set); 645 } 646 case SIOCDELRT: 647 auto current_process_credentials = Process::current().credentials(); 648 if (!current_process_credentials->is_superuser()) 649 return EPERM; 650 if (route.rt_gateway.sa_family != AF_INET) 651 return EAFNOSUPPORT; 652 653 auto destination = IPv4Address(((sockaddr_in&)route.rt_dst).sin_addr.s_addr); 654 auto gateway = IPv4Address(((sockaddr_in&)route.rt_gateway).sin_addr.s_addr); 655 auto genmask = IPv4Address(((sockaddr_in&)route.rt_genmask).sin_addr.s_addr); 656 657 return update_routing_table(destination, gateway, genmask, route.rt_flags, adapter, UpdateTable::Delete); 658 } 659 660 return EINVAL; 661 }; 662 663 auto ioctl_arp = [request, arg]() -> ErrorOr<void> { 664 auto user_req = static_ptr_cast<arpreq*>(arg); 665 arpreq arp_req; 666 TRY(copy_from_user(&arp_req, user_req)); 667 668 auto current_process_credentials = Process::current().credentials(); 669 670 switch (request) { 671 case SIOCSARP: 672 if (!current_process_credentials->is_superuser()) 673 return EPERM; 674 if (arp_req.arp_pa.sa_family != AF_INET) 675 return EAFNOSUPPORT; 676 update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateTable::Set); 677 return {}; 678 679 case SIOCDARP: 680 if (!current_process_credentials->is_superuser()) 681 return EPERM; 682 if (arp_req.arp_pa.sa_family != AF_INET) 683 return EAFNOSUPPORT; 684 update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateTable::Delete); 685 return {}; 686 } 687 688 return EINVAL; 689 }; 690 691 auto ioctl_interface = [request, arg]() -> ErrorOr<void> { 692 auto user_ifr = static_ptr_cast<ifreq*>(arg); 693 ifreq ifr; 694 TRY(copy_from_user(&ifr, user_ifr)); 695 696 char namebuf[IFNAMSIZ + 1]; 697 memcpy(namebuf, ifr.ifr_name, IFNAMSIZ); 698 namebuf[sizeof(namebuf) - 1] = '\0'; 699 700 auto adapter = NetworkingManagement::the().lookup_by_name({ namebuf, strlen(namebuf) }); 701 if (!adapter) 702 return ENODEV; 703 704 auto current_process_credentials = Process::current().credentials(); 705 706 switch (request) { 707 case SIOCSIFADDR: 708 if (!current_process_credentials->is_superuser()) 709 return EPERM; 710 if (ifr.ifr_addr.sa_family != AF_INET) 711 return EAFNOSUPPORT; 712 adapter->set_ipv4_address(IPv4Address(((sockaddr_in&)ifr.ifr_addr).sin_addr.s_addr)); 713 return {}; 714 715 case SIOCSIFNETMASK: 716 if (!current_process_credentials->is_superuser()) 717 return EPERM; 718 if (ifr.ifr_addr.sa_family != AF_INET) 719 return EAFNOSUPPORT; 720 adapter->set_ipv4_netmask(IPv4Address(((sockaddr_in&)ifr.ifr_netmask).sin_addr.s_addr)); 721 return {}; 722 723 case SIOCGIFADDR: { 724 auto ip4_addr = adapter->ipv4_address().to_u32(); 725 auto& socket_address_in = reinterpret_cast<sockaddr_in&>(ifr.ifr_addr); 726 socket_address_in.sin_family = AF_INET; 727 socket_address_in.sin_addr.s_addr = ip4_addr; 728 return copy_to_user(user_ifr, &ifr); 729 } 730 731 case SIOCGIFNETMASK: { 732 auto ip4_netmask = adapter->ipv4_netmask().to_u32(); 733 auto& socket_address_in = reinterpret_cast<sockaddr_in&>(ifr.ifr_addr); 734 socket_address_in.sin_family = AF_INET; 735 // NOTE: NOT ifr_netmask. 736 socket_address_in.sin_addr.s_addr = ip4_netmask; 737 738 return copy_to_user(user_ifr, &ifr); 739 } 740 741 case SIOCGIFHWADDR: { 742 auto mac_address = adapter->mac_address(); 743 switch (adapter->adapter_type()) { 744 case NetworkAdapter::Type::Loopback: 745 ifr.ifr_hwaddr.sa_family = ARPHRD_LOOPBACK; 746 break; 747 case NetworkAdapter::Type::Ethernet: 748 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; 749 break; 750 default: 751 VERIFY_NOT_REACHED(); 752 } 753 mac_address.copy_to(Bytes { ifr.ifr_hwaddr.sa_data, sizeof(ifr.ifr_hwaddr.sa_data) }); 754 return copy_to_user(user_ifr, &ifr); 755 } 756 757 case SIOCGIFBRDADDR: { 758 // Broadcast address is basically the reverse of the netmask, i.e. 759 // instead of zeroing out the end, you OR with 1 instead. 760 auto ip4_netmask = adapter->ipv4_netmask().to_u32(); 761 auto broadcast_addr = adapter->ipv4_address().to_u32() | ~ip4_netmask; 762 auto& socket_address_in = reinterpret_cast<sockaddr_in&>(ifr.ifr_addr); 763 socket_address_in.sin_family = AF_INET; 764 socket_address_in.sin_addr.s_addr = broadcast_addr; 765 return copy_to_user(user_ifr, &ifr); 766 } 767 768 case SIOCGIFMTU: { 769 auto ip4_metric = adapter->mtu(); 770 771 ifr.ifr_addr.sa_family = AF_INET; 772 ifr.ifr_metric = ip4_metric; 773 return copy_to_user(user_ifr, &ifr); 774 } 775 776 case SIOCGIFFLAGS: { 777 // FIXME: stub! 778 constexpr short flags = 1; 779 ifr.ifr_addr.sa_family = AF_INET; 780 ifr.ifr_flags = flags; 781 return copy_to_user(user_ifr, &ifr); 782 } 783 784 case SIOCGIFCONF: { 785 // FIXME: stub! 786 return EINVAL; 787 } 788 } 789 790 return EINVAL; 791 }; 792 793 switch (request) { 794 case SIOCSIFADDR: 795 case SIOCSIFNETMASK: 796 case SIOCGIFADDR: 797 case SIOCGIFHWADDR: 798 case SIOCGIFNETMASK: 799 case SIOCGIFBRDADDR: 800 case SIOCGIFMTU: 801 case SIOCGIFFLAGS: 802 case SIOCGIFCONF: 803 return ioctl_interface(); 804 805 case SIOCADDRT: 806 case SIOCDELRT: 807 return ioctl_route(); 808 809 case SIOCSARP: 810 case SIOCDARP: 811 return ioctl_arp(); 812 813 case FIONREAD: { 814 int readable = 0; 815 if (buffer_mode() == BufferMode::Bytes) { 816 readable = static_cast<int>(m_receive_buffer->immediately_readable()); 817 } else { 818 if (m_receive_queue.size() != 0u) { 819 readable = static_cast<int>(TRY(protocol_size(m_receive_queue.first().data->bytes()))); 820 } 821 } 822 823 return copy_to_user(static_ptr_cast<int*>(arg), &readable); 824 } 825 } 826 827 return EINVAL; 828} 829 830ErrorOr<void> IPv4Socket::close() 831{ 832 [[maybe_unused]] auto rc = shutdown(SHUT_RDWR); 833 return {}; 834} 835 836void IPv4Socket::shut_down_for_reading() 837{ 838 Socket::shut_down_for_reading(); 839 set_can_read(true); 840} 841 842void IPv4Socket::set_can_read(bool value) 843{ 844 m_can_read = value; 845 if (value) 846 evaluate_block_conditions(); 847} 848 849void IPv4Socket::drop_receive_buffer() 850{ 851 m_receive_buffer = nullptr; 852} 853 854}