diff --git a/src/Filelists.mk b/src/Filelists.mk index 7d30bb8f..7d9f108b 100644 --- a/src/Filelists.mk +++ b/src/Filelists.mk @@ -71,6 +71,7 @@ CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \ APIFILES=$(LWIPDIR)/api/api_lib.c \ $(LWIPDIR)/api/api_msg.c \ $(LWIPDIR)/api/err.c \ + $(LWIPDIR)/api/if.c \ $(LWIPDIR)/api/netbuf.c \ $(LWIPDIR)/api/netdb.c \ $(LWIPDIR)/api/netifapi.c \ diff --git a/src/api/if.c b/src/api/if.c new file mode 100644 index 00000000..e511bf53 --- /dev/null +++ b/src/api/if.c @@ -0,0 +1,73 @@ +/** + * @file + * Interface Identification APIs from: + * RFC 3493: Basic Socket Interface Extensions for IPv6 + * Section 4: Interface Identification + */ + +/* + * Copyright (c) 2017 Joel Cunningham + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Joel Cunningham + * + */ +#include "lwip/opt.h" + +#if LWIP_SOCKET + +#include "lwip/netifapi.h" + +char * +lwip_if_indextoname(unsigned ifindex, char *ifname) +{ + err_t err; + if (ifindex > 0xff) { + return NULL; + } + + err = netifapi_netif_index_to_name((u8_t)ifindex, ifname); + if (!err && ifname[0] != '\0') { + return ifname; + } + return NULL; +} + +unsigned int +lwip_if_nametoindex(const char *ifname) +{ + err_t err; + u8_t index; + + err = netifapi_netif_name_to_index(ifname, &index); + if (!err) { + return index; + } + return 0; /* invalid index */ +} + +#endif /* LWIP_SOCKET */ diff --git a/src/api/netifapi.c b/src/api/netifapi.c index fef05a34..364889d7 100644 --- a/src/api/netifapi.c +++ b/src/api/netifapi.c @@ -46,6 +46,8 @@ #include "lwip/memp.h" #include "lwip/priv/tcpip_priv.h" +#include /* strncpy */ + #define NETIFAPI_VAR_REF(name) API_VAR_REF(name) #define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) #define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) @@ -95,6 +97,37 @@ netifapi_do_netif_set_addr(struct tcpip_api_call_data *m) } #endif /* LWIP_IPV4 */ +/** +* Call netif_name_to_index() inside the tcpip_thread context. +*/ +static err_t +netifapi_do_name_to_index(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; + + msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name); + return ERR_OK; +} + +/** +* Call netif_index_to_name() inside the tcpip_thread context. +*/ +static err_t +netifapi_do_index_to_name(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; + + if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) { + /* return failure via empty name */ + msg->msg.ifs.name[0] = '\0'; + } + return ERR_OK; +} + /** * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the * tcpip_thread context. @@ -218,4 +251,66 @@ netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, return err; } +/** +* @ingroup netifapi_netif +* Call netif_name_to_index() in a thread-safe way by running that function inside the +* tcpip_thread context. +* +* @param name the interface name of the netif +* @param index output index of the found netif +*/ +err_t +netifapi_netif_name_to_index(const char *name, u8_t *index) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + *index = 0; + +#if LWIP_MPU_COMPATIBLE + strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, IF_NAMESIZE - 1); + NETIFAPI_VAR_REF(msg).msg.ifs.name[IF_NAMESIZE - 1] = '\0'; +#else + NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name; +#endif /* LWIP_MPU_COMPATIBLE */ + err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call); + if (!err) { + *index = NETIFAPI_VAR_REF(msg).msg.ifs.index; + } + NETIFAPI_VAR_FREE(msg); + return err; +} + +/** +* @ingroup netifapi_netif +* Call netif_index_to_name() in a thread-safe way by running that function inside the +* tcpip_thread context. +* +* @param index the interface index of the netif +* @param name output name of the found netif, empty '\0' string if netif not found. +* name should be of at least IF_NAMESIZE bytes +*/ +err_t +netifapi_netif_index_to_name(u8_t index, char *name) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).msg.ifs.index = index; +#if !LWIP_MPU_COMPATIBLE + NETIFAPI_VAR_REF(msg).msg.ifs.name = name; +#endif /* LWIP_MPU_COMPATIBLE */ + err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call); +#if LWIP_MPU_COMPATIBLE + if (!err) { + strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, IF_NAMESIZE - 1); + name[IF_NAMESIZE - 1] = '\0'; + } +#endif /* LWIP_MPU_COMPATIBLE */ + NETIFAPI_VAR_FREE(msg); + return err; +} + #endif /* LWIP_NETIF_API */ diff --git a/src/core/netif.c b/src/core/netif.c index 6956f0ab..b2fb80c5 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -65,6 +65,7 @@ #include "lwip/stats.h" #include "lwip/sys.h" #include "lwip/ip.h" +#include "lwip/if.h" #if ENABLE_LOOPBACK #if LWIP_NETIF_LOOPBACK_MULTITHREADING #include "lwip/tcpip.h" @@ -1269,3 +1270,52 @@ netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipa return ERR_IF; } #endif /* LWIP_IPV6 */ + +/** +* @ingroup netif_if +* Return the interface index for the netif with name +* or 0 (invalid interface) if not found/on error +* +* @param name the name of the netif +*/ +u8_t +netif_name_to_index(const char *name) +{ + struct netif *netif = netif_find(name); + if (netif != NULL) { + return netif_num_to_index(netif); + } + /* No name found, return invalid index */ + return 0; +} + +/** +* @ingroup netif_if +* Return the interface name for the netif matching index +* or NULL if not found/on error +* +* @param index the interface index of the netif +* @param name char buffer of at least IF_NAMESIZE bytes +*/ +char * +netif_index_to_name(u8_t index, char *name) +{ + struct netif *curif = netif_list; + u8_t num; + if (index == 0) { + return NULL; /* indexes start at 1 */ + } + num = netif_index_to_num(index); + + /* find netif from num */ + while (curif != NULL) { + if (curif->num == num) { + name[0] = curif->name[0]; + name[1] = curif->name[1]; + lwip_itoa(&name[2], IF_NAMESIZE - 2, num); + return name; + } + curif = curif->next; + } + return NULL; +} diff --git a/src/include/lwip/if.h b/src/include/lwip/if.h new file mode 100644 index 00000000..bce4a5f8 --- /dev/null +++ b/src/include/lwip/if.h @@ -0,0 +1,54 @@ +/** + * @file + * Interface Identification APIs from: + * RFC 3493: Basic Socket Interface Extensions for IPv6 + * Section 4: Interface Identification + */ + +/* + * Copyright (c) 2017 Joel Cunningham + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Joel Cunningham + * + */ +#ifndef LWIP_HDR_IF_H +#define LWIP_HDR_IF_H + +#include "lwip/opt.h" + +#define IF_NAMESIZE 6 /* 2 chars, 3 nums, 1 \0 */ + +char * lwip_if_indextoname(unsigned ifindex, char *ifname); +unsigned int lwip_if_nametoindex(const char *ifname); + +#if LWIP_COMPAT_SOCKETS +#define if_indextoname(ifindex, ifname) lwip_if_indextoname(ifindex,ifname) +#define if_nametoindex(ifname) lwip_if_nametoindex(ifname) +#endif /* LWIP_COMPAT_SOCKETS */ + +#endif /* LWIP_HDR_IF_H */ diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index 8160488c..6fd20a36 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -490,6 +490,14 @@ err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t #define NETIF_SET_HWADDRHINT(netif, hint) #endif /* LWIP_NETIF_HWADDRHINT */ +/* @ingroup netif */ +u8_t netif_name_to_index(const char *name); +char * netif_index_to_name(u8_t index, char *name); + +/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 */ +#define netif_num_to_index(netif) ((netif)->num + 1) +#define netif_index_to_num(index) ((index) - 1) + #ifdef __cplusplus } #endif diff --git a/src/include/lwip/netifapi.h b/src/include/lwip/netifapi.h index 8bd2b4f7..79369c28 100644 --- a/src/include/lwip/netifapi.h +++ b/src/include/lwip/netifapi.h @@ -40,6 +40,7 @@ #include "lwip/netif.h" #include "lwip/dhcp.h" #include "lwip/autoip.h" +#include "lwip/if.h" #include "lwip/priv/tcpip_priv.h" #ifdef __cplusplus @@ -73,6 +74,14 @@ struct netifapi_msg { netifapi_void_fn voidfunc; netifapi_errt_fn errtfunc; } common; + struct { +#if LWIP_MPU_COMPATIBLE + char name[IF_NAMESIZE]; +#else /* LWIP_MPU_COMPATIBLE */ + char *name; +#endif /* LWIP_MPU_COMPATIBLE */ + u8_t index; + } ifs; } msg; }; @@ -92,6 +101,11 @@ err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc); +/** @ingroup netifapi_netif */ +err_t netifapi_netif_name_to_index(const char *name, u8_t *index); +/** @ingroup netifapi_netif */ +err_t netifapi_netif_index_to_name(u8_t index, char *name); + /** @ingroup netifapi_netif */ #define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) /** @ingroup netifapi_netif */ diff --git a/src/include/posix/net/if.h b/src/include/posix/net/if.h new file mode 100644 index 00000000..cf7df7ed --- /dev/null +++ b/src/include/posix/net/if.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/if.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/if.h"