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

📄 cfparse.y

📁 同时支持IPv4和IPv6的BGP协议实现
💻 Y
📖 第 1 页 / 共 4 页
字号:
	}	p->next = list;	return(p);}static intset_filter(headp, prefix, line)	struct filtinfo **headp;	struct in6_prefix *prefix;	int line;{	struct filtinfo *filter;	if ((filter = malloc(sizeof(*filter))) == NULL) {		warnx("can't allocate space for filter");		return(-1);	}	memset(filter, 0, sizeof(*filter));	memset(filter, 0, sizeof(struct filtinfo));	filter->filtinfo_addr = prefix->paddr.sin6_addr; /* XXX */	filter->filtinfo_plen = prefix->plen;	if (*headp) {		if (find_filter(*headp, filter)) {			fprintf(stderr, "%s:%d route filter(%s/%d) doubly "				"defined\n",				configfilename, line,ip6str2(&prefix->paddr),				prefix->plen);			return(-1);		}		insque(filter, *headp);	} else {		filter->filtinfo_next = filter->filtinfo_prev = filter;		*headp = filter;	}	return(0);}static voidparam_config(){	struct in_addr ipv4id;	if (yy_debug) {		/* debug flag */		logflags = yy_debug;		cprint("set %x to the debug flag\n", (u_int)logflags);	}	if (yy_asnum >= 0) {	/* our AS number */		my_as_number = yy_asnum;		cprint("set %d to AS number\n", my_as_number);	}	if (yy_bgpsbsize >= 0) { /* BGP socket buffer size */		bgpsbsize = yy_bgpsbsize;		cprint("set %d to the BGP socket buffer size\n", bgpsbsize);	}	if (yy_holdtime >= 0) {	/* BGP holdtimer value */		bgpHoldtime = yy_holdtime;		cprint("set %d to BGP hold timer\n", bgpHoldtime);	}	if ((yy_rrflag >= 0)) {		IamRR = yy_rrflag;		cprint("act as a route reflector\n");	}	if (yy_rip > 0) {		ripyes = yy_rip;		cprint("Enable RIPng\n");	}	if (yy_bgp > 0) {		bgpyes = yy_bgp;		cprint("Enable BGP4+\n");	}	if (dumpfile)		free(dumpfile);	if (yy_dumpfile) {		dumpfile = strdup(yy_dumpfile);		cprint("set %s to the dump file\n", dumpfile);	}	else		dumpfile = strdup(DUMPFILENAME);	if (yy_routerid != -1) {		ipv4id.s_addr = bgpIdentifier = yy_routerid;		cprint("set %s to the BGP Identifier\n", inet_ntoa(ipv4id));	}	if (yy_clusterid != -1) {		ipv4id.s_addr = clusterId = yy_clusterid;		cprint("set %s to the BGP cluster ID\n", inet_ntoa(ipv4id));	}}static intstatic_config(){	struct yy_route_entry *yrte;	struct rt_entry *rte = NULL;	struct ifinfo *ifp;	extern struct rt_entry static_rte_head;	cprint("Static Route config\n");	for (yrte = yy_static_head; yrte; yrte = yrte->next) {		cprint("  Destination: %s/%d",		       ip6str2(&yrte->prefix.paddr), yrte->prefix.plen);		if ((rte = malloc(sizeof(*rte))) == NULL) {			warnx("can't allocate space for a static route");			return(-1);		}		memset(rte, 0, sizeof(*rte));		/* XXX: scoped addr support */		rte->rt_ripinfo.rip6_dest = yrte->prefix.paddr.sin6_addr;		rte->rt_ripinfo.rip6_plen = yrte->prefix.plen;		if (rte->rt_ripinfo.rip6_plen == 128)			rte->rt_flags |= RTF_HOST;		switch(yrte->gwtype) {		case GW_IFACE:			cprint(" to Interface %s", yrte->reu.ifname);			if ((ifp = find_if_by_name(yrte->reu.ifname))			    == NULL) {				warnx("%s line %d: invalid interface name: %s",				      configfilename, yrte->line,				      yrte->reu.ifname);				goto bad;			}			rte->rt_proto.rtp_type = RTPROTO_IF;			rte->rt_proto.rtp_if = ifp;			/* use our own address as gateway */			if (!IN6_IS_ADDR_UNSPECIFIED(&ifp->ifi_laddr))				rte->rt_gw = ifp->ifi_laddr;			else				rte->rt_gw = ifp->ifi_gaddr;			rte->rt_flags |= RTF_BGPDIFSTATIC;			break;		case GW_ADDR:			cprint(" gateway: %s", ip6str2(&yrte->reu.gateway));			if (IN6_IS_ADDR_LINKLOCAL(&yrte->reu.gateway.sin6_addr)) {				/* XXX: link vs I/F issue... */				u_int linkid = yrte->reu.gateway.sin6_scope_id;				if (linkid == 0) {					warnx("%s line %d: "					      "link-local gateway without"					      "scope id: %s",					      configfilename, yrte->line,					      ip6str2(&yrte->reu.gateway));					goto bad;				}				if ((ifp = find_if_by_index(linkid)) == NULL) {					yywarn("%s line %d: "					       "invalid scope id",					       configfilename, yrte->line,					       ip6str2(&yrte->reu.gateway));					goto bad;				}			}			else if (in6_is_addr_onlink(&yrte->reu.gateway.sin6_addr,						    &ifp) == 0) {					warnx("bad gateway (off-link): %s",					      ip6str2(&yrte->reu.gateway));					return(-1);			}			rte->rt_proto.rtp_type = RTPROTO_IF;			rte->rt_proto.rtp_if = ifp;			rte->rt_gw = yrte->reu.gateway.sin6_addr;			rte->rt_flags |= RTF_GATEWAY;			rte->rt_flags |= RTF_BGPDGWSTATIC;			break;		default:			cprint(" unknown gateway type(%d)", yrte->gwtype);			goto bad;		}		cprint("\n");		insque(rte, &static_rte_head);	}	return(0);  bad:	if (rte)		free(rte);	return(-1);}static intrip_config(){	struct yy_ripifinfo *info;	struct attr_list *attr;	struct ifinfo *ifp;	struct ripif *ripif;	extern int rip_use_sitelocal;	if (ripyes == 0)		return(0);	rip_init();	cprint("RIP config\n");	if (yy_rip_sitelocal >= 0) {		cprint("  Use site-local addresses in RIPng\n");		rip_use_sitelocal = yy_rip_sitelocal;	}	for (info = yy_ripifinfo_head; info; info = info->next) {		cprint("  %s: ", info->ifname);		if ((ifp = find_if_by_name(info->ifname)) == NULL ||		    (ripif = find_rip_by_index(ifp->ifi_ifn->if_index)) ==		    NULL) {			warnx("%s line %d: invalid interface: %s\n", 			      configfilename, info->line,			      info->ifname);			return(-1);		}		for (attr = info->attribute; attr; attr = attr->next) {			switch(attr->code) {			case RIPIFA_DEFAULT:				ripif->rip_mode |= IFS_DEFAULTORIGINATE;				ripif->rip_filterset.deffilterflags					|= DEFAULT_FILTERIN;				cprint("default_originate ");				break;			case RIPIFA_NORIPIN:				ripif->rip_mode |= IFS_NORIPIN;				cprint("noripin ");				break;			case RIPIFA_NORIPOUT:				ripif->rip_mode |= IFS_NORIPOUT;				cprint("noripout ");				break;			case RIPIFA_METRICIN:				ripif->rip_metricin = attr->attru.number;				cprint("metricin %d ", attr->attru.number);				break;			case RIPIFA_FILINDEF:				ripif->rip_filterset.deffilterflags					|= DEFAULT_FILTERIN;				cprint("input_filter_default ");				break;			case RIPIFA_FILOUTDEF:				ripif->rip_filterset.deffilterflags					|= DEFAULT_FILTEROUT;				cprint("output_filter_default ");				break;			case RIPIFA_RESINDEF:				ripif->rip_filterset.deffilterflags					|= DEFAULT_RESTRICTIN;				cprint("input_restriction_default ");				break;			case RIPIFA_RESOUTDEF:				ripif->rip_filterset.deffilterflags					|= DEFAULT_RESTRICTOUT;				cprint("output_restriction_default ");				break;			case RIPIFA_FILINPFX:				if (set_filter(&ripif->rip_filterin,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("input_filter(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case RIPIFA_FILOUTPFX:				if (set_filter(&ripif->rip_filterout,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("output_filter(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case RIPIFA_RESINPFX:				if (set_filter(&ripif->rip_restrictin,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("input_restriction(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case RIPIFA_RESOUTPFX:				if (set_filter(&ripif->rip_restrictout,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("output_restriction(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case RIPIFA_DESCR:				if (ripif->rip_desc) {					free(ripif->rip_desc);					ripif->rip_desc = NULL;				}				ripif->rip_desc = strdup(attr->attru.str);				if (ripif->rip_desc == NULL) {					warnx("can't allocate memory "					      "for RIPng I/F description");					return(-1);				}				cprint("descr=%s ", attr->attru.str);				break;			default:				cprint("unknown_attribute(%d) ", attr->code);			}		}		cprint("\n");	}	return(0);}static intbgp_config(){	struct yy_bgppeerinfo *info;	struct attr_list *attr;	struct rpcb *bnp;	if (bgpyes == 0)		return(0);	if (my_as_number == 0) {		warnx("%s: BGP specified without internal AS number",		      configfilename);		return(-1);	}	cprint("BGP config\n");	for (info = yy_bgppeer_head; info; info = info->next) {		/* make a new peer structure */		bnp = bgp_new_peer();		if (bgb == NULL) {			bgb = bnp;			bgb->rp_next = bgb->rp_prev = bgb;		}		else			insque(bnp, bgb);		cprint("  peer: %s ", ip6str2(&info->peeraddr));		if (info->asnum < 0) { /* IBGP */			cprint("IBGP ");			bnp->rp_mode |= BGPO_IGP;			bnp->rp_as = my_as_number;			if (info->peertype == BGPPEER_CLIENT) {				if (!IamRR) {					warnx("%s line %d: a BGP client "					      "specified while we're not "					      "a reflector",					      configfilename, info->line);					return(-1);				}				bnp->rp_mode |= BGPO_RRCLIENT;				cprint("CLIENT ");			}			if (info->routerid) {				bnp->rp_mode |= BGPO_IDSTATIC;				bnp->rp_id = info->routerid;				cprint("routerID: %x ",				       (u_int)(ntohl(info->routerid)));			}		}		else {		/* EBGP */			cprint("EBGP ");			bnp->rp_as = info->asnum;		}		/* peer address setting */		bnp->rp_addr = info->peeraddr;		bnp->rp_addr.sin6_port = htons(BGP_PORT);		if (IN6_IS_ADDR_LINKLOCAL(&bnp->rp_addr.sin6_addr))			bnp->rp_laddr = bnp->rp_addr.sin6_addr; /* copy  */		else			bnp->rp_gaddr = bnp->rp_addr.sin6_addr; /* ummh  */		{			struct ifinfo *ife_dummy = NULL; /* XXX */			if (in6_is_addr_onlink(&bnp->rp_addr.sin6_addr,					       &ife_dummy))				bnp->rp_mode |= BGPO_ONLINK;		}		for (attr = info->attribute; attr; attr = attr->next) {			switch(attr->code) {			case BGPPA_IFNAME:				cprint("interface: %s ", attr->attru.str);				if ((bnp->rp_ife = find_if_by_name(attr->attru.str)))					bnp->rp_mode |= BGPO_IFSTATIC;				else {					warnx("Bad interface for a BGP peer "					      ": %s", attr->attru.str);					return(-1);				}				/* scope check: XXX for link-local only */				if (bnp->rp_addr.sin6_scope_id &&				    bnp->rp_addr.sin6_scope_id !=				    bnp->rp_ife->ifi_ifn->if_index) {					warnx("BGP peer address(%s) "					      "condradicts interface(%s)",					      ip6str2(&bnp->rp_addr),					      attr->attru.str);					return(-1);				}				    				break;			case BGPPA_NOSYNC:				cprint("nosync ");				bnp->rp_mode |= BGPO_NOSYNC;				break;			case BGPPA_NEXTHOPSELF:				cprint("nexthop_self ");				bnp->rp_mode |= BGPO_NEXTHOPSELF;				break;			case BGPPA_LCLADDR:				cprint("lcladdr %s ",				       ip6str2(&attr->attru.in6addr));				bnp->rp_lcladdr = attr->attru.in6addr;				break;			case BGPPA_PREFERENCE:				cprint("preference %d ", attr->attru.number);				bnp->rp_prefer = htonl(attr->attru.number);				break;			case BGPPA_PREPEND:				cprint("prepend %d ", attr->attru.number);				bnp->rp_ebgp_as_prepends = attr->attru.number;				break;			case BGPPA_DESCR:				cprint("descr=%s ", attr->attru.str);				bnp->rp_descr = strdup(attr->attru.str);				break;			case BGPPA_FILINDEF:				bnp->rp_filterset.deffilterflags |=				  DEFAULT_FILTERIN;				cprint("input_filter_default ");				break;			case BGPPA_FILOUTDEF:				bnp->rp_filterset.deffilterflags |=				  DEFAULT_FILTEROUT;				cprint("output_filter_default ");				break;			case BGPPA_RESINDEF:				bnp->rp_filterset.deffilterflags |=				  DEFAULT_RESTRICTIN;				cprint("input_restriction_default ");				break;			case BGPPA_RESOUTDEF:				bnp->rp_filterset.deffilterflags |=				  DEFAULT_RESTRICTOUT;				cprint("output_restriction_default ");				break;			case BGPPA_FILINPFX:				if (set_filter(&bnp->rp_filterset.filterin,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("input_filter(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case BGPPA_FILOUTPFX:				if (set_filter(&bnp->rp_filterset.filterout,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("output_filter(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case BGPPA_RESINPFX:				if (set_filter(&bnp->rp_filterset.restrictin,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("input_restriction(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			case BGPPA_RESOUTPFX:				if (set_filter(&bnp->rp_filterset.restrictout,					       &attr->attru.prefix,					       attr->line))					return(-1);				cprint("output_restriction(%s/%d) ",				       ip6str2(&attr->attru.prefix.paddr),				       attr->attru.prefix.plen);				break;			default:				cprint("unknown_attribute(%d) ", attr->code);			}		}		cprint("\n");		/*		 * We need to disambigute the scope for a peer with a scoped		 * address.		 * XXX: site-local address?		 */		if (IN6_IS_ADDR_LINKLOCAL(&bnp->rp_addr.sin6_addr)) {			if (bnp->rp_addr.sin6_scope_id == 0 &&			    bnp->rp_ife == NULL) {				warnx("%s line %d: link-local peer(%s) "				      "without I/F or scope ID",				      configfilename, info->line,				      ip6str2(&bnp->rp_addr));				return(-1);			}		}	}	return(0);}static intadd_protoexport(bnp, attr, ptype, pdata)	struct rpcb *bnp;	struct attr_list *attr;	int ptype;	void *pdata;{	struct rtproto *rtp = NULL;	if ((rtp = malloc(sizeof(*rtp))) == NULL) {		warnx("can't allocate space for export protocol");		return(-1);	}	rtp->rtp_type = ptype;	switch(ptype) {	case RTPROTO_IF:		rtp->rtp_if = (struct ifinfo *)pdata;		break;	case RTPROTO_BGP:		rtp->rtp_bgp = (struct rpcb *)pdata;		break;	case RTPROTO_RIP:		rtp->rtp_rip = (struct ripif *)pdata;		break;	/* default? */	}	if (bnp->rp_adj_ribs_out != NULL) {		if (find_rtp(rtp, bnp->rp_adj_ribs_out)) {			warnx("%s line %d: export protocol doubly defined",			      configfilename, attr->line);			free(rtp); /* necessary? */			return(-1);		}		insque(rtp, bnp->rp_adj_ribs_out);	} else {		rtp->rtp_next = rtp;		rtp->rtp_prev = rtp;		bnp->rp_adj_ribs_out = rtp;

⌨️ 快捷键说明

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