Revision: 2d4f8563ca5b
Branch: default
Author: Brian Kocoloski <
bko...@sandia.gov>
Date: Wed Jun 26 15:02:29 2013
Log: Updates to lwip to accommodate Portals
http://code.google.com/p/kitten/source/detail?r=2d4f8563ca5b
Added:
/include/lwip/if.h
/include/lwip/sockios.h
Modified:
/include/lwip/sockets.h
/kernel/linux_syscalls/fcntl.c
/kernel/netdev.c
/net/api/sockets.c
=======================================
--- /dev/null
+++ /include/lwip/if.h Wed Jun 26 15:02:29 2013
@@ -0,0 +1,79 @@
+#ifndef _LWIP_IF_H
+#define _LWIP_IF_H 1
+
+#include "lwip/sockets.h"
+
+#define IF_NAMESIZE 16
+
+/* Device mapping structure. I'd just gone off and designed a
+ beautiful scheme using only loadable modules with arguments for
+ driver options and along come the PCMCIA people 8)
+
+ Ah well. The get() side of this is good for WDSETUP, and it'll be
+ handy for debugging things. The set side is fine for now and being
+ very small might be worth keeping for clean configuration. */
+
+struct ifmap
+ {
+ unsigned long int mem_start;
+ unsigned long int mem_end;
+ unsigned short int base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+ /* 3 bytes spare */
+ };
+
+/* Interface request structure used for socket ioctl's. All interface
+ ioctl's must have parameter definitions which begin with ifr_name.
+ The remainder may be interface specific. */
+
+struct ifreq
+ {
+# define IFHWADDRLEN 6
+# define IFNAMSIZ IF_NAMESIZE
+ union
+ {
+ char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
+ } ifr_ifrn;
+
+ union
+ {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short int ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ]; /* Just fits the size */
+ char ifru_newname[IFNAMSIZ];
+ void * ifru_data;
+ } ifr_ifru;
+ };
+# define ifr_name ifr_ifrn.ifrn_name /* interface name */
+# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+# define ifr_addr ifr_ifru.ifru_addr /* address */
+# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
+# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+# define ifr_flags ifr_ifru.ifru_flags /* flags */
+# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
+# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+# define ifr_map ifr_ifru.ifru_map /* device map */
+# define ifr_slave ifr_ifru.ifru_slave /* slave device */
+# define ifr_data ifr_ifru.ifru_data /* for use by interface */
+# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
+# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
+# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
+# define ifr_newname ifr_ifru.ifru_newname /* New name */
+# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+unsigned int if_nametoindex(const char * ifname);
+
+
+#endif /* LWIP_IF_H */
=======================================
--- /dev/null
+++ /include/lwip/sockios.h Wed Jun 26 15:02:29 2013
@@ -0,0 +1,148 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions of the socket-level I/O control calls.
+ *
+ * Version: @(#)sockios.h 1.0.2 03/09/93
+ *
+ * Authors: Ross Biro
+ * Fred N. van Kempen, <
wal...@uWalt.NL.Mugnet.ORG>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _LWIP_SOCKIOS_H
+#define _LWIP_SOCKIOS_H
+
+//#include <asm/sockios.h>
+
+/* Linux-specific socket ioctls */
+#define SIOCINQ FIONREAD
+#define SIOCOUTQ TIOCOUTQ /* output queue size (not sent + not
acked) */
+
+/* Routing table calls. */
+#define SIOCADDRT 0x890B /* add routing table entry */
+#define SIOCDELRT 0x890C /* delete routing table entry */
+#define SIOCRTMSG 0x890D /* call to routing system */
+
+/* Socket configuration controls. */
+#define SIOCGIFNAME 0x8910 /* get iface name */
+#define SIOCSIFLINK 0x8911 /* set iface channel */
+#define SIOCGIFCONF 0x8912 /* get iface list */
+#define SIOCGIFFLAGS 0x8913 /* get flags */
+#define SIOCSIFFLAGS 0x8914 /* set flags */
+#define SIOCGIFADDR 0x8915 /* get PA address */
+#define SIOCSIFADDR 0x8916 /* set PA address */
+#define SIOCGIFDSTADDR 0x8917 /* get remote PA address */
+#define SIOCSIFDSTADDR 0x8918 /* set remote PA address */
+#define SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
+#define SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
+#define SIOCGIFNETMASK 0x891b /* get network PA mask */
+#define SIOCSIFNETMASK 0x891c /* set network PA mask */
+#define SIOCGIFMETRIC 0x891d /* get metric */
+#define SIOCSIFMETRIC 0x891e /* set metric */
+#define SIOCGIFMEM 0x891f /* get memory address (BSD) */
+#define SIOCSIFMEM 0x8920 /* set memory address (BSD) */
+#define SIOCGIFMTU 0x8921 /* get MTU size */
+#define SIOCSIFMTU 0x8922 /* set MTU size */
+#define SIOCSIFNAME 0x8923 /* set interface name */
+#define SIOCSIFHWADDR 0x8924 /* set hardware address */
+#define SIOCGIFENCAP 0x8925 /* get/set encapsulations */
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927 /* Get hardware address */
+#define SIOCGIFSLAVE 0x8929 /* Driver slaving support */
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931 /* Multicast address lists */
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933 /* name -> if_index mapping */
+#define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */
+#define SIOCSIFPFLAGS 0x8934 /* set/get extended flags set */
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936 /* delete PA address */
+#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
+#define SIOCGIFCOUNT 0x8938 /* get number of devices */
+
+#define SIOCGIFBR 0x8940 /* Bridging support */
+#define SIOCSIFBR 0x8941 /* Set bridging options */
+
+#define SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
+#define SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
+
+/* SIOCGIFDIVERT was: 0x8944 Frame diversion support */
+/* SIOCSIFDIVERT was: 0x8945 Set frame diversion options */
+
+#define SIOCETHTOOL 0x8946 /* Ethtool interface */
+
+#define SIOCGMIIPHY 0x8947 /* Get address of MII PHY in use. */
+#define SIOCGMIIREG 0x8948 /* Read MII PHY register. */
+#define SIOCSMIIREG 0x8949 /* Write MII PHY register. */
+
+#define SIOCWANDEV 0x894A /* get/set netdev parameters */
+
+#define SIOCOUTQNSD 0x894B /* output queue size (not sent only) */
+
+/* ARP cache control calls. */
+ /* 0x8950 - 0x8952 * obsolete calls, don't re-use */
+#define SIOCDARP 0x8953 /* delete ARP table entry */
+#define SIOCGARP 0x8954 /* get ARP table entry */
+#define SIOCSARP 0x8955 /* set ARP table entry */
+
+/* RARP cache control calls. */
+#define SIOCDRARP 0x8960 /* delete RARP table entry */
+#define SIOCGRARP 0x8961 /* get RARP table entry */
+#define SIOCSRARP 0x8962 /* set RARP table entry */
+
+/* Driver configuration calls */
+
+#define SIOCGIFMAP 0x8970 /* Get device parameters */
+#define SIOCSIFMAP 0x8971 /* Set device parameters */
+
+/* DLCI configuration calls */
+
+#define SIOCADDDLCI 0x8980 /* Create new DLCI device */
+#define SIOCDELDLCI 0x8981 /* Delete DLCI device */
+
+#define SIOCGIFVLAN 0x8982 /* 802.1Q VLAN support */
+#define SIOCSIFVLAN 0x8983 /* Set 802.1Q VLAN options */
+
+/* bonding calls */
+
+#define SIOCBONDENSLAVE 0x8990 /* enslave a device to the bond */
+#define SIOCBONDRELEASE 0x8991 /* release a slave from the bond*/
+#define SIOCBONDSETHWADDR 0x8992 /* set the hw addr of the bond */
+#define SIOCBONDSLAVEINFOQUERY 0x8993 /* rtn info about slave state */
+#define SIOCBONDINFOQUERY 0x8994 /* rtn info about bond state */
+#define SIOCBONDCHANGEACTIVE 0x8995 /* update to a new active slave */
+
+/* bridge calls */
+#define SIOCBRADDBR 0x89a0 /* create new bridge device */
+#define SIOCBRDELBR 0x89a1 /* remove bridge device */
+#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
+#define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
+
+/* hardware time stamping: parameters in linux/net_tstamp.h */
+#define SIOCSHWTSTAMP 0x89b0
+
+/* Device private ioctl calls */
+
+/*
+ * These 16 ioctls are available to devices via the do_ioctl() device
+ * vector. Each device should include this file and redefine these names
+ * as their own. Because these are device dependent it is a good idea
+ * _NOT_ to issue them to random objects and hope.
+ *
+ * THESE IOCTLS ARE _DEPRECATED_ AND WILL DISAPPEAR IN 2.5.X -DaveM
+ */
+
+#define SIOCDEVPRIVATE 0x89F0 /* to 89FF */
+
+/*
+ * These 16 ioctl calls are protocol private
+ */
+
+#define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */
+#endif /* _LWIP_SOCKIOS_H */
=======================================
--- /include/lwip/sockets.h Mon Apr 1 14:03:40 2013
+++ /include/lwip/sockets.h Wed Jun 26 15:02:29 2013
@@ -40,6 +40,9 @@
#include <stddef.h> /* for size_t */
+/* BJK: For O_NONBLOCK */
+#include <asm-generic/fcntl.h>
+
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
#include "lwip/inet6.h"
@@ -78,6 +81,28 @@
#endif /* LWIP_IPV6 */
};
+/* BJK: Adding structures to support sendmsg/recvmsg */
+typedef u32_t socklen_t;
+
+struct iovec {
+ char * iov_base; /* Base address of iov data */
+ int iov_len; /* Length of iov data */
+};
+
+struct msghdr {
+ void * msg_name; /* Address to send to/receive from */
+ socklen_t msg_namelen; /* Length of address data */
+
+ struct iovec * msg_iov; /* Vector of data to send/receive into */
+ size_t msg_iovlen; /* Number of elements in the vector */
+
+ void * msg_control; /* Ancillary data (ed BSD filedesc passing).
*/
+ size_t msg_controllen; /* Ancillary data buffer length.
+ !! This type should be socklen_t but the
+ definition of the kernel is incompatible
+ with this. */
+};
+
/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
to prevent this code from redefining it. */
#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
@@ -349,6 +374,7 @@
#endif /* LWIP_TIMEVAL_PRIVATE */
void lwip_socket_init(void);
+int lwip_lasterr(int s);
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
=======================================
--- /kernel/linux_syscalls/fcntl.c Mon Jun 10 15:05:51 2013
+++ /kernel/linux_syscalls/fcntl.c Wed Jun 26 15:02:29 2013
@@ -1,7 +1,61 @@
#include <lwk/kfs.h>
-#include <arch-generic/fcntl.h>
+#include <lwip/sockets.h>
+
+
+#ifdef CONFIG_LWIP_SOCKET
+
+/** Return a LWIP connection number from a user fd */
+static inline int
+lwip_connection(
+ const struct file * file
+)
+{
+ return (int)(uintptr_t) file->private_data;
+}
+
+
+static inline int
+lwip_from_fd(
+ int fd
+)
+{
+ struct file * file = get_current_file( fd );
+ if( !file )
+ return -1;
+ //if( file->fops != &kfs_socket_fops )
+ //return -1;
+ return lwip_connection( file );
+}
+int
+sys_fcntl(int fd, int cmd, long arg)
+{
+ int ret = -1;
+
+ switch(cmd) {
+ case F_GETFL:
+ ret = lwip_fcntl(lwip_from_fd(fd), cmd, arg);
+ break;
+ case F_SETFL:
+ /* BJK: Currently, lwip only supports O_NONBLOCK if it is
+ * accompanied by no other flags.
+ */
+ if (arg & O_NONBLOCK) {
+ arg &= O_NONBLOCK;
+ }
+ ret = lwip_fcntl(lwip_from_fd(fd), cmd, arg);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+#else
+#include <arch-generic/fcntl.h>
+
int
sys_fcntl(int fd, int cmd, long arg)
{
@@ -38,3 +92,4 @@
return ret;
/* not reached */
}
+#endif
=======================================
--- /kernel/netdev.c Sun Jun 9 00:16:32 2013
+++ /kernel/netdev.c Wed Jun 26 15:02:29 2013
@@ -9,19 +9,23 @@
#include <arch/vsyscall.h>
#include <lwk/kfs.h>
#include <lwk/fdTable.h>
+
+/**
+ * Holds a comma separated list of network devices to configure.
+ */
+static char netdev_str[128];
+param_string(net, netdev_str, sizeof(netdev_str));
+
+#ifdef CONFIG_LWIP_SOCKET
+
#include <lwip/init.h>
#include <lwip/tcp.h>
#include <lwip/api.h>
#include <lwip/sockets.h>
+#include <lwip/sockios.h>
#include <lwip/tcpip.h>
#include <lwip/stats.h>
-
-
-/**
- * Holds a comma separated list of network devices to configure.
- */
-static char netdev_str[128];
-param_string(net, netdev_str, sizeof(netdev_str));
+#include <lwip/if.h>
/** Return a LWIP connection number from a user fd */
@@ -88,6 +92,7 @@
{
return lwip_listen( lwip_from_fd(fd), backlog );
}
+
static int
@@ -103,11 +108,21 @@
return 0;
}
-
+/* BJK: Allow ioctls on sockets */
+static int
+socket_ioctl(
+ struct file * file,
+ int request,
+ uaddr_t address
+)
+{
+ return lwip_ioctl(lwip_connection(file), request, (void *)address);
+}
struct kfs_fops kfs_socket_fops = {
.write = socket_write,
.read = socket_read,
.close = socket_close,
+ .ioctl = socket_ioctl,
};
@@ -158,7 +173,6 @@
file->private_data = (void*)(uintptr_t) conn;
return fd;
}
-
static int
translate_sockaddr(
@@ -185,7 +199,6 @@
return 0;
}
-
static unsigned long
sys_bind(
@@ -247,7 +260,6 @@
return lwip_connect( conn, (struct sockaddr *) buf, len );
}
-
static int
sys_accept(
@@ -343,7 +355,6 @@
return 0;
}
-
int
sys_select(
@@ -386,7 +397,6 @@
return rc;
}
-
static int
sys_setsockopt(
@@ -409,7 +419,6 @@
/* printk( KERN_INFO "%s: Inside sys_setsockopt level=%d, optname=%d,
optval=%s, optlen=%d\n", __func__, level, optname, (char *)optval, optlen);
*/
return setsockopt(conn, level, optname, kbuf, optlen);
}
-
static int
sys_getsockopt(
@@ -437,6 +446,110 @@
return(ret);
}
+/* BJK: The rest of the functions defined here are to support Portals on
UDP */
+static ssize_t
+sys_sendto(
+ int sockfd,
+ const void * buf,
+ size_t len,
+ int flags,
+ struct sockaddr * dest_addr,
+ socklen_t addrlen
+)
+{
+ int ret = lwip_sendto(lwip_from_fd(sockfd), buf, len, flags,
dest_addr, addrlen);
+
+ if (ret == -1) {
+ ret = -lwip_lasterr(lwip_from_fd(sockfd));
+ }
+
+ return ret;
+}
+
+static ssize_t
+sys_sendmsg(
+ int sockfd,
+ const struct msghdr * msg,
+ int flags
+)
+{
+ int i;
+ ssize_t written, total;
+ struct iovec * vec;
+
+ total = 0;
+ for (i = 0; i < msg->msg_iovlen; i++) {
+ vec = &(msg->msg_iov[i]);
+ written = lwip_sendto(lwip_from_fd(sockfd), vec->iov_base,
vec->iov_len, flags,
+ (struct sockaddr *)msg->msg_name, msg->msg_namelen);
+
+ switch (written) {
+ case -1:
+ return -lwip_lasterr(lwip_from_fd(sockfd));
+ case 0:
+ return written;
+ default:
+ total += written;
+ break;
+ }
+ }
+
+ return total;
+}
+
+static ssize_t
+sys_recvfrom(
+ int sockfd,
+ void * buf,
+ size_t len,
+ int flags,
+ struct sockaddr * src_addr,
+ socklen_t * addrlen
+)
+{
+ int ret = lwip_recvfrom(lwip_from_fd(sockfd), buf, len,flags,
src_addr, addrlen);
+
+ if (ret == -1) {
+ ret = -lwip_lasterr(lwip_from_fd(sockfd));
+ }
+
+ return ret;
+}
+
+static ssize_t
+sys_recvmsg(
+ int sockfd,
+ struct msghdr * msg,
+ int flags
+)
+{
+ int i;
+ ssize_t read, total;
+ struct iovec * vec;
+
+ total = 0;
+ for (i = 0; i < msg->msg_iovlen; i++) {
+ vec = &(msg->msg_iov[i]);
+ read = lwip_recvfrom(lwip_from_fd(sockfd), vec->iov_base,
vec->iov_len, flags,
+ (struct sockaddr *)msg->msg_name, &(msg->msg_namelen));
+
+ switch (read) {
+ case -1:
+ return -lwip_lasterr(lwip_from_fd(sockfd));
+ case 0:
+ return total;
+ default:
+ total += read;
+ break;
+ }
+ }
+
+ return total;
+}
+
+#endif // CONFIG_SOCKET
+
+
/**
* Initializes the network subsystem; called once at boot.
@@ -444,15 +557,18 @@
void
netdev_init(void)
{
- printk(KERN_INFO "%s: Bringing up network devices: '%s'\n",
- __func__, netdev_str);
+ printk( KERN_INFO "%s: Bringing up network devices: '%s'\n",
+ __func__,
+ netdev_str
+ );
- driver_init_list("net", netdev_str);
+ driver_init_list( "net", netdev_str );
- // Bring up the lightweight IP stack
- tcpip_init(NULL, NULL);
+#ifdef CONFIG_LWIP_SOCKET
+ // Full sockets are enabled. Bring up the entire system
+ tcpip_init( 0, 0 );
- // Install the socket system call handlers
+ // Install the socket system calls
syscall_register( __NR_socket, (syscall_ptr_t) sys_socket );
syscall_register( __NR_bind, (syscall_ptr_t) sys_bind );
syscall_register( __NR_connect, (syscall_ptr_t) sys_connect );
@@ -461,5 +577,14 @@
syscall_register( __NR_select, (syscall_ptr_t) sys_select );
syscall_register( __NR_setsockopt, (syscall_ptr_t) sys_setsockopt );
syscall_register( __NR_getsockopt, (syscall_ptr_t) sys_getsockopt );
+
+ syscall_register( __NR_sendto, (syscall_ptr_t) sys_sendto );
+ syscall_register( __NR_sendmsg, (syscall_ptr_t) sys_sendmsg );
+ syscall_register( __NR_recvfrom, (syscall_ptr_t) sys_recvfrom );
+ syscall_register( __NR_recvmsg, (syscall_ptr_t) sys_recvmsg );
+#elif defined( CONFIG_NETWORK )
+ // No sockets enabled, just bring up the LWIP library
+ lwip_init();
+#endif
}
=======================================
--- /net/api/sockets.c Mon Apr 1 14:03:40 2013
+++ /net/api/sockets.c Wed Jun 26 15:02:29 2013
@@ -43,6 +43,7 @@
#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
#include "lwip/sockets.h"
+#include "lwip/sockios.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/igmp.h"
@@ -52,6 +53,8 @@
#include "lwip/udp.h"
#include "lwip/tcpip.h"
#include "lwip/pbuf.h"
+#include "lwip/netif.h"
+#include "lwip/if.h"
#if LWIP_CHECKSUM_ON_COPY
#include "lwip/inet_chksum.h"
#endif
@@ -247,6 +250,7 @@
static void event_callback(struct netconn *conn, enum netconn_evt evt,
u16_t len);
static void lwip_getsockopt_internal(void *arg);
static void lwip_setsockopt_internal(void *arg);
+static struct lwip_sock * get_socket(int s);
/**
* Initialize this module. This function has to be called before any other
@@ -256,6 +260,23 @@
lwip_socket_init(void)
{
}
+
+/**
+ * Return the last error associated with a given socket
+ */
+int
+lwip_lasterr(int s)
+{
+ struct lwip_sock * sock;
+
+ sock = get_socket(s);
+
+ if (!sock) {
+ return 0;
+ }
+
+ return sock->err;
+}
/**
* Map a externally used socket index to the internal socket
representation.
@@ -502,7 +523,7 @@
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port));
err = netconn_bind(sock->conn, ipX_2_ip(&local_addr), local_port);
-
+
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
sock_set_errno(sock, err_to_errno(err));
@@ -665,6 +686,7 @@
sock_set_errno(sock, EWOULDBLOCK);
return -1;
}
+
/* No data was left from the previous operation, so we try to get
some from the network. */
@@ -2512,6 +2534,36 @@
sock_set_errno(sock, 0);
return 0;
+
+ /* BJK: read IP address for interface name given in argp */
+ case SIOCGIFADDR: {
+ struct netif * netif;
+ struct ifreq * devinfo = (struct ifreq *)argp;
+
+ netif = netif_find(devinfo->ifr_name);
+ if (!netif) {
+ return -ENOSYS;
+ }
+
+ ((struct sockaddr_in *)&(devinfo->ifr_addr))->sin_addr.s_addr =
netif->ip_addr.addr;
+ return 0;
+ }
+
+ /* BJK: Return index associated with iface name */
+ case SIOCGIFINDEX: {
+ struct netif * netif;
+ struct ifreq * devinfo = (struct ifreq *)argp;
+
+ netif = netif_find(devinfo->ifr_name);
+ if (!netif) {
+ return -ENOSYS;
+ }
+
+ // Adding 1 always ensures index is nonzero
+ devinfo->ifr_ifindex = netif->num + 1;
+ return 0;
+ }
+
default:
break;
} /* switch (cmd) */
@@ -2544,6 +2596,7 @@
netconn_set_nonblocking(sock->conn, val & O_NONBLOCK);
ret = 0;
}
+
break;
default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s,
cmd, val));
@@ -2551,5 +2604,4 @@
}
return ret;
}
-
#endif /* LWIP_SOCKET */