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

📄 bgp_util.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	    }	  }	  if ((bnp = bnp->rp_next) == bgb)	    break;	}      }      if ((ibnp = ibnp->rp_next) == bgb)	break;          }  }  /*   *  2) A Route from a Client peer   *   *     Reflect to all the Non-Client peers and also to the   *     Client peers other than the originator. (Hence the   *     Client peers are not required to be fully meshed).   */  if (IamRR) {    ibnp = bgb;    while (ibnp) {      if (ibnp->rp_mode & BGPO_IGP) {	bnp = bgb;	while (bnp) {	  if ((bnp->rp_mode & BGPO_RRCLIENT) &&	      ibnp != bnp ) {	    struct rtproto *rtp;	    MALLOC(rtp, struct rtproto);	  	    rtp->rtp_type = RTPROTO_BGP;	    rtp->rtp_bgp  = bnp;	    if (ibnp->rp_adj_ribs_out)	      insque(rtp, ibnp->rp_adj_ribs_out);	    else {	      rtp->rtp_next = rtp;	      rtp->rtp_prev = rtp;	      ibnp->rp_adj_ribs_out = rtp;	    }	  }	  if ((bnp = bnp->rp_next) == bgb)	    break;	}      }      if ((ibnp = ibnp->rp_next) == bgb)	break;          }  }  /*     * Whether IamRR or NOT,   *   *  3) Route from an EBGP peer   *   *     Send to all the Client and Non-Client Peers.   */  ibnp = bgb;  while(ibnp) {    if (ibnp->rp_mode & BGPO_IGP) {      bnp = bgb;      while (bnp) {	if (!(bnp->rp_mode & BGPO_IGP)) {	  struct rtproto *rtp;	  MALLOC(rtp, struct rtproto);	  rtp->rtp_type = RTPROTO_BGP;	  rtp->rtp_bgp  = bnp;	  if (ibnp->rp_adj_ribs_out)	    insque(rtp, ibnp->rp_adj_ribs_out);	  else {	    rtp->rtp_next = rtp;	    rtp->rtp_prev = rtp;	    ibnp->rp_adj_ribs_out = rtp;	  }	}	if ((bnp = bnp->rp_next) == bgb)	  break;      }    }    if ((ibnp = ibnp->rp_next) == bgb)      break;        }#if 0  /*   *  Whether IamRR or not,   *   *  4) Route of direct Interface,   *   *     Send to all the Client and Non-Client Peers.   */  ibnp = bgb;  while (ibnp) {    if (ibnp->rp_mode & BGPO_IGP) {      ife = ifentry;      while (ife) {	struct rtproto *rtp;	if (ife != ibnp->rp_ife) {/* split holizon (ad-hoc) I/F not known */	  MALLOC(rtp, struct rtproto);	  	  rtp->rtp_type = RTPROTO_IF;	  rtp->rtp_if   = ife;	  if (ibnp->rp_adj_ribs_out)	    insque(rtp, ibnp->rp_adj_ribs_out);	  else {	    rtp->rtp_next = rtp;	    rtp->rtp_prev = rtp;	    ibnp->rp_adj_ribs_out = rtp;	  }	}	if ((ife = ife->ifi_next) == ifentry)	  break;      }    }    if ((ibnp = ibnp->rp_next) == bgb)      break;        } /* while */#endif  /*  commeted out !  */#if 0  /*   *  whether IamRR or not,   *   *  5) Route from RIPng,   *   *     Send to all the Client and Non-Client Peers.   */  if (ripyes) {    ibnp = bgb;    while (ibnp) {      if (ibnp->rp_mode & BGPO_IGP) {	ripif = ripifs;	while (ripif) {	  struct rtproto *rtp;	  MALLOC(rtp, struct rtproto);	  	  rtp->rtp_type = RTPROTO_RIP;	  rtp->rtp_rip  = ripif;	  if (ibnp->rp_adj_ribs_out)	    insque(rtp, ibnp->rp_adj_ribs_out);	  else {	    rtp->rtp_next = rtp;	    rtp->rtp_prev = rtp;	    ibnp->rp_adj_ribs_out = rtp;	  }	  if ((ripif = ripif->rip_next) == ripifs)	    break;	}      }      if ((ibnp = ibnp->rp_next) == bgb)	break;          } /* while */  }#endif}ints_pipe(fd)     int fd[2];{  return(socketpair(AF_UNIX, SOCK_STREAM, 0, fd));}intbgpd_sendfile(sockfd, fd)     int sockfd;     int fd;{  int    slen;  u_char buf[sizeof(int)];  u_int  netfd;  netfd = htonl(fd);  memcpy(buf, (u_char *)&netfd, sizeof(int));  if ((slen = write(sockfd, buf, sizeof(int))) < 0) {    syslog(LOG_NOTICE, "<bgpd_sendfile>: write failed, sockfd=%d.", sockfd);    dperror("<bgpd_sendfile>: write");    return -1;  }  return 0;}intrecvfile(sockfd)     int sockfd;{  int    rlen;  u_char buf[sizeof(int)];  memset(buf, 0, sizeof(int));  if ((rlen = read(sockfd, buf, sizeof(int))) < 0) {    dperror("<recvfile>: read");    return -1;  }  return ntohl(*(int *)buf);/* <-- the FD !! */}char *bgp_peerstr(bnp)	struct rpcb *bnp;{	char *cp;	struct rpcb *abnp;	if (!IN6_IS_ADDR_UNSPECIFIED(&bnp->rp_addr.sin6_addr))		cp = ip6str2(&bnp->rp_addr);	else if (!IN6_IS_ADDR_UNSPECIFIED(&bnp->rp_gaddr))		cp = ip6str(&bnp->rp_gaddr, 0);	else {		unsigned int ifindex = 0;		if (bnp->rp_ife && bnp->rp_ife->ifi_ifn)			ifindex = bnp->rp_ife->ifi_ifn->if_index;		cp = ip6str(&bnp->rp_laddr, ifindex);	}	if (cp == NULL)		/* XXX */		return(NULL);	if ((abnp = find_aopen_peer(bnp)) && abnp->rp_descr) {		int cplen = strlen(cp), space = MAXHOSTNAMELEN - cplen;		int desclen = strlen(abnp->rp_descr);		/* "3" is size of a pair of parenthesizes and terminator(\0) */		if (space >= desclen + 3) {			/* copy the description for the peer */			cp[cplen] = '(';			strcpy(&cp[cplen + 1], abnp->rp_descr);			strcpy(&cp[cplen + 1 + desclen], ")");		}	}	return(cp);}struct bgpcblist *make_bgpcb_list(){	struct bgpcblist *d = NULL, *new;	struct rpcb *bnp;	extern struct rpcb *bgb;		bnp = bgb;	while(bnp) {		if (bnp->rp_state == BGPSTATE_ESTABLISHED) {			MALLOC(new, struct bgpcblist);			new->bnp = bnp;	/* set the pointer */			/* make chain */			new->next = d;			d = new;		}		if ((bnp = bnp->rp_next) == bgb)			break;	}	return(d);}voidfree_bgpcb_list(head)	struct bgpcblist *head;{	struct bgpcblist *d, *next;	for(d = head; d;) {		next = d->next;		free(d);		d = next;	}}/* * Check an incoming BGP route to be filtered or not. */intbgp_input_filter(bnp, rte)	struct rpcb *bnp;	/* unused */	struct rt_entry *rte;{	struct rpcb *abnp;	if ((abnp = find_aopen_peer(bnp)) == NULL)		return(1);	/* treat it as filtered */	/* Check filters. Site-locals are always filtered. */	if (input_filter_check(&abnp->rp_filterset, 0,				&rte->rt_ripinfo)) {		IFLOG(LOG_BGPINPUT)			syslog(LOG_DEBUG,			       "<%s>: input route %s/%d to %s was filtered",			       __FUNCTION__,			       ip6str(&rte->rt_ripinfo.rip6_dest, 0),			       rte->rt_ripinfo.rip6_plen,			       bgp_peerstr(bnp));		return(1);	}	return 0;}/* * Check an outoging BGP route to be filtered or not. * XXX: the routine is (currently) almost same as bgp_input_filter(). */intbgp_output_filter(bnp, rte)	struct rpcb *bnp;	struct rt_entry *rte;{	struct rpcb *abnp;	if ((rte->rt_flags & (RTF_BLACKHOLE|RTF_REJECT)) != 0) {	  IFLOG(LOG_BGPOUTPUT)	    syslog(LOG_DEBUG,		   "<%s>: rejected route (%s/%d) not advertised to %s",		   __FUNCTION__,		   ip6str(&rte->rt_ripinfo.rip6_dest, 0),		   rte->rt_ripinfo.rip6_plen,		   bgp_peerstr(bnp));	  return(1);	}	if ((abnp = find_aopen_peer(bnp)) == NULL)		return(1);	/* treat it as filtered */	/* Check filters. Site-locals are always filtered. */	if (output_filter_check(&abnp->rp_filterset, 0,				&rte->rt_ripinfo)) {		IFLOG(LOG_BGPOUTPUT)			syslog(LOG_DEBUG,			       "<%s>: output route %s/%d to %s was filtered",			       __FUNCTION__,			       ip6str(&rte->rt_ripinfo.rip6_dest, 0),			       rte->rt_ripinfo.rip6_plen,			       bgp_peerstr(bnp));		return(1);	}	return 0;}voidbgp_paraminit(){	extern u_int32_t bgpIdentifier;	if (bgpIdentifier == 0 &&	    (bgpIdentifier = get_32id()) == 0)	    fatalx("<bgp_paraminit>: no 32bit ID was found."		   " bgpIdentifier should be defined by hand");}voidbgp_sockinit(){    struct sockaddr_in6 bgpsin;        /* my address      */    int on;    extern int bgpsock;    extern fd_set fdmask;    if ((bgpsock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {      dperror("<conf_check>: socket");      terminate();    }    on = 1;    if (setsockopt(bgpsock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) {	dperror("<conf_check>: setsockopt(SO_REUSEPORT)");	/* error, but not so serious */    }    memset(&bgpsin,   0, sizeof(bgpsin));    /* sockaddr_in6  */    bgpsin.sin6_len      = sizeof(struct sockaddr_in6);    bgpsin.sin6_family   = AF_INET6;    bgpsin.sin6_port     = htons(BGP_PORT);    bgpsin.sin6_flowinfo = 0;    if (bind(bgpsock, (struct sockaddr *)&bgpsin, sizeof(bgpsin)) < 0) {      dperror("<conf_check>: bind");      terminate();    }    on = 1;#ifdef ADVANCEDAPI#ifdef IPV6_RECVPKTINFO    if (setsockopt(bgpsock, IPPROTO_IPV6, IPV6_RECVPKTINFO,		   &on, sizeof(on)) < 0)      fatal("<conf_check>: setsockopt(IPV6_RECVPKTINFO)");#else  /* old adv. API */    if (setsockopt(bgpsock, IPPROTO_IPV6, IPV6_PKTINFO,		   &on, sizeof(on)) < 0)      fatal("<conf_check>: setsockopt(IPV6_PKTINFO)");#endif #endif    if (listen(bgpsock, 5) < 0) {      dperror("<conf_check>: listen");      terminate();    }    FD_SET(bgpsock, &fdmask);           /* (global) */}voidbgp_update_stat(bnp, type)     struct rpcb *bnp;     int type;{	struct rpcb *abnp = find_aopen_peer(bnp);	time_t tloc, period;	if (abnp == NULL)		return;	switch(type) {	case BGPS_ESTABLISHED:		abnp->rp_stat.established++;		(void)time(&tloc);		abnp->rp_stat.last_established = tloc;		break;	case BGPS_OPENSENT:		abnp->rp_stat.opensent++;		break;	case BGPS_OPENRCVD:		abnp->rp_stat.openrcvd++;		break;	case BGPS_UPDATESENT:		abnp->rp_stat.updatesent++;		break;	case BGPS_UPDATERCVD:		abnp->rp_stat.updatercvd++;		break;	case BGPS_NOTIFYSENT:		abnp->rp_stat.notifysent++;		break;	case BGPS_NOTIFYRCVD:		abnp->rp_stat.notifyrcvd++;		break;	case BGPS_KEEPALIVESENT:		abnp->rp_stat.keepalivesent++;		break;	case BGPS_KEEPALIVERCVD:		abnp->rp_stat.keepalivercvd++;		break;	case BGPS_WITHDRAWSENT:		abnp->rp_stat.withdrawsent++;		break;	case BGPS_WITHDRAWRCVD:		abnp->rp_stat.withdrawrcvd++;		break;	case BGPS_CLOSED:		(void)time(&tloc);		abnp->rp_stat.last_closed = tloc;		if (bnp->rp_state != BGPSTATE_ESTABLISHED)			break;		period = tloc - abnp->rp_stat.last_established;		if (period > abnp->rp_stat.max_established_period) {			/* this covers the first time */			abnp->rp_stat.max_established_period = period;		}		if (abnp->rp_stat.min_established_period == 0 ||		    period < abnp->rp_stat.min_established_period)			abnp->rp_stat.min_established_period = period;		break;	}}

⌨️ 快捷键说明

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