Exemple #1
0
static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length)
{
	uint32_t sp;
	uint32_t ls_type;
	struct in_addr ls_id;
	struct in_addr adv_router;

	sp = stream_get_getp(s);

	length -= OSPF_HEADER_SIZE;

	zlog_debug("Link State Request");
	zlog_debug("  # Requests %d", length / 12);

	for (; length > 0; length -= 12) {
		ls_type = stream_getl(s);
		ls_id.s_addr = stream_get_ipv4(s);
		adv_router.s_addr = stream_get_ipv4(s);

		zlog_debug("  LS type %d", ls_type);
		zlog_debug("  Link State ID %s", inet_ntoa(ls_id));
		zlog_debug("  Advertising Router %s", inet_ntoa(adv_router));
	}

	stream_set_getp(s, sp);
}
Exemple #2
0
static void
link_params_set_value(struct stream *s, struct if_link_params *iflp)
{
  
  if (iflp == NULL)
    return;
  
  iflp->lp_status = stream_getl (s);
  iflp->te_metric = stream_getl (s);
  iflp->max_bw = stream_getf (s);
  iflp->max_rsv_bw = stream_getf (s);
  uint32_t bwclassnum = stream_getl (s);
  {
    unsigned int i;
    for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
      iflp->unrsv_bw[i] = stream_getf (s);
    if (i < bwclassnum)
      zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
                " - outdated library?",
                __func__, bwclassnum, MAX_CLASS_TYPE);
  }
  iflp->admin_grp = stream_getl (s);
  iflp->rmt_as = stream_getl (s);
  iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
  
  iflp->av_delay = stream_getl (s);
  iflp->min_delay = stream_getl (s);
  iflp->max_delay = stream_getl (s);
  iflp->delay_var = stream_getl (s);
  
  iflp->pkt_loss = stream_getf (s);
  iflp->res_bw = stream_getf (s);
  iflp->ava_bw = stream_getf (s);
  iflp->use_bw = stream_getf (s);
}
Exemple #3
0
static int
attr_parse (struct stream *s, u_int16_t len)
{
  u_int flag;
  u_int type;
  u_int16_t length;
  u_int16_t lim;

  lim = s->getp + len;

  printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);

  while (s->getp < lim)
    {
      flag = stream_getc (s);
      type = stream_getc (s);

      if (flag & BGP_ATTR_FLAG_EXTLEN)
	length = stream_getw (s);
      else
	length = stream_getc (s);

      printf ("FLAG: %d\n", flag);
      printf ("TYPE: %d\n", type);
      printf ("Len: %d\n", length);

      switch (type)
	{
	case BGP_ATTR_ORIGIN:
	  {
	    u_char origin;
	    origin = stream_getc (s);
	    printf ("ORIGIN: %d\n", origin);
	  }
	  break;
	case BGP_ATTR_AS_PATH:
	  {
	    struct aspath *aspath;

	    aspath = aspath_parse (s, length, 1);
	    printf ("ASPATH: %s\n", aspath->str);
	    aspath_free(aspath);
	  }
	  break;
	case BGP_ATTR_NEXT_HOP:
	  {
	    struct in_addr nexthop;
	    nexthop.s_addr = stream_get_ipv4 (s);
	    printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
	  }
	  break;
	default:
	  stream_getw_from (s, length);
	  break;
	}
    }

  return 0;
}
Exemple #4
0
/* Nexthop lookup for IPv4. */
static void
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
{
  struct in_addr addr;

  addr.s_addr = stream_get_ipv4 (client->ibuf);
  zsend_ipv4_nexthop_lookup (client, addr);
}
Exemple #5
0
/* Nexthop lookup for IPv4. */
static void
zread_ipv4_import_lookup (struct zserv *client, u_short length)
{
  struct prefix_ipv4 p;

  p.family = AF_INET;
  p.prefixlen = stream_getc (client->ibuf);
  p.prefix.s_addr = stream_get_ipv4 (client->ibuf);

  zsend_ipv4_import_lookup (client, &p);
}
Exemple #6
0
/* Zebra route add and delete treatment. */
static int
rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct zapi_ipv4 api;
  unsigned long ifindex;
  struct in_addr nexthop;
  struct prefix_ipv4 p;
  
  s = zclient->ibuf;
  ifindex = 0;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv4 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      nexthop.s_addr = stream_get_ipv4 (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      ifindex = stream_getl (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  else
    api.distance = 255;
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  /* Then fetch IPv4 prefixes. */
  if (command == ZEBRA_IPV4_ROUTE_ADD)
    rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, 
                          &nexthop, api.metric, api.distance);
  else 
    rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);

  return 0;
}
Exemple #7
0
/* Nexthop lookup for IPv4. */
static int
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
{
  struct in_addr addr;
  char buf[BUFSIZ];

  addr.s_addr = stream_get_ipv4 (client->ibuf);
  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
    zlog_debug("%s: looking up %s", __func__,
               inet_ntop (AF_INET, &addr, buf, BUFSIZ));
  return zsend_ipv4_nexthop_lookup (client, addr);
}
Exemple #8
0
int
isis_zebra_read_ipv4 (int command, struct zclient *zclient,
                      zebra_size_t length)
{
    struct stream *stream;
    struct zapi_ipv4 api;
    struct prefix_ipv4 p;
    unsigned long ifindex;
    struct in_addr nexthop;

    stream = zclient->ibuf;
    memset (&p, 0, sizeof (struct prefix_ipv4));
    ifindex = 0;

    api.type = stream_getc (stream);
    api.flags = stream_getc (stream);
    api.message = stream_getc (stream);

    p.family = AF_INET;
    p.prefixlen = stream_getc (stream);
    stream_get (&p.prefix, stream, PSIZE (p.prefixlen));

    if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
        api.nexthop_num = stream_getc (stream);
        nexthop.s_addr = stream_get_ipv4 (stream);
    }
    if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
        api.ifindex_num = stream_getc (stream);
        ifindex = stream_getl (stream);
    }
    if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
        api.distance = stream_getc (stream);
    if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
        api.metric = stream_getl (stream);
    else
        api.metric = 0;

    if (command == ZEBRA_IPV4_ROUTE_ADD)
    {
        zlog_debug ("IPv4 Route add from Z");
    }

    return 0;
}
Exemple #9
0
static int
bgp_import_check (struct prefix *p, u_int32_t *igpmetric,
                  struct in_addr *igpnexthop)
{
  struct stream *s;
  int ret;
  u_int16_t length, command;
  u_char version, marker;
  int nbytes;
  struct in_addr addr;
  struct in_addr nexthop;
  u_int32_t metric = 0;
  u_char nexthop_num;
  u_char nexthop_type;

