コード例 #1
0
ファイル: bgp_dump.c プロジェクト: inet-framework/inet-quagga
void
bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
		      struct stream *packet)
{
  struct stream *obuf;

  /* If dump file pointer is disabled return immediately. */
  if (bgp_dump->fp == NULL)
    return;

  /* Make dump stream. */
  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  /* Dump header and common part. */
  bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE);
  bgp_dump_common (obuf, peer);

  /* Packet contents. */
  stream_put (obuf, STREAM_DATA (packet), stream_get_endp (packet));
  
  /* Set length. */
  bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);

  /* Write to the stream. */
  fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump->fp);
  fflush (bgp_dump->fp);
}
コード例 #2
0
ファイル: rip_auth.c プロジェクト: Quagga-RE/wip-tcs-rfc6506
/* write RIP-2 hash authentication data trailer */
static void
rip_auth_write_trailer (struct stream *s, struct rip_interface *ri, char *auth_str)
{
  unsigned char digest[RIP_AUTH_MAX_SIZE];
  unsigned hash_error;

  if (IS_RIP_DEBUG_AUTH)
    zlog_debug ("writing authentication trailer after %zuB of main body", stream_get_endp (s));
  assert (ri->auth_type == RIP_AUTH_HASH);

  /* Set authentication data. */
  stream_putw (s, RIP_FAMILY_AUTH);
  stream_putw (s, RIP_AUTH_DATA);

  /* Generate a digest for the RIP packet and write it to the packet. */
  switch (ri->hash_algo)
  {
  case HASH_KEYED_MD5:
    if (IS_RIP_DEBUG_AUTH)
      zlog_debug ("%s: %zuB of input buffer, %zuB of key", __func__, stream_get_endp (s), strlen (auth_str));
    hash_error = hash_make_keyed_md5 ((caddr_t) STREAM_DATA (s), stream_get_endp (s), auth_str, strlen (auth_str), digest);
    stream_write (s, digest, HASH_SIZE_MD5);
    break;
#ifdef HAVE_LIBGCRYPT
  case HASH_HMAC_SHA1:
  case HASH_HMAC_SHA256:
  case HASH_HMAC_SHA384:
  case HASH_HMAC_SHA512:
    {
      u_int8_t compr_auth_str[RIP_AUTH_MAX_SIZE];
      size_t compr_authlen;
      /* RFC4822 2.5: Fill Apad, process whole packet with HMAC rounds. */
      size_t saved_endp = stream_get_endp (s);

      hash_key_compress_rfc4822 (ri->hash_algo, auth_str, strlen (auth_str), compr_auth_str, &compr_authlen);
      stream_write (s, hash_apad_sha512, hash_digest_length[ri->hash_algo]);
      if (IS_RIP_DEBUG_AUTH)
        zlog_debug ("%s: %zuB of input buffer, %zuB of key (%zuB compressed)",
          __func__, stream_get_endp (s), strlen (auth_str), compr_authlen);
      hash_error = hash_make_hmac (ri->hash_algo, STREAM_DATA (s),
        stream_get_endp (s), compr_auth_str, compr_authlen, STREAM_DATA (s) + saved_endp);
      break;
    }
#endif /* HAVE_LIBGCRYPT */
  default:
    assert (0);
  }
  if (hash_error)
    if (IS_RIP_DEBUG_AUTH)
      zlog_debug ("hash function returned error %u", hash_error);
}
コード例 #3
0
ファイル: bgp_dump.c プロジェクト: ColinBS/quagga-rtrlib
/* Dump BGP status change. */
void
bgp_dump_state (struct peer *peer, int status_old, int status_new)
{
  struct stream *obuf;

  /* If dump file pointer is disabled return immediately. */
  if (bgp_dump_all.fp == NULL)
    return;

  /* Make dump stream. */
  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE_AS4,
		   bgp_dump_all.type);
  bgp_dump_common (obuf, peer, 1);/* force this in as4speak*/

  stream_putw (obuf, status_old);
  stream_putw (obuf, status_new);

  /* Set length. */
  bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);

  /* Write to the stream. */
  fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_all.fp);
  fflush (bgp_dump_all.fp);
}
コード例 #4
0
ファイル: zserv.c プロジェクト: MichaelQQ/Quagga-PE
static int
zebra_server_send_message(struct zserv *client)
{
  if (client->t_suicide)
    return -1;
  switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
		       stream_get_endp(client->obuf)))
    {
    case BUFFER_ERROR:
      zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
      		 __func__, client->sock);
      /* Schedule a delayed close since many of the functions that call this
         one do not check the return code.  They do not allow for the
	 possibility that an I/O error may have caused the client to be
	 deleted. */
      client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
					   client, 0);
      return -1;
    case BUFFER_EMPTY:
      THREAD_OFF(client->t_write);
      break;
    case BUFFER_PENDING:
      THREAD_WRITE_ON(zebrad.master, client->t_write,
		      zserv_flush_data, client, client->sock);
      break;
    }
  return 0;
}
コード例 #5
0
ファイル: bgp_dump.c プロジェクト: dogbert2/quagga
/* Dump BGP status change. */
void
bgp_dump_state (struct peer *peer, int status_old, int status_new)
{
  int ret;
  struct stream *obuf;

  /* If dump file pointer is disabled return immediately. */
  if (bgp_dump_all.fp == NULL)
    return;

  /* Make dump stream. */
  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE_AS4);
  bgp_dump_common (obuf, peer, 1);/* force this in as4speak*/

  stream_putw (obuf, status_old);
  stream_putw (obuf, status_new);

  /* Set length. */
  bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);

  /* Write to the stream. */
  ret = fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_all.fp);
  if (ret != 1)
    {
      zlog_warn ("bgp_dump_state: fwrite returned %d, expected 1: %s", ret, strerror (errno));
    }
  fflush (bgp_dump_all.fp);
}
コード例 #6
0
int authenticate_pdu(struct isis_passwd *external,struct isis_passwd
*local,struct stream *stream, uint32_t auth_tlv_offset)
{
    unsigned char digest[ISIS_AUTH_MD5_SIZE];
    
    if(local->type != external->type)
        return ISIS_ERROR;
    
    switch(local->type)
    {
    
        case ISIS_PASSWD_TYPE_UNUSED:
            //do the respective operation
            break;
        case ISIS_PASSWD_TYPE_CLEARTXT:
            //do the respective operation
            break;
            
        case ISIS_PASSWD_TYPE_HMAC_MD5:
            if(external->len != ISIS_AUTH_MD5_SIZE)
                return ISIS_ERROR;
            
            memset(STREAM_DATA (stream)+auth_tlv_offset+3, 0, 
                    ISIS_AUTH_MD5_SIZE);
            hmac_md5(STREAM_DATA(stream),stream_get_endp(stream),
                    (unsigned char*)&(local->passwd), local->len, 
                    (caddr_t)&digest);
            memcpy(STREAM_DATA (stream)+auth_tlv_offset+3,
                    external->passwd,ISIS_AUTH_MD5_SIZE);
            
            return memcmp(digest,external->passwd,ISIS_AUTH_MD5_SIZE);            
        case ISIS_PASSWD_TYPE_PRIVATE:
            //do the operation
            break;
            
        default:
            zlog_err("Authentication type is unrecognized.");
            return ISIS_ERROR;
    
    }
    /*If authentication is not enabled pass the PDU*/
    return ISIS_OK;

}
コード例 #7
0
ファイル: bgp_dump.c プロジェクト: dogbert2/quagga
static void
bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
		      struct stream *packet)
{
  int ret;
  struct stream *obuf;

