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

📄 bgp.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	goto done;      }      /* V */      switch (bnp->rp_inpkt[i]) {      case PATH_ORG_IGP: case PATH_ORG_EGP: case PATH_ORG_XX:	if ((logflags & LOG_BGPINPUT))	  syslog(LOG_DEBUG, "BGP+ RECV\t\t%s", origin_str[bnp->rp_inpkt[i]]);	origin = bnp->rp_inpkt[i++];	break;      default:	/* If the ORIGIN attribute has an undefined value, then the Error	   Subcode is set to Invalid Origin Attribute.  The Data field contains	   the unrecognized attribute (type, length and value). */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_ORIGIN,		   atrlen, &bnp->rp_inpkt[k]);	goto done;	break;      }      break;    case  PA4_TYPE_ASPATH:      /* ASPATH (Type Code 2) well-known mandatory */         PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if ( (bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	  !(bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      /* construct AS_PATH */      if ((asp = msg2aspath(bnp, i, atrdatalen, &error)) == NULL) {	switch (error) {	case EINVAL:	  bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_ASPATH, 0, NULL);	  goto done;	default:   /* AS path loop detected. this msg is to be ignore. */	  goto done;  /*  iw97                                            */	}      }      i += atrdatalen;      break;    case PA4_TYPE_NEXTHOP:      /* NEXT_HOP (Type Code 3) well-known mandatory */         /* check syntax only. */       PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if ( (bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	  !(bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {       /* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS, atrlen,		   &bnp->rp_inpkt[k]);	goto done;      }      /* IPv4 specific */      if (atrdatalen != PA_LEN_NEXTHOP) {         /* Attribute Length Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      i += sizeof(struct in_addr);      break;    case PA4_TYPE_METRIC:      /* MULTI_EXIT_DISC (Type Code 4) optional non-transitive */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      /* optional non-transitive attributes the Partial bit must be	 set to 0. */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	   (bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      if (atrdatalen != PA4_LEN_METRIC) {      /* Attribute Length Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      if ((logflags & LOG_BGPINPUT))	syslog(LOG_DEBUG, "BGP+ RECV\t\t%d",	       ntohl(*(u_int32_t *)&bnp->rp_inpkt[i]));      med = *(u_int32_t *)&bnp->rp_inpkt[i];     /* net-order */      i += atrdatalen;      break;    case PA4_TYPE_LOCALPREF:      /* LOCAL_PREF (Type Code 5) well-known mandatory      */      /*  If it is received from an external peer,          */      /* then this attribute MUST be ignored. [BGP4+ 5.1.5] */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      if (bnp->rp_mode & BGPO_IGP) {	/* T */	if ( (bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	    !(bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	     (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	  bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		     atrlen, &bnp->rp_inpkt[k]);	  goto done;	}	if (atrdatalen != PA4_LEN_LOCALPREF) {  /* Attribute Length Error */	  bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		     atrlen,&bnp->rp_inpkt[k]);	  goto done;	}	/* V */	if ((logflags & LOG_BGPINPUT))	  syslog(LOG_DEBUG, "BGP+ RECV\t\t%d",		 ntohl(*(u_int32_t *)&bnp->rp_inpkt[i]));	if (bnp->rp_mode & BGPO_IGP)	  localpref = *(u_int32_t *)&bnp->rp_inpkt[i]; /* net-order */      }      i += atrdatalen;      break;    case PA4_TYPE_ATOMICAGG:      /* ATOMIC_AGGREGATE (Type Code 6) well-known discretinary */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if ( (bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	  !(bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      if (atrdatalen != PA4_LEN_ATOMICAGG) {    /* Attribute Length Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      aggregated = PATH_FLAG_ATOMIC_AGG;      i += PA4_LEN_ATOMICAGG; /* this has no data */      break;    case PA4_TYPE_AGGREGATOR:      /* AGGREGATOR (Type Code 7) optional transitive            */      /* this is used for debugging (furthermore, for IPv4 only) */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)    ||	  !(bnp->rp_inpkt[k] & PA_FLAG_TRANS))    {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      if (atrdatalen != PA4_LEN_AGGREGATOR) {   /* Attribute Length Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      i += PA4_LEN_AGGREGATOR;  /* specific for IPv4, so ignored. */      break;#ifdef notyet    case PA4_TYPE_COMMUNITY:      /* COMMUNITY (Type Code 8) optional transitive       */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)    ||	  !(bnp->rp_inpkt[k] & PA_FLAG_TRANS))    {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      if (atrdatalen != 0) {	      if ((coml = msg2communitylist(bnp, i, atrdatalen)) == NULL)		      goto done;      }      i += atrdatalen;      break;#endif /* notyet */    case PA4_TYPE_ORIGINATOR:      /* ORIGINATOR_ID (Type Code 9) optional non-transitive       */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      /* optional non-transitive attributes the Partial bit must be	 set to 0. */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	   (bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      if (atrdatalen != PA4_LEN_ORIGINATOR) {   /* Attribute Length Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      /* This attribute is 4 bytes long and it will be created by a RR. 	 [rfc1966] */      if ((logflags & LOG_BGPINPUT))	syslog(LOG_DEBUG, "BGP+ RECV\t\t%s", 	       /*	     ntohl(*(u_int32_t *)&bnp->rp_inpkt[i])); */	       inet_ntoa(*(struct in_addr *)&bnp->rp_inpkt[i]));      if ( (bnp->rp_mode & BGPO_IGP) &&	  !(bnp->rp_mode & BGPO_RRCLIENT))	originatorid = *(u_int32_t *)&bnp->rp_inpkt[i];      i += atrdatalen;      break;    case PA4_TYPE_CLUSTERLIST:      /* CLUSTER_LIST (Type Code 10) optional non-transitive       */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      /* optional non-transitive attributes the Partial bit must be	 set to 0. */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	   (bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* V */      /* construct CLUSTER_LIST */      /* If the local CLUSTER_ID is found in the cluster-list,	 the advertisement will be ignored.        [rfc1966] */      if (atrdatalen != 0             &&	  (bnp->rp_mode & BGPO_IGP))  {	if ((cll = msg2clstrlist(bnp, i, atrdatalen)) == NULL)	  goto done;      }      i += atrdatalen;      break;    case PA4_TYPE_MPREACHNLRI:      /* MP_REACH_NLRI (Type Code 14) optional non-transitive */      PA4_TYPE_CODE_CHECK;      PA4_LEN_PARSE;      /* T */      if (!(bnp->rp_inpkt[k] & PA_FLAG_OPT)     ||	   (bnp->rp_inpkt[k] & PA_FLAG_TRANS)   ||	   (bnp->rp_inpkt[k] & PA_FLAG_PARTIAL))   {	/* Attribute Flags Error */	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_FLAGS,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }      /* Address Family Identifier            (2 octets) */      if (ntohs(*(u_int16_t *)&bnp->rp_inpkt[i]) != AFN_IP6) {	syslog(LOG_NOTICE,	       "<%s>: AFI is not AFN_IP6 (%d).", __FUNCTION__, AFN_IP6);	i += atrdatalen;	break;   /* Gently ignore :-) */      }      i += 2;      /* SAFI */      /* Subsequent Address Family Identifier (1 octet) */      if (bnp->rp_inpkt[i++] != PA4_MP_UCAST) {      /* implmntd for UNIcast only */	syslog(LOG_NOTICE,	       "<%s>: SAFI isn't (%d). I only support unicast", __FUNCTION__,	       PA4_MP_UCAST);	i = k + atrlen;	break;    /* Quietly ignore :-< */      }      /* Length of Next Hop Network Address   (1 octet) */      nhnalen = bnp->rp_inpkt[i++];      if (!((nhnalen == sizeof(struct in6_addr)) ||	    (nhnalen == sizeof(struct in6_addr) * 2))) {	syslog(LOG_NOTICE,	       "<%s>: nexthop address length (%d) cannot accepted.",	       __FUNCTION__, (int)nhnalen);	i = k + atrlen;	break; /* this attribute */      }      /* Network Address of Next Hop          (variable)  */      gnhaddr = *(struct in6_addr *)&bnp->rp_inpkt[i]; /* (normally) */      if ((logflags & LOG_BGPINPUT)) {	syslog(LOG_DEBUG, "BGP+ RECV\t\tNextHop");	syslog(LOG_DEBUG, "BGP+ RECV\t\t%s", ip6str(&gnhaddr, 0));      }      /*       * A BGP speaker shall advertise to its peer in the Network Address of       * Next Hop field the global IPv6 address of the next hop, potentially       * followed by the link-local IPv6 address of the next hop.       * [RFC 2545, Section 3]       */      if (IN6_IS_ADDR_LINKLOCAL(&gnhaddr)) { /* consider site-local as well? */	syslog(LOG_NOTICE,	       "<%s>: 1st next hop(%s) from %s is not global",	       __FUNCTION__, ip6str(&gnhaddr, 0), bgp_peerstr(bnp));	break;			/* go to next attribute */      }      IFLOG(LOG_BGPINPUT) {	if (!(IN6_IS_ADDR_UNSPECIFIED(&bnp->rp_gaddr)) &&   /* global */	    !(IN6_ARE_ADDR_EQUAL(&bnp->rp_gaddr, &gnhaddr)))	  syslog(LOG_DEBUG,		 "<%s>: Third Party NextHop %s from %s", __FUNCTION__,		 ip6str(&gnhaddr, 0), bgp_peerstr(bnp));      }      i += sizeof(struct in6_addr);      /*    RFC 2283,2545  bellow  */      if (nhnalen == sizeof(struct in6_addr) * 2) {	if (!IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)&bnp->rp_inpkt[i])) {	  syslog(LOG_NOTICE,		 "<%s>: 2nd next hop(%s) from %s is not link-local(ignored)",		 __FUNCTION__,		 ip6str((struct in6_addr *)&bnp->rp_inpkt[i], 0),		 bgp_peerstr(bnp));	}	else if ((bnp->rp_mode & BGPO_ONLINK) == 0) {	  /*	   * The link-local address shall be included in the Next Hop field	   * if and only if the BGP speaker shares a common subnet with the	   * entity identified by the global IPv6 address carried in the	   * Network Address of Next Hop field and the peer the route is	   * being advertised to.	   * [RFC 2545, Section 3.]	   */	  syslog(LOG_NOTICE,		 "<%s>: link-local next hop (%s) from an off-link peer(%s) "		 "(ignored)", __FUNCTION__,		 ip6str((struct in6_addr *)&bnp->rp_inpkt[i], 0),		 bgp_peerstr(bnp)); 	}	else {	  lnhaddr = *(struct in6_addr *)&bnp->rp_inpkt[i];	  IFLOG(LOG_BGPINPUT) {	    syslog(LOG_DEBUG, "BGP+ RECV\t\t%s",		   ip6str(&lnhaddr, 0));	    if (!(IN6_IS_ADDR_UNSPECIFIED(&bnp->rp_laddr)) &&		!(IN6_ARE_ADDR_EQUAL(&bnp->rp_laddr, &lnhaddr)))	      syslog(LOG_DEBUG,		     "<%s>: Third Party NextHop %s", __FUNCTION__,		     ip6str(&lnhaddr, 0));	  }	}	i += sizeof(struct in6_addr);      }      /* Number of SNPAs (1 octet) */      snpanum = bnp->rp_inpkt[i++];      for (j = 0; j < snpanum; j++) {	snpalen = bnp->rp_inpkt[i++];	i += ((snpalen % 2) ? snpalen / 2 + 1 : snpalen / 2);      }#ifdef DRAFT_IETF_00      /* Network Layer Reachability Information Length (2 Octets) */      nlrilen = ntohs(*(u_short *)&bnp->rp_inpkt[i]);      i += 2;      if (i + nlrilen  !=  k + atrlen) {	bgp_notify(bnp, BGP_ERR_UPDATE, BGP_ERRUPD_LENGTH,		   atrlen, &bnp->rp_inpkt[k]);	goto done;      }#endif      /***  NLRI (4+) ***/      if ((logflags & LOG_BGPINPUT))	syslog(LOG_DEBUG, "BGP+ RECV\t\tNLRI");      while (i < k + atrlen) {      /* Malformation is detected ASAP */	struct rt_entry *rte;       /* to be installed               */	int              poctets;   /* (minimum len in octet bound)  */	struct ifinfo   *ife;       /* search for                    */	struct rt_entry *orte;      /* which I had                   */	time_t tloc;	MALLOC(rte, struct rt_entry);	/* log update time */	(void)time(&tloc);	rte->rt_time = tloc;	orte = NULL;	/*  Length (1 octet)  */	if ((rte->rt_ripinfo.rip6_plen = bnp->rp_inpkt[i++]) > 128) {	  syslog(LOG_NOTICE,		 "<%s>: Bad prefix length (=%d) in NLRI", __FUNCTION__,		 rte->rt_ripinfo.rip6_plen);	  free(rte);	  i = k + atrlen;	  break;   /* ignore  rest of MP_REACH_NLRI */	}	poctets = POCTETS(rte->rt_ripinfo.rip6_plen);	/*  Prefix (variable)  */	memcpy( rte->rt_ripinfo.rip6_dest.s6_addr,	       &bnp->rp_inpkt[i],	       poctets);	i += poctets;	if ((logflags & LOG_BGPINPUT))	  syslog(LOG_DEBUG, "BGP+ RECV\t\t%s/%d(nxthop=%s and %s) from %s",		 ip6str(&rte->rt_ripinfo.rip6_dest, 0),		 rte->rt_ripinfo.rip6_plen,		 ip6str(&gnhaddr, 0),		 IN6_IS_ADDR_UNSPECIFIED(&lnhaddr) ? "none" :		 ip6str(&lnhaddr, 0),		 bgp_peerstr(bnp));	if (!IN6_IS_ADDR_ROUTABLE(&rte->rt_ripinfo.rip6_dest)) {

⌨️ 快捷键说明

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