⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bgp_packet.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* If peer does not have the capability, send notification. */  if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))    {      plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",		peer->host);      bgp_notify_send (peer,		       BGP_NOTIFY_HEADER_ERR,		       BGP_NOTIFY_HEADER_BAD_MESTYPE);      return;    }  /* Status must be Established. */  if (peer->status != Established)     {      plog_err (peer->log,		"%s [Error] Route refresh packet received under status %s",		peer->host, LOOKUP (bgp_status_msg, peer->status));      bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);      return;    }  s = peer->ibuf;    /* Parse packet. */  afi = stream_getw (s);  reserved = stream_getc (s);  safi = stream_getc (s);  if (BGP_DEBUG (normal, NORMAL))    zlog_info ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",	       peer->host, afi, safi);  /* Check AFI and SAFI. */  if ((afi != AFI_IP && afi != AFI_IP6)      || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST	  && safi != BGP_SAFI_VPNV4))    {      if (BGP_DEBUG (normal, NORMAL))	{	  zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",		     peer->host, afi, safi);	}      return;    }  /* Adjust safi code. */  if (safi == BGP_SAFI_VPNV4)    safi = SAFI_MPLS_VPN;  if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)    {      u_char *end;      u_char when_to_refresh;      u_char orf_type;      u_int16_t orf_len;      if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)        {          zlog_info ("%s ORF route refresh length error", peer->host);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          return;        }      when_to_refresh = stream_getc (s);      end = stream_pnt (s) + (size - 5);      while (stream_pnt (s) < end)	{	  orf_type = stream_getc (s); 	  orf_len = stream_getw (s);	  if (orf_type == ORF_TYPE_PREFIX	      || orf_type == ORF_TYPE_PREFIX_OLD)	    {	      u_char *p_pnt = stream_pnt (s);	      u_char *p_end = stream_pnt (s) + orf_len;	      struct orf_prefix orfp;	      u_char common = 0;	      u_int32_t seq;	      int psize;	      char name[BUFSIZ];	      char buf[BUFSIZ];	      int ret;	      if (BGP_DEBUG (normal, NORMAL))		{		  zlog_info ("%s rcvd Prefixlist ORF(%d) length %d",			     peer->host, orf_type, orf_len);		}	      /* ORF prefix-list name */	      sprintf (name, "%s.%d.%d", peer->host, afi, safi);	      while (p_pnt < p_end)		{		  memset (&orfp, 0, sizeof (struct orf_prefix));		  common = *p_pnt++;		  if (common & ORF_COMMON_PART_REMOVE_ALL)		    {		      if (BGP_DEBUG (normal, NORMAL))			zlog_info ("%s rcvd Remove-All pfxlist ORF request", peer->host);		      prefix_bgp_orf_remove_all (name);		      break;		    }		  memcpy (&seq, p_pnt, sizeof (u_int32_t));		  p_pnt += sizeof (u_int32_t);		  orfp.seq = ntohl (seq);		  orfp.ge = *p_pnt++;		  orfp.le = *p_pnt++;		  orfp.p.prefixlen = *p_pnt++;		  orfp.p.family = afi2family (afi);		  psize = PSIZE (orfp.p.prefixlen);		  memcpy (&orfp.p.u.prefix, p_pnt, psize);		  p_pnt += psize;		  if (BGP_DEBUG (normal, NORMAL))		    zlog_info ("%s rcvd %s %s seq %u %s/%d ge %d le %d",			       peer->host,			       (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"), 			       (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),			       orfp.seq, 			       inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),			       orfp.p.prefixlen, orfp.ge, orfp.le);		  ret = prefix_bgp_orf_set (name, afi, &orfp,				 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),				 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));		  if (ret != CMD_SUCCESS)		    {		      if (BGP_DEBUG (normal, NORMAL))			zlog_info ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);		      prefix_bgp_orf_remove_all (name);		      break;		    }		}	      peer->orf_plist[afi][safi] =			 prefix_list_lookup (AFI_ORF_PREFIX, name);	    }	  stream_forward (s, orf_len);	}      if (BGP_DEBUG (normal, NORMAL))	zlog_info ("%s rcvd Refresh %s ORF request", peer->host,		   when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");      if (when_to_refresh == REFRESH_DEFER)	return;    }  /* First update is deferred until ORF or ROUTE-REFRESH is received */  if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))    UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);  /* Perform route refreshment to the peer */  bgp_announce_route (peer, afi, safi);}intbgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length){  u_char *end;  struct capability cap;  u_char action;  struct bgp *bgp;  afi_t afi;  safi_t safi;  bgp = peer->bgp;  end = pnt + length;  while (pnt < end)    {      /* We need at least action, capability code and capability length. */      if (pnt + 3 > end)        {          zlog_info ("%s Capability length error", peer->host);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          return -1;        }      action = *pnt;      /* Fetch structure to the byte stream. */      memcpy (&cap, pnt + 1, sizeof (struct capability));      /* Action value check.  */      if (action != CAPABILITY_ACTION_SET	  && action != CAPABILITY_ACTION_UNSET)        {          zlog_info ("%s Capability Action Value error %d",		     peer->host, action);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          return -1;        }      if (BGP_DEBUG (normal, NORMAL))	zlog_info ("%s CAPABILITY has action: %d, code: %u, length %u",		   peer->host, action, cap.code, cap.length);      /* Capability length check. */      if (pnt + (cap.length + 3) > end)        {          zlog_info ("%s Capability length error", peer->host);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          return -1;        }      /* We know MP Capability Code. */      if (cap.code == CAPABILITY_CODE_MP)        {	  afi = ntohs (cap.mpc.afi);	  safi = cap.mpc.safi;          /* Ignore capability when override-capability is set. */          if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))	    continue;	  /* Address family check.  */	  if ((afi == AFI_IP 	       || afi == AFI_IP6)	      && (safi == SAFI_UNICAST 		  || safi == SAFI_MULTICAST 		  || safi == BGP_SAFI_VPNV4))	    {	      if (BGP_DEBUG (normal, NORMAL))		zlog_info ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",			   peer->host,			   action == CAPABILITY_ACTION_SET 			   ? "Advertising" : "Removing",			   ntohs(cap.mpc.afi) , cap.mpc.safi);		  	      /* Adjust safi code. */	      if (safi == BGP_SAFI_VPNV4)		safi = SAFI_MPLS_VPN;	      	      if (action == CAPABILITY_ACTION_SET)		{		  peer->afc_recv[afi][safi] = 1;		  if (peer->afc[afi][safi])		    {		      peer->afc_nego[afi][safi] = 1;		      bgp_announce_route (peer, afi, safi);		    }		}	      else		{		  peer->afc_recv[afi][safi] = 0;		  peer->afc_nego[afi][safi] = 0;		  if (peer_active_nego (peer))		    bgp_clear_route (peer, afi, safi);		  else		    BGP_EVENT_ADD (peer, BGP_Stop);		} 	    }        }      else if (cap.code == CAPABILITY_CODE_REFRESH	       || cap.code == CAPABILITY_CODE_REFRESH_OLD)        {          /* Check length. */          if (cap.length != 0)            {              zlog_info ("%s Route Refresh Capability length error %d",                         peer->host, cap.length);              bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);              return -1;            }	            if (BGP_DEBUG (normal, NORMAL))            zlog_info ("%s CAPABILITY has %s ROUTE-REFRESH capability(%s) for all address-families",		       peer->host,		       action == CAPABILITY_ACTION_SET		       ? "Advertising" : "Removing",		       cap.code == CAPABILITY_CODE_REFRESH_OLD		       ? "old" : "new");	            /* BGP refresh capability */	  if (action == CAPABILITY_ACTION_SET)	    {	      if (cap.code == CAPABILITY_CODE_REFRESH_OLD)		SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);	      else		SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);	    }	  else	    {	      if (cap.code == CAPABILITY_CODE_REFRESH_OLD)		UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);	      else		UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);	    }        }      else        {          zlog_warn ("%s unrecognized capability code: %d - ignored",                     peer->host, cap.code);        }      pnt += cap.length + 3;    }  return 0;}/* Dynamic Capability is received. */voidbgp_capability_receive (struct peer *peer, bgp_size_t size){  u_char *pnt;  int ret;  /* Fetch pointer. */  pnt = stream_pnt (peer->ibuf);  if (BGP_DEBUG (normal, NORMAL))    zlog_info ("%s rcv CAPABILITY", peer->host);  /* If peer does not have the capability, send notification. */  if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))    {      plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",		peer->host);      bgp_notify_send (peer,		       BGP_NOTIFY_HEADER_ERR,		       BGP_NOTIFY_HEADER_BAD_MESTYPE);      return;    }  /* Status must be Established. */  if (peer->status != Established)    {      plog_err (peer->log,		"%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));      bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);      return;    }  /* Parse packet. */  ret = bgp_capability_msg_parse (peer, pnt, size);}/* BGP read utility function. */intbgp_read_packet (struct peer *peer){  int nbytes;  int readsize;  readsize = peer->packet_size - peer->ibuf->putp;  /* If size is zero then return. */  if (! readsize)    return 0;  /* Read packet from fd. */  nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);  /* If read byte is smaller than zero then error occured. */  if (nbytes < 0)     {      if (errno == EAGAIN)	return -1;      plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",		 peer->host, strerror (errno));      BGP_EVENT_ADD (peer, TCP_fatal_error);      return -1;    }    /* When read byte is zero : clear bgp peer and return */  if (nbytes == 0)     {      if (BGP_DEBUG (events, EVENTS))	plog_info (peer->log, "%s [Event] BGP connection closed fd %d",		   peer->host, peer->fd);      if (peer->status == Established) 	peer->last_reset = PEER_DOWN_CLOSE_SESSION;      BGP_EVENT_ADD (peer, TCP_connection_closed);      return -1;    }  /* We read partial packet. */  if (peer->ibuf->putp != peer->packet_size)    return -1;  return 0;}/* Marker check. */intbgp_marker_all_one (struct stream *s, int length){  int i;  for (i = 0; i < length; i++)    if (s->data[i] != 0xff)      return 0;  return 1;}/* Starting point of packet process function. */intbgp_read (struct thread *thread){  int ret;  u_char type = 0;  struct peer *peer;  bgp_size_t size;  char notify_data_length[2];  /* Yes first of all get peer pointer. */  peer = THREAD_ARG (thread);  peer->t_read = NULL;  /* For non-blocking IO check. */  if (peer->status == Connect)    {      bgp_connect_check (peer);      goto done;    }  else    {      if (peer->fd < 0)	{	  zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);	  return -1;	}      BGP_READ_ON (peer->t_read, bgp_read, peer->fd);    }  /* Read packet header to determine type of the packet */  if (peer->packet_size == 0)    peer->packet_size = BGP_HEADER_SIZE;  if (peer->ibuf->putp < BGP_HEADER_SIZE)    {      ret = bgp_read_packet (peer);      /* Header read error or partial read packet. */      if (ret < 0) 	goto done;      /* Get size and type. */      stream_forward (peer->ibuf, BGP_MARKER_SIZE);      memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);      size = stream_getw (peer->ibuf);      type = stream_getc (peer->ibuf);      if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)	zlog_info ("%s rcv message type %d, length (excl. header) %d",		   peer->host, type, size - BGP_HEADER_SIZE);      /* Marker check */      if (type == BGP_MSG_OPEN	  && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))	{	  bgp_notify_send (peer,			   BGP_NOTIFY_HEADER_ERR, 			   BGP_NOTIFY_HEADER_NOT_SYNC);	  goto done;	}      /* BGP type check. */      if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE 	  && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE 	  && type != BGP_MSG_ROUTE_REFRESH_NEW	  && type != BGP_MSG_ROUTE_REFRESH_OLD	  && type != BGP_MSG_CAPABILITY)	{	  if (BGP_DEBUG (normal, NORMAL))	    plog_err (peer->log,		      "%s unknown message type 0x%02x",		      peer->host, type);	  bgp_notify_send_with_data (peer,				     BGP_NOTIFY_HEADER_ERR,			 	     BGP_NOTIFY_HEADER_BAD_MESTYPE,				     &type, 1);	  goto done;	}      /* Mimimum packet length check. */      if ((size < BGP_HEADER_SIZE)	  || (size > BGP_MAX_PACKET_SIZE)	  || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)	  || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)	  || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)	  || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)	  || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)	  || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)	  || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))	{	  if (BGP_DEBUG (normal, NORMAL))	    plog_err (peer->log,		      "%s bad message length - %d for %s",		      peer->host, size, 		      type == 128 ? "ROUTE-REFRESH" :		      bgp_type_str[(int) type]);	  bgp_notify_send_with_data (peer,				     BGP_NOTIFY_HEADER_ERR,			  	     BGP_NOTIFY_HEADER_BAD_MESLEN,				     notify_data_length, 2);	  goto done;	}      /* Adjust size to message length. */      peer->packet_size = size;    }  ret = bgp_read_packet (peer);  if (ret < 0)     goto done;  /* Get size and type again. */  size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);  type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);  /* BGP packet dump function. */  bgp_dump_packet (peer, type, peer->ibuf);    size = (peer->packet_size - BGP_HEADER_SIZE);  /* Read rest of the packet and call each sort of packet routine */  switch (type)     {    case BGP_MSG_OPEN:      peer->open_in++;      bgp_open_receive (peer, size);      break;    case BGP_MSG_UPDATE:      peer->readtime = time(NULL);    /* Last read timer reset */      bgp_update_receive (peer, size);      break;    case BGP_MSG_NOTIFY:      bgp_notify_receive (peer, size);      break;    case BGP_MSG_KEEPALIVE:      peer->readtime = time(NULL);    /* Last read timer reset */      bgp_keepalive_receive (peer, size);      break;    case BGP_MSG_ROUTE_REFRESH_NEW:    case BGP_MSG_ROUTE_REFRESH_OLD:      peer->refresh_in++;      bgp_route_refresh_receive (peer, size);      break;    case BGP_MSG_CAPABILITY:      peer->dynamic_cap_in++;      bgp_capability_receive (peer, size);      break;    }  /* Clear input buffer. */  peer->packet_size = 0;  if (peer->ibuf)    stream_reset (peer->ibuf); done:  if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))    {      if (BGP_DEBUG (events, EVENTS))	zlog_info ("%s [Event] Accepting BGP peer delete", peer->host);      peer_delete (peer);    }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -