Beispiel #1
0
static int
bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
{
  struct stream *s = BGP_INPUT (peer);
  u_int16_t restart_flag_time;
  int restart_bit = 0;
  size_t end = stream_get_getp (s) + caphdr->length;

  SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
  restart_flag_time = stream_getw(s);
  if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
    restart_bit = 1;
  UNSET_FLAG (restart_flag_time, 0xF000);
  peer->v_gr_restart = restart_flag_time;

  if (BGP_DEBUG (normal, NORMAL))
    {
      zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
      zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
                  peer->host, restart_bit ? " " : " not ",
                  peer->v_gr_restart);
    }

  while (stream_get_getp (s) + 4 <= end)
    {
      afi_t afi = stream_getw (s);
      safi_t safi = stream_getc (s);
      u_char flag = stream_getc (s);
      
      if (!bgp_afi_safi_valid_indices (afi, &safi))
        {
          if (BGP_DEBUG (normal, NORMAL))
            zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
                        " Ignore the Graceful Restart capability",
                        peer->host, afi, safi);
        }
      else if (!peer->afc[afi][safi])
        {
          if (BGP_DEBUG (normal, NORMAL))
            zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
                        " Ignore the Graceful Restart capability",
                        peer->host, afi, safi);
        }
      else
        {
          if (BGP_DEBUG (normal, NORMAL))
            zlog_debug ("%s Address family %s is%spreserved", peer->host,
                        afi_safi_print (afi, safi),
                        CHECK_FLAG (peer->af_cap[afi][safi],
                                    PEER_CAP_RESTART_AF_PRESERVE_RCV)
                        ? " " : " not ");

          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
          if (CHECK_FLAG (flag, RESTART_F_BIT))
            SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
          
        }
    }
  return 0;
}
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;	
}
Beispiel #3
0
static void ospf_packet_db_desc_dump(struct stream *s, uint16_t length)
{
	struct ospf_db_desc *dd;
	char dd_flags[8];

	uint32_t gp;

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

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

	length -= OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE;

	stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE);

	ospf_lsa_header_list_dump(s, length);

	stream_set_getp(s, gp);
}
Beispiel #4
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);
}
Beispiel #5
0
void
clear_checksum_streams (uint16_t checksum)
{
  struct listnode * node, * nnode;
  struct sisis_listener * listener;

  for(ALL_LIST_ELEMENTS (sm->listen_sockets, node, nnode, listener))
  {
     if(stream_get_getp(listener->chksum_stream) < stream_get_endp(listener->chksum_stream))
     {
       uint16_t checksum_head = stream_getw(listener->chksum_stream);
       if(checksum_head != checksum)
       {
         stream_putw(listener->chksum_stream, checksum_head);
         uint16_t next_checksum = stream_peekw(listener->chksum_stream);
         while(next_checksum != checksum_head)
         {
           next_checksum = stream_getw(listener->chksum_stream);
           if(next_checksum != checksum)
             stream_putw(listener->chksum_stream, next_checksum);
         }
       }
     }
  }
}
Beispiel #6
0
unsigned int
are_checksums_same (void)
{
  int same = 0;
  int first_iter = 1;
  struct listnode * node, * nnode;
  struct sisis_listener * listener;
  u_int16_t chksum_swp;
  int i =  0;

  for(ALL_LIST_ELEMENTS (sm->listen_sockets, node, nnode, listener))
  {
    zlog_debug("iter: %d", i);
    i++;
    zlog_debug("getp before: %d", stream_get_getp(listener->chksum_stream));
    zlog_debug("endp before: %d", stream_get_endp(listener->chksum_stream));
    if(stream_get_endp(listener->chksum_stream) != stream_get_getp(listener->chksum_stream))
    {
      u_int16_t chksum = stream_getw(listener->chksum_stream);
      zlog_debug("getp after: %d", stream_get_getp(listener->chksum_stream));
      zlog_debug("endp after: %d", stream_get_endp(listener->chksum_stream));
      zlog_debug("checksum: %d", chksum);
      if(first_iter)
      {
        chksum_swp = chksum;
        first_iter = 0;
      }
      else if(chksum == chksum_swp)
      {
        same = 1;
        chksum_swp = chksum;
      }
      else
      {
        return 0;
      }
    }
  }

  return same;
}
Beispiel #7
0
static int
bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
{
  struct stream *s = BGP_INPUT (peer);
  size_t end = stream_get_getp (s) + hdr->length;
  
  assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
  
  /* We must have at least one ORF entry, as the caller has already done
   * minimum length validation for the capability code - for ORF there must
   * at least one ORF entry (header and unknown number of pairs of bytes).
   */
  do
    {
      if (bgp_capability_orf_entry (peer, hdr) == -1)
        return -1;
    } 
  while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
  
  return 0;
}
Beispiel #8
0
static void ospf_packet_ls_ack_dump(struct stream *s, uint16_t length)
{
	uint32_t sp;

	length -= OSPF_HEADER_SIZE;
	sp = stream_get_getp(s);

	zlog_debug("Link State Acknowledgment");
	ospf_lsa_header_list_dump(s, length);

	stream_set_getp(s, sp);
}
Beispiel #9
0
void
reset_checksum_streams (void)
{
  struct listnode * node, * nnode;
  struct sisis_listener * listener;

  for(ALL_LIST_ELEMENTS (sm->listen_sockets, node, nnode, listener))
  {
    if(stream_get_endp(listener->chksum_stream) == stream_get_getp(listener->chksum_stream))
      stream_reset(listener->chksum_stream);
  }
}
Beispiel #10
0
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;
}
Beispiel #11
0
void ospf_packet_dump(struct stream *s)
{
	struct ospf_header *ospfh;
	unsigned long gp;

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

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

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

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

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

	stream_set_getp(s, gp);
}
Beispiel #12
0
static void
print_stream (struct stream *s)
{
  size_t getp = stream_get_getp (s);
  
  printf ("endp: %zu, readable: %zu, writeable: %zu\n",
          stream_get_endp (s),
          STREAM_READABLE (s),
          STREAM_WRITEABLE (s));
  
  while (STREAM_READABLE (s))
    {
      printf ("0x%x ", *stream_pnt (s));
      stream_forward_getp (s, 1);
    }
  
  printf ("\n");
  
  /* put getp back to where it was */
  stream_set_getp (s, getp);
}
Beispiel #13
0
/*udp write process*/
int udp_write(struct peer *peer){
        struct stream *s;
  	int num;
  	int count =0;
      	int writenum;

        //get first stream;
  	s = misaka_write_packet (peer->obuf);
  	if (!s)
    		return 0;	
	/* udp Nonblocking write */
  	do
        {

      		/* Number of bytes to be sent.  */
      		writenum = stream_get_endp (s) - stream_get_getp (s);
		
      		/* Call write() system call.*/
      		num = sendto(peer->fd, STREAM_PNT (s), writenum, \
                0, (struct sockaddr*)&s->dsu.sin, sizeof(struct sockaddr));

      		if (num < 0)
		{
	 		       
		}

      		if (num != writenum)
		{
	  		     
		}
   
      		/*OK we send packet so delete packet. */
      		misaka_packet_delete (peer->obuf);

    	 }while (++count < MISAKA_WRITE_PACKET_MAX && (s = misaka_write_packet (peer->obuf)) != NULL);
         return count;  
}
Beispiel #14
0
static void ospf_packet_ls_upd_dump(struct stream *s, uint16_t length)
{
	uint32_t sp;
	struct lsa_header *lsa;
	int lsa_len;
	uint32_t count;

	length -= OSPF_HEADER_SIZE;

	sp = stream_get_getp(s);

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

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

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

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

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

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

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

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

                  /* Unsupported Capability. */
                  if (ret < 0)
                    {
                      /* Store return data. */
                      memcpy (*error, sp, caphdr.length + 2);
                      *error += caphdr.length + 2;
                    }
                }
            }
            break;
          case CAPABILITY_CODE_REFRESH:
          case CAPABILITY_CODE_REFRESH_OLD:
            {
              /* BGP refresh capability */
              if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
                SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
              else
                SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
            }
            break;
          case CAPABILITY_CODE_ORF:
          case CAPABILITY_CODE_ORF_OLD:
            if (bgp_capability_orf (peer, &caphdr))
              return -1;
            break;
          case CAPABILITY_CODE_RESTART:
            if (bgp_capability_restart (peer, &caphdr))
              return -1;
            break;
          case CAPABILITY_CODE_DYNAMIC:
            SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
            break;
          case CAPABILITY_CODE_AS4:
              /* Already handled as a special-case parsing of the capabilities
               * at the beginning of OPEN processing. So we care not a jot
               * for the value really, only error case.
               */
              if (!bgp_capability_as4 (peer, &caphdr))
                return -1;
              break;            
          default:
            if (caphdr.code > 128)
              {
                /* We don't send Notification for unknown vendor specific
                   capabilities.  It seems reasonable for now...  */
                zlog_warn ("%s Vendor specific capability %d",
                           peer->host, caphdr.code);
              }
            else
              {
                zlog_warn ("%s unrecognized capability code: %d - ignored",
                           peer->host, caphdr.code);
                memcpy (*error, sp, caphdr.length + 2);
                *error += caphdr.length + 2;
              }
          }
      if (stream_get_getp(s) != (start + caphdr.length))
        {
          if (stream_get_getp(s) > (start + caphdr.length))
            zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
                       peer->host, LOOKUP (capcode_str, caphdr.code),
                       caphdr.length);
          stream_set_getp (s, start + caphdr.length);
        }
    }
  return 0;
}
Beispiel #16
0
/* peek into option, stores ASN to *as4 if the AS4 capability was found.
 * Returns  0 if no as4 found, as4cap value otherwise.
 */