  /* If dump file pointer is disabled return immediately. */
  if (bgp_dump->fp == NULL)
    return;

  /* Make dump stream. */
  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  /* Dump header and common part. */
  if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
    { 
      bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE_AS4);
    }
  else
    {
      bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE);
    }
  bgp_dump_common (obuf, peer, 0);

  /* Packet contents. */
  stream_put (obuf, STREAM_DATA (packet), stream_get_endp (packet));
  
  /* Set length. */
  bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);

  /* Write to the stream. */
  ret = fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump->fp);
  if (ret != 1)
    {
      zlog_warn ("bgp_dump_packet_func: fwrite returned %d, expected 1: %s", ret, strerror (errno));
    }
  fflush (bgp_dump->fp);
}
コード例 #8
0
ファイル: sv_sisis.c プロジェクト: ecks/sis-is
int
shim_sisis_write (struct stream * obuf, struct buffer * wb)
{
  struct listnode * node, * nnode;
  struct sisis_listener * listener;

  printf("num of listeners %d\n", listcount(sm->listen_sockets));
  for(ALL_LIST_ELEMENTS (sm->listen_sockets, node,  nnode, listener))
  {
    printf("listener fd: %d\n", listener->sisis_fd);
    buffer_write(wb, listener->sisis_fd, STREAM_DATA(obuf), stream_get_endp(obuf));
  }

  return 0;
}
コード例 #9
0
ファイル: svz_tunnel.c プロジェクト: ecks/sis-is
int
svz_tunnel_send_message (struct tclient * tclient)
{
  if (tclient->sock < 0)
    return -1;
  switch(buffer_write(tclient->wb, tclient->sock, STREAM_DATA(tclient->obuf) + stream_get_getp(tclient->obuf),
                      stream_get_endp(tclient->obuf) - stream_get_getp(tclient->obuf)))
  {
    case BUFFER_ERROR:
      zlog_warn("%s: buffer_write failed to tclient fd %d, closing",
                __func__, tclient->sock);
      return svz_tunnel_failed(tclient);
    case BUFFER_EMPTY:
      THREAD_OFF(tclient->t_write);
      break;
    case BUFFER_PENDING:
      THREAD_WRITE_ON(master, tclient->t_write, 
                      svz_tunnel_flush_data, tclient, tclient->sock);
      break;
  }
  return 0;
}
コード例 #10
0
ファイル: zclient.c プロジェクト: gvsurenderreddy/quagga
int
zclient_send_message(struct zclient *zclient)
{
  if (zclient->sock < 0)
    return -1;
  switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
		       stream_get_endp(zclient->obuf)))
    {
    case BUFFER_ERROR:
      zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
      		 __func__, zclient->sock);
      return zclient_failed(zclient);
      break;
    case BUFFER_EMPTY:
      THREAD_OFF(zclient->t_write);
      break;
    case BUFFER_PENDING:
      THREAD_WRITE_ON(master, zclient->t_write,
		      zclient_flush_data, zclient, zclient->sock);
      break;
    }
  return 0;
}
コード例 #11
0
ファイル: bgp_dump.c プロジェクト: KaloNK/quagga
static struct bgp_info *
bgp_dump_route_node_record (int afi, struct bgp_node *rn,
                            struct bgp_info *info, unsigned int seq)
{
  struct stream *obuf;
  size_t sizep;
  size_t endp;

  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  /* MRT header */
  if (afi == AFI_IP)
    bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
                     BGP_DUMP_ROUTES);
  else if (afi == AFI_IP6)
    bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST,
                     BGP_DUMP_ROUTES);

  /* Sequence number */
  stream_putl (obuf, seq);

  /* Prefix length */
  stream_putc (obuf, rn->p.prefixlen);

  /* Prefix */
  if (afi == AFI_IP)
    {
      /* We'll dump only the useful bits (those not 0), but have to
       * align on 8 bits */
      stream_write (obuf, (u_char *) &rn->p.u.prefix4, 
                    (rn->p.prefixlen + 7) / 8);
    }
  else if (afi == AFI_IP6)
    {
      /* We'll dump only the useful bits (those not 0), but have to
       * align on 8 bits */
      stream_write (obuf, (u_char *) &rn->p.u.prefix6,
                    (rn->p.prefixlen + 7) / 8);
    }

  /* Save where we are now, so we can overwride the entry count later */
  sizep = stream_get_endp (obuf);

  /* Entry count */
  uint16_t entry_count = 0;

  /* Entry count, note that this is overwritten later */
  stream_putw (obuf, 0);

  endp = stream_get_endp (obuf);
  for (; info; info = info->next)
    {
      size_t cur_endp;

      /* Peer index */
      stream_putw (obuf, info->peer->table_dump_index);

      /* Originated */
#ifdef HAVE_CLOCK_MONOTONIC
      stream_putl (obuf, time (NULL) - (bgp_clock () - info->uptime));
#else
      stream_putl (obuf, info->uptime);
#endif /* HAVE_CLOCK_MONOTONIC */

      /* Dump attribute. */
      /* Skip prefix & AFI/SAFI for MP_NLRI */
      bgp_dump_routes_attr (obuf, info->attr, &rn->p);

      cur_endp = stream_get_endp (obuf);
      if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
          + BGP_DUMP_HEADER_SIZE)
        {
          stream_set_endp (obuf, endp);
          break;
        }

      entry_count++;
      endp = cur_endp;
    }

  /* Overwrite the entry count, now that we know the right number */
  stream_putw_at (obuf, sizep, entry_count);

  bgp_dump_set_size (obuf, MSG_TABLE_DUMP_V2);
  fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);

  return info;
}
コード例 #12
0
ファイル: bgp_dump.c プロジェクト: ColinBS/quagga-rtrlib
/* Runs under child process. */
static unsigned int
bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
{
  struct stream *obuf;
  struct bgp_info *info;
  struct bgp_node *rn;
  struct bgp *bgp;
  struct bgp_table *table;

  bgp = bgp_get_default ();
  if (!bgp)
    return seq;

  if (bgp_dump_routes.fp == NULL)
    return seq;

  /* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
     so this should only be done on the first call to bgp_dump_routes_func.
     ( this function will be called once for ipv4 and once for ipv6 ) */
  if(first_run)
    bgp_dump_routes_index_table(bgp);

  obuf = bgp_dump_obuf;
  stream_reset(obuf);

  /* Walk down each BGP route. */
  table = bgp->rib[afi][SAFI_UNICAST];

  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    {
      if(!rn->info)
        continue;

      stream_reset(obuf);

      /* MRT header */
      if (afi == AFI_IP)
	bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
			 BGP_DUMP_ROUTES);
      else if (afi == AFI_IP6)
	bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST,
			 BGP_DUMP_ROUTES);

      /* Sequence number */
      stream_putl(obuf, seq);

      /* Prefix length */
      stream_putc (obuf, rn->p.prefixlen);

      /* Prefix */
      if (afi == AFI_IP)
        {
          /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
          stream_write(obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8);
        }
      else if (afi == AFI_IP6)
        {
          /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */
          stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8);
        }

      /* Save where we are now, so we can overwride the entry count later */
      int sizep = stream_get_endp(obuf);

      /* Entry count */
      uint16_t entry_count = 0;

      /* Entry count, note that this is overwritten later */
      stream_putw(obuf, 0);

      for (info = rn->info; info; info = info->next)
        {
          entry_count++;

          /* Peer index */
          stream_putw(obuf, info->peer->table_dump_index);

          /* Originated */
#ifdef HAVE_CLOCK_MONOTONIC
          stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime));
