static int mcp_ppp_all_config_syn_parse_update(struct stream *data_s)
{
	int type;
	int len;
	struct stream* tmp_s;

    tmp_s = stream_new(10240);
	while(STREAM_READABLE(data_s) >= 4)
	{
		type = stream_getw(data_s);
		len = stream_getw(data_s);
		//zlog_debug("<%s,%d> type:%d len:%d", __FUNCTION__, __LINE__, type, len);

        if(len == 0)
            continue;
            
		switch(type)
		{
		    case MCP_PPPD_CONFIG_SYN_REMOT_USERINFO: 
				stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len);
				mcp_recv_pppd_remote_userinfo_ack(tmp_s);
				stream_forward_getp(data_s, len);
				stream_reset(tmp_s);
				break;
				
			case MCP_PPPD_CONFIG_SYN_MULTILINK_INFO: 
				stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len);
				mcp_recv_pppd_multilink_info_ack(tmp_s);
				stream_forward_getp(data_s, len);
				stream_reset(tmp_s);
				break;

			case MCP_PPPD_CONFIG_SYN_INTERFACE_INFO: 
			    stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len);
			    mcp_recv_pppd_interface_info_ack(tmp_s, 1);
				stream_forward_getp(data_s, len);
				stream_reset(tmp_s);
				break;
			    
			default:
				zlog_err("mcp<%s:%d> wrong type:%u",__FUNCTION__,__LINE__,type);
				goto error;
		}		
	}

    stream_free(tmp_s);
	return 0;

error:
    stream_free(tmp_s);
	return -1;	
}
示例#2
0
文件: zserv.c 项目: OPSF/uClinux
/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client. 
 *
 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
 *   from the client, after the ZEBRA_INTERFACE_ADD has been
 *   sent from zebra to the client
 * - redistribute new address info to all clients in the following situations
 *    - at startup, when zebra figures out the available interfaces
 *    - when an interface is added (where support for
 *      RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
 *      an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
 *      received)
 *    - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
 *      and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
 *    - when an RTM_NEWADDR message is received from the kernel,
 * 
 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE: 
 *
 *                   zsend_interface_address(DELETE)
 *                           ^                         
 *                           |                        
 *          zebra_interface_address_delete_update    
 *             ^                        ^      ^
 *             |                        |      if_delete_update (not called on 
 *             |                        |                         Solaris)
 *         ip_address_uninstall        connected_delete_ipv4
 *         [ipv6_addresss_uninstall]   [connected_delete_ipv6]
 *             ^                        ^
 *             |                        |
 *             |                  RTM_NEWADDR on routing/netlink socket
 *             |
 *         vty commands:
 *     "no ip address A.B.C.D/M [label LINE]"
 *     "no ip address A.B.C.D/M secondary"
 *     ["no ipv6 address X:X::X:X/M"]
 *
 */
int
zsend_interface_address (int cmd, struct zserv *client, 
                         struct interface *ifp, struct connected *ifc)
{
  int blen;
  struct stream *s;
  struct prefix *p;

  /* Check this client need interface information. */
  if (! client->ifinfo)
    return -1;

  s = client->obuf;
  stream_reset (s);

  /* Place holder for size. */
  stream_putw (s, 0);

  stream_putc (s, cmd);
  stream_putl (s, ifp->ifindex);

  /* Interface address flag. */
  stream_putc (s, ifc->flags);

  /* Prefix information. */
  p = ifc->address;
  stream_putc (s, p->family);
  blen = prefix_blen (p);
  stream_put (s, &p->u.prefix, blen);

  /* 
   * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
   * but zebra_interface_address_delete_read() in the gnu version 
   * expects to find it
   */
  stream_putc (s, p->prefixlen);

  /* Destination. */
  p = ifc->destination;
  if (p)
    stream_put (s, &p->u.prefix, blen);
  else
    stream_put (s, NULL, blen);

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));

  return 0;
}
示例#3
0
文件: token.c 项目: 74AC153/paren
void token_print(stream_t *s, tok_state_t *state)
{
	char buf[17];
	switch(state->type) {
	case TOK_SYM: 
		stream_put(s, "TOK_SYM(", state->u.sym, ")\n", NULL);
		break;
	case TOK_LIT:
		stream_put(s, "TOK_LIT(0x", fmt_u64(buf, state->u.lit), ")\n", NULL);
		break;
	default:
		stream_put(s, token_type_names[state->type], "\n", NULL);
		break;
	}
}
示例#4
0
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int
zsend_router_id_update (struct zserv *client, struct prefix *p)
{
  struct stream *s;
  int blen;

  /* Check this client need interface information. */
  if (!client->ridinfo)
    return 0;

  s = client->obuf;
  stream_reset (s);

  /* Message type. */
  zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);

  /* Prefix information. */
  stream_putc (s, p->family);
  blen = prefix_blen (p);
  stream_put (s, &p->u.prefix, blen);
  stream_putc (s, p->prefixlen);

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  return zebra_server_send_message(client);
}
示例#5
0
/*
 * The cmd passed to zsend_interface_update  may be ZEBRA_INTERFACE_UP or
 * ZEBRA_INTERFACE_DOWN.
 *
 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
 * the clients in one of 2 situations:
 *   - an if_up is detected e.g., as a result of an RTM_IFINFO message
 *   - a vty command modifying the bandwidth of an interface is received.
 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
 */