as_t
peek_for_as4_capability (struct peer *peer, u_char length)
{
  struct stream *s = BGP_INPUT (peer);
  size_t orig_getp = stream_get_getp (s);
  size_t end = orig_getp + length;
  as_t as4 = 0;
  
  /* The full capability parser will better flag the error.. */
  if (STREAM_READABLE(s) < length)
    return 0;

  if (BGP_DEBUG (as4, AS4))
    zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
                " peeking for as4",
	        peer->host, length);
  /* the error cases we DONT handle, we ONLY try to read as4 out of
   * correctly formatted options.
   */
  while (stream_get_getp(s) < end) 
    {
      u_char opt_type;
      u_char opt_length;
      
      /* Check the length. */
      if (stream_get_getp (s) + 2 > end)
        goto end;
      
      /* Fetch option type and length. */
      opt_type = stream_getc (s);
      opt_length = stream_getc (s);
      
      /* Option length check. */
      if (stream_get_getp (s) + opt_length > end)
        goto end;
      
      if (opt_type == BGP_OPEN_OPT_CAP)
        {
          unsigned long capd_start = stream_get_getp (s);
          unsigned long capd_end = capd_start + opt_length;
          
          assert (capd_end <= end);
          
	  while (stream_get_getp (s) < capd_end)
	    {
	      struct capability_header hdr;
	      
	      if (stream_get_getp (s) + 2 > capd_end)
                goto end;
              
              hdr.code = stream_getc (s);
              hdr.length = stream_getc (s);
              
	      if ((stream_get_getp(s) +  hdr.length) > capd_end)
		goto end;

	      if (hdr.code == CAPABILITY_CODE_AS4)
	        {
	          if (BGP_DEBUG (as4, AS4))
	            zlog_info ("[AS4] found AS4 capability, about to parse");
	          as4 = bgp_capability_as4 (peer, &hdr);
	          
	          goto end;
                }
              stream_forward_getp (s, hdr.length);
	    }
	}
    }

