Esempio n. 1
0
static void ospf_router_lsa_dump(struct stream *s, uint16_t length)
{
	char buf[BUFSIZ];
	struct router_lsa *rl;
	int i, len;

	rl = (struct router_lsa *)stream_pnt(s);

	zlog_debug("  Router-LSA");
	zlog_debug("    flags %s",
		   ospf_router_lsa_flags_dump(rl->flags, buf, BUFSIZ));
	zlog_debug("    # links %d", ntohs(rl->links));

	len = ntohs(rl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
	for (i = 0; len > 0; i++) {
		zlog_debug("    Link ID %s", inet_ntoa(rl->link[i].link_id));
		zlog_debug("    Link Data %s",
			   inet_ntoa(rl->link[i].link_data));
		zlog_debug("    Type %d", (uint8_t)rl->link[i].type);
		zlog_debug("    TOS %d", (uint8_t)rl->link[i].tos);
		zlog_debug("    metric %d", ntohs(rl->link[i].metric));

		len -= 12;
	}
}
Esempio n. 2
0
static void ospf_packet_db_desc_dump(struct stream *s, uint16_t length)
{
	struct ospf_db_desc *dd;
	char dd_flags[8];

	uint32_t gp;

	gp = stream_get_getp(s);
	dd = (struct ospf_db_desc *)stream_pnt(s);

	zlog_debug("Database Description");
	zlog_debug("  Interface MTU %d", ntohs(dd->mtu));
	zlog_debug("  Options %d (%s)", dd->options,
		   ospf_options_dump(dd->options));
	zlog_debug("  Flags %d (%s)", dd->flags,
		   ospf_dd_flags_dump(dd->flags, dd_flags, sizeof dd_flags));
	zlog_debug("  Sequence Number 0x%08lx",
		   (unsigned long)ntohl(dd->dd_seqnum));

	length -= OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE;

	stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE);

	ospf_lsa_header_list_dump(s, length);

	stream_set_getp(s, gp);
}
Esempio n. 3
0
File: zserv.c Progetto: OPSF/uClinux
void
zebra_read_ipv6 (int command, struct zserv *client, u_short length)
{
  u_char type;
  u_char flags;
  struct in6_addr nexthop, *gate;
  u_char *lim;
  u_char *pnt;
  unsigned int ifindex;

  pnt = stream_pnt (client->ibuf);
  lim = pnt + length;

  type = stream_getc (client->ibuf);
  flags = stream_getc (client->ibuf);
  stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr));
  
  while (stream_pnt (client->ibuf) < lim)
    {
      int size;
      struct prefix_ipv6 p;
      
      ifindex = stream_getl (client->ibuf);

      memset (&p, 0, sizeof (struct prefix_ipv6));
      p.family = AF_INET6;
      p.prefixlen = stream_getc (client->ibuf);
      size = PSIZE(p.prefixlen);
      stream_get (&p.prefix, client->ibuf, size);

      if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
        gate = NULL;
      else
        gate = &nexthop;

      if (command == ZEBRA_IPV6_ROUTE_ADD)
        rib_add_ipv6 (type, flags, &p, gate, ifindex, 0, 0, 0);
      else
        rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0);
    }
}
Esempio n. 4
0
static void ospf_lsa_header_list_dump(struct stream *s, uint16_t length)
{
	struct lsa_header *lsa;

	zlog_debug("  # LSA Headers %d", length / OSPF_LSA_HEADER_SIZE);

	/* LSA Headers. */
	while (length > 0) {
		lsa = (struct lsa_header *)stream_pnt(s);
		ospf_lsa_header_dump(lsa);

		stream_forward_getp(s, OSPF_LSA_HEADER_SIZE);
		length -= OSPF_LSA_HEADER_SIZE;
	}
}
Esempio n. 5
0
static void ospf_summary_lsa_dump(struct stream *s, uint16_t length)
{
	struct summary_lsa *sl;
	int size;
	int i;

	sl = (struct summary_lsa *)stream_pnt(s);

	zlog_debug("  Summary-LSA");
	zlog_debug("    Network Mask %s", inet_ntoa(sl->mask));

	size = ntohs(sl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
	for (i = 0; size > 0; size -= 4, i++)
		zlog_debug("    TOS=%d metric %d", sl->tos,
			   GET_METRIC(sl->metric));
}
Esempio n. 6
0
static void ospf_network_lsa_dump(struct stream *s, uint16_t length)
{
	struct network_lsa *nl;
	int i, cnt;

	nl = (struct network_lsa *)stream_pnt(s);
	cnt = (ntohs(nl->header.length) - (OSPF_LSA_HEADER_SIZE + 4)) / 4;

	zlog_debug("  Network-LSA");
	/*
	zlog_debug ("LSA total size %d", ntohs (nl->header.length));
	zlog_debug ("Network-LSA size %d",
	ntohs (nl->header.length) - OSPF_LSA_HEADER_SIZE);
	*/
	zlog_debug("    Network Mask %s", inet_ntoa(nl->mask));
	zlog_debug("    # Attached Routers %d", cnt);
	for (i = 0; i < cnt; i++)
		zlog_debug("      Attached Router %s",
			   inet_ntoa(nl->routers[i]));
}
Esempio n. 7
0
void ospf_packet_dump(struct stream *s)
{
	struct ospf_header *ospfh;
	unsigned long gp;

	/* Preserve pointer. */
	gp = stream_get_getp(s);

	/* OSPF Header dump. */
	ospfh = (struct ospf_header *)stream_pnt(s);

	/* Until detail flag is set, return. */
	if (!(term_debug_ospf_packet[ospfh->type - 1] & OSPF_DEBUG_DETAIL))
		return;

	/* Show OSPF header detail. */
	ospf_header_dump(ospfh);
	stream_forward_getp(s, OSPF_HEADER_SIZE);

	switch (ospfh->type) {
	case OSPF_MSG_HELLO:
		ospf_packet_hello_dump(s, ntohs(ospfh->length));
		break;
	case OSPF_MSG_DB_DESC:
		ospf_packet_db_desc_dump(s, ntohs(ospfh->length));
		break;
	case OSPF_MSG_LS_REQ:
		ospf_packet_ls_req_dump(s, ntohs(ospfh->length));
		break;
	case OSPF_MSG_LS_UPD:
		ospf_packet_ls_upd_dump(s, ntohs(ospfh->length));
		break;
	case OSPF_MSG_LS_ACK:
		ospf_packet_ls_ack_dump(s, ntohs(ospfh->length));
		break;
	default:
		break;
	}

	stream_set_getp(s, gp);
}
Esempio n. 8
0
static void ospf_as_external_lsa_dump(struct stream *s, uint16_t length)
{
	struct as_external_lsa *al;
	int size;
	int i;

	al = (struct as_external_lsa *)stream_pnt(s);
	zlog_debug("  %s", ospf_lsa_type_msg[al->header.type].str);
	zlog_debug("    Network Mask %s", inet_ntoa(al->mask));

	size = ntohs(al->header.length) - OSPF_LSA_HEADER_SIZE - 4;
	for (i = 0; size > 0; size -= 12, i++) {
		zlog_debug("    bit %s TOS=%d metric %d",
			   IS_EXTERNAL_METRIC(al->e[i].tos) ? "E" : "-",
			   al->e[i].tos & 0x7f, GET_METRIC(al->e[i].metric));
		zlog_debug("    Forwarding address %s",
			   inet_ntoa(al->e[i].fwd_addr));
		zlog_debug("    External Route Tag %" ROUTE_TAG_PRI,
			   al->e[i].route_tag);
	}
}
Esempio n. 9
0
static void
print_stream (struct stream *s)
{
  size_t getp = stream_get_getp (s);
  
  printf ("endp: %zu, readable: %zu, writeable: %zu\n",
          stream_get_endp (s),
          STREAM_READABLE (s),
          STREAM_WRITEABLE (s));
  
  while (STREAM_READABLE (s))
    {
      printf ("0x%x ", *stream_pnt (s));
      stream_forward_getp (s, 1);
    }
  
  printf ("\n");
  
  /* put getp back to where it was */
  stream_set_getp (s, getp);
}
Esempio n. 10
0
static void ospf_packet_hello_dump(struct stream *s, uint16_t length)
{
	struct ospf_hello *hello;
	int i;

	hello = (struct ospf_hello *)stream_pnt(s);

	zlog_debug("Hello");
	zlog_debug("  NetworkMask %s", inet_ntoa(hello->network_mask));
	zlog_debug("  HelloInterval %d", ntohs(hello->hello_interval));
	zlog_debug("  Options %d (%s)", hello->options,
		   ospf_options_dump(hello->options));
	zlog_debug("  RtrPriority %d", hello->priority);
	zlog_debug("  RtrDeadInterval %ld",
		   (unsigned long)ntohl(hello->dead_interval));
	zlog_debug("  DRouter %s", inet_ntoa(hello->d_router));
	zlog_debug("  BDRouter %s", inet_ntoa(hello->bd_router));

	length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE;
	zlog_debug("  # Neighbors %d", length / 4);
	for (i = 0; length > 0; i++, length -= sizeof(struct in_addr))
		zlog_debug("    Neighbor %s", inet_ntoa(hello->neighbors[i]));
}
Esempio n. 11
0
static void ospf_packet_ls_upd_dump(struct stream *s, uint16_t length)
{
	uint32_t sp;
	struct lsa_header *lsa;
	int lsa_len;
	uint32_t count;

	length -= OSPF_HEADER_SIZE;

	sp = stream_get_getp(s);

	count = stream_getl(s);
	length -= 4;

	zlog_debug("Link State Update");
	zlog_debug("  # LSAs %d", count);

	while (length > 0 && count > 0) {
		if (length < OSPF_HEADER_SIZE || length % 4 != 0) {
			zlog_debug("  Remaining %d bytes; Incorrect length.",
				   length);
			break;
		}

		lsa = (struct lsa_header *)stream_pnt(s);
		lsa_len = ntohs(lsa->length);
		ospf_lsa_header_dump(lsa);

		switch (lsa->type) {
		case OSPF_ROUTER_LSA:
			ospf_router_lsa_dump(s, length);
			break;
		case OSPF_NETWORK_LSA:
			ospf_network_lsa_dump(s, length);
			break;
		case OSPF_SUMMARY_LSA:
		case OSPF_ASBR_SUMMARY_LSA:
			ospf_summary_lsa_dump(s, length);
			break;
		case OSPF_AS_EXTERNAL_LSA:
			ospf_as_external_lsa_dump(s, length);
			break;
		case OSPF_AS_NSSA_LSA:
			ospf_as_external_lsa_dump(s, length);
			break;
		case OSPF_OPAQUE_LINK_LSA:
		case OSPF_OPAQUE_AREA_LSA:
		case OSPF_OPAQUE_AS_LSA:
			ospf_opaque_lsa_dump(s, length);
			break;
		default:
			break;
		}

		stream_forward_getp(s, lsa_len);
		length -= lsa_len;
		count--;
	}

	stream_set_getp(s, sp);
}
Esempio n. 12
0
/**
 * Parse given capability.
 * XXX: This is reading into a stream, but not using stream API
 *
 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
 *                           capabilities were encountered.
 */
static int
bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
		      u_char **error)
{
  int ret;
  struct stream *s = BGP_INPUT (peer);
  size_t end = stream_get_getp (s) + length;
  
  assert (STREAM_READABLE (s) >= length);
  
  while (stream_get_getp (s) < end)
    {
      size_t start;
      u_char *sp = stream_pnt (s);
      struct capability_header caphdr;
      
      /* We need at least capability code and capability length. */
      if (stream_get_getp(s) + 2 > end)
	{
	  zlog_info ("%s Capability length error (< header)", peer->host);
	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
	  return -1;
	}
      
      caphdr.code = stream_getc (s);
      caphdr.length = stream_getc (s);
      start = stream_get_getp (s);
      
      /* Capability length check sanity check. */
      if (start + caphdr.length > end)
	{
	  zlog_info ("%s Capability length error (< length)", peer->host);
	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
	  return -1;
	}
      
      if (BGP_DEBUG (normal, NORMAL))
	zlog_debug ("%s OPEN has %s capability (%u), length %u",
		   peer->host,
		   LOOKUP (capcode_str, caphdr.code),
		   caphdr.code, caphdr.length);
      
      /* Length sanity check, type-specific, for known capabilities */
      switch (caphdr.code)
        {
          case CAPABILITY_CODE_MP:
          case CAPABILITY_CODE_REFRESH:
          case CAPABILITY_CODE_REFRESH_OLD:
          case CAPABILITY_CODE_ORF:
          case CAPABILITY_CODE_ORF_OLD:
          case CAPABILITY_CODE_RESTART:
          case CAPABILITY_CODE_AS4:
          case CAPABILITY_CODE_DYNAMIC:
              /* Check length. */
              if (caphdr.length < cap_minsizes[caphdr.code])
                {
                  zlog_info ("%s %s Capability length error: got %u,"
                             " expected at least %u",
                             peer->host, 
                             LOOKUP (capcode_str, caphdr.code),
                             caphdr.length, 
			     (unsigned) cap_minsizes[caphdr.code]);
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                  return -1;
                }
          /* we deliberately ignore unknown codes, see below */
          default:
            break;
        }
      
      switch (caphdr.code)
        {
          case CAPABILITY_CODE_MP:
            {
	      *mp_capability = 1;

              /* Ignore capability when override-capability is set. */
              if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
                {
                  /* Set negotiated value. */
                  ret = bgp_capability_mp (peer, &caphdr);

                  /* Unsupported Capability. */
                  if (ret < 0)
                    {
                      /* Store return data. */
                      memcpy (*error, sp, caphdr.length + 2);
                      *error += caphdr.length + 2;
                    }
                }
            }
            break;
          case CAPABILITY_CODE_REFRESH:
          case CAPABILITY_CODE_REFRESH_OLD:
            {
              /* BGP refresh capability */
              if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
                SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
              else
                SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
            }
            break;
          case CAPABILITY_CODE_ORF:
          case CAPABILITY_CODE_ORF_OLD:
            if (bgp_capability_orf (peer, &caphdr))
              return -1;
            break;
          case CAPABILITY_CODE_RESTART:
            if (bgp_capability_restart (peer, &caphdr))
              return -1;
            break;
          case CAPABILITY_CODE_DYNAMIC:
            SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
            break;
          case CAPABILITY_CODE_AS4:
              /* Already handled as a special-case parsing of the capabilities
               * at the beginning of OPEN processing. So we care not a jot
               * for the value really, only error case.
               */
              if (!bgp_capability_as4 (peer, &caphdr))
                return -1;
              break;            
          default:
            if (caphdr.code > 128)
              {
                /* We don't send Notification for unknown vendor specific
                   capabilities.  It seems reasonable for now...  */
                zlog_warn ("%s Vendor specific capability %d",
                           peer->host, caphdr.code);
              }
            else
              {
                zlog_warn ("%s unrecognized capability code: %d - ignored",
                           peer->host, caphdr.code);
                memcpy (*error, sp, caphdr.length + 2);
                *error += caphdr.length + 2;
              }
          }
      if (stream_get_getp(s) != (start + caphdr.length))
        {
          if (stream_get_getp(s) > (start + caphdr.length))
            zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
                       peer->host, LOOKUP (capcode_str, caphdr.code),
                       caphdr.length);
          stream_set_getp (s, start + caphdr.length);
        }
    }
  return 0;
}
Esempio n. 13
0
/* Parse open option */
int
bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
{
  int ret;
  u_char *end;
  u_char opt_type;
  u_char opt_length;
  u_char *pnt;
  u_char *error;
  u_char error_data[BGP_MAX_PACKET_SIZE];

  /* Fetch pointer. */
  pnt = stream_pnt (peer->ibuf);

  ret = 0;
  opt_type = 0;
  opt_length = 0;
  end = pnt + length;
  error = error_data;

  if (BGP_DEBUG (normal, NORMAL))
    zlog_info ("%s rcv OPEN w/ OPTION parameter len: %u",
	       peer->host, length);
  
  while (pnt < end) 
    {
      /* Check the length. */
      if (pnt + 2 > end)
	{
	  zlog_info ("%s Option length error", peer->host);
	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
	  return -1;
	}

      /* Fetch option type and length. */
      opt_type = *pnt++;
      opt_length = *pnt++;
      
      /* Option length check. */
      if (pnt + opt_length > end)
	{
	  zlog_info ("%s Option length error", peer->host);
	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
	  return -1;
	}

      if (BGP_DEBUG (normal, NORMAL))
	zlog_info ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
		   peer->host, opt_type,
		   opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
		   opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
		   opt_length);
  
      switch (opt_type)
	{
	case BGP_OPEN_OPT_AUTH:
	  ret = bgp_auth_parse (peer, pnt, opt_length);
	  break;
	case BGP_OPEN_OPT_CAP:
	  ret = bgp_capability_parse (peer, pnt, opt_length, &error);
	  *capability = 1;
	  break;
	default:
	  bgp_notify_send (peer, 
			   BGP_NOTIFY_OPEN_ERR, 
			   BGP_NOTIFY_OPEN_UNSUP_PARAM); 
	  ret = -1;
	  break;
	}

      /* Parse error.  To accumulate all unsupported capability codes,
         bgp_capability_parse does not return -1 when encounter
         unsupported capability code.  To detect that, please check
         error and erro_data pointer, like below.  */
      if (ret < 0)
	return -1;

      /* Forward pointer. */
      pnt += opt_length;
    }

  /* All OPEN option is parsed.  Check capability when strict compare
     flag is enabled.*/
  if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
    {
      /* If Unsupported Capability exists. */
      if (error != error_data)
	{
	  bgp_notify_send_with_data (peer, 
				     BGP_NOTIFY_OPEN_ERR, 
				     BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
				     error_data, error - error_data);
	  return -1;
	}

      /* Check local capability does not negotiated with remote
         peer. */
      if (! strict_capability_same (peer))
	{
	  bgp_notify_send (peer, 
			   BGP_NOTIFY_OPEN_ERR, 
			   BGP_NOTIFY_OPEN_UNSUP_CAPBL);
	  return -1;
	}
    }

  /* Check there is no common capability send Unsupported Capability
     error. */
  if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
    {
      if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] 
	  && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
	  && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
	  && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
	  && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
	{
	  plog_err (peer->log, "%s [Error] No common capability", peer->host);

	  if (error != error_data)

	    bgp_notify_send_with_data (peer, 
				       BGP_NOTIFY_OPEN_ERR, 
				       BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
				       error_data, error - error_data);
	  else
	    bgp_notify_send (peer, 
			     BGP_NOTIFY_OPEN_ERR, 
			     BGP_NOTIFY_OPEN_UNSUP_CAPBL);
	  return -1;
	}
    }
  return 0;
}