int
zsend_interface_update (int cmd, struct zserv *client, struct interface_FOO *ifp)
{
  struct stream *s;

  /* Check this client need interface information. */
  if (! client->ifinfo)
    return 0;

  s = client->obuf;
  stream_reset (s);

  zserv_create_header (s, cmd);

  /* Interface information. */
  stream_put (s, ifp->name, INTERFACE_NAMSIZ);
  stream_putl (s, ifp->ifindex);
  stream_putc (s, ifp->status);
  stream_putq (s, ifp->flags);
  stream_putl (s, ifp->metric);
  stream_putl (s, ifp->mtu);
  stream_putl (s, ifp->mtu6);
  stream_putl (s, ifp->bandwidth);

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  return zebra_server_send_message(client);
}
示例#6
0
文件: zserv.c 项目: OPSF/uClinux
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int
zsend_router_id_update (struct zserv *client, struct prefix *p)
{
  struct stream *s;
  int blen;

  /* Check this client need interface information. */
  if (!client->ridinfo)
    return -1;

  s = client->obuf;
  stream_reset (s);

  /* Place holder for size. */
  stream_putw (s, 0);

  /* Message type. */
  stream_putc (s, ZEBRA_ROUTER_ID_UPDATE);

  /* Prefix information. */
  stream_putc (s, p->family);
  blen = prefix_blen (p);
  stream_put (s, &p->u.prefix, blen);
  stream_putc (s, p->prefixlen);

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  return writen (client->sock, s->data, stream_get_endp (s));
}
示例#7
0
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);
}
示例#8
0
struct bgp_nexthop_cache *
zlookup_query_ipv6 (struct in6_addr *addr)
{
  int ret;
  struct stream *s;

  /* Check socket. */
  if (zlookup->sock < 0)
    return NULL;

  s = zlookup->obuf;
  stream_reset (s);
  zclient_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
  stream_put (s, addr, 16);
  stream_putw_at (s, 0, stream_get_endp (s));
  
  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 NULL;
    }
  if (ret == 0)
    {
      zlog_err ("zlookup->sock connection closed");
      close (zlookup->sock);
      zlookup->sock = -1;
      return NULL;
    }

  return zlookup_read_ipv6 ();
}
示例#9
0
文件: zserv.c 项目: OPSF/uClinux
/*
 * The cmd passed to zsend_interface_update  may be ZEBRA_INTERFACE_UP or
 * ZEBRA_INTERFACE_DOWN.
 *
 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
 * the clients in one of 2 situations:
 *   - an if_up is detected e.g., as a result of an RTM_IFINFO message
 *   - a vty command modifying the bandwidth of an interface is received.
 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
 */
