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>
