/*
 * 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 "vrf.h"

#include "zebra/interface.h"
#include "zebra/rib.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)
    {
      if (ifap->ifa_addr == NULL)
        {
          zlog_err ("%s: nonsensical ifaddr with NULL ifa_addr, ifname %s",
                    __func__, (ifap->ifa_name ? ifap->ifa_name : "(null)"));
          continue;
        }
       
      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;
	  int flags = 0;

	  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_dstaddr &&
	      !IPV4_ADDR_SAME(&addr->sin_addr,
			      &((struct sockaddr_in *)
			      	ifap->ifa_dstaddr)->sin_addr))
	    {
	      dest = (struct sockaddr_in *) ifap->ifa_dstaddr;
	      dest_pnt = &dest->sin_addr;
	      flags = ZEBRA_IFA_PEER;
	    }
	  else if (ifap->ifa_broadaddr &&
		   !IPV4_ADDR_SAME(&addr->sin_addr,
				   &((struct sockaddr_in *)
				     ifap->ifa_broadaddr)->sin_addr))
	    {
	      dest = (struct sockaddr_in *) ifap->ifa_broadaddr;
	      dest_pnt = &dest->sin_addr;
	    }

	  connected_add_ipv4 (ifp, flags, &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;
	  int flags = 0;

	  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_dstaddr &&
	      !IPV6_ADDR_SAME(&addr->sin6_addr,
			      &((struct sockaddr_in6 *)
			      	ifap->ifa_dstaddr)->sin6_addr))
	    {
	      dest = (struct sockaddr_in6 *) ifap->ifa_dstaddr;
	      dest_pnt = &dest->sin6_addr;
	      flags = ZEBRA_IFA_PEER;
	    }
	  else if (ifap->ifa_broadaddr &&
		   !IPV6_ADDR_SAME(&addr->sin6_addr,
				   &((struct sockaddr_in6 *)
				     ifap->ifa_broadaddr)->sin6_addr))
	    {
	      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, flags, &addr->sin6_addr, prefixlen, 
	                      dest_pnt, NULL);
	}
#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;
  int flags = 0;

  /* 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;

  ret = if_ioctl (SIOCGIFDSTADDR, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      if (errno != EADDRNOTAVAIL) 
	zlog_warn ("SIOCGIFDSTADDR fail: %s", safe_strerror (errno));
    }
  else if (!IPV4_ADDR_SAME(&addr.sin_addr, &ifreq.ifr_dstaddr.sin_addr))
    {
      memcpy (&dest, &ifreq.ifr_dstaddr, sizeof (struct sockaddr_in));
      dest_pnt = &dest.sin_addr;
      flags = ZEBRA_IFA_PEER;
    }
  if (!dest_pnt)
    {
      ret = if_ioctl (SIOCGIFBRDADDR, (caddr_t) &ifreq);
      if (ret < 0) 
	{
	  if (errno != EADDRNOTAVAIL) 
	    zlog_warn ("SIOCGIFBRDADDR fail: %s", safe_strerror (errno));
	}
      else if (!IPV4_ADDR_SAME(&addr.sin_addr, &ifreq.ifr_broadaddr.sin_addr))
        {
	  memcpy (&dest, &ifreq.ifr_broadaddr, sizeof (struct sockaddr_in));
	  dest_pnt = &dest.sin_addr;
        }
    }


  /* Set address to the interface. */
  connected_add_ipv4 (ifp, flags, &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 (struct zebra_vrf *zvrf)
{
  if (zvrf->vrf_id != VRF_DEFAULT)
    {
      zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
      return;
    }
  /* 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 */
}
