blob: 7ad570f4a401295b04b64cd61bbdc41e63de322f [file] [log] [blame]
/*
* Get interface's address and mask information by sysctl() function.
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "if.h"
#include "sockunion.h"
#include "prefix.h"
#include "connected.h"
#include "memory.h"
#include "ioctl.h"
#include "log.h"
int
ifstat_update_sysctl ()
{
caddr_t ref, buf, end;
size_t bufsiz;
struct if_msghdr *ifm;
struct interface *ifp;
#define MIBSIZ 6
int mib[MIBSIZ] =
{
CTL_NET,
PF_ROUTE,
0,
0, /* AF_INET & AF_INET6 */
NET_RT_IFLIST,
0
};
/* Query buffer size. */
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
{
zlog_warn ("sysctl() error by %s", safe_strerror (errno));
return -1;
}
/* We free this memory at the end of this function. */
ref = buf = XMALLOC (MTYPE_TMP, bufsiz);
/* Fetch interface informations into allocated buffer. */
if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0)
{
zlog (NULL, LOG_WARNING, "sysctl error by %s", safe_strerror (errno));
return -1;
}
/* Parse both interfaces and addresses. */
for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen)
{
ifm = (struct if_msghdr *) buf;
if (ifm->ifm_type == RTM_IFINFO)
{
ifp = if_lookup_by_index (ifm->ifm_index);
if (ifp)
ifp->stats = ifm->ifm_data;
}
}
/* Free sysctl buffer. */
XFREE (MTYPE_TMP, ref);
return 0;
}
/* Interface listing up function using sysctl(). */
void
interface_list ()
{
caddr_t ref, buf, end;
size_t bufsiz;
struct if_msghdr *ifm;
int ifm_read (struct if_msghdr *);
int ifam_read (struct ifa_msghdr *);
#define MIBSIZ 6
int mib[MIBSIZ] =
{
CTL_NET,
PF_ROUTE,
0,
0, /* AF_INET & AF_INET6 */
NET_RT_IFLIST,
0
};
/* Query buffer size. */
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
{
zlog (NULL, LOG_WARNING, "sysctl() error by %s", safe_strerror (errno));
return;
}
/* We free this memory at the end of this function. */
ref = buf = XMALLOC (MTYPE_TMP, bufsiz);
/* Fetch interface informations into allocated buffer. */
if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0)
{
zlog (NULL, LOG_WARNING, "sysctl error by %s", safe_strerror (errno));
return;
}
/* Parse both interfaces and addresses. */
for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen)
{
ifm = (struct if_msghdr *) buf;
switch (ifm->ifm_type)
{
case RTM_IFINFO:
ifm_read (ifm);
break;
case RTM_NEWADDR:
ifam_read ((struct ifa_msghdr *) ifm);
break;
default:
zlog_info ("interfaces_list(): unexpected message type");
XFREE (MTYPE_TMP, ref);
return;
break;
}
}
/* Free sysctl buffer. */
XFREE (MTYPE_TMP, ref);
}