/*
 * Interface looking up by ioctl ().
 * 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 "ioctl.h"
#include "connected.h"
#include "memory.h"
#include "log.h"

#include "zebra/interface.h"

/* Interface looking up using infamous SIOCGIFCONF. */
static int
interface_list_ioctl (void)
{
  int ret;
  int sock;
#define IFNUM_BASE 32
  int ifnum;
  struct ifreq *ifreq;
  struct ifconf ifconf;
  struct interface *ifp;
  int n;
  int lastlen;

  /* Normally SIOCGIFCONF works with AF_INET socket. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) 
    {
      zlog_warn ("Can't make AF_INET socket stream: %s", safe_strerror (errno));
      return -1;
    }

  /* Set initial ifreq count.  This will be double when SIOCGIFCONF
     fail.  Solaris has SIOCGIFNUM. */
#ifdef SIOCGIFNUM
  ret = ioctl (sock, SIOCGIFNUM, &ifnum);
  if (ret < 0)
    ifnum = IFNUM_BASE;
  else
    ifnum++;
#else
  ifnum = IFNUM_BASE;
#endif /* SIOCGIFNUM */

  ifconf.ifc_buf = NULL;

  lastlen = 0;
  /* Loop until SIOCGIFCONF success. */
  for (;;) 
    {
      ifconf.ifc_len = sizeof (struct ifreq) * ifnum;
      ifconf.ifc_buf = XREALLOC(MTYPE_TMP, ifconf.ifc_buf, ifconf.ifc_len);

      ret = ioctl(sock, SIOCGIFCONF, &ifconf);

      if (ret < 0) 
	{
	  zlog_warn ("SIOCGIFCONF: %s", safe_strerror(errno));
	  goto end;
	}
      /* Repeatedly get info til buffer fails to grow. */
      if (ifconf.ifc_len > lastlen)
	{
          lastlen = ifconf.ifc_len;
	  ifnum += 10;
	  continue;
	}
      /* Success. */
      break;
    }

  /* Allocate interface. */
  ifreq = ifconf.ifc_req;

#ifdef OPEN_BSD
  for (n = 0; n < ifconf.ifc_len; )
    {
      int size;

      ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n);
      ifp = if_get_by_name_len(ifreq->ifr_name,
			       strnlen(ifreq->ifr_name,
				       sizeof(ifreq->ifr_name)));
      if_add_update (ifp);
      size = ifreq->ifr_addr.sa_len;
      if (size < sizeof (ifreq->ifr_addr))
	size = sizeof (ifreq->ifr_addr);
      size += sizeof (ifreq->ifr_name);
      n += size;
    }
#else
  for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq))
    {
      ifp = if_get_by_name_len(ifreq->ifr_name,
			       strnlen(ifreq->ifr_name,
				       sizeof(ifreq->ifr_name)));
      if_add_update (ifp);
      ifreq++;
    }
#endif /* OPEN_BSD */

 end:
  close (sock);
  XFREE (MTYPE_TMP, ifconf.ifc_buf);

  return ret;
}

/* Get interface's index by ioctl. */
static int
if_get_index (struct interface *ifp)
{
#if defined(HAVE_IF_NAMETOINDEX)
  /* Modern systems should have if_nametoindex(3). */
  ifp->ifindex = if_nametoindex(ifp->name);
#elif defined(SIOCGIFINDEX) && !defined(HAVE_BROKEN_ALIASES)
  /* Fall-back for older linuxes. */
  int ret;
  struct ifreq ifreq;
  static int if_fake_index;

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFINDEX, (caddr_t) &ifreq);
  if (ret < 0)
    {
      /* Linux 2.0.X does not have interface index. */
      ifp->ifindex = if_fake_index++;
      return ifp->ifindex;
    }

  /* OK we got interface index. */
#ifdef ifr_ifindex
  ifp->ifindex = ifreq.ifr_ifindex;
#else
  ifp->ifindex = ifreq.ifr_index;
#endif

#else
/* Linux 2.2.X does not provide individual interface index 
   for aliases and we know it. For others issue a warning. */
#if !defined(HAVE_BROKEN_ALIASES)
#warning "Using if_fake_index. You may want to add appropriate"
#warning "mapping from ifname to ifindex for your system..."
#endif
  /* This branch probably won't provide usable results, but anyway... */
  static int if_fake_index = 1;
  ifp->ifindex = if_fake_index++;
