mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 04:50:35 +00:00 
			
		
		
		
	Remove compiled warnings for the zebra directory Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by:
		
			
				
	
	
		
			249 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Interface name and statistics get function using proc file system
 | 
						|
 * Copyright (C) 1999 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 "prefix.h"
 | 
						|
#include "log.h"
 | 
						|
 | 
						|
#include "zebra/ioctl.h"
 | 
						|
#include "zebra/connected.h"
 | 
						|
#include "zebra/interface.h"
 | 
						|
 | 
						|
/* Proc filesystem one line buffer. */
 | 
						|
#define PROCBUFSIZ                  1024
 | 
						|
 | 
						|
/* Path to device proc file system. */
 | 
						|
#ifndef _PATH_PROC_NET_DEV
 | 
						|
#define _PATH_PROC_NET_DEV        "/proc/net/dev"
 | 
						|
#endif /* _PATH_PROC_NET_DEV */
 | 
						|
 | 
						|
/* Return statistics data pointer. */
 | 
						|
static char *
 | 
						|
interface_name_cut (char *buf, char **name)
 | 
						|
{
 | 
						|
  char *stat;
 | 
						|
 | 
						|
  /* Skip white space.  Line will include header spaces. */
 | 
						|
  while (*buf == ' ')
 | 
						|
    buf++;
 | 
						|
  *name = buf;
 | 
						|
 | 
						|
  /* Cut interface name. */
 | 
						|
  stat = strrchr (buf, ':');
 | 
						|
  *stat++ = '\0';
 | 
						|
 | 
						|
  return stat;
 | 
						|
}
 | 
						|
 | 
						|
/* Fetch each statistics field. */
 | 
						|
static int
 | 
						|
ifstat_dev_fields (int version, char *buf, struct interface *ifp)
 | 
						|
{
 | 
						|
  switch (version) 
 | 
						|
    {
 | 
						|
    case 3:
 | 
						|
      sscanf(buf,
 | 
						|
	     "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
 | 
						|
	     &ifp->stats.rx_bytes,
 | 
						|
	     &ifp->stats.rx_packets,
 | 
						|
	     &ifp->stats.rx_errors,
 | 
						|
	     &ifp->stats.rx_dropped,
 | 
						|
	     &ifp->stats.rx_fifo_errors,
 | 
						|
	     &ifp->stats.rx_frame_errors,
 | 
						|
	     &ifp->stats.rx_compressed,
 | 
						|
	     &ifp->stats.rx_multicast,
 | 
						|
 | 
						|
	     &ifp->stats.tx_bytes,
 | 
						|
	     &ifp->stats.tx_packets,
 | 
						|
	     &ifp->stats.tx_errors,
 | 
						|
	     &ifp->stats.tx_dropped,
 | 
						|
	     &ifp->stats.tx_fifo_errors,
 | 
						|
	     &ifp->stats.collisions,
 | 
						|
	     &ifp->stats.tx_carrier_errors,
 | 
						|
	     &ifp->stats.tx_compressed);
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
 | 
						|
	     &ifp->stats.rx_bytes,
 | 
						|
	     &ifp->stats.rx_packets,
 | 
						|
	     &ifp->stats.rx_errors,
 | 
						|
	     &ifp->stats.rx_dropped,
 | 
						|
	     &ifp->stats.rx_fifo_errors,
 | 
						|
	     &ifp->stats.rx_frame_errors,
 | 
						|
 | 
						|
	     &ifp->stats.tx_bytes,
 | 
						|
	     &ifp->stats.tx_packets,
 | 
						|
	     &ifp->stats.tx_errors,
 | 
						|
	     &ifp->stats.tx_dropped,
 | 
						|
	     &ifp->stats.tx_fifo_errors,
 | 
						|
	     &ifp->stats.collisions,
 | 
						|
	     &ifp->stats.tx_carrier_errors);
 | 
						|
      ifp->stats.rx_multicast = 0;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",
 | 
						|
	     &ifp->stats.rx_packets,
 | 
						|
	     &ifp->stats.rx_errors,
 | 
						|
	     &ifp->stats.rx_dropped,
 | 
						|
	     &ifp->stats.rx_fifo_errors,
 | 
						|
	     &ifp->stats.rx_frame_errors,
 | 
						|
 | 
						|
	     &ifp->stats.tx_packets,
 | 
						|
	     &ifp->stats.tx_errors,
 | 
						|
	     &ifp->stats.tx_dropped,
 | 
						|
	     &ifp->stats.tx_fifo_errors,
 | 
						|
	     &ifp->stats.collisions,
 | 
						|
	     &ifp->stats.tx_carrier_errors);
 | 
						|
      ifp->stats.rx_bytes = 0;
 | 
						|
      ifp->stats.tx_bytes = 0;
 | 
						|
      ifp->stats.rx_multicast = 0;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/* Update interface's statistics. */
 | 
						|
static void
 | 
						|
ifstat_update_proc (void)
 | 
						|
{
 | 
						|
  FILE *fp;
 | 
						|
  char buf[PROCBUFSIZ];
 | 
						|
  int version;
 | 
						|
  struct interface *ifp;
 | 
						|
  char *stat;
 | 
						|
  char *name;
 | 
						|
 | 
						|
  /* Open /proc/net/dev. */
 | 
						|
  fp = fopen (_PATH_PROC_NET_DEV, "r");
 | 
						|
  if (fp == NULL)
 | 
						|
    {
 | 
						|
      zlog_warn ("Can't open proc file %s: %s",
 | 
						|
		 _PATH_PROC_NET_DEV, safe_strerror (errno));
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Drop header lines. */
 | 
						|
  fgets (buf, PROCBUFSIZ, fp);
 | 
						|
  fgets (buf, PROCBUFSIZ, fp);
 | 
						|
 | 
						|
  /* To detect proc format veresion, parse second line. */
 | 
						|
  if (strstr (buf, "compressed"))
 | 
						|
    version = 3;
 | 
						|
  else if (strstr (buf, "bytes"))
 | 
						|
    version = 2;
 | 
						|
  else
 | 
						|
    version = 1;
 | 
						|
 | 
						|
  /* Update each interface's statistics. */
 | 
						|
  while (fgets (buf, PROCBUFSIZ, fp) != NULL)
 | 
						|
    {
 | 
						|
      stat = interface_name_cut (buf, &name);
 | 
						|
      ifp = if_get_by_name (name);
 | 
						|
      ifstat_dev_fields (version, stat, ifp);
 | 
						|
    }
 | 
						|
  fclose(fp);
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
/* Interface structure allocation by proc filesystem. */
 | 
						|
int
 | 
						|
interface_list_proc ()
 | 
						|
{
 | 
						|
  FILE *fp;
 | 
						|
  char buf[PROCBUFSIZ];
 | 
						|
  struct interface *ifp;
 | 
						|
  char *name;
 | 
						|
 | 
						|
  /* Open /proc/net/dev. */
 | 
						|
  fp = fopen (_PATH_PROC_NET_DEV, "r");
 | 
						|
  if (fp == NULL)
 | 
						|
    {
 | 
						|
      zlog_warn ("Can't open proc file %s: %s",
 | 
						|
		 _PATH_PROC_NET_DEV, safe_strerror (errno));
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Drop header lines. */
 | 
						|
  fgets (buf, PROCBUFSIZ, fp);
 | 
						|
  fgets (buf, PROCBUFSIZ, fp);
 | 
						|
 | 
						|
  /* Only allocate interface structure.  Other jobs will be done in
 | 
						|
     if_ioctl.c. */
 | 
						|
  while (fgets (buf, PROCBUFSIZ, fp) != NULL)
 | 
						|
    {
 | 
						|
      interface_name_cut (buf, &name);
 | 
						|
      ifp = if_get_by_name (name);
 | 
						|
      if_add_update (ifp);
 | 
						|
    }
 | 
						|
  fclose(fp);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
#if defined(HAVE_IPV6) && defined(HAVE_PROC_NET_IF_INET6)
 | 
						|
 | 
						|
#ifndef _PATH_PROC_NET_IF_INET6
 | 
						|
#define _PATH_PROC_NET_IF_INET6          "/proc/net/if_inet6"
 | 
						|
#endif /* _PATH_PROC_NET_IF_INET6 */
 | 
						|
 | 
						|
int
 | 
						|
ifaddr_proc_ipv6 ()
 | 
						|
{
 | 
						|
  FILE *fp;
 | 
						|
  char buf[PROCBUFSIZ];
 | 
						|
  int n;
 | 
						|
  char addr[33];
 | 
						|
  char ifname[21];
 | 
						|
  int ifindex, plen, scope, status;
 | 
						|
  struct interface *ifp;
 | 
						|
  struct prefix_ipv6 p;
 | 
						|
 | 
						|
  /* Open proc file system. */
 | 
						|
  fp = fopen (_PATH_PROC_NET_IF_INET6, "r");
 | 
						|
  if (fp == NULL)
 | 
						|
    {
 | 
						|
      zlog_warn ("Can't open proc file %s: %s",
 | 
						|
		 _PATH_PROC_NET_IF_INET6, safe_strerror (errno));
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
  
 | 
						|
  /* Get interface's IPv6 address. */
 | 
						|
  while (fgets (buf, PROCBUFSIZ, fp) != NULL)
 | 
						|
    {
 | 
						|
      n = sscanf (buf, "%32s %02x %02x %02x %02x %20s", 
 | 
						|
		  addr, &ifindex, &plen, &scope, &status, ifname);
 | 
						|
      if (n != 6)
 | 
						|
	continue;
 | 
						|
 | 
						|
      ifp = if_get_by_name (ifname);
 | 
						|
 | 
						|
      /* Fetch interface's IPv6 address. */
 | 
						|
      str2in6_addr (addr, &p.prefix);
 | 
						|
      p.prefixlen = plen;
 | 
						|
 | 
						|
      connected_add_ipv6 (ifp, 0, &p.prefix, p.prefixlen, NULL, ifname);
 | 
						|
    }
 | 
						|
  fclose (fp);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
#endif /* HAVE_IPV6 && HAVE_PROC_NET_IF_INET6 */
 |