  /* If lookup connection is not available return valid. */
  if (zlookup->sock < 0)
    {
      if (igpmetric)
	*igpmetric = 0;
      return 1;
    }

  /* Send query to the lookup connection */
  s = zlookup->obuf;
  stream_reset (s);
  zclient_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
  
  stream_putc (s, p->prefixlen);
  stream_put_in_addr (s, &p->u.prefix4);
  
  stream_putw_at (s, 0, stream_get_endp (s));
  
  /* Write the packet. */
  ret = writen (zlookup->sock, s->data, stream_get_endp (s));

  if (ret < 0)
    {
      zlog_err ("can't write to zlookup->sock");
      close (zlookup->sock);
      zlookup->sock = -1;
      return 1;
    }
  if (ret == 0)
    {
      zlog_err ("zlookup->sock connection closed");
      close (zlookup->sock);
      zlookup->sock = -1;
      return 1;
    }

  /* Get result. */
  stream_reset (s);

  /* Fetch length. */
  nbytes = stream_read (s, zlookup->sock, 2);
  length = stream_getw (s);

  /* Fetch whole data. */
  nbytes = stream_read (s, zlookup->sock, length - 2);
  marker = stream_getc (s);
  version = stream_getc (s);

  if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER)
    {
      zlog_err("%s: socket %d version mismatch, marker %d, version %d",
               __func__, zlookup->sock, marker, version);
      return 0;
    }
    
  command = stream_getw (s);
  
  addr.s_addr = stream_get_ipv4 (s);
  metric = stream_getl (s);
  nexthop_num = stream_getc (s);

  /* Set IGP metric value. */
  if (igpmetric)
    *igpmetric = metric;

  /* If there is nexthop then this is active route. */
  if (nexthop_num)
    {
      nexthop.s_addr = 0;
      nexthop_type = stream_getc (s);
      if (nexthop_type == ZEBRA_NEXTHOP_IPV4)
	{
	  nexthop.s_addr = stream_get_ipv4 (s);
	  if (igpnexthop)
	    *igpnexthop = nexthop;
	}
      else
	*igpnexthop = nexthop;

      return 1;
    }
  else
    return 0;
}
Exemple #10
0
static struct bgp_nexthop_cache *
zlookup_read (void)
{
  struct stream *s;
  uint16_t length;
  u_char marker;
  u_char version;
  uint16_t command;
  int nbytes;
  struct in_addr raddr;
  uint32_t metric;
  int i;
  u_char nexthop_num;
  struct nexthop *nexthop;
  struct bgp_nexthop_cache *bnc;

  s = zlookup->ibuf;
  stream_reset (s);

  nbytes = stream_read (s, zlookup->sock, 2);
  length = stream_getw (s);

  nbytes = stream_read (s, zlookup->sock, length - 2);
  marker = stream_getc (s);
  version = stream_getc (s);
  
  if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER)
    {
      zlog_err("%s: socket %d version mismatch, marker %d, version %d",
               __func__, zlookup->sock, marker, version);
      return NULL;
    }
    
  command = stream_getw (s);
  
  raddr.s_addr = stream_get_ipv4 (s);
  metric = stream_getl (s);
  nexthop_num = stream_getc (s);

  if (nexthop_num)
    {
      bnc = bnc_new ();
      bnc->valid = 1;
      bnc->metric = metric;
      bnc->nexthop_num = nexthop_num;

      for (i = 0; i < nexthop_num; i++)
	{
	  nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
	  nexthop->type = stream_getc (s);
	  switch (nexthop->type)
	    {
	    case ZEBRA_NEXTHOP_IPV4:
	      nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
	      break;
	    case ZEBRA_NEXTHOP_IFINDEX:
	    case ZEBRA_NEXTHOP_IFNAME:
	      nexthop->ifindex = stream_getl (s);
	      break;
            default:
              /* do nothing */
              break;
	    }
	  bnc_nexthop_add (bnc, nexthop);
	}
    }
  else
    return NULL;

  return bnc;
}
Exemple #11
0
/* Zebra server IPv4 prefix delete function. */
static void
zread_ipv4_delete (struct zserv *client, u_short length)
{
  int i;
  struct stream *s;
  struct zapi_ipv4 api;
  struct in_addr nexthop;
  unsigned long ifindex;
  struct prefix_ipv4 p;
  u_char nexthop_num;
  u_char nexthop_type;
  u_char ifname_len;
  
  s = client->ibuf;
  ifindex = 0;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv4 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      nexthop_num = stream_getc (s);

      for (i = 0; i < nexthop_num; i++)
	{
	  nexthop_type = stream_getc (s);

	  switch (nexthop_type)
	    {
	    case ZEBRA_NEXTHOP_IFINDEX:
	      ifindex = stream_getl (s);
	      break;
	    case ZEBRA_NEXTHOP_IFNAME:
	      ifname_len = stream_getc (s);
	      stream_forward (s, ifname_len);
	      break;
	    case ZEBRA_NEXTHOP_IPV4:
	      nexthop.s_addr = stream_get_ipv4 (s);
	      break;
	    case ZEBRA_NEXTHOP_IPV6:
	      stream_forward (s, IPV6_MAX_BYTELEN);
	      break;
	    }
	}
    }

  /* Distance. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  else
    api.distance = 0;

  /* Metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;
    
  rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
		   client->rtm_table);
}
Exemple #12
0
/* 
 * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
 * add kernel route. 
 */