int
zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
{
  struct stream *s;

  /* Check this client need interface information. */
  if (! client->ifinfo)
    return -1;

  s = client->obuf;
  stream_reset (s);

  /* Place holder for size. */
  stream_putw (s, 0);

  /* Zebra command. */
  stream_putc (s, cmd);

  /* Interface information. */
  stream_put (s, ifp->name, INTERFACE_NAMSIZ);
  stream_putl (s, ifp->ifindex);
  stream_putc (s, ifp->status);
  stream_putl (s, ifp->flags);
  stream_putl (s, ifp->metric);
  stream_putl (s, ifp->mtu);
  stream_putl (s, ifp->mtu6);
  stream_putl (s, ifp->bandwidth);

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));

  return 0;
}
示例#10
0
文件: zserv.c 项目: OPSF/uClinux
int
zsend_interface_delete (struct zserv *client, struct interface *ifp)
{
  struct stream *s;

  /* Check this client need interface information. */
  if (! client->ifinfo)
    return -1;

  s = client->obuf;
  stream_reset (s);

  /* Packet length placeholder. */
  stream_putw (s, 0);

  /* Interface information. */
  stream_putc (s, ZEBRA_INTERFACE_DELETE);
  stream_put (s, ifp->name, INTERFACE_NAMSIZ);
  stream_putl (s, ifp->ifindex);
  stream_putc (s, ifp->status);
  stream_putl (s, ifp->flags);
  stream_putl (s, ifp->metric);
  stream_putl (s, ifp->mtu);
  stream_putl (s, ifp->mtu6);
  stream_putl (s, ifp->bandwidth);

  /* Write packet length. */
  stream_putw_at (s, 0, stream_get_endp (s));

  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));

  return 0;
}
示例#11
0
static void
rip_auth_write_leading_rte
(
  struct stream *s,
  struct rip_interface *ri,
  const u_int8_t key_id,
  char *auth_str,
  u_int16_t main_body_len
)
{
  u_int8_t dlen;

  if (IS_RIP_DEBUG_AUTH)
    zlog_debug ("writing authentication header for %uB of main body", main_body_len);
  stream_putw (s, RIP_FAMILY_AUTH);
  switch (ri->auth_type)
  {
  case RIP_AUTH_SIMPLE_PASSWORD:
    {
      u_int8_t padded_simple_password[RIP_AUTH_SIMPLE_SIZE] = { 0 };
      memcpy (padded_simple_password, auth_str, MIN (RIP_AUTH_SIMPLE_SIZE, strlen (auth_str)));
      stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
      stream_put (s, padded_simple_password, RIP_AUTH_SIMPLE_SIZE);
      break;
    }
  case RIP_AUTH_HASH:
    if (IS_RIP_DEBUG_AUTH)
      zlog_debug ("hash algorithm is '%s'", LOOKUP (hash_algo_str, ri->hash_algo));
    stream_putw (s, RIP_AUTH_HASH);
    stream_putw (s, main_body_len);
    stream_putc (s, key_id);
    switch (ri->hash_algo)
    {
    case HASH_KEYED_MD5:
      /* Auth Data Len.  Set 16 for MD5 authentication data. Older ripds
       * however expect RIP_HEADER_SIZE + HASH_SIZE_MD5 so we allow for this
       * to be configurable. */
      dlen = ri->md5_auth_len;
      break;
    case HASH_HMAC_SHA1:
    case HASH_HMAC_SHA256:
    case HASH_HMAC_SHA384:
    case HASH_HMAC_SHA512:
      dlen = hash_digest_length[ri->hash_algo];
      break;
    default:
      assert (0);
    }
    if (IS_RIP_DEBUG_AUTH)
      zlog_debug ("declared auth data length is %uB", dlen);
    stream_putc (s, dlen);
    stream_putl (s, time (NULL)); /* Sequence Number (non-decreasing). */
    stream_putl (s, 0); /* reserved, MBZ */
    stream_putl (s, 0); /* reserved, MBZ */
    break;
  default:
    assert (0);
  }
}
示例#12
0
文件: zserv.c 项目: OPSF/uClinux
/*
 * This function is called in the following situations:
 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
 *   from the client.
 * - at startup, when zebra figures out the available interfaces
 * - when an interface is added (where support for
 *   RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
 *   an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
 *   received)
 */
