Routing.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include <Kernel/Net/Routing.h>
  2. #include <Kernel/Thread.h>
  3. //#define ROUTING_DEBUG
  4. Lockable<HashMap<IPv4Address, MACAddress>>& arp_table()
  5. {
  6. static Lockable<HashMap<IPv4Address, MACAddress>>* the;
  7. if (!the)
  8. the = new Lockable<HashMap<IPv4Address, MACAddress>>;
  9. return *the;
  10. }
  11. bool RoutingDecision::is_zero() const
  12. {
  13. return adapter.is_null() || next_hop.is_zero();
  14. }
  15. RoutingDecision route_to(const IPv4Address& target, const IPv4Address& source)
  16. {
  17. auto target_addr = target.to_u32();
  18. auto source_addr = source.to_u32();
  19. WeakPtr<NetworkAdapter> local_adapter = nullptr;
  20. WeakPtr<NetworkAdapter> gateway_adapter = nullptr;
  21. NetworkAdapter::for_each([source_addr, &target_addr, &local_adapter, &gateway_adapter](auto& adapter) {
  22. auto adapter_addr = adapter.ipv4_address().to_u32();
  23. auto adapter_mask = adapter.ipv4_netmask().to_u32();
  24. if (source_addr != 0 && source_addr != adapter_addr)
  25. return;
  26. if ((target_addr & adapter_mask) == (adapter_addr & adapter_mask))
  27. local_adapter = adapter.make_weak_ptr();
  28. if (adapter.ipv4_gateway().to_u32() != 0)
  29. gateway_adapter = adapter.make_weak_ptr();
  30. });
  31. if (!local_adapter && !gateway_adapter) {
  32. #ifdef ROUTING_DEBUG
  33. kprintf("Routing: Couldn't find a suitable adapter for route to %s\n",
  34. target.to_string().characters());
  35. #endif
  36. return { nullptr, {} };
  37. }
  38. WeakPtr<NetworkAdapter> adapter = nullptr;
  39. IPv4Address next_hop_ip;
  40. if (local_adapter) {
  41. #ifdef ROUTING_DEBUG
  42. kprintf("Routing: Got adapter for route (direct): %s (%s/%s) for %s\n",
  43. local_adapter->name().characters(),
  44. local_adapter->ipv4_address().to_string().characters(),
  45. local_adapter->ipv4_netmask().to_string().characters(),
  46. target.to_string().characters());
  47. #endif
  48. adapter = local_adapter;
  49. next_hop_ip = target;
  50. } else if (gateway_adapter) {
  51. #ifdef ROUTING_DEBUG
  52. kprintf("Routing: Got adapter for route (using gateway %s): %s (%s/%s) for %s\n",
  53. gateway_adapter->ipv4_gateway().to_string().characters(),
  54. gateway_adapter->name().characters(),
  55. gateway_adapter->ipv4_address().to_string().characters(),
  56. gateway_adapter->ipv4_netmask().to_string().characters(),
  57. target.to_string().characters());
  58. #endif
  59. adapter = gateway_adapter;
  60. next_hop_ip = gateway_adapter->ipv4_gateway();
  61. } else {
  62. return { nullptr, {} };
  63. }
  64. {
  65. LOCKER(arp_table().lock());
  66. auto addr = arp_table().resource().get(next_hop_ip);
  67. if (addr.has_value()) {
  68. #ifdef ROUTING_DEBUG
  69. kprintf("Routing: Using cached ARP entry for %s (%s)\n",
  70. next_hop_ip.to_string().characters(),
  71. addr.value().to_string().characters());
  72. #endif
  73. return { adapter, addr.value() };
  74. }
  75. }
  76. #ifdef ROUTING_DEBUG
  77. kprintf("Routing: Sending ARP request via adapter %s for IPv4 address %s\n",
  78. adapter->name().characters(),
  79. next_hop_ip.to_string().characters());
  80. #endif
  81. ARPPacket request;
  82. request.set_operation(ARPOperation::Request);
  83. request.set_target_hardware_address({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
  84. request.set_target_protocol_address(next_hop_ip);
  85. request.set_sender_hardware_address(adapter->mac_address());
  86. request.set_sender_protocol_address(adapter->ipv4_address());
  87. adapter->send({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, request);
  88. (void)current->block_until("Routing (ARP)", [next_hop_ip] {
  89. return arp_table().resource().get(next_hop_ip).has_value();
  90. });
  91. {
  92. LOCKER(arp_table().lock());
  93. auto addr = arp_table().resource().get(next_hop_ip);
  94. if (addr.has_value()) {
  95. #ifdef ROUTING_DEBUG
  96. kprintf("Routing: Got ARP response using adapter %s for %s (%s)\n",
  97. adapter->name().characters(),
  98. next_hop_ip.to_string().characters(),
  99. addr.value().to_string().characters());
  100. #endif
  101. return { adapter, addr.value() };
  102. }
  103. }
  104. #ifdef ROUTING_DEBUG
  105. kprintf("Routing: Couldn't find route using adapter %s for %s\n",
  106. adapter->name().characters(),
  107. target.to_string().characters());
  108. #endif
  109. return { nullptr, {} };
  110. }