diff --git a/net/icmp/icmp_ping.c b/net/icmp/icmp_ping.c index 53838b47ecf..3cd900b94fd 100644 --- a/net/icmp/icmp_ping.c +++ b/net/icmp/icmp_ping.c @@ -58,6 +58,7 @@ #include "netdev/netdev.h" #include "devif/devif.h" +#include "arp/arp.h" #include "icmp/icmp.h" /**************************************************************************** @@ -331,6 +332,18 @@ int icmp_ping(net_ipaddr_t addr, uint16_t id, uint16_t seqno, { struct icmp_ping_s state; net_lock_t save; +#ifdef CONFIG_NET_ARP_SEND + int ret; + + /* Make sure that the IP address mapping is in the ARP table */ + + ret = arp_send(addr); + if (ret < 0) + { + ndbg("ERROR: Not reachable\n"); + return -ENETUNREACH; + } +#endif /* Initialize the state structure */ diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c index b87a0192f06..de5a01efccf 100644 --- a/net/socket/net_sendfile.c +++ b/net/socket/net_sendfile.c @@ -2,7 +2,7 @@ * net/socket/net_sendfile.c * * Copyright (C) 2013 UVC Ingenieure. All rights reserved. - * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2014 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * Max Holtzberg * @@ -65,10 +65,10 @@ #include "netdev/netdev.h" #include "devif/devif.h" +#include "arp/arp.h" #include "tcp/tcp.h" #include "socket/socket.h" - /**************************************************************************** * Definitions ****************************************************************************/ @@ -322,10 +322,14 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon * * NOTE 2: If we are actually harvesting IP addresses on incoming IP * packets, then this check should not be necessary; the MAC mapping - * should already be in the ARP table. + * should already be in the ARP table in many cases. + * + * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP + * address mapping is already in the ARP table. */ -#if defined(CONFIG_NET_ETHERNET) && !defined (CONFIG_NET_ARP_IPIN) +#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ + !defined(CONFIG_NET_ARP_SEND) if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL) #endif { @@ -463,6 +467,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, if (!psock || psock->s_crefs <= 0) { + ndbg("ERROR: Invalid socket\n"); err = EBADF; goto errout; } @@ -471,10 +476,23 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) { + ndbg("ERROR: Not connected\n"); err = ENOTCONN; goto errout; } + /* Make sure that the IP address mapping is in the ARP table */ + +#ifdef CONFIG_NET_ARP_SEND + ret = arp_send(conn->ripaddr); + if (ret < 0) + { + ndbg("ERROR: Not reachable\n"); + err = ENETUNREACH; + goto errout; + } +#endif + /* Set the socket state to sending */ psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); diff --git a/net/socket/sendto.c b/net/socket/sendto.c index 2827bd3b089..09a5dd7d4c1 100644 --- a/net/socket/sendto.c +++ b/net/socket/sendto.c @@ -55,6 +55,7 @@ #include "netdev/netdev.h" #include "devif/devif.h" +#include "arp/arp.h" #include "udp/udp.h" #include "socket/socket.h" @@ -322,6 +323,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, #ifdef CONFIG_NET_TCP return psock_send(psock, buf, len, flags); #else + ndbg("ERROR: No to address\n"); err = EINVAL; goto errout; #endif @@ -335,6 +337,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, if (to->sa_family != AF_INET || tolen < sizeof(struct sockaddr_in)) #endif { + ndbg("ERROR: Invalid address\n"); err = EBADF; goto errout; } @@ -343,6 +346,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, if (!psock || psock->s_crefs <= 0) { + ndbg("ERROR: Invalid socket\n"); err = EBADF; goto errout; } @@ -351,10 +355,23 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, if (psock->s_type != SOCK_DGRAM) { + ndbg("ERROR: Connected socket\n"); err = EISCONN; goto errout; } + /* Make sure that the IP address mapping is in the ARP table */ + +#ifdef CONFIG_NET_ARP_SEND + ret = arp_send(into->sin_addr.s_addr); + if (ret < 0) + { + ndbg("ERROR: Not reachable\n"); + err = ENETUNREACH; + goto errout; + } +#endif + /* Perform the UDP sendto operation */ #ifdef CONFIG_NET_UDP diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index bb0eb729f40..231eeebe7a8 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -71,6 +71,7 @@ #include "socket/socket.h" #include "netdev/netdev.h" +#include "arp/arp.h" #include "tcp/tcp.h" #include "devif/devif.h" @@ -539,10 +540,14 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, * * NOTE 2: If we are actually harvesting IP addresses on incoming IP * packets, then this check should not be necessary; the MAC mapping - * should already be in the ARP table. + * should already be in the ARP table in many cases. + * + * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP + * address mapping is already in the ARP table. */ -#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) +#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ + !defined(CONFIG_NET_ARP_SEND) if (arp_find(conn->ripaddr) != NULL) #endif { @@ -721,6 +726,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev, ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, size_t len) { + FAR struct tcp_conn_s *conn; net_lock_t save; ssize_t result = 0; int err; @@ -728,16 +734,31 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, if (!psock || psock->s_crefs <= 0) { + ndbg("ERROR: Invalid socket\n"); err = EBADF; goto errout; } if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) { + ndbg("ERROR: Not connected\n"); err = ENOTCONN; goto errout; } + /* Make sure that the IP address mapping is in the ARP table */ + + conn = (FAR struct tcp_conn_s *)psock->s_conn; +#ifdef CONFIG_NET_ARP_SEND + ret = arp_send(conn->ripaddr); + if (ret < 0) + { + ndbg("ERROR: Not reachable\n"); + err = ENETUNREACH; + goto errout; + } +#endif + /* Dump the incoming buffer */ BUF_DUMP("psock_tcp_send", buf, len); @@ -750,8 +771,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, if (len > 0) { - FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; - /* Allocate resources to receive a callback */ if (!psock->s_sndcb) diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 66453773d7e..22f68608256 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -59,6 +59,7 @@ #include "netdev/netdev.h" #include "devif/devif.h" +#include "arp/arp.h" #include "tcp/tcp.h" #include "socket/socket.h" @@ -388,10 +389,14 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, * * NOTE 2: If we are actually harvesting IP addresses on incoming IP * packets, then this check should not be necessary; the MAC mapping - * should already be in the ARP table. + * should already be in the ARP table in many cases. + * + * NOTE 3: If CONFIG_NET_ARP_SEND then we can be assured that the IP + * address mapping is already in the ARP table. */ -#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) +#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ + !defined(CONFIG_NET_ARP_SEND) if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL) #endif { @@ -505,6 +510,7 @@ end_wait: ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, size_t len) { + FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; struct send_s state; net_lock_t save; int err; @@ -514,6 +520,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, if (!psock || psock->s_crefs <= 0) { + ndbg("ERROR: Invalid socket\n"); err = EBADF; goto errout; } @@ -522,10 +529,24 @@ ssize_t psock_tcp_send(FAR struct socket *psock, if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) { + ndbg("ERROR: Not connected\n"); err = ENOTCONN; goto errout; } + /* Make sure that the IP address mapping is in the ARP table */ + + conn = (FAR struct tcp_conn_s *)psock->s_conn; +#ifdef CONFIG_NET_ARP_SEND + ret = arp_send(conn->ripaddr); + if (ret < 0) + { + ndbg("ERROR: Not reachable\n"); + err = ENETUNREACH; + goto errout; + } +#endif + /* Set the socket state to sending */ psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); @@ -546,8 +567,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, if (len > 0) { - FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; - /* Allocate resources to receive a callback */ state.snd_cb = tcp_callback_alloc(conn);