Esempio n. 1
0
static int
trie_node_same(struct f_trie_node *t1, struct f_trie_node *t2)
{
  if ((t1 == NULL) && (t2 == NULL))
    return 1;

  if ((t1 == NULL) || (t2 == NULL))
    return 0;

  if ((t1->plen != t2->plen) ||
      (! ipa_equal(t1->addr, t2->addr)) ||
      (! ipa_equal(t1->accept, t2->accept)))
    return 0;

  return trie_node_same(t1->c[0], t2->c[0]) && trie_node_same(t1->c[1], t2->c[1]);
}
Esempio n. 2
0
File: locks.c Progetto: BIRD/bird
static inline int
olock_same(struct object_lock *x, struct object_lock *y)
{
  return
    x->type == y->type &&
    x->iface == y->iface &&
    x->vrf == y->vrf &&
    x->port == y->port &&
    x->inst == y->inst &&
    ipa_equal(x->addr, y->addr);
}
Esempio n. 3
0
File: bgp.c Progetto: deepfield/bird
/**
 * bgp_incoming_connection - handle an incoming connection
 * @sk: TCP socket
 * @dummy: unused
 *
 * This function serves as a socket hook for accepting of new BGP
 * connections. It searches a BGP instance corresponding to the peer
 * which has connected and if such an instance exists, it creates a
 * &bgp_conn structure, attaches it to the instance and either sends
 * an Open message or (if there already is an active connection) it
 * closes the new connection by sending a Notification message.
 */
static int
bgp_incoming_connection(sock *sk, int dummy UNUSED)
{
  struct proto_config *pc;

  DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
  WALK_LIST(pc, config->protos)
    if (pc->protocol == &proto_bgp && pc->proto)
      {
	struct bgp_proto *p = (struct bgp_proto *) pc->proto;
	if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
	    (!ipa_has_link_scope(sk->daddr) || (p->cf->iface == sk->iface)))
	  {
	    /* We are in proper state and there is no other incoming connection */
	    int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
	      (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);

	    if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
	    {
	      bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
	      bgp_handle_graceful_restart(p);
	      bgp_conn_enter_idle_state(p->conn);
	      acc = 1;
	    }

	    BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
		      sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL,
		      sk->dport, acc ? "accepted" : "rejected");

	    if (!acc)
	      goto reject;

	    int hops = p->cf->multihop ? : 1;

	    if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
	      goto err;

	    if (p->cf->ttl_security)
	      if (sk_set_min_ttl(sk, 256 - hops) < 0)
		goto err;

	    bgp_setup_conn(p, &p->incoming_conn);
	    bgp_setup_sk(&p->incoming_conn, sk);
	    bgp_send_open(&p->incoming_conn);
	    return 0;

	  err:
	    sk_log_error(sk, p->p.name);
	    log(L_ERR "%s: Incoming connection aborted", p->p.name);
	    rfree(sk);
	    return 0;
	  }
      }
Esempio n. 4
0
/**
 * bgp_find_proto - find existing proto for incoming connection
 * @sk: TCP socket
 *
 */
static struct bgp_proto *
bgp_find_proto(sock *sk)
{
  struct proto_config *pc;

  WALK_LIST(pc, config->protos)
    if ((pc->protocol == &proto_bgp) && pc->proto)
      {
	struct bgp_proto *p = (struct bgp_proto *) pc->proto;
	if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
	    (!ipa_is_link_local(sk->daddr) || (p->cf->iface == sk->iface)))
	  return p;
      }

  return NULL;
}
Esempio n. 5
0
File: bgp.c Progetto: rogerhu/dd-wrt
/**
 * bgp_incoming_connection - handle an incoming connection
 * @sk: TCP socket
 * @dummy: unused
 *
 * This function serves as a socket hook for accepting of new BGP
 * connections. It searches a BGP instance corresponding to the peer
 * which has connected and if such an instance exists, it creates a
 * &bgp_conn structure, attaches it to the instance and either sends
 * an Open message or (if there already is an active connection) it
 * closes the new connection by sending a Notification message.
 */
static int
bgp_incoming_connection(sock *sk, int dummy UNUSED)
{
    struct proto_config *pc;

    DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
    WALK_LIST(pc, config->protos)
    if (pc->protocol == &proto_bgp && pc->proto)
    {
        struct bgp_proto *p = (struct bgp_proto *) pc->proto;
        if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
                (!ipa_has_link_scope(sk->daddr) || (p->cf->iface == sk->iface)))
        {
            /* We are in proper state and there is no other incoming connection */
            int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
                      (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);

            BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
                      sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL,
                      sk->dport, acc ? "accepted" : "rejected");

            if (!acc)
                goto err;

            int hops = p->cf->multihop ? : 1;
            if (p->cf->ttl_security)
            {
                /* TTL security support */
                if ((sk_set_ttl(sk, 255) < 0) ||
                        (sk_set_min_ttl(sk, 256 - hops) < 0))
                {
                    log(L_ERR "TTL security configuration failed, closing session");
                    goto err;
                }
            }
            else
                sk_set_ttl(sk, hops);

            bgp_setup_conn(p, &p->incoming_conn);
            bgp_setup_sk(&p->incoming_conn, sk);
            bgp_send_open(&p->incoming_conn);
            return 0;
        }
    }
