diff --git a/include/net.h b/include/net.h index b7555c0..3faecff 100644 --- a/include/net.h +++ b/include/net.h @@ -226,6 +226,7 @@ IPaddr_t net_get_gateway(void); IPaddr_t net_get_nameserver(void); const char *net_get_domainname(void); +struct eth_device *net_route(IPaddr_t ip); /* Do the work */ void net_poll(void); diff --git a/net/net.c b/net/net.c index 33d6e2c..9495467 100644 --- a/net/net.c +++ b/net/net.c @@ -144,6 +144,27 @@ } } +struct eth_device *net_route(IPaddr_t dest) +{ + struct eth_device *edev; + + for_each_netdev(edev) { + if (!edev->ipaddr) + continue; + + if ((dest & edev->netmask) == (edev->ipaddr & edev->netmask)) { + pr_debug("Route: Using %s (ip=%pI4, nm=%pI4) to reach %pI4\n", + dev_name(&edev->dev), &edev->ipaddr, &edev->netmask, + &dest); + return edev; + } + } + + pr_debug("Route: No device found for %pI4\n", &dest); + + return NULL; +} + static int arp_request(struct eth_device *edev, IPaddr_t dest, unsigned char *ether) { char *pkt; @@ -154,6 +175,9 @@ unsigned retries = 0; int ret; + if (!edev) + return -EHOSTUNREACH; + if (!arp_packet) { arp_packet = net_alloc_packet(); if (!arp_packet) @@ -295,9 +319,11 @@ int ret; if (!edev) { - edev = eth_get_current(); + edev = net_route(dest); + if (!edev && net_gateway) + edev = net_route(net_gateway); if (!edev) - return ERR_PTR(-ENETDOWN); + return ERR_PTR(-EHOSTUNREACH); } if (!is_valid_ether_addr(edev->ethaddr)) {