int
zsend_interface_add (struct zserv *client, struct interface *ifp)
{
  struct stream *s;

  /* Check this client need interface information. */
  if (! client->ifinfo)
    return -1;

  s = client->obuf;
  stream_reset (s);

  /* Place holder for size. */
  stream_putw (s, 0);

  /* Message type. */
  stream_putc (s, ZEBRA_INTERFACE_ADD);

  /* Interface information. */
  stream_put (s, ifp->name, INTERFACE_NAMSIZ);
  stream_putl (s, ifp->ifindex);
  stream_putc (s, ifp->status);
  stream_putl (s, ifp->flags);
  stream_putl (s, ifp->metric);
  stream_putl (s, ifp->mtu);
  stream_putl (s, ifp->mtu6);
  stream_putl (s, ifp->bandwidth);
#ifdef HAVE_SOCKADDR_DL
  stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
#else
  stream_putl (s, ifp->hw_addr_len);
  if (ifp->hw_addr_len)
    stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
#endif /* HAVE_SOCKADDR_DL */

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));

  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));

  return 0;
}
示例#13
0
PUBLIC sw_t
cmd_read_binary_b0__from_current_EF(const CmdAPDU *apdu)
{
	u8 i;

	if (apdu->Lc)
		return 0x0001;

	if (!apdu->Le)
		return 0x0001;

	/* ACK */
	stream_put(current->response, apdu->header->INS);

	/* for each block */
	for (i = 1; i <= apdu->Le; i++) {
		stream_put(current->response, i);
	}

	return SW__OK;
}
/* basic parsing test */
static void
parse_test (struct peer *peer, struct test_segment *t, int type)
{
  int ret;
  int oldfailed = failed;
  struct attr attr;
  struct bgp_nlri nlri;
#define RANDOM_FUZZ 35
  
  stream_reset (peer->ibuf);
  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
  
  stream_write (peer->ibuf, t->data, t->len);
  
  printf ("%s: %s\n", t->name, t->desc);

  if (type == BGP_ATTR_MP_REACH_NLRI)
    ret = bgp_mp_reach_parse (peer, t->len, &attr, BGP_ATTR_FLAG_OPTIONAL, BGP_INPUT_PNT (peer), &nlri);
  else
    ret = bgp_mp_unreach_parse (peer, t->len, BGP_ATTR_FLAG_OPTIONAL, BGP_INPUT_PNT (peer), &nlri);

  if (!ret)
    {
      safi_t safi = t->safi;
      
      if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
        failed++;
      
      printf ("MP: %u/%u (%u): recv %u, nego %u\n",
              t->afi, t->safi, safi,
              peer->afc_recv[t->afi][safi],
              peer->afc_nego[t->afi][safi]);
    }
  
  printf ("parsed?: %s\n", ret ? "no" : "yes");
  
  if (ret != t->parses)
    failed++;
  
  if (tty)
    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
                                         : VT100_GREEN "OK" VT100_RESET);
  else
    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
  
  if (failed)
    printf (" (%u)", failed);
  
  printf ("\n\n");
}
示例#15
0
static void
zserv_encode_interface (struct stream *s, struct interface *ifp)
{
  /* Interface information. */
  stream_put (s, ifp->name, INTERFACE_NAMSIZ);
  stream_putl (s, ifp->ifindex);
  stream_putc (s, ifp->status);
  stream_putq (s, ifp->flags);
  stream_putl (s, ifp->metric);
  stream_putl (s, ifp->mtu);
  stream_putl (s, ifp->mtu6);
  stream_putl (s, ifp->bandwidth);
#ifdef HAVE_STRUCT_SOCKADDR_DL
  stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
#else
  stream_putl (s, ifp->hw_addr_len);
  if (ifp->hw_addr_len)
    stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
#endif /* HAVE_STRUCT_SOCKADDR_DL */

  /* Write packet size. */
  stream_putw_at (s, 0, stream_get_endp (s));
}
示例#16
0
void
logon ()
{
  int len;
  char *sn = PARAM_SCREEN_NAME;
  char *pass;
  char login[11];
  stream_t stream;
  u_int16_t streamid = htons(0x16);

  log (LOG_NOTICE, _("Loging into provider as '%s'\n"), sn);
  get_password (sn, &pass);
  len = strlen (sn);
  if (len < 10)
    {
      strncpy (login, sn, len);
      memset (&login[len], ' ', 10 - len);
      sn = login;
      sn[10]=0;
    }

  stream_init(&stream);
  stream_put(&stream, sizeof(streamid), &streamid);
  add_atom(&stream, UNI_PID, UNI_START_STREAM, 0);
  add_atom(&stream, MAN_PID, MAN_SET_CONTEXT_RELATIVE, 1);
  add_atom(&stream, MAN_PID, MAN_SET_CONTEXT_INDEX, 5);
  add_atom(&stream, DE_PID , DE_DATA, sn);
  add_atom(&stream, MAN_PID, MAN_END_CONTEXT, 0);
  add_atom(&stream, MAN_PID, MAN_END_CONTEXT, 0);
  add_atom(&stream, MAN_PID, MAN_SET_CONTEXT_RELATIVE, 2);
  add_atom(&stream, DE_PID , DE_DATA, pass);
  add_atom(&stream, MAN_PID, MAN_END_CONTEXT, 0);
  add_atom(&stream, MAN_PID, MAN_SET_CONTEXT_RELATIVE, 16);
  add_atom(&stream, MAN_PID, MAN_SET_CONTEXT_INDEX, 1);
  add_atom(&stream, MAN_PID, MAN_END_CONTEXT, 0);
  add_atom(&stream, MAN_PID, MAN_END_CONTEXT, 0);
  add_atom(&stream, UNI_PID, UNI_END_STREAM, 0);
  fdo_send (TOKEN ("Dd"), stream.data, stream.used);
  stream_destroy(&stream);

  fdo_unregister (TOKEN ("SD"));
  fdo_register (TOKEN ("At"), login_confirm);
  fdo_register (TOKEN ("AT"), atom_handler);
  fdo_register (TOKEN ("at"), atom_handler);
}
示例#17
0
/* Main thread */
void usb_thread (void)
{
    for (;;)
    {
        bcond_wait(&usb_active);
        t_yield();
        int16_t c;
        while ((c = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)) > 0)
            stream_put(&cdc_instr, c);

        t_yield();
        while ( ! stream_empty(&cdc_outstr))
            CDC_Device_SendByte(&VirtualSerial_CDC_Interface, stream_get(&cdc_outstr));

        CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
        USB_USBTask();
    }
}
示例#18
0
/* make an aspath from a data stream */
static struct aspath *
make_aspath (const u_char *data, size_t len, int use32bit)
{
  struct stream *s = NULL;
  struct aspath *as;
  
  if (len)
    {
      s = stream_new (len);
      stream_put (s, data, len);
    }
  as = aspath_parse (s, len, use32bit);
  
  if (s)
    stream_free (s);
  
  return as;
}
示例#19
0
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);
}
示例#20
0
/* Dump common information. */
static void
bgp_dump_common (struct stream *obuf, struct peer *peer, int forceas4)
{
  char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

  /* Source AS number and Destination AS number. */
  if (forceas4 || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) )
    {
      stream_putl (obuf, peer->as);
      stream_putl (obuf, peer->local_as);
    }
  else
    {
      stream_putw (obuf, peer->as);
      stream_putw (obuf, peer->local_as);
    }

  if (peer->su.sa.sa_family == AF_INET)
    {
      stream_putw (obuf, peer->ifindex);
      stream_putw (obuf, AFI_IP);

      stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);

      if (peer->su_local)
	stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
      else
	stream_put (obuf, empty, IPV4_MAX_BYTELEN);
    }