#endif

  return ifp->ifindex;
}

#ifdef SIOCGIFHWADDR
static int
if_get_hwaddr (struct interface *ifp)
{
  int ret;
  struct ifreq ifreq;
  int i;

  strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ);
  ifreq.ifr_addr.sa_family = AF_INET;

  /* Fetch Hardware address if available. */
  ret = if_ioctl (SIOCGIFHWADDR, (caddr_t) &ifreq);
  if (ret < 0)
    ifp->hw_addr_len = 0;
  else
    {
      memcpy (ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6);

      for (i = 0; i < 6; i++)
	if (ifp->hw_addr[i] != 0)
	  break;

      if (i == 6)
	ifp->hw_addr_len = 0;
      else
	ifp->hw_addr_len = 6;
    }
  return 0;
}
#endif /* SIOCGIFHWADDR */

#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>

static int
if_getaddrs (void)
{
  int ret;
  struct ifaddrs *ifap;
  struct ifaddrs *ifapfree;
  struct interface *ifp;
  int prefixlen;

  ret = getifaddrs (&ifap); 
  if (ret != 0)
    {
      zlog_err ("getifaddrs(): %s", safe_strerror (errno));
      return -1;
    }

  for (ifapfree = ifap; ifap; ifap = ifap->ifa_next)
    {
      ifp = if_lookup_by_name (ifap->ifa_name);
      if (ifp == NULL)
	{
	  zlog_err ("if_getaddrs(): Can't lookup interface %s\n",
		    ifap->ifa_name);
	  continue;
	}

      if (ifap->ifa_addr->sa_family == AF_INET)
	{
	  struct sockaddr_in *addr;
	  struct sockaddr_in *mask;
	  struct sockaddr_in *dest;
	  struct in_addr *dest_pnt;

	  addr = (struct sockaddr_in *) ifap->ifa_addr;
	  mask = (struct sockaddr_in *) ifap->ifa_netmask;
	  prefixlen = ip_masklen (mask->sin_addr);

	  dest_pnt = NULL;

	  if (ifap->ifa_flags & IFF_POINTOPOINT) 
	    {
	      dest = (struct sockaddr_in *) ifap->ifa_dstaddr;
	      dest_pnt = &dest->sin_addr;
	    }

	  if (ifap->ifa_flags & IFF_BROADCAST)
	    {
	      dest = (struct sockaddr_in *) ifap->ifa_broadaddr;
	      dest_pnt = &dest->sin_addr;
	    }

	  connected_add_ipv4 (ifp, 0, &addr->sin_addr,
			      prefixlen, dest_pnt, NULL);
	}
#ifdef HAVE_IPV6
      if (ifap->ifa_addr->sa_family == AF_INET6)
	{
	  struct sockaddr_in6 *addr;
	  struct sockaddr_in6 *mask;
	  struct sockaddr_in6 *dest;
	  struct in6_addr *dest_pnt;

	  addr = (struct sockaddr_in6 *) ifap->ifa_addr;
	  mask = (struct sockaddr_in6 *) ifap->ifa_netmask;
	  prefixlen = ip6_masklen (mask->sin6_addr);

	  dest_pnt = NULL;

	  if (ifap->ifa_flags & IFF_POINTOPOINT) 
	    {
	      if (ifap->ifa_dstaddr)
		{
		  dest = (struct sockaddr_in6 *) ifap->ifa_dstaddr;
		  dest_pnt = &dest->sin6_addr;
		}
	    }

	  if (ifap->ifa_flags & IFF_BROADCAST)
	    {
	      if (ifap->ifa_broadaddr)
		{
		  dest = (struct sockaddr_in6 *) ifap->ifa_broadaddr;
		  dest_pnt = &dest->sin6_addr;
		}
	    }

#if defined(KAME)
	  if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) 
	    {
	      addr->sin6_scope_id =
			ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]);
	      addr->sin6_addr.s6_addr[2] = addr->sin6_addr.s6_addr[3] = 0;
	    }	
#endif          

	  connected_add_ipv6 (ifp, &addr->sin6_addr, prefixlen, dest_pnt);
	}
#endif /* HAVE_IPV6 */
    }

  freeifaddrs (ifapfree);

  return 0; 
}
#else /* HAVE_GETIFADDRS */
/* Interface address lookup by ioctl.  This function only looks up
   IPv4 address. */
int
if_get_addr (struct interface *ifp)
{
  int ret;
  struct ifreq ifreq;
  struct sockaddr_in addr;
  struct sockaddr_in mask;
  struct sockaddr_in dest;
  struct in_addr *dest_pnt;
  u_char prefixlen;

  /* Interface's name and address family. */
  strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ);
  ifreq.ifr_addr.sa_family = AF_INET;

  /* Interface's address. */
  ret = if_ioctl (SIOCGIFADDR, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      if (errno != EADDRNOTAVAIL)
	{
	  zlog_warn ("SIOCGIFADDR fail: %s", safe_strerror (errno));
	  return ret;
	}
      return 0;
    }
  memcpy (&addr, &ifreq.ifr_addr, sizeof (struct sockaddr_in));

  /* Interface's network mask. */
  ret = if_ioctl (SIOCGIFNETMASK, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      if (errno != EADDRNOTAVAIL) 
	{
	  zlog_warn ("SIOCGIFNETMASK fail: %s", safe_strerror (errno));
	  return ret;
	}
      return 0;
    }
#ifdef ifr_netmask
  memcpy (&mask, &ifreq.ifr_netmask, sizeof (struct sockaddr_in));
#else
  memcpy (&mask, &ifreq.ifr_addr, sizeof (struct sockaddr_in));
#endif /* ifr_netmask */
  prefixlen = ip_masklen (mask.sin_addr);

  /* Point to point or borad cast address pointer init. */
  dest_pnt = NULL;

  if (ifp->flags & IFF_POINTOPOINT) 
    {
      ret = if_ioctl (SIOCGIFDSTADDR, (caddr_t) &ifreq);
      if (ret < 0) 
	{
	  if (errno != EADDRNOTAVAIL) 
	    {
	      zlog_warn ("SIOCGIFDSTADDR fail: %s", safe_strerror (errno));
	      return ret;
	    }
	  return 0;
	}
      memcpy (&dest, &ifreq.ifr_dstaddr, sizeof (struct sockaddr_in));
      dest_pnt = &dest.sin_addr;
    }
  if (ifp->flags & IFF_BROADCAST)
    {
      ret = if_ioctl (SIOCGIFBRDADDR, (caddr_t) &ifreq);
      if (ret < 0) 
	{
	  if (errno != EADDRNOTAVAIL) 
	    {
	      zlog_warn ("SIOCGIFBRDADDR fail: %s", safe_strerror (errno));
	      return ret;
	    }
	  return 0;
	}
      memcpy (&dest, &ifreq.ifr_broadaddr, sizeof (struct sockaddr_in));
      dest_pnt = &dest.sin_addr;
    }


  /* Set address to the interface. */
  connected_add_ipv4 (ifp, 0, &addr.sin_addr, prefixlen, dest_pnt, NULL);

  return 0;
}
#endif /* HAVE_GETIFADDRS */

/* Fetch interface information via ioctl(). */
static void
interface_info_ioctl ()
{
  struct listnode *node, *nnode;
  struct interface *ifp;
  
  for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
    {
      if_get_index (ifp);
#ifdef SIOCGIFHWADDR
      if_get_hwaddr (ifp);
#endif /* SIOCGIFHWADDR */
      if_get_flags (ifp);
#ifndef HAVE_GETIFADDRS
      if_get_addr (ifp);
#endif /* ! HAVE_GETIFADDRS */
      if_get_mtu (ifp);
      if_get_metric (ifp);
    }
}

/* Lookup all interface information. */
void
interface_list ()
{
  /* Linux can do both proc & ioctl, ioctl is the only way to get
     interface aliases in 2.2 series kernels. */
#ifdef HAVE_PROC_NET_DEV
  interface_list_proc ();
#endif /* HAVE_PROC_NET_DEV */
  interface_list_ioctl ();

  /* After listing is done, get index, address, flags and other
     interface's information. */
  interface_info_ioctl ();

#ifdef HAVE_GETIFADDRS
  if_getaddrs ();
#endif /* HAVE_GETIFADDRS */

#if defined(HAVE_IPV6) && defined(HAVE_PROC_NET_IF_INET6)
  /* Linux provides interface's IPv6 address via
     /proc/net/if_inet6. */
  ifaddr_proc_ipv6 ();
#endif /* HAVE_IPV6 && HAVE_PROC_NET_IF_INET6 */
}
