diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 22 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 3 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 7 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.h | 3 | ||||
-rw-r--r-- | Kernel/Net/Socket.h | 3 | ||||
-rw-r--r-- | Kernel/Process.cpp | 30 | ||||
-rw-r--r-- | Kernel/Process.h | 1 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscall.h | 1 |
9 files changed, 63 insertions, 9 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index f6b4b96ed6..681674ba61 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -46,12 +46,28 @@ IPv4Socket::~IPv4Socket() all_sockets().resource().remove(this); } -bool IPv4Socket::get_address(sockaddr* address, socklen_t* address_size) +bool IPv4Socket::get_local_address(sockaddr* address, socklen_t* address_size) { // FIXME: Look into what fallback behavior we should have here. - if (*address_size != sizeof(sockaddr_in)) + if (*address_size < sizeof(sockaddr_in)) return false; - memcpy(address, &m_peer_address, sizeof(sockaddr_in)); + auto& ia = (sockaddr_in&)*address; + ia.sin_family = AF_INET; + ia.sin_port = m_local_port; + memcpy(&ia.sin_addr, &m_local_address, sizeof(IPv4Address)); + *address_size = sizeof(sockaddr_in); + return true; +} + +bool IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size) +{ + // FIXME: Look into what fallback behavior we should have here. + if (*address_size < sizeof(sockaddr_in)) + return false; + auto& ia = (sockaddr_in&)*address; + ia.sin_family = AF_INET; + ia.sin_port = m_peer_port; + memcpy(&ia.sin_addr, &m_peer_address, sizeof(IPv4Address)); *address_size = sizeof(sockaddr_in); return true; } diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index 3d7b145293..33b4f9d420 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -22,7 +22,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) override; virtual KResult connect(FileDescriptor&, const sockaddr*, socklen_t, ShouldBlock = ShouldBlock::Yes) override; - virtual bool get_address(sockaddr*, socklen_t*) override; + virtual bool get_local_address(sockaddr*, socklen_t*) override; + virtual bool get_peer_address(sockaddr*, socklen_t*) override; virtual void attach(FileDescriptor&) override; virtual void detach(FileDescriptor&) override; virtual bool can_read(FileDescriptor&) const override; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index c6cf763b2f..17ee5fc2cf 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -24,7 +24,7 @@ LocalSocket::~LocalSocket() { } -bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size) +bool LocalSocket::get_local_address(sockaddr* address, socklen_t* address_size) { // FIXME: Look into what fallback behavior we should have here. if (*address_size != sizeof(sockaddr_un)) @@ -34,6 +34,11 @@ bool LocalSocket::get_address(sockaddr* address, socklen_t* address_size) return true; } +bool LocalSocket::get_peer_address(sockaddr* address, socklen_t* address_size) +{ + return get_local_address(address, address_size); +} + KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size) { ASSERT(!is_connected()); diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index 81b902a982..db481912f2 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -12,7 +12,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) override; virtual KResult connect(FileDescriptor&, const sockaddr*, socklen_t, ShouldBlock = ShouldBlock::Yes) override; - virtual bool get_address(sockaddr*, socklen_t*) override; + virtual bool get_local_address(sockaddr*, socklen_t*) override; + virtual bool get_peer_address(sockaddr*, socklen_t*) override; virtual void attach(FileDescriptor&) override; virtual void detach(FileDescriptor&) override; virtual bool can_read(FileDescriptor&) const override; diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index 151e250268..0fb9544cbb 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -30,7 +30,8 @@ public: virtual KResult bind(const sockaddr*, socklen_t) = 0; virtual KResult connect(FileDescriptor&, const sockaddr*, socklen_t, ShouldBlock) = 0; - virtual bool get_address(sockaddr*, socklen_t*) = 0; + virtual bool get_local_address(sockaddr*, socklen_t*) = 0; + virtual bool get_peer_address(sockaddr*, socklen_t*) = 0; virtual bool is_local() const { return false; } virtual bool is_ipv4() const { return false; } virtual void attach(FileDescriptor&) = 0; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index cae1d20648..80de78b8a5 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2120,7 +2120,7 @@ int Process::sys$accept(int accepting_socket_fd, sockaddr* address, socklen_t* a } auto accepted_socket = socket.accept(); ASSERT(accepted_socket); - bool success = accepted_socket->get_address(address, address_size); + bool success = accepted_socket->get_local_address(address, address_size); ASSERT(success); auto accepted_socket_descriptor = FileDescriptor::create(move(accepted_socket), SocketRole::Accepted); // NOTE: The accepted socket inherits fd flags from the accepting socket. @@ -2240,7 +2240,33 @@ int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) return -ENOTSOCK; auto& socket = *descriptor->socket(); - if (!socket.get_address(addr, addrlen)) + if (!socket.get_local_address(addr, addrlen)) + return -EINVAL; // FIXME: Should this be another error? I'm not sure. + + return 0; +} + +int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen) +{ + if (!validate_read_typed(addrlen)) + return -EFAULT; + + if (*addrlen <= 0) + return -EINVAL; + + if (!validate_write(addr, *addrlen)) + return -EFAULT; + + auto* descriptor = file_descriptor(sockfd); + if (!descriptor) + return -EBADF; + + if (!descriptor->is_socket()) + return -ENOTSOCK; + + auto& socket = *descriptor->socket(); + + if (!socket.get_peer_address(addr, addrlen)) return -EINVAL; // FIXME: Should this be another error? I'm not sure. return 0; diff --git a/Kernel/Process.h b/Kernel/Process.h index f0f6fb246f..ff3d4e5e5c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -176,6 +176,7 @@ public: int sys$getsockopt(const Syscall::SC_getsockopt_params*); int sys$setsockopt(const Syscall::SC_setsockopt_params*); int sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen); + int sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen); int sys$restore_signal_mask(dword mask); int sys$create_thread(int(*)(void*), void*); void sys$exit_thread(int code); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 131fbc647e..338252f632 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -274,6 +274,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, return current->process().sys$writev((int)arg1, (const struct iovec*)arg2, (int)arg3); case Syscall::SC_getsockname: return current->process().sys$getsockname((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3); + case Syscall::SC_getpeername: + return current->process().sys$getpeername((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3); default: kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 7acd3124bd..2d093f6a74 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -105,6 +105,7 @@ __ENUMERATE_SYSCALL(writev) \ __ENUMERATE_SYSCALL(beep) \ __ENUMERATE_SYSCALL(getsockname) \ + __ENUMERATE_SYSCALL(getpeername) \ namespace Syscall { |