From rec@rcousins.com  Thu Jul  9 16:04:19 1998
Received: from www.RCousins.com ([209.31.225.65])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id QAA11893
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 9 Jul 1998 16:04:18 -0700 (PDT)
          (envelope-from rec@rcousins.com)
Received: (from rec@localhost)
	by www.RCousins.com (8.8.8/8.8.8) id QAA03280;
	Thu, 9 Jul 1998 16:04:11 -0700 (PDT)
Message-Id: <199807092304.QAA03280@www.RCousins.com>
Date: Thu, 9 Jul 1998 16:04:11 -0700 (PDT)
From: rec@rcousins.com
Reply-To: rec@rcousins.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: problem with SIOCGIFCONF
X-Send-Pr-Version: 3.2

>Number:         7230
>Category:       kern
>Synopsis:       problem with SIOCGIFCONF
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul  9 16:10:01 PDT 1998
>Closed-Date:    Thu Jul 9 16:55:04 PDT 1998
>Last-Modified:  Thu Jul  9 16:56:53 PDT 1998
>Originator:     Robert Cousus
>Release:        FreeBSD 2.2.6-RELEASE i386
>Organization:
>Environment:

	K6 cpu, 128 megs RAM, 15 gigs Disk, 2 LAN ifces.

>Description:

	SIOCGIFCONF does not return an array of struct ifreq with one
	entry per network interface.

>How-To-Repeat:

	Compile and run the attached program to demonstrate the problem.
        (Note: program runs correctly under Solaris 2.5.1.)
-----------------
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>

char buffer[1<<12];

int main(int argc, char *argv[])
{
  int res;			/* result from call */
  int sock;			/* socket file descriptor */
  int i;			/* loop variable */
  struct ifconf ifconf;		/* used in test below */
  struct ifreq *ptr;		/* pointer to walk buffer */

  sock = socket(PF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    perror("socket(PF_INET, SOCK_DGRAM, 0)");
    exit(1);
  }

  ifconf.ifc_len = sizeof(buffer); /* establish size of buffer */
  ifconf.ifc_buf = buffer;	/* point to buffer */

  res = ioctl(sock, SIOCGIFCONF, &ifconf);
  if (res < 0) {
    perror("ioctl(sock, SIOCGIFCONF, &ifconf)");
    exit(1);
  }

  /* 
   * At this point, the ifconf.ifc_len should tell how many bytes consumed
   * in the buffer and ifconf.ifc_req should point to an array of ifreq
   * structures.
   *

   /*
    * Test 1: The return value should be a multiple of sizeof(ifreq).
    */

  if (ifconf.ifc_len % sizeof(struct ifreq)) {
    printf("Failed test1: %d %% %d = %d\n",
	   ifconf.ifc_len, sizeof(struct ifreq),
	   ifconf.ifc_len % sizeof(struct ifreq));
  }

  /*
   * Test 2: We should be able to print out the names of all
   * interfaces by looping through the array.
   */

   ptr = ifconf.ifc_req;	/* point to beginning of array */
   for (i = 0; i < (ifconf.ifc_len/sizeof(struct ifreq)); i++, ptr++)
     printf("Interface %d: %s\n", i, ptr->ifr_name);

   exit(0);
}
-----------------
>Fix:
	
	Unknown.

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: fenner 
State-Changed-When: Thu Jul 9 16:55:04 PDT 1998 
State-Changed-Why:  
The SIOCGIFCONF interface changed in 4.3-Reno (when sa_len was introduced). 
The return value includes a list of struct ifreqs, but you have to check 
the size of the struct sockaddr inside the struct ifreq to see where the 
next ifreq starts.  See, for example, the code on page 436 of _UNIX 
Network Programming, Volume 1_, second edition. 
>Unformatted:
Robert Cousins
