Ejemplo n.º 1
0
Archivo: ioctl.c Proyecto: ton31337/frr
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
{
	int ret;
	struct ifreq ifreq;
	struct sockaddr_in addr;
	struct sockaddr_in broad;
	struct sockaddr_in mask;
	struct prefix_ipv4 ifaddr;
	struct prefix_ipv4 *p;

	p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);

	ifaddr = *p;

	strlcpy(ifreq.ifr_name, dplane_ctx_get_ifname(ctx),
		sizeof(ifreq.ifr_name));

	addr.sin_addr = p->prefix;
	addr.sin_family = p->family;
	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
	if (ret < 0)
		return ret;

	/* We need mask for make broadcast addr. */
	masklen2ip(p->prefixlen, &mask.sin_addr);

	if (dplane_ctx_intf_is_broadcast(ctx)) {
		apply_mask_ipv4(&ifaddr);
		addr.sin_addr = ifaddr.prefix;

		broad.sin_addr.s_addr =
			(addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
		broad.sin_family = p->family;

		memcpy(&ifreq.ifr_broadaddr, &broad,
		       sizeof(struct sockaddr_in));
		ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq);
		if (ret < 0)
			return ret;
	}

	mask.sin_family = p->family;
#ifdef SUNOS_5
	memcpy(&mask, &ifreq.ifr_addr, sizeof(mask));
#else
	memcpy(&ifreq.ifr_addr, &mask, sizeof(struct sockaddr_in));
#endif /* SUNOS5 */
	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);
	if (ret < 0)
		return ret;

	return 0;
}
Ejemplo n.º 2
0
/* Set up interface's address, netmask (and broadcast? ).
   Solaris uses ifname:number semantics to set IP address aliases. */
int if_set_prefix(struct interface *ifp, struct connected *ifc)
{
	int ret;
	struct ifreq ifreq;
	struct sockaddr_in addr;
	struct sockaddr_in broad;
	struct sockaddr_in mask;
	struct prefix_ipv4 ifaddr;
	struct prefix_ipv4 *p;

	p = (struct prefix_ipv4 *)ifc->address;

	ifaddr = *p;

	strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ);

	addr.sin_addr = p->prefix;
	addr.sin_family = p->family;
	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));

	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);

	if (ret < 0)
		return ret;

	/* We need mask for make broadcast addr. */
	masklen2ip(p->prefixlen, &mask.sin_addr);

	if (if_is_broadcast(ifp)) {
		apply_mask_ipv4(&ifaddr);
		addr.sin_addr = ifaddr.prefix;

		broad.sin_addr.s_addr =
			(addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
		broad.sin_family = p->family;

		memcpy(&ifreq.ifr_broadaddr, &broad,
		       sizeof(struct sockaddr_in));
		ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq);
		if (ret < 0)
			return ret;
	}

	mask.sin_family = p->family;
#ifdef SUNOS_5
	memcpy(&mask, &ifreq.ifr_addr, sizeof(mask));
#else
	memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
#endif /* SUNOS_5 */
	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);

	return ((ret < 0) ? ret : 0);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/* Set up interface's IP address, netmask (and broadcas? ).  *BSD may
   has ifaliasreq structure.  */
int
if_unset_prefix (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct ifaliasreq addreq;
  struct sockaddr_in addr;
  struct sockaddr_in mask;
  struct prefix_ipv4 *p;

  p = (struct prefix_ipv4 *)ifc->address;

  memset (&addreq, 0, sizeof addreq);
  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);

  memset (&addr, 0, sizeof (struct sockaddr_in));
  addr.sin_addr = p->prefix;
  addr.sin_family = p->family;
#ifdef HAVE_SIN_LEN
  addr.sin_len = sizeof (struct sockaddr_in);
#endif
  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in));

  memset (&mask, 0, sizeof (struct sockaddr_in));
  masklen2ip (p->prefixlen, &mask.sin_addr);
  mask.sin_family = p->family;
#ifdef HAVE_SIN_LEN
  mask.sin_len = sizeof (struct sockaddr_in);
#endif
  memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in));
  
  ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq);
  if (ret < 0)
    return ret;
  return 0;
}
Ejemplo n.º 5
0
/* get interface MTU */
void
if_get_mtu (struct interface *ifp)
{
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

#if defined(SIOCGIFMTU)
  if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) 
    {
      zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)");
      ifp->mtu = -1;
      return;
    }

#ifdef SUNOS_5
  ifp->mtu = ifreq.ifr_metric;
#else
  ifp->mtu = ifreq.ifr_mtu;
#endif /* SUNOS_5 */

#else
  zlog (NULL, LOG_INFO, "Can't lookup mtu on this system");
  ifp->mtu = -1;
#endif
}
Ejemplo n.º 6
0
/* get interface flags */
void
if_get_flags (struct interface *ifp)
{
  int ret;
  struct ifreq ifreq;
#ifdef HAVE_BSD_LINK_DETECT
  struct ifmediareq ifmr;
#endif /* HAVE_BSD_LINK_DETECT */

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
      return;
    }
