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

📄 dump.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		fputc('\n', fp);		/* statistics */		fprintf(fp, "  Responses: in/out/fail: "			LONGLONG "/" LONGLONG "/" LONGLONG "\n",			(unsigned long long)ripif->rip_responsercvd,			(unsigned long long)ripif->rip_responsesent,			(unsigned long long)ripif->rip_respfail);		fprintf(fp, "  Requests: in/out/fail: "			LONGLONG "/" LONGLONG "/" LONGLONG "\n",			(unsigned long long)ripif->rip_requestrcvd,			(unsigned long long)ripif->rip_requestsent,			(unsigned long long)ripif->rip_reqsentfail);		/* RIPng routing table */		fprintf(fp, "  RIPng routing table\n");				dump_rip_rtable(fp, ripif->rip_adj_ribs_in);		/* RIPng filter statistics */		fprintf(fp, "  RIPng filter information\n");		dump_filterinfo(fp, "  ", &ripif->rip_filterset);		if ((ripif = ripif->rip_next) == ripifs)			break;	}}static struct bgproute_list *init_bgp_route_list(){	static struct bgproute_list head;	memset(&head, 0, sizeof(head));	head.next = head.prev = &head;	return(&head);}/* * Compare two IPv6 prefixes. A supplement function. * Return value: *   -1 if rte1 < rte2 *    0 if rte1 == rte2 *   +1 if rte1 > rte2 */static intprefix_comp(rte1, rte2)	struct rt_entry *rte1, *rte2;{	u_int32_t i32_1, i32_2;	int i;	for (i = 0; i < 4; i++) {		i32_1 = ntohl(*(u_int32_t *)&(rte1->rt_ripinfo.rip6_dest.s6_addr[i * 4]));		i32_2 = ntohl(*(u_int32_t *)&(rte2->rt_ripinfo.rip6_dest.s6_addr[i * 4]));		if (i32_1 < i32_2)			return(-1);		if (i32_1 > i32_2)			return(1);		/* continue to next 32 bits */	}	/* Two addresses are equal. Compare prefix length. */	if (rte1->rt_ripinfo.rip6_plen < rte2->rt_ripinfo.rip6_plen)		return(-1);	if (rte1->rt_ripinfo.rip6_plen > rte2->rt_ripinfo.rip6_plen)		return(1);	return(0);		/* completely equal */}static voidinsert_bgp_route_entry(list, rte, bnp)	struct bgproute_list *list;	struct rt_entry *rte;	struct rpcb *bnp;{	struct bgproute_list *brl, *newbrl;	struct rt_entry *orte;	struct bgproute_entry **brep, *newbre;	int cmp;	for (brl = bgp_route_head(list); !bgp_route_isend(brl, list);	     brl = bgp_route_next(brl)) {		if (brl->entry == NULL || (orte = brl->entry->rte) == NULL) {			syslog(LOG_ERR, "<%s>: bogus bgproute list(%p)",				__FUNCTION__, brl);			continue; /* XXX */		}		if ((cmp = prefix_comp(rte, orte)) == 0) /* rte == orte */			goto insert_entry;		else if (cmp > 0) /* rte > orte */			continue;		else {			break;	/* insert new list and entry */		}	}	if ((newbrl = (struct bgproute_list *)malloc(sizeof(*newbrl))) == NULL)		fatalx("<insert_bgp_route_entry>: malloc failed"); /* XXX */	memset(newbrl, 0, sizeof(*newbrl));	bgp_route_insert(newbrl, brl);	brl = newbrl;	  insert_entry:	for (brep = &brl->entry; *brep; brep = &(*brep)->next) {		orte = (*brep)->rte;		/*		 * if the new entry is preferred to the old one, insert here.		 * A route that is installed to the kernel is the most preferable		 * one. There is no preference between routes that is not up. 		 */		if ((rte->rt_flags & RTF_INSTALLED) ||		    !(orte->rt_flags & RTF_UP))			break;	}	/* allocate a new entry and insert it */	if ((newbre = (struct bgproute_entry *)malloc(sizeof(*newbre))) == NULL)		fatalx("<insert_bgp_route_entry>: malloc failed"); /* XXX */	newbre->head = brl;	newbre->bnp = bnp;	newbre->rte = rte;	newbre->next = *brep;	*brep = newbre;}static struct bgproute_list *make_bgp_route_list(){	extern struct rpcb *bgb;	struct bgproute_list *brl;	struct rpcb *bnp = bgb;	struct rt_entry *rte;	brl = init_bgp_route_list();		while(bnp) {		if (bnp->rp_state == BGPSTATE_ESTABLISHED) {			rte = bnp->rp_adj_ribs_in;			while(rte) {				insert_bgp_route_entry(brl, rte, bnp);				if ((rte = rte->rt_next) == bnp->rp_adj_ribs_in)					break;			}		}		if ((bnp = bnp->rp_next) == bgb)			break;	}	return(brl);}static voidfree_bgp_route_list(head)	struct bgproute_list *head;{	struct bgproute_list *brl, *brl_next;	struct bgproute_entry *bre, *bre_next;	for (brl = bgp_route_head(head); !bgp_route_isend(brl, head);	     brl = brl_next) {		brl_next = bgp_route_next(brl);	/* brl will soon be freed */		for (bre = brl->entry; bre; bre = bre_next) {			bre_next = bre->next; /* bre will soon be freed */			free(bre);		}		remque(brl);		free(brl);	}}static voidshow_bgp_route_entry(fp, bre)	FILE *fp;	struct bgproute_entry *bre;{	struct rpcb *bnp = bre->bnp;	char inetaddrstr[INET_ADDRSTRLEN]; /* XXX */	char *indent = " ";	dump_bgp_rtentry(fp, bre->rte, indent);	fprintf(fp, "%s  PeerInfo: Addr: %s,\n", indent, bgp_peerstr(bnp));		fprintf(fp, "%s            ID: %s, Type: %s\n", indent,		inet_ntop(AF_INET, &bnp->rp_id, inetaddrstr, INET_ADDRSTRLEN),		(bnp->rp_mode & BGPO_IGP) ? "IBGP" : "EBGP");	fprintf(fp, "%s  Last Update: %s", indent,		ctime(&bre->rte->rt_time));	if (bre->rte->rt_flags & RTF_INSTALLED)		dump_bgp_exportlist(fp, bre->rte, indent);}static struct bgproute_entry *bgp_route_headentry(head)	struct bgproute_list *head;{	struct bgproute_list *brl;	brl = bgp_route_head(head);	return(brl->entry);}static struct bgproute_entry *bgp_route_nextentry(listhead, prev)	struct bgproute_list *listhead;	struct bgproute_entry *prev;{	struct bgproute_list *brl;	if (prev->next)		return(prev->next);	for (brl = prev->head->next; brl != listhead; brl = brl->next) {		if (brl->entry)			return(brl->entry);	}	return(NULL);}/* show a sorted list of BGP routes per prefix */static voidprint_bgp_routes(fp)	FILE *fp;{	struct bgproute_list *brl;	struct bgproute_entry *bre;	brl = make_bgp_route_list(); /* make a sorted list */	for (bre = bgp_route_headentry(brl); bre;	     bre = bgp_route_nextentry(brl, bre)) {		fputc('\n', fp);		show_bgp_route_entry(fp, bre);	}	free_bgp_route_list(brl);}static voidshow_bgp_peer(FILE *fp, struct rpcb *bnp, char *indent){	char inetaddrstr[INET_ADDRSTRLEN];	static char *bgpstate[] = {"", /* dummy */				   "IDLE", "CONNECT", "ACTIVE",				   "OPENSENT", "OPENCONFERM",				   "ESTABLISHED"};	struct rpcb *abnp = find_aopen_peer(bnp);	fprintf(fp, "%sAS: %d, ", indent, bnp->rp_as);	fprintf(fp, "Router Id: %s, ",		inet_ntop(AF_INET, &bnp->rp_id,			  inetaddrstr, INET_ADDRSTRLEN));	fprintf(fp, "state: %s, ", bgpstate[bnp->rp_state]);	fprintf(fp, "localpref: %d\n", (int)ntohl(bnp->rp_prefer));	fprintf(fp, "%sMode:", indent);	if (bnp->rp_mode & BGPO_PASSIVE) fprintf(fp, " PASSIVE");	if (bnp->rp_mode & BGPO_IFSTATIC) fprintf(fp, " IFSTATIC");	if (bnp->rp_mode & BGPO_IGP)		fprintf(fp, " IBGP");	else		fprintf(fp, " EBGP");	if (bnp->rp_mode & BGPO_RRCLIENT) fprintf(fp, " RRCLIENT");	if (bnp->rp_mode & BGPO_ONLINK) fprintf(fp, " ONLINK");	if (bnp->rp_mode & BGPO_IDSTATIC) fprintf(fp, " IDSTATIC");	if (bnp->rp_mode & BGPO_NOSYNC) fprintf(fp, " NOSYNC");	if (bnp->rp_mode & BGPO_NEXTHOPSELF) fprintf(fp, " NEXTHOPSELF");	if (abnp) {		if (abnp->rp_filterset.deffilterflags & DEFAULT_FILTERIN)			fprintf(fp, " FILTERIN_DEFAULT");		if (abnp->rp_filterset.deffilterflags & DEFAULT_FILTEROUT)			fprintf(fp, " FILTEROUT_DEFAULT");		if (abnp->rp_filterset.deffilterflags & DEFAULT_RESTRICTIN)			fprintf(fp, " RESTRICTIN_DEFAULT");		if (abnp->rp_filterset.deffilterflags & DEFAULT_RESTRICTOUT)			fprintf(fp, " RESTRICTOUT_DEFAULT");	}	fputc('\n', fp);	fprintf(fp, "%sHis global addr: %s\n", indent, bgp_peerstr(bnp));	fprintf(fp, "%sHis local addr: %s\n", indent, bgp_peerstr(bnp));	fprintf(fp, "%sOur addr: %s\n", indent,		ip6str(&bnp->rp_myaddr.sin6_addr, 0));	fprintf(fp, "%sTimers:", indent);	if (bnp->rp_connect_timer)		fprintf(fp, " connect=%d:%02d",			(int)(bnp->rp_connect_timer->tsk_timeval.tv_sec/60),			(int)(bnp->rp_connect_timer->tsk_timeval.tv_sec%60));	if (bnp->rp_hold_timer)		fprintf(fp, " hold=%d:%02d",			(int)(bnp->rp_hold_timer->tsk_timeval.tv_sec/60),			(int)(bnp->rp_hold_timer->tsk_timeval.tv_sec%60));	if (bnp->rp_keepalive_timer)		fprintf(fp, " keepalive=%d:%02d",			(int)(bnp->rp_keepalive_timer->tsk_timeval.tv_sec/60),			(int)(bnp->rp_keepalive_timer->tsk_timeval.tv_sec%60));	fputc('\n', fp);	/*	 * Dump filter information and statistics if	 * - there is an actively opened peer (it must be, though), and	 *   + bnp is active, or	 *   + it is an actively opend peer and there is no other active peer.	 */	if (abnp &&	    (bnp->rp_state != BGPSTATE_IDLE ||	     ((bnp->rp_mode & BGPO_PASSIVE) == 0 &&	      find_active_peer(bnp) == NULL))) {		fprintf(fp, "%sStatistics:\n", indent);		fprintf(fp, "%s Connection retries: " LONGLONG "\n",			indent,			(unsigned long long)abnp->rp_stat.rps_connretry);		fprintf(fp, "%s Peering establishments: " LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.established);		fprintf(fp, "%s OPENs: in/out: " LONGLONG "/" LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.openrcvd,			(unsigned long long)abnp->rp_stat.opensent);		fprintf(fp, "%s UPDATEs: in/out: " LONGLONG "/" LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.updatercvd,			(unsigned long long)abnp->rp_stat.updatesent);		fprintf(fp, "%s NOTIFYs: in/out: " LONGLONG "/" LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.notifyrcvd,			(unsigned long long)abnp->rp_stat.notifysent);		fprintf(fp, "%s KEEPALIVEs: in/out: "			LONGLONG "/" LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.keepalivercvd,			(unsigned long long)abnp->rp_stat.keepalivesent);		fprintf(fp, "%s WITHDRAWs: in/out: "			LONGLONG "/" LONGLONG "\n",			indent, (unsigned long long)abnp->rp_stat.withdrawrcvd,			(unsigned long long)abnp->rp_stat.withdrawsent);		if (abnp->rp_stat.last_established) {			/* ctime appends \n */			fprintf(fp, "%s Last esbalished: %s", indent,				ctime(&abnp->rp_stat.last_established));			if (bnp->rp_state == BGPSTATE_ESTABLISHED)				fprintf(fp,					"%s   has been established for %s\n",					indent,					sec2str(tloc_now -						abnp->rp_stat.last_established));			fprintf(fp, "%s Max established period: %s\n", indent,				sec2str(abnp->rp_stat.max_established_period));			fprintf(fp, "%s Min established period: %s\n", indent,				sec2str(abnp->rp_stat.min_established_period));		}		if (abnp->rp_stat.last_closed) {			/* ctime appends \n */			fprintf(fp, "%s Last closed: %s", indent,				ctime(&abnp->rp_stat.last_closed));		}		if (bnp->rp_state != BGPSTATE_ESTABLISHED) {			time_t blankperiod;			if (abnp->rp_stat.last_closed)				blankperiod = tloc_now -					abnp->rp_stat.last_closed;			else				blankperiod = tloc_now - bgpd_start_time;			fprintf(fp, "%s   hasn't been established for %s\n",				indent, sec2str(blankperiod));		}		fprintf(fp, "%sFilters:\n", indent);		dump_filterinfo(fp, indent, &abnp->rp_filterset);	}	if (bnp->rp_ebgp_as_prepends)		fprintf(fp, "%sour own AS number will be prepended "			"to each advertised AS path %d time%s\n", indent,			bnp->rp_ebgp_as_prepends,			(bnp->rp_ebgp_as_prepends == 1) ? "" : "s");#if 0	fprintf(fp, "  Imported routes from the peer:\n");	dump_bgp_rtable(fp, bnp->rp_adj_ribs_in);	fprintf(fp, "  Exported routes to the peer:\n");	dump_exports(fp, bnp->rp_adj_ribs_out);#endif}static voidprint_bgp_dump(FILE *fp){	struct rpcb *bnp;	char inetaddrstr[INET_ADDRSTRLEN];	extern struct rpcb *bgb;	extern u_int16_t    my_as_number;	extern u_int32_t    bgpIdentifier;	extern u_int32_t    clusterId;	extern u_int16_t    bgpHoldtime;	extern byte         IamRR;	bnp = bgb;	if (bnp) {		fprintf(fp, "\n=== BGP local information ===\n");		fprintf(fp, "  AS: %d, ", my_as_number);		fprintf(fp, "RouterId: %s, ",			inet_ntop(AF_INET, &bgpIdentifier,				  inetaddrstr, INET_ADDRSTRLEN));		fprintf(fp, "ClusterId: %s\n",			inet_ntop(AF_INET, &clusterId,				  inetaddrstr, INET_ADDRSTRLEN));		fprintf(fp, "  HoldTime: %d", bgpHoldtime);		if (IamRR)			fprintf(fp, ", Reflector");		fputc('\n', fp);		fprintf(fp, "\n=== BGP per peer information ===\n");	}	/* show established peer first */	while(bnp) {		if (bnp->rp_state == BGPSTATE_ESTABLISHED) {			show_bgp_peer(fp, bnp, "  ");			fputc('\n', fp);		}		if ((bnp = bnp->rp_next) == bgb)			break;	}	/*	 * Then show non-established peers, skipping established passive-opend	 * peers.	 */	bnp = bgb;	while(bnp) {		if (bnp->rp_state != BGPSTATE_ESTABLISHED &&		    find_epeer_by_rpcb(bnp) == NULL) {			show_bgp_peer(fp, bnp, "  ");			fputc('\n', fp);		}		if ((bnp = bnp->rp_next) == bgb)			break;	}	if (bnp) {		fprintf(fp, "\n=== BGP routing information ===\n");		print_bgp_routes(fp);	}}voidbgpd_dump_file(){	FILE *fp;	if ((fp = fopen(dumpfile, "w")) == NULL) {		syslog(LOG_ERR, "<%s>: can't open dump file(%s): %s",			__FUNCTION__, dumpfile, strerror(errno));		return;	}	(void)time(&tloc_now);	fprintf(fp, "\n************ bgpd dump on %s", ctime(&tloc_now));	print_if_dump(fp);	print_rip_dump(fp);	print_bgp_dump(fp);	fclose(fp);}static char *aspath2str(struct aspath *aspath){	struct asnum *asn;	struct asseg *asg;	int l = 0, bufwlen, palen, slen;	static char buf[LINE_MAX];	if ((asg = aspath->asp_segment) == NULL)		return("Nil");	for (palen = 0 ; palen < aspath->asp_len ; palen++) {		if (asg->asg_type == PA_PATH_SET) {			strcpy(&buf[l], "set(");			l += 4;		}		asn = asg->asg_asn;		for (slen = 0; slen < asg->asg_len; slen++) {			bufwlen = sprintf(&buf[l], "%u ", asn->asn_num);			l += bufwlen;			asn = asn->asn_next;		}		if (asg->asg_type == PA_PATH_SET) {			strcpy(&buf[l-1], ") ");			l++;		}		asg = asg->asg_next;	}	return(buf);}static char *cll2str(cll)	struct clstrlist *cll;{	static char buf[LINE_MAX];	char inetaddrstr[INET_ADDRSTRLEN];	struct clstrlist *cll_top = cll;	int l = 0;	if (cll == NULL)		return("Nil");	while(cll) {		l += sprintf(&buf[l], "%s ", inet_ntop(AF_INET, &cll->cll_id,						       inetaddrstr,						       INET_ADDRSTRLEN));		if ((cll = cll->cll_next) == cll_top)			break;	}	return(buf);}

⌨️ 快捷键说明

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