From f6388b2bf63df4d6ea452770541ac8d79c6a817e Mon Sep 17 00:00:00 2001 From: Fabrizio Bertocci Date: Thu, 13 May 2021 08:55:10 -0400 Subject: [PATCH] Added some debugging printf to troubleshoot issue for BSD --- libc/calls/ioctl-siocgifconf.c | 67 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/libc/calls/ioctl-siocgifconf.c b/libc/calls/ioctl-siocgifconf.c index 9896185c2..e967c3f9f 100644 --- a/libc/calls/ioctl-siocgifconf.c +++ b/libc/calls/ioctl-siocgifconf.c @@ -16,24 +16,77 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" +#include "libc/sysv/errfuns.h" #include "libc/calls/internal.h" #include "libc/sock/sock.h" #include "libc/sock/internal.h" #include "libc/sysv/consts/sio.h" + +#include "libc/stdio/stdio.h" +#define PRINTF weaken(printf) + +/* SIOCGIFCONF: + * Takes an struct ifconf object of a given size + * Modifies the following: + * - ifc_len: set it to the number of valid ifreq structures representing + * the interfaces + * - ifc_ifcu.ifcu_req: sets the name of the interface for each interface + * The ifc_len is an input/output parameter: set it to the total size of + * the ifcu_buf (ifcu_req) buffer on input. + */ int ioctl_siocgifconf_nt(int, struct ifconf *) hidden; static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) { /* Same as the default for now... */ - return sys_ioctl(fd, SIOCGIFCONF, ifc); - /* - int rc; + if (IsBsd()) { + if (!weaken(malloc)) { + return enomem(); + } else { + /* On BSD the size of the struct ifreq is smaller (16 bytes + * instead of 24 bytes), so buffers need to be adjusted accordingly + * + * TODO: Since BSD requires a SMALLER buffer we don't need to + * malloc a temp buffer, insted reuse the same buffer and + * safely move overlapping ifrn_name chunks + */ + int i; + struct ifconf ifc_bsd; + size_t num_ifreq = ifc->ifc_len / sizeof(struct ifreq); - if ((rc = sys_ioctl(fd, SIOCGIFCONF, &ifc)) != -1) { - return rc; + PRINTF("Mac version!\n"); + ifc_bsd.ifc_len = (num_ifreq * sizeof(struct ifreq_bsd)); /* Adjust max buffer */ + ifc_bsd.ifc_buf = weaken(malloc)(ifc_bsd.ifc_len); + PRINTF("numInterf Linux=%lu\n", num_ifreq); + PRINTF("BSD size=%lu\n", ifc_bsd.ifc_len); + PRINTF("Linux size=%lu\n", ifc->ifc_len); + if (!ifc_bsd.ifc_buf) { + PRINTF("Malloc failed\n"); + return enomem(); + } + PRINTF("Calling ioctl()\n"); + i = sys_ioctl(fd, SIOCGIFCONF, &ifc_bsd); + PRINTF("rc=%d\n", i); + if (i < 0) { + weaken(free)(ifc_bsd.ifc_buf); + return -1; + } + + /* Number of interfaces returned */ + num_ifreq = ifc_bsd.ifc_len / sizeof(struct ifreq_bsd); + for (i = 1; i < num_ifreq; ++i) { + /* The first interface always match the same position */ + memcpy(ifc->ifc_req[i].ifr_name, ifc_bsd.ifc_req[i].ifr_name, IFNAMSIZ); + } + ifc->ifc_len = num_ifreq * sizeof(struct ifreq); + weaken(free)(ifc_bsd.ifc_buf); + return 0; + } + } else { + // 100% compatible with Linux + return sys_ioctl(fd, SIOCGIFCONF, ifc); } - return rc; - */ } /**