diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 37 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.h | 6 | ||||
-rw-r--r-- | Kernel/Net/NetworkAdapter.cpp | 4 | ||||
-rw-r--r-- | Kernel/Net/NetworkAdapter.h | 2 | ||||
-rw-r--r-- | Kernel/Net/NetworkTask.cpp | 3 | ||||
-rw-r--r-- | Kernel/Net/Socket.h | 4 | ||||
-rw-r--r-- | Kernel/Net/TCPSocket.cpp | 4 | ||||
-rw-r--r-- | Kernel/Net/UDPSocket.cpp | 2 | ||||
-rw-r--r-- | Kernel/UnixTypes.h | 3 |
9 files changed, 55 insertions, 10 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index effbb89381..1b6951021b 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -195,7 +195,7 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt #endif if (type() == SOCK_RAW) { - routing_decision.adapter->send_ipv4(routing_decision.next_hop, m_peer_address, (IPv4Protocol)protocol(), (const u8*)data, data_length); + routing_decision.adapter->send_ipv4(routing_decision.next_hop, m_peer_address, (IPv4Protocol)protocol(), (const u8*)data, data_length, m_ttl); return data_length; } @@ -313,3 +313,38 @@ String IPv4Socket::absolute_path(const FileDescription&) const return builder.to_string(); } + +KResult IPv4Socket::setsockopt(int level, int option, const void* value, socklen_t value_size) +{ + if (level != IPPROTO_IP) + return Socket::setsockopt(level, option, value, value_size); + + switch (option) { + case IP_TTL: + if (value_size < sizeof(int)) + return KResult(-EINVAL); + if (*(const int*)value < 0 || *(const int*)value > 255) + return KResult(-EINVAL); + m_ttl = (u8)*(const int*)value; + return KSuccess; + default: + return KResult(-ENOPROTOOPT); + } +} + +KResult IPv4Socket::getsockopt(int level, int option, void* value, socklen_t* value_size) +{ + if (level != IPPROTO_IP) + return Socket::getsockopt(level, option, value, value_size); + + + switch (option) { + case IP_TTL: + if (*value_size < sizeof(int)) + return KResult(-EINVAL); + *(int*)value = m_ttl; + return KSuccess; + default: + return KResult(-ENOPROTOOPT); + } +} diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index ced971f1cf..2480634bee 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -31,6 +31,8 @@ public: virtual bool can_write(FileDescription&) const override; virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override; virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override; + virtual KResult setsockopt(int level, int option, const void*, socklen_t) override; + virtual KResult getsockopt(int level, int option, void*, socklen_t*) override; void did_receive(const IPv4Address& peer_address, u16 peer_port, KBuffer&&); @@ -47,6 +49,8 @@ public: String absolute_path(const FileDescription& description) const override; + u8 ttl() const { return m_ttl; } + protected: IPv4Socket(int type, int protocol); virtual const char* class_name() const override { return "IPv4Socket"; } @@ -83,5 +87,7 @@ private: u32 m_bytes_received { 0 }; + u8 m_ttl { 64 }; + bool m_can_read { false }; }; diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index 39cac3363c..9cba392b71 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -58,7 +58,7 @@ void NetworkAdapter::send(const MACAddress& destination, const ARPPacket& packet send_raw((const u8*)eth, size_in_bytes); } -void NetworkAdapter::send_ipv4(const MACAddress& destination_mac, const IPv4Address& destination_ipv4, IPv4Protocol protocol, const u8* payload, size_t payload_size) +void NetworkAdapter::send_ipv4(const MACAddress& destination_mac, const IPv4Address& destination_ipv4, IPv4Protocol protocol, const u8* payload, size_t payload_size, u8 ttl) { size_t size_in_bytes = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet) + payload_size; auto buffer = ByteBuffer::create_zeroed(size_in_bytes); @@ -74,7 +74,7 @@ void NetworkAdapter::send_ipv4(const MACAddress& destination_mac, const IPv4Addr ipv4.set_protocol((u8)protocol); ipv4.set_length(sizeof(IPv4Packet) + payload_size); ipv4.set_ident(1); - ipv4.set_ttl(64); + ipv4.set_ttl(ttl); ipv4.set_checksum(ipv4.compute_checksum()); m_packets_out++; m_bytes_out += size_in_bytes; diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h index b063163eed..9f145870b9 100644 --- a/Kernel/Net/NetworkAdapter.h +++ b/Kernel/Net/NetworkAdapter.h @@ -34,7 +34,7 @@ public: void set_ipv4_gateway(const IPv4Address&); void send(const MACAddress&, const ARPPacket&); - void send_ipv4(const MACAddress&, const IPv4Address&, IPv4Protocol, const u8* payload, size_t payload_size); + void send_ipv4(const MACAddress&, const IPv4Address&, IPv4Protocol, const u8* payload, size_t payload_size, u8 ttl); Optional<KBuffer> dequeue_packet(); diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index f5b404fcd8..bce343364f 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -272,7 +272,8 @@ void handle_icmp(const EthernetFrameHeader& eth, const IPv4Packet& ipv4_packet) if (size_t icmp_payload_size = icmp_packet_size - sizeof(ICMPEchoPacket)) memcpy(response.payload(), request.payload(), icmp_payload_size); response.header.set_checksum(internet_checksum(&response, icmp_packet_size)); - adapter->send_ipv4(eth.source(), ipv4_packet.source(), IPv4Protocol::ICMP, buffer.data(), buffer.size()); + // FIXME: What is the right TTL value here? Is 64 ok? Should we use the same TTL as the echo request? + adapter->send_ipv4(eth.source(), ipv4_packet.source(), IPv4Protocol::ICMP, buffer.data(), buffer.size(), 64); } } diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index 98a3d221f5..c297aa8e7b 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -76,8 +76,8 @@ public: virtual ssize_t sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0; virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0; - KResult setsockopt(int level, int option, const void*, socklen_t); - KResult getsockopt(int level, int option, void*, socklen_t*); + virtual KResult setsockopt(int level, int option, const void*, socklen_t); + virtual KResult getsockopt(int level, int option, void*, socklen_t*); pid_t origin_pid() const { return m_origin_pid; } pid_t acceptor_pid() const { return m_acceptor_pid; } diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index 8f3c15cb5e..8be47ed526 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -170,7 +170,7 @@ void TCPSocket::send_tcp_packet(u16 flags, const void* payload, int payload_size routing_decision.adapter->send_ipv4( routing_decision.next_hop, peer_address(), IPv4Protocol::TCP, - buffer.data(), buffer.size()); + buffer.data(), buffer.size(), ttl()); m_packets_out++; m_bytes_out += buffer.size(); @@ -210,7 +210,7 @@ void TCPSocket::send_outgoing_packets() #endif routing_decision.adapter->send_ipv4( routing_decision.next_hop, peer_address(), IPv4Protocol::TCP, - packet.buffer.data(), packet.buffer.size()); + packet.buffer.data(), packet.buffer.size(), ttl()); m_packets_out++; m_bytes_out += packet.buffer.size(); diff --git a/Kernel/Net/UDPSocket.cpp b/Kernel/Net/UDPSocket.cpp index da6f6d140f..103c824226 100644 --- a/Kernel/Net/UDPSocket.cpp +++ b/Kernel/Net/UDPSocket.cpp @@ -77,7 +77,7 @@ int UDPSocket::protocol_send(const void* data, int data_length) local_port(), peer_address().to_string().characters(), peer_port()); - routing_decision.adapter->send_ipv4(routing_decision.next_hop, peer_address(), IPv4Protocol::UDP, buffer.data(), buffer.size()); + routing_decision.adapter->send_ipv4(routing_decision.next_hop, peer_address(), IPv4Protocol::UDP, buffer.data(), buffer.size(), ttl()); return data_length; } diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h index d23b48251c..34047f2916 100644 --- a/Kernel/UnixTypes.h +++ b/Kernel/UnixTypes.h @@ -337,10 +337,13 @@ struct pollfd { #define SO_KEEPALIVE 3 #define SO_ERROR 4 +#define IPPROTO_IP 0 #define IPPROTO_ICMP 1 #define IPPROTO_TCP 6 #define IPPROTO_UDP 17 +#define IP_TTL 2 + struct sockaddr { u16 sa_family; char sa_data[14]; |