#ifdef HAVE_IPV6
  else if (peer->su.sa.sa_family == AF_INET6)
    {
      /* Interface Index and Address family. */
      stream_putw (obuf, peer->ifindex);
      stream_putw (obuf, AFI_IP6);

      /* Source IP Address and Destination IP Address. */
      stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);

      if (peer->su_local)
	stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
      else
	stream_put (obuf, empty, IPV6_MAX_BYTELEN);
    }
#endif /* HAVE_IPV6 */
}
void remark_bundle_notify_mcp(unsigned int ifnum, unsigned int ifunit)
{
    struct remark_bundle bundleinfo;
    struct ppp_mcp_sock *peer;
    struct stream* s_new;

    return;
    peer = g_ppp_mcp_sock;
    
    bundleinfo.master = ifnum;
    bundleinfo.slave = ifunit;

    s_new = stream_new(1024);
    stream_putl(s_new, 4 + sizeof(struct remark_bundle));
    ppp_put_control_to_stream(s_new, REMARK_BUDLE_CMD);
    stream_put(s_new, (unsigned char*)(&bundleinfo), sizeof(struct remark_bundle));
    stream_fifo_push (peer->obuf, s_new);

    MCP_WRITE_ON (peer->t_write, ppp_tcp_write, peer, peer->fd);
//    MCP_TIMER_ON (peer->t_wait_bundle_ack, ppp_tcp_wait_notify_ack_timer, peer, CLIENT_WAIT_IPINFO_ACK_TIMER);

    return;
}
示例#22
0
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS)
{
	struct mcast_route_data mroute;
	struct stream *s;
	int suc = -1;

	memset(&mroute, 0, sizeof(mroute));
	STREAM_GET(&mroute.sg.src, msg, 4);
	STREAM_GET(&mroute.sg.grp, msg, 4);
	STREAM_GETL(msg, mroute.ifindex);

	if (IS_ZEBRA_DEBUG_KERNEL) {
		char sbuf[40];
		char gbuf[40];

		strlcpy(sbuf, inet_ntoa(mroute.sg.src), sizeof(sbuf));
		strlcpy(gbuf, inet_ntoa(mroute.sg.grp), sizeof(gbuf));

		zlog_debug("Asking for (%s,%s) mroute information", sbuf, gbuf);
	}

	suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);

stream_failure:
	s = stream_new(ZEBRA_MAX_PACKET_SIZ);

	stream_reset(s);

	zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id(zvrf));
	stream_put_in_addr(s, &mroute.sg.src);
	stream_put_in_addr(s, &mroute.sg.grp);
	stream_put(s, &mroute.lastused, sizeof(mroute.lastused));
	stream_putl(s, suc);

	stream_putw_at(s, 0, stream_get_endp(s));
	zserv_send_message(client, s);
}
示例#23
0
/* Dump common information. */
void
bgp_dump_common (struct stream *obuf, struct peer *peer)
{
  char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

  /* Source AS number and Destination AS number. */
  stream_putw (obuf, peer->as);
  stream_putw (obuf, peer->local_as);

  if (peer->afc[AFI_IP][SAFI_UNICAST])
    {
      stream_putw (obuf, peer->ifindex);
      stream_putw (obuf, AFI_IP);

      stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);

      if (peer->su_local)
	stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
      else
	stream_put (obuf, empty, IPV4_MAX_BYTELEN);
    }
#ifdef HAVE_IPV6
  else if (peer->afc[AFI_IP6][SAFI_UNICAST])
    {
      /* Interface Index and Address family. */
      stream_putw (obuf, peer->ifindex);
      stream_putw (obuf, AFI_IP6);

      /* Source IP Address and Destination IP Address. */
      stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);

      if (peer->su_local)
	stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
      else
	stream_put (obuf, empty, IPV6_MAX_BYTELEN);
    }