#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */

  /* Per-default, IFF_RUNNING is held high, unless link-detect says
   * otherwise - we abuse IFF_RUNNING inside kroute as a link-state flag,
   * following practice on Linux and Solaris kernels
   */
  SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
  
  if (CHECK_FLAG (ifp->status, KROUTE_INTERFACE_LINKDETECTION))
    {
      (void) memset(&ifmr, 0, sizeof(ifmr));
      strncpy (ifmr.ifm_name, ifp->name, IFNAMSIZ);
      
      /* Seems not all interfaces implement this ioctl */
      if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
        zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno));
      else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
        {
          if (ifmr.ifm_status & IFM_ACTIVE)
            SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
          else
            UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
        }
  }
#endif /* HAVE_BSD_LINK_DETECT */

  if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
}
Ejemplo n.º 7
0
/* get interface flags */
void if_get_flags (struct interface *ifp)
{
	int ret = 0;
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
	if (ret < 0)
	{
		zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
		return;
	}

	if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
}
Ejemplo n.º 8
0
/* Get interface's index by ioctl. */
int
if_get_index (struct interface_FOO *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)
#ifndef _MSC_VER
#warning "Using if_fake_index. You may want to add appropriate"
#endif
#ifndef _MSC_VER
#warning "mapping from ifname to ifindex for your system..."
#endif
#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;
}
Ejemplo n.º 9
0
Archivo: ioctl.c Proyecto: ton31337/frr
/*
 * Helper for interface-addr install, non-netlink
 */
static int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
{
	int ret;
	struct ifaliasreq addreq;
	struct sockaddr_in addr, mask, peer;
	struct prefix_ipv4 *p;

	p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);

	memset(&addreq, 0, sizeof(addreq));
	strlcpy((char *)&addreq.ifra_name, dplane_ctx_get_ifname(ctx),
		sizeof(addreq.ifra_name));

	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_addr = p->prefix;
	addr.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	addr.sin_len = sizeof(struct sockaddr_in);
#endif
	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));

	if (dplane_ctx_intf_is_connected(ctx)) {
		p = (struct prefix_ipv4 *)dplane_ctx_get_intf_dest(ctx);
		memset(&mask, 0, sizeof(struct sockaddr_in));
		peer.sin_addr = p->prefix;
		peer.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		peer.sin_len = sizeof(struct sockaddr_in);
#endif
		memcpy(&addreq.ifra_broadaddr, &peer,
		       sizeof(struct sockaddr_in));
	}

	memset(&mask, 0, sizeof(struct sockaddr_in));
	masklen2ip(p->prefixlen, &mask.sin_addr);
	mask.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	mask.sin_len = sizeof(struct sockaddr_in);
#endif
	memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));

	ret = if_ioctl(SIOCAIFADDR, (caddr_t)&addreq);
	if (ret < 0)
		return ret;
	return 0;

}
Ejemplo n.º 10
0
/*
 * get interface metric
 *   -- if value is not avaliable set -1
 */
void
if_get_metric (struct interface *ifp)
{
#ifdef SIOCGIFMETRIC
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0) 
    return;
  ifp->metric = ifreq.ifr_metric;
  if (ifp->metric == 0)
    ifp->metric = 1;
#else /* SIOCGIFMETRIC */
  ifp->metric = -1;
#endif /* SIOCGIFMETRIC */
}
Ejemplo n.º 11
0
/*
 * get interface metric
 *   -- if value is not avaliable set -1
 */
