예제 #1
0
static int
open_packet_socket (struct isis_circuit *circuit)
{
  struct sockaddr_ll s_addr;
  int fd, retval = ISIS_OK;

  fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
  if (fd < 0)
    {
      zlog_warn ("open_packet_socket(): socket() failed %s",
		 safe_strerror (errno));
      return ISIS_WARNING;
    }

  /*
   * Bind to the physical interface
   */
  memset (&s_addr, 0, sizeof (struct sockaddr_ll));
  s_addr.sll_family = AF_PACKET;
  s_addr.sll_protocol = htons (ETH_P_ALL);
  s_addr.sll_ifindex = circuit->interface->ifindex;

  if (bind (fd, (struct sockaddr *) (&s_addr),
	    sizeof (struct sockaddr_ll)) < 0)
    {
      zlog_warn ("open_packet_socket(): bind() failed: %s", safe_strerror (errno));
      close (fd);
      return ISIS_WARNING;
    }

  circuit->fd = fd;

  if (if_is_broadcast (circuit->interface))
    {
      /*
       * Join to multicast groups
       * according to
       * 8.4.2 - Broadcast subnetwork IIH PDUs
       * FIXME: is there a case only one will fail??
       */
      /* joining ALL_L1_ISS */
      retval |= isis_multicast_join (circuit->fd, 1,
                                      circuit->interface->ifindex);
      /* joining ALL_L2_ISS */
      retval |= isis_multicast_join (circuit->fd, 2,
                                      circuit->interface->ifindex);
      /* joining ALL_ISS (used in RFC 5309 p2p-over-lan as well) */
      retval |= isis_multicast_join (circuit->fd, 3,
                                    circuit->interface->ifindex);
    }
  else
    {
      retval =
        isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
    }

  return retval;
}
예제 #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);
}
/* Send RIP request packet to specified interface. */
static void
rip_request_interface_send (struct interface *ifp, u_char version)
{
  struct sockaddr_in to;

  /* RIPv2 support multicast. */
  if (version == RIPv2 && if_is_multicast (ifp))
    {
      
      if (IS_RIP_DEBUG_EVENT)
	zlog_debug ("multicast request on %s", ifp->name);

      rip_request_send (NULL, ifp, version, NULL);
      return;
    }

  /* RIPv1 and non multicast interface. */
  if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
    {
      struct listnode *cnode, *cnnode;
      struct connected *connected;

      if (IS_RIP_DEBUG_EVENT)
	zlog_debug ("broadcast request to %s", ifp->name);

      for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
	{
	  if (connected->address->family == AF_INET)
	    {
	      memset (&to, 0, sizeof (struct sockaddr_in));
	      to.sin_port = htons (RIP_PORT_DEFAULT);
              if (connected->destination)
                /* use specified broadcast or peer destination addr */
                to.sin_addr = connected->destination->u.prefix4;
              else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
	        /* calculate the appropriate broadcast address */
                to.sin_addr.s_addr =
		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
				      connected->address->prefixlen);
	      else
		/* do not know where to send the packet */
	        continue;

	      if (IS_RIP_DEBUG_EVENT)
		zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
	      
	      rip_request_send (&to, ifp, version, connected);
	    }
	}
    }
}
예제 #4
0
/* Interface address modification. */
int
netlink_address (int cmd, int family, struct interface *ifp,
                 struct connected *ifc)
{
    int bytelen;
    struct prefix *p;

    struct
    {
        struct nlmsghdr n;
        struct ifaddrmsg ifa;
        char buf[1024];
    } req;

    p = ifc->address;
    memset (&req, 0, sizeof req);

    bytelen = (family == AF_INET ? 4 : 16);

    req.n.nlmsg_len = NLMSG_LENGTH (sizeof(struct ifaddrmsg));
    req.n.nlmsg_flags = NLM_F_REQUEST;
    req.n.nlmsg_type = cmd;
    req.ifa.ifa_family = family;

    req.ifa.ifa_index = ifp->ifindex;
    req.ifa.ifa_prefixlen = p->prefixlen;

    addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);

    if (family == AF_INET && cmd == RTM_NEWADDR)
    {
        if (if_is_broadcast (ifp) && ifc->destination)
        {
            p = ifc->destination;
            addattr_l(&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix, bytelen);
        }
    }

    if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
        SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);

    if (ifc->label)
        addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
                   strlen (ifc->label) + 1);

    return netlink_talk (&req.n, &netlink_cmd);
}
예제 #5
0
/*
 * Create the socket and set the tx/rx funcs
 */