static void
zread_ipv4_add (struct zserv *client, u_short length)
{
  int i;
  struct rib *rib;
  struct prefix_ipv4 p;
  u_char message;
  struct in_addr nexthop;
  u_char nexthop_num;
  u_char nexthop_type;
  struct stream *s;
  unsigned int ifindex;
  u_char ifname_len;

  /* Get input stream.  */
  s = client->ibuf;

  /* Allocate new rib. */
  rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
  memset (rib, 0, sizeof (struct rib));

  /* Type, flags, message. */
  rib->type = stream_getc (s);
  rib->flags = stream_getc (s);
  message = stream_getc (s); 
  rib->uptime = time (NULL);

  /* IPv4 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop parse. */
  if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
    {
      nexthop_num = stream_getc (s);

      for (i = 0; i < nexthop_num; i++)
	{
	  nexthop_type = stream_getc (s);

	  switch (nexthop_type)
	    {
	    case ZEBRA_NEXTHOP_IFINDEX:
	      ifindex = stream_getl (s);
	      nexthop_ifindex_add (rib, ifindex);
	      break;
	    case ZEBRA_NEXTHOP_IFNAME:
	      ifname_len = stream_getc (s);
	      stream_forward (s, ifname_len);
	      break;
	    case ZEBRA_NEXTHOP_IPV4:
	      nexthop.s_addr = stream_get_ipv4 (s);
	      nexthop_ipv4_add (rib, &nexthop);
	      break;
	    case ZEBRA_NEXTHOP_IPV6:
	      stream_forward (s, IPV6_MAX_BYTELEN);
	      break;
      case ZEBRA_NEXTHOP_BLACKHOLE:
        nexthop_blackhole_add (rib);
        break;
	    }
	}
    }

  /* Distance. */
  if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
    rib->distance = stream_getc (s);

  /* Metric. */
  if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
    rib->metric = stream_getl (s);
    
  rib_add_ipv4_multipath (&p, rib);
}
static int zclient_read_nexthop(struct zclient *zlookup,
				struct pim_zlookup_nexthop nexthop_tab[],
				const int tab_size,
				struct in_addr addr)
{
  int num_ifindex = 0;
  struct stream *s;
  const uint16_t MIN_LEN = 14; /* getc=1 getc=1 getw=2 getipv4=4 getc=1 getl=4 getc=1 */
  uint16_t length, len;
  u_char marker;
  u_char version;
  uint16_t command;
  int nbytes;
  struct in_addr raddr;
  uint8_t distance;
  uint32_t metric;
  int nexthop_num;
  int i;

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: addr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str);
  }

  s = zlookup->ibuf;
  stream_reset(s);

  nbytes = stream_read(s, zlookup->sock, 2);
  if (nbytes < 2) {
    zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d",
	     __FILE__, __PRETTY_FUNCTION__, nbytes);
    zclient_lookup_failed(zlookup);
    return -1;
  }
  length = stream_getw(s);

  len = length - 2;

  if (len < MIN_LEN) {
    zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
	     __FILE__, __PRETTY_FUNCTION__, len, MIN_LEN);
    zclient_lookup_failed(zlookup);
    return -2;
  }

  nbytes = stream_read(s, zlookup->sock, len);
  if (nbytes < (length - 2)) {
    zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d < len=%d",
	     __FILE__, __PRETTY_FUNCTION__, nbytes, len);
    zclient_lookup_failed(zlookup);
    return -3;
  }
  marker = stream_getc(s);
  version = stream_getc(s);
  
  if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) {
    zlog_err("%s: socket %d version mismatch, marker %d, version %d",
	     __func__, zlookup->sock, marker, version);
    return -4;
  }
    
  command = stream_getw(s);
  if (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) {
    zlog_err("%s: socket %d command mismatch: %d",
            __func__, zlookup->sock, command);
    return -5;
  }

  raddr.s_addr = stream_get_ipv4(s);

  if (raddr.s_addr != addr.s_addr) {
    char addr_str[100];
    char raddr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
    zlog_warn("%s: address mismatch: addr=%s raddr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str, raddr_str);
    /* warning only */
  }

  distance = stream_getc(s);
  metric = stream_getl(s);
  nexthop_num = stream_getc(s);

  if (nexthop_num < 1) {
    zlog_err("%s: socket %d bad nexthop_num=%d",
            __func__, zlookup->sock, nexthop_num);
    return -6;
  }

  len -= MIN_LEN;

  for (i = 0; i < nexthop_num; ++i) {
    enum nexthop_types_t nexthop_type;

    if (len < 1) {
      zlog_err("%s: socket %d empty input expecting nexthop_type: len=%d",
	       __func__, zlookup->sock, len);
      return -7;
    }
    
    nexthop_type = stream_getc(s);
    --len;

    switch (nexthop_type) {
    case ZEBRA_NEXTHOP_IFINDEX:
    case ZEBRA_NEXTHOP_IFNAME:
    case ZEBRA_NEXTHOP_IPV4_IFINDEX:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      if (nexthop_type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {
	if (len < 4) {
	  zlog_err("%s: socket %d short input expecting nexthop IPv4-addr: len=%d",
		   __func__, zlookup->sock, len);
	  return -8;
	}
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
	len -= 4;
      }
      else {
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
      }
      nexthop_tab[num_ifindex].ifindex           = stream_getl(s);
      nexthop_tab[num_ifindex].protocol_distance = distance;
      nexthop_tab[num_ifindex].route_metric      = metric;
      ++num_ifindex;
      break;
    case ZEBRA_NEXTHOP_IPV4:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
      len -= 4;
      nexthop_tab[num_ifindex].ifindex             = 0;
      nexthop_tab[num_ifindex].protocol_distance   = distance;
      nexthop_tab[num_ifindex].route_metric        = metric;
      {
	char addr_str[100];
	char nexthop_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	pim_inet4_dump("<nexthop?>", nexthop_tab[num_ifindex].nexthop_addr, nexthop_str, sizeof(nexthop_str));
	zlog_warn("%s %s: zebra returned recursive nexthop %s for address %s",
		  __FILE__, __PRETTY_FUNCTION__,
		  nexthop_str, addr_str);
      }
      ++num_ifindex;
      break;
    default:
      /* do nothing */
      {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		  nexthop_type, addr_str);
      }
      break;
    }
  }

  return num_ifindex;
}
Exemple #14
0
/* Zebra route add and delete treatment. */
static int
zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct zapi_ipv4 api;
  struct in_addr nexthop;
  struct prefix_ipv4 p;

  s = zclient->ibuf;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv4 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      nexthop.s_addr = stream_get_ipv4 (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      stream_getl (s); /* ifindex, unused */
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  if (command == ZEBRA_IPV4_ROUTE_ADD)
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}
      bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
			   api.metric, api.type);
    }
  else
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
		     "nexthop %s metric %u",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}
      bgp_redistribute_delete((struct prefix *)&p, api.type);
    }

  return 0;
}
Exemple #15
0
static int redist_read_ipv4_route(int command, struct zclient *zclient,
				  zebra_size_t length, vrf_id_t vrf_id)
{
  struct stream *s;
  struct zapi_ipv4 api;
  unsigned long ifindex;
  struct in_addr nexthop;
  struct prefix_ipv4 p;
  int min_len = 4;

  if (length < min_len) {
    zlog_warn("%s %s: short buffer: length=%d min=%d",
	      __FILE__, __PRETTY_FUNCTION__,
	      length, min_len);
    return -1;
  }

  s = zclient->ibuf;
  ifindex = 0;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc(s);
  api.flags = stream_getc(s);
  api.message = stream_getc(s);

  /* IPv4 prefix length. */
  memset(&p, 0, sizeof(struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc(s);

  min_len +=
    PSIZE(p.prefixlen) +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? 5 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? 5 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? 1 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? 4 : 0;

  if (PIM_DEBUG_ZEBRA) {
    zlog_debug("%s %s: length=%d min_len=%d flags=%s%s%s%s",
	       __FILE__, __PRETTY_FUNCTION__,
	       length, min_len,
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
  }

  if (length < min_len) {
    zlog_warn("%s %s: short buffer: length=%d min_len=%d flags=%s%s%s%s",
	      __FILE__, __PRETTY_FUNCTION__,
	      length, min_len,
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
    return -1;
  }

  /* IPv4 prefix. */
  stream_get(&p.prefix, s, PSIZE(p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) {
    api.nexthop_num = stream_getc(s);
    nexthop.s_addr = stream_get_ipv4(s);
  }
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) {
    api.ifindex_num = stream_getc(s);
    ifindex = stream_getl(s);
  }

  api.distance = CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ?
    stream_getc(s) :
    0;

  api.metric = CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ?
    stream_getl(s) :
    0;

  switch (command) {
  case ZEBRA_IPV4_ROUTE_ADD:
    if (PIM_DEBUG_ZEBRA) {
      char buf[2][INET_ADDRSTRLEN];
      zlog_debug("%s: add %s %s/%d "
		 "nexthop %s ifindex %ld metric%s %u distance%s %u",
		 __PRETTY_FUNCTION__,
		 zebra_route_string(api.type),
		 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		 p.prefixlen,
		 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		 ifindex,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss",
		 api.metric,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss",
		 api.distance);
    }
    break;
  case ZEBRA_IPV4_ROUTE_DELETE:
    if (PIM_DEBUG_ZEBRA) {
      char buf[2][INET_ADDRSTRLEN];
      zlog_debug("%s: delete %s %s/%d "
		 "nexthop %s ifindex %ld metric%s %u distance%s %u",
		 __PRETTY_FUNCTION__,
		 zebra_route_string(api.type),
		 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		 p.prefixlen,
		 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		 ifindex,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss",
		 api.metric,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss",
		 api.distance);
    }
    break;
  default:
    zlog_warn("%s: unknown command=%d", __PRETTY_FUNCTION__, command);
    return -1;
  }

  sched_rpf_cache_refresh();

  return 0;
}
Exemple #16
0
int
main (int argc, char **argv)
{
  int ret;
  FILE *fp;
  struct stream *s;
  time_t now;
  int type;
  int subtype;
  size_t len;
  int source_as;
  int dest_as;
  int ifindex;
  int family;
  struct in_addr sip;
  struct in_addr dip;
  u_int16_t viewno, seq_num;
  struct prefix_ipv4 p;

  s = stream_new (10000);

  if (argc != 2)
    {
      fprintf (stderr, "Usage: %s FILENAME\n", argv[0]);
      exit (1);
    }
  fp = fopen (argv[1], "r");
  if (!fp)
    {
      perror ("fopen");
      exit (1);
    }
  
  while (1)
    {
      stream_reset (s);

      ret = fread (s->data, 12, 1, fp);
      if (!ret || feof (fp))
	{
	  printf ("END OF FILE\n");
	  break;
	}
      if (ferror (fp))
	{
	  printf ("ERROR OF FREAD\n");
	  break;
	}

      /* Extract header. */
      now = stream_getl (s);
      type = stream_getw (s);
      subtype = stream_getw (s);
      len = stream_getl (s);

      printf ("TIME: %s", ctime (&now));

      /* printf ("TYPE: %d/%d\n", type, subtype); */

      if (type == MSG_PROTOCOL_BGP4MP)
	printf ("TYPE: BGP4MP");
      else if (type == MSG_PROTOCOL_BGP4MP_ET)
	printf ("TYPE: BGP4MP_ET");
      else if (type == MSG_TABLE_DUMP)
	printf ("TYPE: MSG_TABLE_DUMP");
      else
	printf ("TYPE: Unknown %d", type);

      if (type == MSG_TABLE_DUMP)
	switch (subtype)
	  {
	  case AFI_IP:
	    printf ("/AFI_IP\n");
	    break;
	  case AFI_IP6:
	    printf ("/AFI_IP6\n");
	    break;
	  default:
	    printf ("/UNKNOWN %d", subtype);
	    break;
	  }
      else
	{
	  switch (subtype)
	    {
	    case BGP4MP_STATE_CHANGE:
	      printf ("/CHANGE\n");
	      break;
	    case BGP4MP_MESSAGE:
	      printf ("/MESSAGE\n");
	      break;
	    case BGP4MP_ENTRY:
	      printf ("/ENTRY\n");
	      break;
	    case BGP4MP_SNAPSHOT:
	      printf ("/SNAPSHOT\n");
	      break;
	    default:
	      printf ("/UNKNOWN %d", subtype);
	      break;
	    }
	}

      printf ("len: %zd\n", len);

      ret = fread (s->data + 12, len, 1, fp);
      if (feof (fp))
	{
	  printf ("ENDOF FILE 2\n");
	  break;
	}
      if (ferror (fp))
	{
	  printf ("ERROR OF FREAD 2\n");
	  break;
	}

      /* printf ("now read %d\n", len); */

      if (type == MSG_TABLE_DUMP)
	{
	  u_char status;
	  time_t originated;
	  struct in_addr peer;
	  u_int16_t attrlen;

	  viewno = stream_getw (s);
	  seq_num = stream_getw (s);
	  printf ("VIEW: %d\n", viewno);
	  printf ("SEQUENCE: %d\n", seq_num);

	  /* start */
	  while (s->getp < len - 16)
	    {
	      p.prefix.s_addr = stream_get_ipv4 (s);
	      p.prefixlen = stream_getc (s);
	      printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);

	      status = stream_getc (s);
	      originated = stream_getl (s);
	      peer.s_addr = stream_get_ipv4 (s);
	      source_as = stream_getw(s);

	      printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
	      printf ("ORIGINATED: %s", ctime (&originated));

	      attrlen = stream_getw (s);
	      printf ("ATTRLEN: %d\n", attrlen);

	      attr_parse (s, attrlen);

	      printf ("STATUS: 0x%x\n", status);
	    }
	}
      else
	{
	  source_as = stream_getw (s);
	  dest_as = stream_getw (s);
	  printf ("source_as: %d\n", source_as);
	  printf ("dest_as: %d\n", dest_as);

	  ifindex = stream_getw (s);
	  family = stream_getw (s);

	  printf ("ifindex: %d\n", ifindex);
	  printf ("family: %d\n", family);

	  sip.s_addr = stream_get_ipv4 (s);
	  dip.s_addr = stream_get_ipv4 (s);
	  
	  printf ("saddr: %s\n", inet_ntoa (sip));
	  printf ("daddr: %s\n", inet_ntoa (dip));

	  printf ("\n");
	}
    }
  fclose (fp);
  return 0;
}