#endif /* HAVE_IPV6 */
}
示例#24
0
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);
}
示例#25
0
/* basic parsing test */
static void
parse_test (struct peer *peer, struct test_segment *t, int type)
{
  int parse_ret = 0, nlri_ret = 0;
  struct attr attr = { };
  struct bgp_nlri nlri = { };
  struct bgp_attr_parser_args attr_args = {
    .peer = peer,
    .length = t->len,
    .total = 1,
    .attr = &attr,
    .type = type,
    .flags = BGP_ATTR_FLAG_OPTIONAL, 
    .startp = BGP_INPUT_PNT (peer),
  };
#define RANDOM_FUZZ 35
  
  stream_reset (peer->ibuf);
  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
  
  stream_write (peer->ibuf, t->data, t->len);
  
  printf ("%s: %s\n", t->name, t->desc);
  
  if (type == BGP_ATTR_MP_REACH_NLRI)
    parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
  else
    parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
  
  if (parse_ret == 0 && t->afi_valid == VALID_AFI)
    assert (nlri.afi == t->afi && nlri.safi == t->safi);
  
  if (!parse_ret)
    {
      if (type == BGP_ATTR_MP_REACH_NLRI)
        nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
      else
        nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
    }
  
  handle_result (peer, t, parse_ret, nlri_ret);
}

static struct bgp *bgp;
static as_t asn = 100;

