Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jun 1999 20:43:40 -0400 (EDT)
From:      Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To:        Jim Shankland <jas@flyingfox.com>
Cc:        archie@whistle.com, wollman@khavrinen.lcs.mit.edu, freebsd-net@FreeBSD.ORG
Subject:   Re: subtle SIOCGIFCONF bug
Message-ID:  <199906050043.UAA12537@khavrinen.lcs.mit.edu>
In-Reply-To: <199906050142.SAA04889@biggusdiskus.flyingfox.com>
References:  <199906050023.UAA12466@khavrinen.lcs.mit.edu> <199906050142.SAA04889@biggusdiskus.flyingfox.com>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Fri, 4 Jun 1999 18:42:03 -0700 (PDT), Jim Shankland <jas@flyingfox.com> said:

> Garrett Wollman <wollman@khavrinen.lcs.mit.edu> writes:
>> The user programs should not use SIOCGIFCONF.

> Instead, they should .... ?

Use an interface which provides clients with enough information to
know when they have retrieved all of the relevant information.  Here's
an example.

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/time.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>

#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define	satosin(sa)	((struct sockaddr_in *)(sa))

int
main(void)
{
	int mib[6], naddrs, ilen;
	char *buf, *cp;
	size_t len;
	struct rt_msghdr *rtm;
	struct if_msghdr *ifm;
	struct ifa_msghdr *ifam;
	struct sockaddr *sa;

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = AF_INET;
	mib[4] = NET_RT_IFLIST;
	mib[5] = 0;

	len = 0;
	if (sysctl(mib, 6, 0, &len, 0, 0) < 0)
		err(1, "sysctl 1");

	cp = buf = malloc(len);
	if (buf == 0)
		err(1, "malloc: %lu", (u_long)len);
	if (sysctl(mib, 6, buf, &len, 0, 0) < 0)
		err(1, "sysctl 2");

	ilen = len;
	cp = buf;
	while (ilen > 0) {
		rtm = (struct rt_msghdr *)cp;
		naddrs = 0;
		if (rtm->rtm_version != RTM_VERSION)
			err(1, "unknown routing message version %d", 
			    rtm->rtm_version);
		if (rtm->rtm_type != RTM_IFINFO)
			err(1, "unknown routing message type %d",
			    rtm->rtm_type);
		ifm = (struct if_msghdr *)rtm;
		printf("Interface %d: <%#x,%#x>:\n", ifm->ifm_index,
		       (u_int)ifm->ifm_flags, (u_int)ifm->ifm_addrs);
		ilen -= ifm->ifm_msglen;
		cp += ifm->ifm_msglen;
		rtm = (struct rt_msghdr *)cp;
		while (ilen > 0 && rtm->rtm_type == RTM_NEWADDR) {
			ifam = (struct ifa_msghdr *)rtm;
			printf("\tAddress %d:\n", ++naddrs);
			ilen -= sizeof(*ifam);
			cp += sizeof(*ifam);
			sa = (struct sockaddr *)cp;
			if (ilen > 0 && ifam->ifam_addrs & RTA_NETMASK) {
				ilen -= (sa->sa_len + 3) & ~3;
				cp += (sa->sa_len + 3) & ~3;
				printf("\t\tnetmask %s\n", 
				       inet_ntoa(satosin(sa)->sin_addr));
				sa = (struct sockaddr *)cp;
			}
			if (ilen > 0 && ifam->ifam_addrs & RTA_IFA) {
				ilen -= (sa->sa_len + 3) & ~3;
				cp += (sa->sa_len + 3) & ~3;
				printf("\t\tIFA %s\n", 
				       inet_ntoa(satosin(sa)->sin_addr));
				sa = (struct sockaddr *)cp;
			}
			if (ilen > 0 && ifam->ifam_addrs & RTA_BRD) {
				ilen -= (sa->sa_len + 3) & ~3;
				cp += (sa->sa_len + 3) & ~3;
				printf("\t\tbroadcast %s\n", 
				       inet_ntoa(satosin(sa)->sin_addr));
			}
			rtm = (struct rt_msghdr *)cp;
		}
	}

	return 0;
}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199906050043.UAA12537>