diff --git a/net/icmp/icmp_sendmsg.c b/net/icmp/icmp_sendmsg.c index f04a35d4c8d..4ac4e631172 100644 --- a/net/icmp/icmp_sendmsg.c +++ b/net/icmp/icmp_sendmsg.c @@ -316,7 +316,17 @@ ssize_t icmp_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Get the device that will be used to route this ICMP ECHO request */ - dev = netdev_findby_ripv4addr(INADDR_ANY, inaddr->sin_addr.s_addr); +#ifdef CONFIG_NET_BINDTODEVICE + if (conn->sconn.s_boundto != 0) + { + dev = net_bound_device(&conn->sconn); + } + else +#endif + { + dev = netdev_findby_ripv4addr(INADDR_ANY, inaddr->sin_addr.s_addr); + } + if (dev == NULL) { nerr("ERROR: Not reachable\n"); diff --git a/net/tcp/tcp_finddev.c b/net/tcp/tcp_finddev.c index b0083f7eca9..a863ca71886 100644 --- a/net/tcp/tcp_finddev.c +++ b/net/tcp/tcp_finddev.c @@ -34,6 +34,7 @@ #include "netdev/netdev.h" #include "inet/inet.h" #include "tcp/tcp.h" +#include "utils/utils.h" /**************************************************************************** * Private Functions @@ -74,7 +75,13 @@ static int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn, if (net_ipv4addr_cmp(addr, INADDR_ANY)) { - return local ? OK : -EINVAL; + if (local) + { + conn->dev = net_bound_device(&conn->sconn); + return OK; + } + + return -EINVAL; } /* We need to select the device that is going to route the TCP packet @@ -124,7 +131,13 @@ static int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn, if (net_ipv6addr_cmp(addr, g_ipv6_unspecaddr)) { - return local ? OK : -EINVAL; + if (local) + { + conn->dev = net_bound_device(&conn->sconn); + return OK; + } + + return -EINVAL; } /* We need to select the device that is going to route the TCP packet diff --git a/net/udp/udp_finddev.c b/net/udp/udp_finddev.c index e47a19b651f..ceb8ba1b50c 100644 --- a/net/udp/udp_finddev.c +++ b/net/udp/udp_finddev.c @@ -33,63 +33,7 @@ #include "netdev/netdev.h" #include "inet/inet.h" #include "udp/udp.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: upd_bound_device - * - * Description: - * If the UDP socket is bound to a device, return the reference to the - * bound device. - * - * Input Parameters: - * conn - UDP connection structure (not currently used). - * - * Returned Value: - * A reference to the bound device. If the retained interface index no - * longer refers to a valid device, this function will unbind the device - * and return an arbitrary network device at the head of the list of - * registered devices. This supports legacy IPv4 DHCPD behavior when - * there is only a single registered network device. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_BINDTODEVICE -static FAR struct net_driver_s *upd_bound_device(FAR struct udp_conn_s *conn) -{ - FAR struct net_driver_s *dev = NULL; - - /* Is the UDP socket bound to a device? */ - - if (conn->sconn.s_boundto != 0) - { - /* Yes..This socket has been bound to an interface. Convert the - * interface index into a device structure reference. - */ - - dev = netdev_findbyindex(conn->sconn.s_boundto); - if (dev == NULL) - { - /* No device? It must have been unregistered. Un-bind the UDP - * socket. - */ - - conn->sconn.s_boundto = 0; - } - } - - /* If no device was bound or the bound device is no longer valid, - * then let's try the default network device. - */ - - return dev == NULL ? netdev_default() : dev; -} -#else -# define upd_bound_device(c) netdev_default(); -#endif +#include "utils/utils.h" /**************************************************************************** * Public Functions @@ -226,7 +170,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn, { /* Return the device bound to this UDP socket, if any */ - return upd_bound_device(conn); + return net_bound_device(&conn->sconn); } else { @@ -252,7 +196,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn, * Return the device bound to this UDP socket, if any. */ - return upd_bound_device(conn); + return net_bound_device(&conn->sconn); } } #endif @@ -292,7 +236,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn, { /* Return the device bound to this UDP socket, if any */ - return upd_bound_device(conn); + return net_bound_device(&conn->sconn); } else { @@ -318,7 +262,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn, * Return the device bound to this UDP socket, if any. */ - return upd_bound_device(conn); + return net_bound_device(&conn->sconn); } } #endif diff --git a/net/utils/Make.defs b/net/utils/Make.defs index 235650ed0e5..91490d9d5d5 100644 --- a/net/utils/Make.defs +++ b/net/utils/Make.defs @@ -49,6 +49,12 @@ else ifeq ($(CONFIG_NET_ICMPv6),y) NET_CSRCS += net_icmpchksum.c endif +# Bound device find + +ifeq ($(CONFIG_NET_BINDTODEVICE),y) +NET_CSRCS += net_bounddev.c +endif + # Include utility build support DEPPATH += --dep-path utils diff --git a/net/utils/net_bounddev.c b/net/utils/net_bounddev.c new file mode 100644 index 00000000000..1885fef90f9 --- /dev/null +++ b/net/utils/net_bounddev.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * net/utils/net_bounddev.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include + +#include +#include + +#include "netdev/netdev.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_bound_device + * + * Description: + * If the socket is bound to a device, return the reference to the + * bound device. + * + * Input Parameters: + * sconn - Socket connection structure (not currently used). + * + * Returned Value: + * A reference to the bound device. If the retained interface index no + * longer refers to a valid device, this function will unbind the device + * and return an arbitrary network device at the head of the list of + * registered devices. This supports legacy IPv4 DHCPD behavior when + * there is only a single registered network device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_BINDTODEVICE +FAR struct net_driver_s *net_bound_device(FAR struct socket_conn_s *sconn) +{ + FAR struct net_driver_s *dev = NULL; + + /* Is the socket bound to a device? */ + + if (sconn->s_boundto != 0) + { + /* Yes..This socket has been bound to an interface. Convert the + * interface index into a device structure reference. + */ + + dev = netdev_findbyindex(sconn->s_boundto); + if (dev == NULL) + { + /* No device? It must have been unregistered. Un-bind the + * socket. + */ + + sconn->s_boundto = 0; + } + } + + /* If no device was bound or the bound device is no longer valid, + * then let's try the default network device. + */ + + return dev == NULL ? netdev_default() : dev; +} +#endif + diff --git a/net/utils/utils.h b/net/utils/utils.h index a891f1682d0..1cc3410f9ee 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -389,6 +389,31 @@ uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len); uint16_t icmpv6_chksum(FAR struct net_driver_s *dev, unsigned int iplen); #endif +/**************************************************************************** + * Name: net_bound_device + * + * Description: + * If the socket is bound to a device, return the reference to the + * bound device. + * + * Input Parameters: + * sconn - Socket connection structure (not currently used). + * + * Returned Value: + * A reference to the bound device. If the retained interface index no + * longer refers to a valid device, this function will unbind the device + * and return an arbitrary network device at the head of the list of + * registered devices. This supports legacy IPv4 DHCPD behavior when + * there is only a single registered network device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_BINDTODEVICE +FAR struct net_driver_s *net_bound_device(FAR struct socket_conn_s *sconn); +#else +# define net_bound_device(c) netdev_default(); +#endif + #undef EXTERN #ifdef __cplusplus }