Esempio n. 6
0
static void
scan_ifs(struct ifreq *r, int cnt)
{
  struct iface i, *pi;
  struct ifa a;
  char *err, *colon;
  unsigned fl;
  ip_addr netmask;
  int l, scope;
  sockaddr *sa;

  if_start_update();
  for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++)
    {
      int sec = 0;
      bzero(&i, sizeof(i));
      bzero(&a, sizeof(a));
      if (colon = strchr(r->ifr_name, ':'))
	{
	  /* It's an alias -- let's interpret it as a secondary interface address */
	  sec = 1;
	  *colon = 0;
	}
      strncpy(i.name, r->ifr_name, sizeof(i.name) - 1);

      if(ioctl(if_scan_sock, SIOCGIFADDR,r)<0) continue;

      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL, 1);
      if (ipa_nonzero(a.ip))
	{
	  l = ipa_classify(a.ip);
	  if (l < 0 || !(l & IADDR_HOST))
	    {
	      log(L_ERR "%s: Invalid interface address", i.name);
	      a.ip = IPA_NONE;
	    }
	  else
	    {
	      a.scope = l & IADDR_SCOPE_MASK;
	      if (a.scope == SCOPE_HOST)
		i.flags |= IF_LOOPBACK | IF_IGNORE;
	    }
	}

      if (ioctl(if_scan_sock, SIOCGIFFLAGS, r) < 0)
	{
	  err = "SIOCGIFFLAGS";
	faulty:
	  log(L_ERR "%s(%s): %m", err, i.name);
	bad:
	  i.flags = (i.flags & ~IF_LINK_UP) | IF_ADMIN_DOWN;
	  continue;
	}
      fl = r->ifr_flags;
      if (fl & IFF_UP)
	i.flags |= IF_LINK_UP;

      if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
	{ err = "SIOCGIFNETMASK"; goto faulty; }
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL, 0);
      l = ipa_mklen(netmask);
      if (l < 0 || l == 31)
	{
	  log(L_ERR "%s: Invalid netmask (%x)", i.name, netmask);
	  goto bad;
	}
      a.pxlen = l;

      if (fl & IFF_POINTOPOINT)
	{
	  a.flags |= IA_UNNUMBERED;
	  if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0)
	    { err = "SIOCGIFDSTADDR"; goto faulty; }
	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1);
	  a.prefix = a.opposite;
	  a.pxlen = BITS_PER_IP_ADDRESS;
	}
      else
	a.prefix = ipa_and(a.ip, ipa_mkmask(a.pxlen));
      if (fl & IFF_LOOPBACK)
	i.flags |= IF_LOOPBACK | IF_IGNORE;
      if (1
#ifndef CONFIG_ALL_MULTICAST
	  && (fl & IFF_MULTICAST)
#endif
#ifndef CONFIG_UNNUM_MULTICAST
	  && !(a.flags & IA_UNNUMBERED)
#endif
	 )
	i.flags |= IF_MULTICAST;

      scope = ipa_classify(a.ip);
      if (scope < 0)
	{
	  log(L_ERR "%s: Invalid address", i.name);
	  goto bad;
	}
      a.scope = scope & IADDR_SCOPE_MASK;

      if (a.pxlen < 32)
	{
	  a.brd = ipa_or(a.prefix, ipa_not(ipa_mkmask(a.pxlen)));
	  if (ipa_equal(a.ip, a.prefix) || ipa_equal(a.ip, a.brd))
	    {
	      log(L_ERR "%s: Using network or broadcast address for interface", i.name);
	      goto bad;
	    }
	  if (fl & IFF_BROADCAST)
	    i.flags |= IF_BROADCAST;
	  if (a.pxlen < 30)
	    i.flags |= IF_MULTIACCESS;
	  else
	    a.opposite = ipa_opposite(a.ip, a.pxlen);
	}
      else
	a.brd = a.opposite;
      a.scope = SCOPE_UNIVERSE;

      if (ioctl(if_scan_sock, SIOCGIFMTU, r) < 0)
	{ err = "SIOCGIFMTU"; goto faulty; }
      i.mtu = r->ifr_mtu;

#ifdef SIOCGIFINDEX
      if (ioctl(if_scan_sock, SIOCGIFINDEX, r) >= 0)
	i.index = r->ifr_ifindex;
      else if (errno != EINVAL)
	DBG("SIOCGIFINDEX failed: %m\n");
      else	/* defined, but not supported by the kernel */
#endif
      /*
       *  The kernel doesn't give us real ifindices, but we still need them
       *  at least for OSPF unnumbered links. So let's make them up ourselves.
       */
      if (pi = if_find_by_name(i.name))
	i.index = pi->index;
      else
	{
	  static int if_index_counter = 1;
	  i.index = if_index_counter++;
	}

      pi = NULL;
      if (sec)
	{
	  a.flags |= IA_SECONDARY;
	  pi = if_find_by_index(i.index);
	}
      if (!pi)
	pi = if_update(&i);
      a.iface = pi;
      ifa_update(&a);
    }
  if_end_update();
}