int
main (void)
{
  struct peer *peer;
  int i, j;
  
  conf_bgp_debug_fsm = -1UL;
  conf_bgp_debug_events = -1UL;
  conf_bgp_debug_packet = -1UL;
  conf_bgp_debug_normal = -1UL;
  conf_bgp_debug_as4 = -1UL;
  term_bgp_debug_fsm = -1UL;
  term_bgp_debug_events = -1UL;
  term_bgp_debug_packet = -1UL;
  term_bgp_debug_normal = -1UL;
  term_bgp_debug_as4 = -1UL;
  
  master = thread_master_create ();
  bgp_master_init ();
  bgp_option_set (BGP_OPT_NO_LISTEN);
  bgp_attr_init ();
  bgp_address_init ();
  
  if (fileno (stdout) >= 0) 
    tty = isatty (fileno (stdout));
  
  if (bgp_get (&bgp, &asn, NULL))
    return -1;
  
  peer = peer_create_accept (bgp);
  peer->host = (char *)"foo";
  peer->status = Established;
  
  for (i = AFI_IP; i < AFI_MAX; i++)
    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
      {
        peer->afc[i][j] = 1;
        peer->afc_adv[i][j] = 1;
      }
  
  i = 0;
  while (mp_reach_segments[i].name)
    parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);

  i = 0;
  while (mp_unreach_segments[i].name)
    parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);

  printf ("failures: %d\n", failed);
  return failed;
}
示例#26
0
文件: zserv.c 项目: OPSF/uClinux
int
zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
{
  struct stream *s;
  struct rib *rib;
  unsigned long nump;
  u_char num;
  struct nexthop *nexthop;

  /* Lookup nexthop. */
  rib = rib_match_ipv6 (addr);

  /* Get output stream. */
  s = client->obuf;
  stream_reset (s);

  /* Fill in result. */
  stream_putw (s, 0);
  stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
  stream_put (s, &addr, 16);

  if (rib)
    {
      stream_putl (s, rib->metric);
      num = 0;
      nump = s->putp;
      stream_putc (s, 0);
      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
	if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
	  {
	    stream_putc (s, nexthop->type);
	    switch (nexthop->type)
	      {
	      case ZEBRA_NEXTHOP_IPV6:
		stream_put (s, &nexthop->gate.ipv6, 16);
		break;
	      case ZEBRA_NEXTHOP_IPV6_IFINDEX:
	      case ZEBRA_NEXTHOP_IPV6_IFNAME:
		stream_put (s, &nexthop->gate.ipv6, 16);
		stream_putl (s, nexthop->ifindex);
		break;
	      case ZEBRA_NEXTHOP_IFINDEX:
	      case ZEBRA_NEXTHOP_IFNAME:
		stream_putl (s, nexthop->ifindex);
		break;
	      default:
                /* do nothing */
		break;
	      }
	    num++;
	  }
      stream_putc_at (s, nump, num);
    }
  else
    {
      stream_putl (s, 0);
      stream_putc (s, 0);
    }

  stream_putw_at (s, 0, stream_get_endp (s));
  
  zebra_server_send_message (client->sock, s->data, stream_get_endp (s));

  return 0;
}
示例#27
0
int stream_abort(ObjectStream* os) {

   ///   // TBD: this should be a per-repo config-option
   ///   static const time_t timeout_sec = 5;

   // fuse may call fuse-flush multiple times (one for every open stream).
   // but will not call flush after calling close().
   if (! (os->flags & OSF_OPEN)) {
      LOG(LOG_ERR, "%s isn't open\n", os->url);
      errno = EINVAL;            /* ?? */
      return -1;
   }
   else if (! (os->flags & OSF_WRITING)) {
      LOG(LOG_ERR, "%s aborting a read-stream is not supported\n", os->url);
      errno = ENOSYS;
      return -1;
   }

   // See NOTE, above, regarding the difference between reads and writes.
   void* retval;
   if (! pthread_tryjoin_np(os->op, &retval)) {
      LOG(LOG_INFO, "op-thread joined\n");
      os->flags |= OSF_JOINED;
   }
   else {

      if (os->flags & OSF_WRITING) {
         // signal ABORT to readfunc
         LOG(LOG_INFO, "(wr) sending (char*)1 (flags=0x%04x)\n", os->flags);
         os->flags |= OSF_ABORT;
         if (stream_put(os, (const char*)1, 1) != 1) {
            LOG(LOG_ERR, "stream_put((char*)1) failed\n");
            pthread_kill(os->op, SIGKILL);
            LOG(LOG_INFO, "killed thread\n");
         }
      }

      // check whether thread has returned.  Could mean a curl
      // error, an S3 protocol error, or server flaking out.
      LOG(LOG_INFO, "waiting for op-thread\n");
      if (stream_wait(os)) {
         LOG(LOG_ERR, "err joining op-thread\n");
         return -1;
      }
   }

   // thread has completed
   os->flags |= OSF_JOINED;
   LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc);

   if ((os->op_rc == CURLE_ABORTED_BY_CALLBACK)
       && (os->iob.read_pos == (char*)1)) {

      LOG(LOG_INFO, "op-thread return is as expected for ABORT\n");
      return 0;
   }
   else {
      errno = (os->op_rc ? EINVAL : 0);
      return os->op_rc;
   }
}
示例#28
0
// wait for the S3 GET/PUT to complete
int stream_sync(ObjectStream* os) {

   ///   // TBD: this should be a per-repo config-option
   ///   static const time_t timeout_sec = 5;
   void* retval;

   // fuse may call fuse-flush multiple times (one for every open stream).
   // but will not call flush after calling close().
   if (! (os->flags & OSF_OPEN)) {
      LOG(LOG_ERR, "%s isn't open\n", os->url);
      errno = EINVAL;            /* ?? */
      return -1;
   }

   // See NOTE, above, regarding the difference between reads and writes.
   if (! pthread_tryjoin_np(os->op, &retval)) {
      LOG(LOG_INFO, "op-thread joined\n");
      os->flags |= OSF_JOINED;
   }
   else {


      // If a stream_get/put timed-out waiting for their
      // writefunc/readfunc, then the locks are likely in an inconsistent
      // state.  [Either (a) the readfunc never posted iob_empty for
      // stream__put(), or (b) the writefunc never posted iob_full for
      // stream_get().]  In either case, the operation started by
      // stream_open() is declared a failure, and we shouldn't do any of
      // the normal cleanup stuff, like trying to write recovery-info, etc.
      // But we do need to the thread to stop before we return, because if
      // the writefunc/readfunc gets another callback, it will access parts
      // of the ObjectStream that are about to be deallocated.
      if (os->flags & OSF_TIMEOUT) {
         LOG(LOG_INFO, "cancelling timed-out thread\n");
         int rc = pthread_cancel(os->op);
         if (rc) {
            LOG(LOG_ERR, "cancellation failed (%s), killing thread\n",
                strerror(errno));
            pthread_kill(os->op, SIGKILL);
            LOG(LOG_INFO, "killed thread\n");
         }

         LOG(LOG_INFO, "waiting for terminated op-thread\n");
         if (stream_wait(os)) {
            LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno));
            return -1;
         }
      }

      // In this case, the get/put timed-out, but it did so inside SAFE_WAIT_KILL(),
      // rather than SAFE_WAIT(), so the thread has already been cancelled
      // and joined.
      else if (os->flags & OSF_TIMEOUT_K) {
         LOG(LOG_INFO, "timed-out thread already killed\n");
         LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc);
         errno = (os->op_rc ? EIO : 0);
         return os->op_rc;
      }