#else
          stream_putl (obuf, info->uptime);
#endif /* HAVE_CLOCK_MONOTONIC */

          /* Dump attribute. */
          /* Skip prefix & AFI/SAFI for MP_NLRI */
          bgp_dump_routes_attr (obuf, info->attr, &rn->p);
        }

      /* Overwrite the entry count, now that we know the right number */
      stream_putw_at (obuf, sizep, entry_count);

      seq++;

      bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);
      fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);

    }

  fflush (bgp_dump_routes.fp);

  return seq;
}
コード例 #13
0
ファイル: bgp_dump.c プロジェクト: ColinBS/quagga-rtrlib
static void
bgp_dump_routes_index_table(struct bgp *bgp)
{
  struct peer *peer;
  struct listnode *node;
  uint16_t peerno = 0;
  struct stream *obuf;

  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  /* MRT header */
  bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE,
		   BGP_DUMP_ROUTES);

  /* Collector BGP ID */
  stream_put_in_addr (obuf, &bgp->router_id);

  /* View name */
  if(bgp->name)
    {
      stream_putw (obuf, strlen(bgp->name));
      stream_put(obuf, bgp->name, strlen(bgp->name));
    }
  else
    {
      stream_putw(obuf, 0);
    }

  /* Peer count */
  stream_putw (obuf, listcount(bgp->peer));

  /* Walk down all peers */
  for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
    {

      /* Peer's type */
      if (sockunion_family(&peer->su) == AF_INET)
        {
          stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP);
        }
      else if (sockunion_family(&peer->su) == AF_INET6)
        {
          stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6);
        }

      /* Peer's BGP ID */
      stream_put_in_addr (obuf, &peer->remote_id);

      /* Peer's IP address */
      if (sockunion_family(&peer->su) == AF_INET)
        {
          stream_put_in_addr (obuf, &peer->su.sin.sin_addr);
        }
      else if (sockunion_family(&peer->su) == AF_INET6)
        {
          stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
                        IPV6_MAX_BYTELEN);
        }

      /* Peer's AS number. */
      /* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */
      stream_putl (obuf, peer->as);

      /* Store the peer number for this peer */
      peer->table_dump_index = peerno;
      peerno++;
    }

  bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2);

  fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
  fflush (bgp_dump_routes.fp);
}
コード例 #14
0
ファイル: aspath_test.c プロジェクト: Quagga/historical
/* validate the given aspath */
static int
validate (struct aspath *as, const struct test_spec *sp)
{
  size_t bytes, bytes4;
  int fails = 0;
  const u_char *out;
  static struct stream *s;
  struct aspath *asinout, *asconfeddel, *asstr, *as4;
  
  out = aspath_snmp_pathseg (as, &bytes);
  asinout = make_aspath (out, bytes, 0);
  
  /* Excercise AS4 parsing a bit, with a dogfood test */
  if (!s)
    s = stream_new (4096);
  bytes4 = aspath_put (s, as, 1);
  as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
  
  asstr = aspath_str2aspath (sp->shouldbe);
  
  asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
  
  printf ("got: %s\n", aspath_print(as));
  
  /* the parsed path should match the specified 'shouldbe' string.
   * We should pass the "eat our own dog food" test, be able to output
   * this path and then input it again. Ie the path resulting from:
   *
   *   aspath_parse(aspath_put(as)) 
   *
   * should:
   *
   * - also match the specified 'shouldbe' value
   * - hash to same value as original path
   * - have same hops and confed counts as original, and as the
   *   the specified counts
   *
   * aspath_str2aspath() and shouldbe should match
   *
   * We do the same for:
   *
   *   aspath_parse(aspath_put(as,USE32BIT))
   *
   * Confederation related tests: 
   * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
   * - aspath_delete_confed_seq should be idempotent.
   */
  if (strcmp(aspath_print (as), sp->shouldbe)
         /* hash validation */
      || (aspath_key_make (as) != aspath_key_make (asinout))
         /* by string */
      || strcmp(aspath_print (asinout), sp->shouldbe)
         /* By 4-byte parsing */
      || strcmp(aspath_print (as4), sp->shouldbe)
         /* by various path counts */
      || (aspath_count_hops (as) != sp->hops)
      || (aspath_count_confeds (as) != sp->confeds)
      || (aspath_count_hops (asinout) != sp->hops)
      || (aspath_count_confeds (asinout) != sp->confeds))
    {
      failed++;
      fails++;
      printf ("shouldbe:\n%s\n", sp->shouldbe);
      printf ("as4:\n%s\n", aspath_print (as4));
      printf ("hash keys: in: %d out->in: %d\n", 
              aspath_key_make (as), aspath_key_make (asinout));
      printf ("hops: %d, counted %d %d\n", sp->hops, 
              aspath_count_hops (as),
              aspath_count_hops (asinout) );
      printf ("confeds: %d, counted %d %d\n", sp->confeds,
              aspath_count_confeds (as),
              aspath_count_confeds (asinout));
      printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
      printbytes (out, bytes);
    }
         /* basic confed related tests */
  if ((aspath_print (asconfeddel) == NULL 
          && sp->shouldbe_delete_confed != NULL)
      || (aspath_print (asconfeddel) != NULL 
          && sp->shouldbe_delete_confed == NULL)
      || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
         /* delete_confed_seq should be idempotent */
      || (aspath_key_make (asconfeddel) 
          != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
    {
      failed++;
      fails++;
      printf ("confed_del: %s\n", aspath_print (asconfeddel));
      printf ("should be: %s\n", sp->shouldbe_delete_confed);
    }
      /* aspath_str2aspath test */
  if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
      || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
      || strcmp(aspath_print (asstr), sp->shouldbe))
    {
      failed++;
      fails++;
      printf ("asstr: %s\n", aspath_print (asstr));
    }
  
    /* loop, private and first as checks */
  if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
      || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
      || (aspath_private_as_check (as) != sp->private_as)
      || (aspath_firstas_check (as,sp->first)
          && sp->first == 0))
    {
      failed++;
      fails++;
      printf ("firstas: %d,  got %d\n", sp->first,
              aspath_firstas_check (as,sp->first));
      printf ("loop does: %d %d, doesnt: %d %d\n",
              sp->does_loop, aspath_loop_check (as, sp->does_loop),
              sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
      printf ("private check: %d %d\n", sp->private_as,
              aspath_private_as_check (as));
    }
  aspath_unintern (asinout);
  aspath_unintern (as4);
  
  aspath_free (asconfeddel);
  aspath_free (asstr);
  stream_reset (s);
  
  return fails;
}
コード例 #15
0
ファイル: bgp_dump.c プロジェクト: inet-framework/inet-quagga
void
bgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi,
		       int type, unsigned int seq)
{
  struct stream *obuf;
  struct attr *attr;
  struct peer *peer;
  int plen;
  int safi = 0;

  /* Make dump stream. */
  obuf = bgp_dump_obuf;
  stream_reset (obuf);

  attr = info->attr;
  peer = info->peer;

  /* We support MRT's old format. */
  if (type == MSG_TABLE_DUMP)
    {
      bgp_dump_header (obuf, MSG_TABLE_DUMP, afi);
      stream_putw (obuf, 0);	/* View # */
      stream_putw (obuf, seq);	/* Sequence number. */
    }
  else
    {
      bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY);
      
      stream_putl (obuf, info->uptime); /* Time Last Change */
      stream_putw (obuf, afi);	/* Address Family */
      stream_putc (obuf, safi);	/* SAFI */
    }

  if (afi == AFI_IP)
    {
      if (type == MSG_TABLE_DUMP)
	{
	  /* Prefix */
	  stream_put_in_addr (obuf, &p->u.prefix4);
	  stream_putc (obuf, p->prefixlen);

	  /* Status */
	  stream_putc (obuf, 1);

	  /* Originated */
	  stream_putl (obuf, info->uptime);

	  /* Peer's IP address */
	  stream_put_in_addr (obuf, &peer->su.sin.sin_addr);

	  /* Peer's AS number. */
	  stream_putw (obuf, peer->as);

	  /* Dump attribute. */
	  bgp_dump_routes_attr (obuf, attr, p);
	}
      else
	{
	  /* Next-Hop-Len */
	  stream_putc (obuf, IPV4_MAX_BYTELEN);
	  stream_put_in_addr (obuf, &attr->nexthop);
	  stream_putc (obuf, p->prefixlen);
	  plen = PSIZE (p->prefixlen);
	  stream_put (obuf, &p->u.prefix4, plen);
	  bgp_dump_routes_attr (obuf, attr, p);
	}
    }