int
isis_sock_init (struct isis_circuit *circuit)
{
  int retval = ISIS_OK;

  if (isisd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));

  retval = open_packet_socket (circuit);

  if (retval != ISIS_OK)
    {
      zlog_warn ("%s: could not initialize the socket", __func__);
      goto end;
    }

  /* Assign Rx and Tx callbacks are based on real if type */
  if (if_is_broadcast (circuit->interface))
    {
      circuit->tx = isis_send_pdu_bcast;
      circuit->rx = isis_recv_pdu_bcast;
    }
  else if (if_is_pointopoint (circuit->interface))
    {
      circuit->tx = isis_send_pdu_p2p;
      circuit->rx = isis_recv_pdu_p2p;
    }
  else
    {
      zlog_warn ("isis_sock_init(): unknown circuit type");
      retval = ISIS_WARNING;
      goto end;
    }

end:
  if (isisd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));

  return retval;
}
예제 #6
0
/* show specified interface structure */
static int
ospf6_interface_show (struct vty *vty, struct interface *ifp)
{
  struct ospf6_interface *oi;
  struct connected *c;
  struct prefix *p;
  struct listnode *i;
  char strbuf[64], drouter[32], bdrouter[32];
  const char *updown[3] = {"down", "up", NULL};
  const char *type;
  struct timeval res, now;
  char duration[32];
  struct ospf6_lsa *lsa;

  /* check physical interface type */
  if (if_is_loopback (ifp))
    type = "LOOPBACK";
  else if (if_is_broadcast (ifp))
    type = "BROADCAST";
  else if (if_is_pointopoint (ifp))
    type = "POINTOPOINT";
  else
    type = "UNKNOWN";

  vty_out (vty, "%s is %s, type %s%s",
           ifp->name, updown[if_is_up (ifp)], type,
	   VNL);
  vty_out (vty, "  Interface ID: %d%s", ifp->ifindex, VNL);

  if (ifp->info == NULL)
    {
      vty_out (vty, "   OSPF not enabled on this interface%s", VNL);
      return 0;
    }
  else
    oi = (struct ospf6_interface *) ifp->info;

  vty_out (vty, "  Internet Address:%s", VNL);

  for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c))
    {
      p = c->address;
      prefix2str (p, strbuf, sizeof (strbuf));
      switch (p->family)
        {
        case AF_INET:
          vty_out (vty, "    inet : %s%s", strbuf,
		   VNL);
          break;
        case AF_INET6:
          vty_out (vty, "    inet6: %s%s", strbuf,
		   VNL);
          break;
        default:
          vty_out (vty, "    ???  : %s%s", strbuf,
		   VNL);
          break;
        }
    }

  if (oi->area)
    {
      vty_out (vty, "  Instance ID %d, Interface MTU %d (autodetect: %d)%s",
	       oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
      vty_out (vty, "  MTU mismatch detection: %s%s", oi->mtu_ignore ?
	       "disabled" : "enabled", VNL);
      inet_ntop (AF_INET, &oi->area->area_id,
                 strbuf, sizeof (strbuf));
      vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf, oi->cost,
	       VNL);
    }
  else
    vty_out (vty, "  Not Attached to Area%s", VNL);

  vty_out (vty, "  State %s, Transmit Delay %d sec, Priority %d%s",
           ospf6_interface_state_str[oi->state],
           oi->transdelay, oi->priority,
	   VNL);
  vty_out (vty, "  Timer intervals configured:%s", VNL);
  vty_out (vty, "   Hello %d, Dead %d, Retransmit %d%s",
           oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
	   VNL);

  inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
  inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
  vty_out (vty, "  DR: %s BDR: %s%s", drouter, bdrouter, VNL);

  vty_out (vty, "  Number of I/F scoped LSAs is %u%s",
           oi->lsdb->count, VNL);

  bane_gettime (BANE_CLK_MONOTONIC, &now);

  timerclear (&res);
  if (oi->thread_send_lsupdate)
    timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
           oi->lsupdate_list->count, duration,
           (oi->thread_send_lsupdate ? "on" : "off"),
           VNL);
  for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VNL);

  timerclear (&res);
  if (oi->thread_send_lsack)
    timersub (&oi->thread_send_lsack->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
           oi->lsack_list->count, duration,
           (oi->thread_send_lsack ? "on" : "off"),
           VNL);
  for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VNL);

  return 0;
}