summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Net/IPv4Socket.cpp37
-rw-r--r--Kernel/Net/IPv4Socket.h6
-rw-r--r--Kernel/Net/NetworkAdapter.cpp4
-rw-r--r--Kernel/Net/NetworkAdapter.h2
-rw-r--r--Kernel/Net/NetworkTask.cpp3
-rw-r--r--Kernel/Net/Socket.h4
-rw-r--r--Kernel/Net/TCPSocket.cpp4
-rw-r--r--Kernel/Net/UDPSocket.cpp2
-rw-r--r--Kernel/UnixTypes.h3
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];