#ifdef HAVE_IPV6
  else if (afi == AFI_IP6)
    {
      if (type == MSG_TABLE_DUMP)
	{
	  /* Prefix */
	  stream_write (obuf, (u_char *)&p->u.prefix6, IPV6_MAX_BYTELEN);
	  stream_putc (obuf, p->prefixlen);

	  /* Status */
	  stream_putc (obuf, 1);

	  /* Originated */
	  stream_putl (obuf, info->uptime);

	  /* Peer's IP address */
	  stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
			IPV6_MAX_BYTELEN);

	  /* Peer's AS number. */
	  stream_putw (obuf, peer->as);

	  /* Dump attribute. */
	  bgp_dump_routes_attr (obuf, attr, p);
	}
      else
	{
	  ;
	}
    }
#endif /* HAVE_IPV6 */

  /* Set length. */
  bgp_dump_set_size (obuf, type);

  fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump_routes.fp);
  fflush (bgp_dump_routes.fp);
}
コード例 #16
0
ファイル: rip_auth.c プロジェクト: Quagga-RE/wip-tcs-rfc6506
/* Take a sequence of payload (routing) RTE structures, decide on particular
 * authentication required for the given interface and build a complete RIP
 * packet in a stream structure. The packet will consist of header, optional
 * heading RTE, the payload RTEs and optional trailing data. Return the stream.
 */