void if_get_metric (struct interface *ifp)
{
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0)
	{
		return;
	}
	ifp->metric = ifreq.ifr_metric;
	if (ifp->metric == 0)
	{
		ifp->metric = 1;
	}
	return;
}
Ejemplo n.º 12
0
/* get interface flags */
void
if_get_flags (struct interface *ifp)
{
  int ret;
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      perror ("ioctl");
      return;
    }

  ifp->flags = ifreq.ifr_flags & 0x0000ffff;
}
Ejemplo n.º 13
0
/* get interface MTU */
void if_get_mtu (struct interface *ifp)
{
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0)
	{
		zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)");
					ifp->mtu6 = ifp->mtu = -1;
		return;
	}

	ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;

	/* propogate */
	zebra_interface_up_update(ifp);
}
Ejemplo n.º 14
0
/* Unset interface's flag. */
int
if_unset_flags (struct interface *ifp, unsigned long flags)
{
  int ret;
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  ifreq.ifr_flags = ifp->flags;
  ifreq.ifr_flags &= ~flags;

  ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq);

  if (ret < 0)
    {
      zlog_info ("can't unset interface flags");
      return ret;
    }
  return 0;
}
Ejemplo n.º 15
0
/* Unset interface's flag. */
int if_unset_flags (struct interface *ifp, uint64_t flags)
{
	int ret = 0;
	struct ifreq ifreq;

	memset (&ifreq, 0, sizeof(struct ifreq));
	ifreq_set_name (&ifreq, ifp);

	ifreq.ifr_flags = ifp->flags;
	ifreq.ifr_flags &= ~flags;

	ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq);

	if (ret < 0)
	{
		zlog_info ("can't unset interface flags");
		return ret;
	}
	return 0;
}
Ejemplo n.º 16
0
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int
if_unset_prefix (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct ifreq ifreq;
  struct sockaddr_in addr;
  struct prefix_ipv4 *p;

  p = (struct prefix_ipv4 *) ifc->address;

  ifreq_set_name (&ifreq, ifp);

  memset (&addr, 0, sizeof (struct sockaddr_in));
  addr.sin_family = p->family;
  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in));
  ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq);
  if (ret < 0)
    return ret;

  return 0;
}
Ejemplo n.º 17
0
Archivo: ioctl.c Proyecto: ton31337/frr
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx)
{
	int ret;
	struct ifreq ifreq;
	struct sockaddr_in addr;
	struct prefix_ipv4 *p;

	p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);

	strlcpy(ifreq.ifr_name, dplane_ctx_get_ifname(ctx),
		sizeof(ifreq.ifr_name));

	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = p->family;
	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq);
	if (ret < 0)
		return ret;

	return 0;
}
Ejemplo n.º 18
0
/* Get interface's index by ioctl. */
int
if_get_index (struct interface *ifp)
{
  static int if_fake_index = 1;

#ifdef HAVE_BROKEN_ALIASES
  /* Linux 2.2.X does not provide individual interface index for aliases. */
  ifp->ifindex = if_fake_index++;
  return ifp->ifindex;
#else
#ifdef SIOCGIFINDEX
  int ret;
  struct ifreq ifreq;

  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
  return ifp->ifindex;

#else
  ifp->ifindex = if_fake_index++;
  return ifp->ifindex;
#endif /* SIOCGIFINDEX */
#endif /* HAVE_BROKEN_ALIASES */
}
Ejemplo n.º 19
0
/* 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;
}
Ejemplo n.º 20
0
int vrf_if_ioctl(unsigned long request, caddr_t buffer, vrf_id_t vrf_id)
{
	return if_ioctl(request, buffer);
}
Ejemplo n.º 21
0
/* Retrieve address information for the given ifp */
static int
if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label)
{
  int ret;
  struct lifreq lifreq;
  struct sockaddr_storage mask, dest;
  char *dest_pnt = NULL;
  u_char prefixlen = 0;
  afi_t af;
  int flags = 0;

  /* Interface's name and address family.
   * We need to use the logical interface name / label, if we've been
   * given one, in order to get the right address
   */
  strncpy (lifreq.lifr_name, (label ? label : ifp->name), IFNAMSIZ);

  /* Interface's address. */
  memcpy (&lifreq.lifr_addr, addr, ADDRLEN (addr));
  af = addr->sa_family;

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

  if (AF_IOCTL (af, SIOCGLIFDSTADDR, (caddr_t) & lifreq) >= 0)
    {
      memcpy (&dest, &lifreq.lifr_dstaddr, ADDRLEN (addr));
      if (af == AF_INET)
        dest_pnt = (char *) &(SIN (&dest)->sin_addr);
      else
        dest_pnt = (char *) &(SIN6 (&dest)->sin6_addr);
      flags = ZEBRA_IFA_PEER;
    }

  if (af == AF_INET)
    {
      ret = if_ioctl (SIOCGLIFNETMASK, (caddr_t) & lifreq);
      
      if (ret < 0)
        {
          if (errno != EADDRNOTAVAIL)
            {
              zlog_warn ("SIOCGLIFNETMASK (%s) fail: %s", ifp->name,
                         safe_strerror (errno));
              return ret;
            }
          return 0;
        }
      memcpy (&mask, &lifreq.lifr_addr, ADDRLEN (addr));

      prefixlen = ip_masklen (SIN (&mask)->sin_addr);
      if (!dest_pnt && (if_ioctl (SIOCGLIFBRDADDR, (caddr_t) & lifreq) >= 0))
	{
          memcpy (&dest, &lifreq.lifr_broadaddr, sizeof (struct sockaddr_in));
          dest_pnt = (char *) &SIN (&dest)->sin_addr;
        }
    }
#ifdef HAVE_IPV6
  else if (af == AF_INET6)
    {
      if (if_ioctl_ipv6 (SIOCGLIFSUBNET, (caddr_t) & lifreq) < 0)
	{
	  if (ifp->flags & IFF_POINTOPOINT)
	    prefixlen = IPV6_MAX_BITLEN;
	  else
	    zlog_warn ("SIOCGLIFSUBNET (%s) fail: %s",
		       ifp->name, safe_strerror (errno));
	}
      else
	{
	  prefixlen = lifreq.lifr_addrlen;
	}
    }
#endif /* HAVE_IPV6 */

  /* Set address to the interface. */
  if (af == AF_INET)
    connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen,
                        (struct in_addr *) dest_pnt, label);
#ifdef HAVE_IPV6
  else if (af == AF_INET6)
    connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen,
                        (struct in6_addr *) dest_pnt, label);
#endif /* HAVE_IPV6 */

  return 0;
}