(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
ifreq.c
       1  /* Copyright (C) 1999-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include "ifreq.h"
      19  
      20  
      21  void
      22  __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
      23  {
      24    int fd = sockfd;
      25    struct ifconf ifc;
      26    int rq_len;
      27    int nifs;
      28  # define RQ_IFS	4
      29  
      30    if (fd < 0)
      31      fd = __opensock ();
      32    if (fd < 0)
      33      {
      34        *num_ifs = 0;
      35        *ifreqs = NULL;
      36        return;
      37      }
      38  
      39    ifc.ifc_buf = NULL;
      40  
      41    /* We may be able to get the needed buffer size directly, rather than
      42       guessing.  */
      43    ifc.ifc_buf = NULL;
      44    ifc.ifc_len = 0;
      45    if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
      46      rq_len = RQ_IFS * sizeof (struct ifreq);
      47    else
      48      rq_len = ifc.ifc_len;
      49  
      50    /* Read all the interfaces out of the kernel.  */
      51    ifc.ifc_len = rq_len;
      52    void *newp = realloc (ifc.ifc_buf, ifc.ifc_len);
      53    if (newp == NULL
      54        || (ifc.ifc_buf = newp, __ioctl (fd, SIOCGIFCONF, &ifc)) < 0)
      55      {
      56        free (ifc.ifc_buf);
      57  
      58        if (fd != sockfd)
      59  	__close (fd);
      60  
      61        *num_ifs = 0;
      62        *ifreqs = NULL;
      63        return;
      64      }
      65  
      66    nifs = ifc.ifc_len / sizeof (struct ifreq);
      67  
      68    if (fd != sockfd)
      69      __close (fd);
      70  
      71    *num_ifs = nifs;
      72    *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
      73  }