end:
  stream_set_getp (s, orig_getp);
  return as4;
}
Beispiel #17
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");
}
int ppp_tcp_write (struct thread *thread)
{
	struct ppp_mcp_sock *peer;
	struct stream *stream;
	int num;
	int write_errno;
	int val, writenum;

	/* Yes first of all get peer pointer. */
	peer = THREAD_ARG (thread);
	peer->t_write = NULL;

	if (peer->fd < 0)
	{
		PPPD_DEBUG_TCP("write: peer's fd is negative value %d", peer->fd);
		return -1;
	}

	if(peer->connect_status != CLIENT_CONNECT_SERVER_OK)
	    return -1;
	
	while (1)
	{
		stream = stream_fifo_head(peer->obuf);
		if (stream == NULL)
			return 0;

		val = fcntl (peer->fd, F_GETFL, 0);
		fcntl (peer->fd, F_SETFL, val | O_NONBLOCK);

		/* Number of bytes to be sent.  */
		writenum = stream_get_endp (stream) - stream_get_getp (stream);

		/* Call write() system call.  */
		num = write (peer->fd, STREAM_PNT (stream), writenum);
		write_errno = errno;
		fcntl (peer->fd, F_SETFL, val);
		if (num < 0)
		{
			if (write_errno == EWOULDBLOCK || write_errno == EAGAIN || write_errno == EINTR)
				break;

            PPPD_DEBUG_TCP("erro,write packet to peer:%s, fd:%u", peer->hostname, peer->fd);
			ppp_connect_mcp_error_deal(peer);
			
			return 0;
		}

		/*发送了数据之后,推迟保活定时器*/
		if(num > 0)
			pppd_postpone_keepalive_timer(peer);

		if (num != writenum) {
			stream_forward_getp(stream, num);
			break;
		} else
		    stream_free(stream_fifo_pop (peer->obuf));
        
		break;
	}

	if(stream_fifo_head (peer->obuf))
		MCP_WRITE_ON (peer->t_write, ppp_tcp_write, peer, peer->fd);

	return 0;
}
Beispiel #19
0
/**
 * Parse open option.
 *
 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
 */
int
bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
{
  int ret;
  u_char *error;
  u_char error_data[BGP_MAX_PACKET_SIZE];
  struct stream *s = BGP_INPUT(peer);
  size_t end = stream_get_getp (s) + length;

  ret = 0;
  error = error_data;

  if (BGP_DEBUG (normal, NORMAL))
    zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
	       peer->host, length);
  
  while (stream_get_getp(s) < end)
    {
      u_char opt_type;
      u_char opt_length;
      
      /* Must have at least an OPEN option header */
      if (STREAM_READABLE(s) < 2)
	{
	  zlog_info ("%s Option length error", peer->host);
	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
	  return -1;
	}

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

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

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

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

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

  /* Check there are no common AFI/SAFIs and send Unsupported Capability
     error. */
  if (*mp_capability &&
      ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
    {
      if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] 
	  && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
	  && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
	  && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
	  && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
	{
	  plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not "
		    "overlap with received MP capabilities",
		    peer->host);

	  if (error != error_data)

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