int
rip_auth_make_packet
(
  struct rip_interface * ri,
  struct stream * packet,
  struct stream * rtes,
  const u_int8_t version,
  const u_int8_t command
)
{
  struct key *key = NULL;
  char *auth_str = NULL;

  if (IS_RIP_DEBUG_AUTH)
    zlog_debug ("interface auth type is '%s', inet RTEs payload size is %zuB",
      LOOKUP (rip_ffff_type_str, ri->auth_type), stream_get_endp (rtes));

  /* packet header, unconditional */
  stream_reset (packet);
  stream_putc (packet, command);
  stream_putc (packet, version);
  stream_putw (packet, 0);

  /* authentication leading RTE, conditional */
  if (version == RIPv2 && ri->auth_type != RIP_NO_AUTH)
  {
    if (ri->key_chain)
    {
      struct keychain *keychain;

      keychain = keychain_lookup (ri->key_chain);
      if (keychain)
      {
        if (IS_RIP_DEBUG_AUTH)
          zlog_debug ("trying configured key chain '%s'", ri->key_chain);
        key = key_lookup_for_send (keychain);
      }
      else
      {
        if (IS_RIP_DEBUG_AUTH)
          zlog_debug ("key chain '%s' is configured, but does not exist", ri->key_chain);
      }
    }
    /* Pick correct auth string for sends, prepare auth_str buffer for use.
     * (left justified and padded).
     *
     * presumes one of ri or key is valid, and that the auth strings they point
     * to are nul terminated. If neither are present, auth_str will be fully
     * zero padded.
     *
     */
    if (key && key->string)
    {
      if (IS_RIP_DEBUG_AUTH)
        zlog_debug ("using keychain '%s', key %u for sending", ri->key_chain, key->index);
      auth_str = key->string;
    }
    else if (ri->auth_str)
    {
      if (IS_RIP_DEBUG_AUTH)
        zlog_debug ("using interface authentication string");
      auth_str = ri->auth_str;
    }
    if (auth_str == NULL)
    {
      if (IS_RIP_DEBUG_AUTH)
        zlog_debug ("authentication string lookup failed");
      return -1;
    }

    rip_auth_write_leading_rte (packet, ri, key ? key->index % 256 : 1, auth_str,
      RIP_HEADER_SIZE + RIP_RTE_SIZE + stream_get_endp (rtes));
  }

  /* RTEs payload, unconditional */
  if (stream_get_endp (rtes) % RIP_RTE_SIZE)
  {
    zlog_err ("%s: malformed input RTE buffer", __func__);
    return -1;
  }
  stream_write (packet, STREAM_DATA (rtes), stream_get_endp (rtes));
  stream_reset (rtes);

  /* authentication trailing data, even more conditional */
  if (version == RIPv2 && ri->auth_type == RIP_AUTH_HASH)
    rip_auth_write_trailer (packet, ri, auth_str);

  return 0;
}
コード例 #17
0
ファイル: bgp_zebra.c プロジェクト: DorChen/quagga
void
bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi)
{
  int flags;
  u_char distance;
  struct peer *peer;
  struct bgp_info *mpinfo;
  size_t oldsize, newsize;

  if (zclient->sock < 0)
    return;

  if (! zclient->redist[ZEBRA_ROUTE_BGP])
    return;

  flags = 0;
  peer = info->peer;

  if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
    {
      SET_FLAG (flags, ZEBRA_FLAG_IBGP);
      SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
    }

  if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
      || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
    SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);

  /* resize nexthop buffer size if necessary */
  if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
      (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)))
    {
      newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1));
      newsize = stream_resize (bgp_nexthop_buf, newsize);
      if (newsize == oldsize)
	{
	  zlog_err ("can't resize nexthop buffer");
	  return;
	}
    }

  stream_reset (bgp_nexthop_buf);

  if (p->family == AF_INET)
    {
      struct zapi_ipv4 api;
      struct in_addr *nexthop;

      api.flags = flags;
      nexthop = &info->attr->nexthop;
      stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
      for (mpinfo = bgp_info_mpath_first (info); mpinfo;
	   mpinfo = bgp_info_mpath_next (mpinfo))
	{
	  nexthop = &mpinfo->attr->nexthop;
	  stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
	}

      api.type = ZEBRA_ROUTE_BGP;
      api.message = 0;
      api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      api.nexthop_num = 1 + bgp_info_mpath_count (info);
      api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
      api.ifindex_num = 0;
      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = info->attr->med;

      distance = bgp_distance_apply (p, info, bgp);

      if (distance)
	{
	  SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
	  api.distance = distance;
	}

      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  int i;
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
		     " count %d",
		     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
		     p->prefixlen,
		     inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])),
		     api.metric, api.nexthop_num);
	  for (i = 1; i < api.nexthop_num; i++)
	    zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
		       i, inet_ntop(AF_INET, api.nexthop[i], buf[1],
				    sizeof(buf[1])));
	}

      zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, 
                       (struct prefix_ipv4 *) p, &api);
    }
#ifdef HAVE_IPV6
  /* We have to think about a IPv6 link-local address curse. */
  if (p->family == AF_INET6)
    {
      unsigned int ifindex;
      struct in6_addr *nexthop;
      struct zapi_ipv6 api;

      ifindex = 0;
      nexthop = NULL;
      
      assert (info->attr->extra);
      
      /* Only global address nexthop exists. */
      if (info->attr->extra->mp_nexthop_len == 16)
	nexthop = &info->attr->extra->mp_nexthop_global;
      
      /* If both global and link-local address present. */
      if (info->attr->extra->mp_nexthop_len == 32)
	{
	  /* Workaround for Cisco's nexthop bug.  */
	  if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
	      && peer->su_remote->sa.sa_family == AF_INET6)
	    nexthop = &peer->su_remote->sin6.sin6_addr;
	  else
	    nexthop = &info->attr->extra->mp_nexthop_local;

	  if (info->peer->nexthop.ifp)
	    ifindex = info->peer->nexthop.ifp->ifindex;
	}

      if (nexthop == NULL)
	return;

      if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)
	{
	  if (info->peer->ifname)
	    ifindex = if_nametoindex (info->peer->ifname);
	  else if (info->peer->nexthop.ifp)
	    ifindex = info->peer->nexthop.ifp->ifindex;
	}

      /* Make Zebra API structure. */
      api.flags = flags;
      api.type = ZEBRA_ROUTE_BGP;
      api.message = 0;
      api.safi = safi;
      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      api.nexthop_num = 1;
      api.nexthop = &nexthop;
      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
      api.ifindex_num = 1;
      api.ifindex = &ifindex;
      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = info->attr->med;

      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET6_ADDRSTRLEN];
	  zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
		     inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
		     p->prefixlen,
		     inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}

      zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, 
                       (struct prefix_ipv6 *) p, &api);
    }
#endif /* HAVE_IPV6 */
}