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

📄 cfparse.y

📁 同时支持IPv4和IPv6的BGP协议实现
💻 Y
📖 第 1 页 / 共 4 页
字号:
		{			struct in_addr routerid;			if ((inet_aton($6.v, &routerid)) == 0) {				yywarn("invalid router ID: %s", $6.v);				free($6.v);				return(-1);			}			free($6.v);			if (add_bgppeer(-1, routerid.s_addr, $8))				return(-1);		}	;peerstatements:		PEER STRING peerattributes EOS		{			memset(&bgppeer_temp, 0, sizeof(bgppeer_temp));			if (get_in6_addr($2.v, &bgppeer_temp.peeraddr)) {				yywarn("bad BGP peer address: %s", $2.v);				free($2.v);				return(-1);			}			bgppeer_temp.peertype = BGPPEER_NORMAL;			bgppeer_temp.attribute = $3;			$$ = &bgppeer_temp;		}	|	CLIENT STRING peerattributes EOS		{			memset(&bgppeer_temp, 0, sizeof(bgppeer_temp));			if (get_in6_addr($2.v, &bgppeer_temp.peeraddr)) {				yywarn("bad BGP peer address: %s", $2.v);				free($2.v);				return(-1);			}			bgppeer_temp.peertype = BGPPEER_CLIENT;			bgppeer_temp.attribute = $3;			$$ = &bgppeer_temp;		}	;peerattributes:		{ $$ = NULL; }	/* empty */	|	peerattributes INTERFACE IFNAME		{			if (($$ = add_attribute($1, ATTR_STRING,						BGPPA_IFNAME, $3.v)) == NULL) {				free($3.v);				return(-1);			}		}	|	peerattributes NOSYNC		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_NOSYNC, 0)) == NULL)				return(-1);		}	|	peerattributes NEXTHOPSELF		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_NEXTHOPSELF, 0)) == NULL)				return(-1);		}	|	peerattributes LCLADDR STRING		{			struct sockaddr_in6 lcladdr;			if (get_in6_addr($3.v, &lcladdr)) {				yywarn("bad IPv6 address: %s", $3.v);				free($3.v);				return(-1);			}			if (($$ = add_attribute($1, ATTR_ADDR, BGPPA_LCLADDR,						&lcladdr)) == NULL)				return(-1);		}	|	peerattributes PREFERENCE NUMBER		{			int pref = $3;			if (($$ = add_attribute($1, ATTR_NUMBER,						BGPPA_PREFERENCE,						(void *)&pref)) == NULL)				return(-1);		}	|	peerattributes PREPEND		{			int pref = BGP_DEF_ASPREPEND;			if (($$ = add_attribute($1, ATTR_NUMBER,						BGPPA_PREPEND,						(void *)&pref)) == NULL)				return(-1);		}	|	peerattributes PREPEND NUMBER		{			int pref = $3;			if (($$ = add_attribute($1, ATTR_NUMBER,						BGPPA_PREPEND,						(void *)&pref)) == NULL)				return(-1);		}	|	peerattributes DESCR DESCSTRING		{			if (($$ = add_attribute($1, ATTR_STRING,						BGPPA_DESCR, $3.v)) == NULL)				return(-1);		}	|	peerattributes FILTERIN DEFAULT		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_FILINDEF, 0)) == NULL)				return(-1);		}	|	peerattributes FILTEROUT DEFAULT		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_FILOUTDEF, 0)) == NULL)				return(-1);		}	|	peerattributes RESTRICTIN DEFAULT		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_RESINDEF, 0)) == NULL)				return(-1);		}	|	peerattributes RESTRICTOUT DEFAULT		{			if (($$ = add_attribute($1, ATTR_FLAG,						BGPPA_RESOUTDEF, 0)) == NULL)				return(-1);		}	|	peerattributes FILTERIN prefix		{			if (($$ = add_attribute($1, ATTR_PREFIX,						BGPPA_FILINPFX, $3)) == NULL)				return(-1);		}	|	peerattributes FILTEROUT prefix		{			if (($$ = add_attribute($1, ATTR_PREFIX,						BGPPA_FILOUTPFX, $3)) == NULL)				return(-1);		}	|	peerattributes RESTRICTIN prefix		{			if (($$ = add_attribute($1, ATTR_PREFIX,						BGPPA_RESINPFX, $3)) == NULL)				return(-1);		}	|	peerattributes RESTRICTOUT prefix		{			if (($$ = add_attribute($1, ATTR_PREFIX,						BGPPA_RESOUTPFX, $3)) == NULL)				return(-1);		}	;/* export */export_statement:		EXPORT PROTO BGP AS NUMBER BCL export_list ECL EOS		{			if (add_export($5, NULL, $7))				return(-1); /* XXX free? */		}	|	EXPORT PROTO BGP PEER STRING BCL export_list ECL EOS 		{			struct sockaddr_in6 peeraddr;			if (get_in6_addr($5.v, &peeraddr)) {				yywarn("bad peer address: %s", $5.v);				free($5.v);				return(-1);			}			if (add_export(-1, &peeraddr, $7))				return(-1);		}	;export_list:		{ $$ = NULL; };	/* empty */	|	export_list protocol		{			if (($$ = add_attribute($1, ATTR_DATA, EXPA_PROTO,						$2)) == NULL)				return(-1);		}	;protocol:			/* XXX: currently too restrictive */		PROTO DIRECT INTERFACE IFNAME all_block EOS		{			struct yy_rtproto *p;			if ((p = malloc(sizeof(*p))) == NULL) {				yywarn("can't allocate memory");				return(-1);			}			memset(p, 0, sizeof(*p));			if (strlen($4.v) >= sizeof(p->rtpu.ifname)) {				yywarn("interface name(%s) is too long",				       $4.v);				free($4.v);				return(-1);			}			p->type = RTP_IFACE;			strcpy(p->rtpu.ifname, $4.v);			$$ = p;		}	|	PROTO BGP AS NUMBER all_block EOS		{			struct yy_rtproto *p;			if ((p = malloc(sizeof(*p))) == NULL) {				yywarn("can't allocate memory");				return(-1);			}			memset(p, 0, sizeof(*p));			p->type = RTP_BGP;			p->rtpu.rtpu_bgp.peeras = $4;			$$ = p;		}	|	PROTO BGP PEER STRING all_block EOS		{			struct yy_rtproto *p;			if ((p = malloc(sizeof(*p))) == NULL) {				yywarn("can't allocate memory");				free($4.v);				return(-1);			}			memset(p, 0, sizeof(*p));			p->type = RTP_BGP;			if (get_in6_addr($4.v, &p->rtpu.rtpu_bgp.peeraddr)) {				yywarn("bad peer address: %s", $4.v);				free($4.v);				return(-1);			}			free($4.v);			$$ = p;		}	|	PROTO RIP all_block EOS		{			struct yy_rtproto *p;			if ((p = malloc(sizeof(*p))) == NULL) {				yywarn("can't allocate memory");				return(-1);			}			memset(p, 0, sizeof(*p));			p->type = RTP_RIP;			$$ = p;		}	|	PROTO IBGP all_block EOS		{			struct yy_rtproto *p;			if ((p = malloc(sizeof(*p))) == NULL) {				yywarn("can't allocate memory");				return(-1);			}			memset(p, 0, sizeof(*p));			p->type = RTP_IBGP;			$$ = p;		}	;/* just for shortcut */all_block:			/* do nothing */		/* empty */	|	BCL ALL EOS ECL	;/* aggregate */aggregate_statement:	AGGREGATE prefix BCL aggregate_substatements ECL EOS	{		if (add_aggregation($2, $4))			return(-1);	};aggregate_substatements:		{ $$ = NULL; }	/* empty */	|	aggregate_substatements protocol		{			if (($$ = add_attribute($1, ATTR_DATA, AGGA_PROTO,						$2)) == NULL)				return(-1);		}	|	aggregate_substatements EXPLICIT BCL prefix_list ECL EOS		{			if (($$ = add_attribute($1, ATTR_LIST, AGGA_EXPFX,						$4)) == NULL)				return(-1);		}	;/* prefix */prefix_list:		{ $$ = NULL; }	/* empty */	|	prefix_list prefix EOS		{			if (($$ = add_attribute($1, ATTR_PREFIX, ATTR_PREFIX,						$2)) == NULL)				return(-1);		}	;prefix:		STRING		{			if (get_in6_addr($1.v, &in6pfx_temp.paddr)) {				yywarn("bad IPv6 prefix: %s", $1.v);				free($1.v);				return(-1);			}			free($1.v);			in6pfx_temp.plen = 128;			$$ = &in6pfx_temp;		}	|	STRING SLASH NUMBER		{			if (get_in6_addr($1.v, &in6pfx_temp.paddr)) {				yywarn("bad IPv6 prefix: %s", $1.v);				free($1.v);				return(-1);			}			if ($3 < 0 || $3 > 128) {				yywarn("bad IPv6 prefixlen: %s", $1.v);				free($1.v);				return(-1);			}			free($1.v);			in6pfx_temp.plen = $3;			$$ = &in6pfx_temp;		}	;%%static intadd_static(new_rte)	struct yy_route_entry *new_rte;{	struct yy_route_entry *rte;	/* canonize the address part */	mask_nclear(&new_rte->prefix.paddr.sin6_addr, new_rte->prefix.plen);	/* check if duplicated */	for (rte = yy_static_head; rte; rte = rte->next) {		if (sa6_equal(&rte->prefix.paddr, &new_rte->prefix.paddr) &&		    rte->prefix.plen == new_rte->prefix.plen) {			yywarn("static route doubly defined: %s/%d",			       ip6str2(&rte->prefix.paddr), rte->prefix.plen);			return(-1);		}	}	/* add a new route */	if ((rte = malloc(sizeof(*rte))) == NULL) {		warnx("can't allocate space for a static route");		return(-1);	}	*rte = *new_rte;	rte->next = yy_static_head;	rte->line = lineno;	yy_static_head = rte;	return(0);}static intadd_aggregation(prefix, aggrinfo)	struct in6_prefix *prefix;	struct attr_list *aggrinfo;{	struct yy_aggrinfo *info;	/* check if duplicated */	for (info = yy_aggr_head; info; info = info->next) {		if (sa6_equal(&info->prefix.paddr, &prefix->paddr) &&		    info->prefix.plen == prefix->plen) {			yywarn("aggregate prefix(%s/%d) doulby defined",			       ip6str2(&prefix->paddr), prefix->plen);			return(-1);		}	}	/* allocate a new one */	if ((info = malloc(sizeof(*info))) == NULL) {		yywarn("can't allocate memory for aggregation");		return(-1);	}	memset(info, 0, sizeof(*info));	info->prefix = *prefix;	info->aggrinfo = aggrinfo;	info->line = lineno;	info->next = yy_aggr_head;	yy_aggr_head = info;	return(0);}static intadd_export(asnum, peer, list)	/* XXX BGP depend */	int asnum;	struct sockaddr_in6 *peer;	struct attr_list *list;{	struct yy_exportinfo *info;	/* check if duplicated */	for (info = yy_exportinfo_head; info; info = info->next) {		if (asnum >= 0 && info->asnum == asnum) {			yywarn("export peer (AS: %d) doubly defined", asnum);			return(-1);		}		if (peer && sa6_equal(peer, &info->peeraddr)) {			yywarn("export peer (addr: %s) doubly defined",			       ip6str2(&info->peeraddr));			return(-1);		}	}	/* allocate a new one */	if ((info = malloc(sizeof(*info))) == NULL) {		yywarn("can't allocate memory for export peer");		return(-1);	}	memset(info, 0, sizeof(*info));	info->asnum = asnum;	info->line = lineno;	if (peer)		info->peeraddr = *peer;	info->protolist = list;	info->next = yy_exportinfo_head;	yy_exportinfo_head = info;	return(0);}static intadd_bgppeer(asnum, routerid, peerinfo)	int asnum;	u_int32_t routerid;	struct yy_bgppeerinfo *peerinfo;{	struct yy_bgppeerinfo *info;	/* check if duplicated */	for (info = yy_bgppeer_head; info; info = info->next) {		if (asnum >= 0 && info->asnum == asnum) {			yywarn("BGP peer (AS: %d) doubly defined", asnum);			return(-1);		}		if (routerid && info->routerid == routerid) {			yywarn("BGP peer (routerID: %x) doubly defined",			       ntohl(routerid));			return(-1);		}		if (sa6_equal(&info->peeraddr, &peerinfo->peeraddr)) {			yywarn("BGP peer (addr: %s) doubly defined",			       ip6str2(&info->peeraddr));			return(-1);		}	}	/* allocate a new one */	if ((info = malloc(sizeof(*info))) == NULL) {		yywarn("can't allocate memory for BGP peerinfo");		return(-1);	}	memset(info, 0, sizeof(*info));	info->asnum = asnum;	info->routerid = routerid;	info->peertype = peerinfo->peertype;	info->peeraddr = peerinfo->peeraddr;	info->attribute = peerinfo->attribute;	info->line = lineno;	info->next = yy_bgppeer_head;	yy_bgppeer_head = info;	return(0);}static struct yy_ripifinfo *add_ripifinfo(ifname)	char *ifname;{	struct yy_ripifinfo *info;	if ((info = malloc(sizeof(*info))) == NULL) {		yywarn("can't allocate memory for ripifinfo");		return(NULL);	}	if (strlen(ifname) >= sizeof(info->ifname)) {		yywarn("interface name(%s) is too long", ifname);		free(info);		return(NULL);	}	memset(info, 0, sizeof(*info));	strcpy(info->ifname, ifname);	info->line = lineno;	info->next = yy_ripifinfo_head;	yy_ripifinfo_head = info;	return(info);}static struct attr_list *add_attribute(list, type, code, val)	struct attr_list *list;	int type, code;	void *val;{	struct attr_list *p;		if ((p = malloc(sizeof(*p))) == NULL) {		yyerror("malloc failed");		return(NULL);	}	memset((void *)p, 0, sizeof(*p));	p->code = code;	p->type = type;	p->line = lineno;	switch(type) {	case ATTR_FLAG:		p->attru.flags++;		break;	case ATTR_PREFIX:		p->attru.prefix = *(struct in6_prefix *)val;		break;	case ATTR_STRING:		p->attru.str = (char *)val;		break;	case ATTR_ADDR:		p->attru.in6addr = *(struct sockaddr_in6 *)val;		break;	case ATTR_NUMBER:		p->attru.number = *(int *)val;		break;	case ATTR_DATA:		p->attru.data = val;		break;	case ATTR_LIST:		p->attru.list = (struct attr_list *)val;		break;	default:		/* XXX what do I do? */		yywarn("unknown attribute type(%d)", type);		break;

⌨️ 快捷键说明

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