#if (LIBCURL_VERSION_MAJOR > 7) || ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR >= 45))
      // Our installed version of libcurl is 7.19.7.  We are experimenting
      // with a custom-built libcurl based on 7.45.0.  We notice that the
      // latter does not call streaming_readfunc() again, if stream_open()
      // provided a content-length (i.e. the request had a content-length
      // header, rather than being chunked-transfer-encoded), and the full
      // number of chars matching the content-length header has been sent.
      // In such a case, stream_sync() shouldn't use "stream_put(..0)" to
      // get the readfunc to quit, because the readfunc isn't running.
      //
      // NOTE: This behavior may actually be present in earlier versions of
      //     libcurl, in which case, the VERSION_MINOR here should be
      //     adjusted downwards, toward 19.
      else if ((os->flags & OSF_WRITING) &&
               os->content_len &&
               (os->content_len == os->written)) {
         LOG(LOG_INFO, "(wr) wrote content-len, no action needed (flags=0x%04x)\n",
             os->flags);
      }
#endif

      // signal EOF to readfunc
      else if (os->flags & OSF_WRITING) {
         LOG(LOG_INFO, "(wr) sending empty buffer (flags=0x%04x)\n", os->flags);
         if (stream_put(os, NULL, 0)) {
            LOG(LOG_ERR, "stream_put(0) failed\n");
            pthread_kill(os->op, SIGKILL);
            LOG(LOG_INFO, "killed thread\n");
         }
      }

      // signal QUIT to writefunc
      else {
         LOG(LOG_INFO, "(rd) sending empty buffer (flags=0x%04x)\n", os->flags);
         if (stream_get(os, NULL, 0)) {
            LOG(LOG_ERR, "stream_get(0) failed\n");
            pthread_kill(os->op, SIGKILL);
            LOG(LOG_INFO, "killed thread\n");
         }
      }


      // check whether thread has returned.  Could mean a curl
      // error, an S3 protocol error, or server flaking out.
      LOG(LOG_INFO, "waiting for op-thread\n");
      if (stream_wait(os)) {
         LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno));
         return -1;
      }
   }


   // thread has completed
   os->flags |= OSF_JOINED;

   if ((   os->flags & OSF_READING)
       && (os->op_rc == CURLE_WRITE_ERROR)) {
      // when we signalled writefunc to quit, it provoked this
      LOG(LOG_INFO, "op-thread returned CURLE_WRITE_ERROR as expected\n");
      return 0;
   }
   else {
      LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc);
      errno = (os->op_rc ? EIO : 0);
      return os->op_rc;
   }
}
示例#29
0
/* basic parsing test */
static void
parse_test (struct peer *peer, struct test_segment *t, int type)
{
  int ret;
  int capability = 0;
  as_t as4 = 0;
  int oldfailed = failed;
  int len = t->len;
#define RANDOM_FUZZ 35
  
  stream_reset (peer->ibuf);
  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
  
  switch (type)
    {
      case CAPABILITY:
        stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
        stream_putc (peer->ibuf, t->len);
        break;
      case DYNCAP:
/*        for (i = 0; i < BGP_MARKER_SIZE; i++)
          stream_putc (peer->, 0xff);
        stream_putw (s, 0);
        stream_putc (s, BGP_MSG_CAPABILITY);*/
        break;
    }
  stream_write (peer->ibuf, t->data, t->len);
  
  printf ("%s: %s\n", t->name, t->desc);

  switch (type)
    {
      case CAPABILITY:
        len += 2; /* to cover the OPT-Param header */
      case OPT_PARAM:
        printf ("len: %u\n", len);
        /* peek_for_as4 wants getp at capibility*/
        as4 = peek_for_as4_capability (peer, len);
        printf ("peek_for_as4: as4 is %u\n", as4);
        /* and it should leave getp as it found it */
        assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
        
        ret = bgp_open_option_parse (peer, len, &capability);
        break;
      case DYNCAP:
        ret = bgp_capability_receive (peer, t->len);
        break;
      default:
        printf ("unknown type %u\n", type);
        exit(1);
    }
  
  if (!ret && t->validate_afi)
    {
      safi_t safi = t->safi;
      
      if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
        failed++;
      
      printf ("MP: %u/%u (%u): recv %u, nego %u\n",
              t->afi, t->safi, safi,
              peer->afc_recv[t->afi][safi],
              peer->afc_nego[t->afi][safi]);
        
      if (t->afi_valid == VALID_AFI)
        {
        
          if (!peer->afc_recv[t->afi][safi])
            failed++;
          if (!peer->afc_nego[t->afi][safi])
            failed++;
        }
    }
  
  if (as4 != t->peek_for)
    {
      printf ("as4 %u != %u\n", as4, t->peek_for);
      failed++;
    }
  
  printf ("parsed?: %s\n", ret ? "no" : "yes");
  
  if (ret != t->parses)
    failed++;
  
  if (tty)
    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
                                         : VT100_GREEN "OK" VT100_RESET);
  else
    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
  
  if (failed)
    printf (" (%u)", failed);
  
  printf ("\n\n");
}
示例#30
0
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);
}