Kernel: Implement basic gateway for network interfaces
This commit is contained in:
parent
dd3641f054
commit
f804e87f7d
|
@ -46,6 +46,9 @@ namespace Kernel
|
||||||
BAN::IPv4Address get_netmask() const { return m_netmask; }
|
BAN::IPv4Address get_netmask() const { return m_netmask; }
|
||||||
void set_netmask(BAN::IPv4Address new_netmask) { m_netmask = new_netmask; }
|
void set_netmask(BAN::IPv4Address new_netmask) { m_netmask = new_netmask; }
|
||||||
|
|
||||||
|
BAN::IPv4Address get_gateway() const { return m_gateway; }
|
||||||
|
void set_gateway(BAN::IPv4Address new_gateway) { m_gateway = new_gateway; }
|
||||||
|
|
||||||
virtual bool link_up() = 0;
|
virtual bool link_up() = 0;
|
||||||
virtual int link_speed() = 0;
|
virtual int link_speed() = 0;
|
||||||
|
|
||||||
|
@ -65,6 +68,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::IPv4Address m_ipv4_address { 0 };
|
BAN::IPv4Address m_ipv4_address { 0 };
|
||||||
BAN::IPv4Address m_netmask { 0 };
|
BAN::IPv4Address m_netmask { 0 };
|
||||||
|
BAN::IPv4Address m_gateway { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ namespace Kernel
|
||||||
if (ipv4_address == s_broadcast_ipv4)
|
if (ipv4_address == s_broadcast_ipv4)
|
||||||
return s_broadcast_mac;
|
return s_broadcast_mac;
|
||||||
|
|
||||||
|
if (interface.get_ipv4_address().mask(interface.get_netmask()) != ipv4_address.mask(interface.get_netmask()))
|
||||||
|
ipv4_address = interface.get_gateway();
|
||||||
|
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
if (m_arp_table.contains(ipv4_address))
|
if (m_arp_table.contains(ipv4_address))
|
||||||
|
|
|
@ -171,6 +171,22 @@ namespace Kernel
|
||||||
dprintln("Netmask set to {}", m_interface->get_netmask());
|
dprintln("Netmask set to {}", m_interface->get_netmask());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case SIOCGIFGWADDR:
|
||||||
|
{
|
||||||
|
auto& ifru_gwaddr = *reinterpret_cast<sockaddr_in*>(&ifreq->ifr_ifru.ifru_gwaddr);
|
||||||
|
ifru_gwaddr.sin_family = AF_INET;
|
||||||
|
ifru_gwaddr.sin_addr.s_addr = m_interface->get_gateway().raw;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case SIOCSIFGWADDR:
|
||||||
|
{
|
||||||
|
auto& ifru_gwaddr = *reinterpret_cast<const sockaddr_in*>(&ifreq->ifr_ifru.ifru_gwaddr);
|
||||||
|
if (ifru_gwaddr.sin_family != AF_INET)
|
||||||
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
m_interface->set_gateway(BAN::IPv4Address { ifru_gwaddr.sin_addr.s_addr });
|
||||||
|
dprintln("Gateway set to {}", m_interface->get_gateway());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case SIOCGIFHWADDR:
|
case SIOCGIFHWADDR:
|
||||||
{
|
{
|
||||||
auto mac_address = m_interface->get_mac_address();
|
auto mac_address = m_interface->get_mac_address();
|
||||||
|
|
|
@ -22,6 +22,7 @@ struct ifreq
|
||||||
union {
|
union {
|
||||||
struct sockaddr ifru_addr;
|
struct sockaddr ifru_addr;
|
||||||
struct sockaddr ifru_netmask;
|
struct sockaddr ifru_netmask;
|
||||||
|
struct sockaddr ifru_gwaddr;
|
||||||
struct sockaddr ifru_hwaddr;
|
struct sockaddr ifru_hwaddr;
|
||||||
unsigned char __min_storage[sizeof(sockaddr) + 6];
|
unsigned char __min_storage[sizeof(sockaddr) + 6];
|
||||||
} ifr_ifru;
|
} ifr_ifru;
|
||||||
|
@ -31,7 +32,9 @@ struct ifreq
|
||||||
#define SIOCSIFADDR 2 /* Set interface address */
|
#define SIOCSIFADDR 2 /* Set interface address */
|
||||||
#define SIOCGIFNETMASK 3 /* Get network mask */
|
#define SIOCGIFNETMASK 3 /* Get network mask */
|
||||||
#define SIOCSIFNETMASK 4 /* Set network mask */
|
#define SIOCSIFNETMASK 4 /* Set network mask */
|
||||||
#define SIOCGIFHWADDR 5 /* Get hardware address */
|
#define SIOCGIFGWADDR 5 /* Get gateway address */
|
||||||
|
#define SIOCSIFGWADDR 6 /* Set gateway address */
|
||||||
|
#define SIOCGIFHWADDR 7 /* Get hardware address */
|
||||||
|
|
||||||
void if_freenameindex(struct if_nameindex* ptr);
|
void if_freenameindex(struct if_nameindex* ptr);
|
||||||
char* if_indextoname(unsigned ifindex, char* ifname);
|
char* if_indextoname(unsigned ifindex, char* ifname);
|
||||||
|
|
|
@ -73,7 +73,7 @@ BAN::MACAddress get_mac_address(int socket)
|
||||||
return mac_address;
|
return mac_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_ipv4_info(int socket, BAN::IPv4Address address, BAN::IPv4Address subnet)
|
void update_ipv4_info(int socket, BAN::IPv4Address address, BAN::IPv4Address netmask, BAN::IPv4Address gateway)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
ifreq ifreq;
|
ifreq ifreq;
|
||||||
|
@ -98,6 +98,19 @@ void update_ipv4_info(int socket, BAN::IPv4Address address, BAN::IPv4Address sub
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gateway.raw)
|
||||||
|
{
|
||||||
|
ifreq ifreq;
|
||||||
|
auto& ifru_gwaddr = *reinterpret_cast<sockaddr_in*>(&ifreq.ifr_ifru.ifru_gwaddr);
|
||||||
|
ifru_gwaddr.sin_family = AF_INET;
|
||||||
|
ifru_gwaddr.sin_addr.s_addr = gateway.raw;
|
||||||
|
if (ioctl(socket, SIOCSIFGWADDR, &ifreq) == -1)
|
||||||
|
{
|
||||||
|
perror("ioctl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_dhcp_packet(int socket, const DHCPPacket& dhcp_packet, BAN::IPv4Address server_ipv4)
|
void send_dhcp_packet(int socket, const DHCPPacket& dhcp_packet, BAN::IPv4Address server_ipv4)
|
||||||
|
@ -359,7 +372,11 @@ int main()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_ipv4_info(socket, dhcp_ack->address, dhcp_ack->subnet);
|
BAN::IPv4Address gateway { 0 };
|
||||||
|
if (!dhcp_ack->routers.empty())
|
||||||
|
gateway = dhcp_ack->routers.front();
|
||||||
|
|
||||||
|
update_ipv4_info(socket, dhcp_ack->address, dhcp_ack->subnet, gateway);
|
||||||
|
|
||||||
close(socket);
|
close(socket);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue