diff --git a/src/api/sockets.c b/src/api/sockets.c index abe3fbc1..b90d6e10 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -2920,6 +2920,38 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ } break; #endif /* LWIP_UDP */ + case SO_BINDTODEVICE: + { + struct ifreq *iface; + struct netif* n = NULL; + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq); + + iface = (struct ifreq*)optval; + if (iface->ifr_name[0] != 0) { + n = netif_find(iface->ifr_name); + if (n == NULL) { + done_socket(sock); + return ENODEV; + } + } + + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) + { + case NETCONN_TCP: + tcp_bind_netif(sock->conn->pcb.tcp, n); + break; + case NETCONN_UDP: + udp_bind_netif(sock->conn->pcb.udp, n); + break; + case NETCONN_RAW: + raw_bind_netif(sock->conn->pcb.raw, n); + break; + default: + break; + } + } + break; default: LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); diff --git a/src/include/lwip/priv/sockets_priv.h b/src/include/lwip/priv/sockets_priv.h index 3e226cbb..aad7e693 100644 --- a/src/include/lwip/priv/sockets_priv.h +++ b/src/include/lwip/priv/sockets_priv.h @@ -58,7 +58,7 @@ extern "C" { #if !LWIP_TCPIP_CORE_LOCKING /** Maximum optlen used by setsockopt/getsockopt */ -#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16 +#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq)) /** This struct is used to pass data to the set/getsockopt_internal * functions running in tcpip_thread context (only a void* is allowed) */ diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index 8011cd51..4f9913a2 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -44,6 +44,7 @@ #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ #include "lwip/ip_addr.h" +#include "lwip/netif.h" #include "lwip/err.h" #include "lwip/inet.h" #include "lwip/errno.h" @@ -175,6 +176,12 @@ will need to increase long long */ #define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \ length) +/* Set socket options argument */ +#define IFNAMSIZ NETIF_NAMESIZE +struct ifreq { + char ifr_name[IFNAMSIZ]; /* Interface name */ +}; + /* Socket protocol types (TCP/UDP/RAW) */ #define SOCK_STREAM 1 #define SOCK_DGRAM 2 @@ -191,32 +198,32 @@ will need to increase long long */ /* * Additional options, not kept in so_options. */ -#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ -#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_DONTLINGER ((int)(~SO_LINGER)) -#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ -#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ -#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ -#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ -#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ -#define SO_SNDTIMEO 0x1005 /* send timeout */ -#define SO_RCVTIMEO 0x1006 /* receive timeout */ -#define SO_ERROR 0x1007 /* get error status and clear */ -#define SO_TYPE 0x1008 /* get socket type */ -#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ -#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ - +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_DONTLINGER ((int)(~SO_LINGER)) +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ +#define SO_BINDTODEVICE 0x100b /* bind to device */ /* * Structure used for manipulating linger option. */ struct linger { - int l_onoff; /* option on/off */ - int l_linger; /* linger time in seconds */ + int l_onoff; /* option on/off */ + int l_linger; /* linger time in seconds */ }; /*