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

📄 parse.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	      } else {		rtp->rtp_next = rtp->rtp_prev = rtp;		asp->rp_adj_ribs_out = rtp;	      }	      MALLOC(rtp, struct rtproto);	      if ((ripif = ripif->rip_next) == ripifs) { /* global */		free(rtp); rtp = NULL;		break;	      }	    } /* while rip-ring */	    SENTENCE_END(i); SKIP_WHITE(i);	    if (buf[i++] != '}') {	      syslog(LOG_ERR,		     "%s:%d syntax error, missing \'}\'", filename, line);	      fatalx("<conf_check>: syntax error");	    }	    SENTENCE_END(i);	    continue;	    /***    rip End   ***/	  }	  /*	   *  "IBGP"	   */	  if (strncasecmp(&buf[i], sysatom[C_IBGP], strlen(sysatom[C_IBGP]))	      == 0) {	    struct rpcb *ibnp;   /* origin */	    i += strlen(sysatom[C_IBGP]);	    SKIP_WHITE(i);	    if (buf[i++] != '{') {	      syslog(LOG_ERR,		     "%s:%d syntax error, missing \'{\'", filename, line);	      fatalx("<conf_check>: syntax error");	  	    }	    SKIP_WHITE(i);	    /*	     *   "ALL"	     */	    if (strncasecmp(&buf[i], sysatom[C_ALL], strlen(sysatom[C_ALL]))		!= 0) {	      syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",		     filename, line, sysatom[C_ALL]);	      fatalx("<conf_check>: syntax error");	    }	    i += strlen(sysatom[C_ALL]);	    ibnp = bgb;  /* global */	    while(1) {	      if (ibnp->rp_mode & BGPO_IGP) {		rtp->rtp_type = RTPROTO_BGP;		rtp->rtp_bgp  = ibnp;		if (asp->rp_adj_ribs_out != NULL) {    /* struct rtproto */		  if (find_rtp(rtp, asp->rp_adj_ribs_out)) {		    syslog(LOG_ERR,			   "%s:%d originating BGP peer doubly defined",			   filename, line);		    fatalx("<conf_check>: originating BGP peer doubly defined");		  }		  insque(rtp, asp->rp_adj_ribs_out);		} else {		  rtp->rtp_next = rtp->rtp_prev = rtp;		  asp->rp_adj_ribs_out = rtp;		}		MALLOC(rtp, struct rtproto);	      }	      if ((ibnp = ibnp->rp_next) == bgb) {		free(rtp); rtp = NULL;		break;	      }	    } /* while bgp-ring */	    SENTENCE_END(i); SKIP_WHITE(i);	    if (buf[i++] != '}') {	      syslog(LOG_ERR,		     "%s:%d syntax error, missing \'}\'", filename, line);	      fatalx("<conf_check>: syntax error");	    }	    SENTENCE_END(i);	    continue;	    /***   IBGP End    ***/	  }	  /**  proto-switching End  **/	  if (buf[i++] == '}')	    break;	  else {	    syslog(LOG_ERR,		   "%s:%d syntax error, missing \'}\'", filename, line);	    fatalx("<conf_check>: syntax error");	  }	} /*  while(1)  */	SKIP_WHITE(i);	SENTENCE_END(i);	continue;      } else {	syslog(LOG_ERR, "%s:%d syntax error", filename, line);	fatalx("<conf_check>: syntax error");	/* error */      }    }    /**  nothing matched  **/    syslog(LOG_ERR, "<conf_check>: %s:%d syntax error", filename, line);    fatalx("<conf_check>: syntax error");  }      /************************************************************************/  if (ripyes)	  rip_import_init();  if (bgpyes) {    struct sockaddr_in6 bgpsin;        /* my address      */    int on;    if (!(bit_test(parsedflag, C_MYASNUM))) {      dperror("<conf_check>: My AS number not defined");      terminate();    }    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) */        if (!(bit_test( parsedflag, C_HOLDTIME)))      bgpHoldtime = BGP_HOLDTIME;       /* default   */    ibgpbnp = bgb;    while(ibgpbnp){      if (ibgpbnp->rp_mode & BGPO_IGP)	ibgpbnp->rp_as = my_as_number;      if ((ibgpbnp = ibgpbnp->rp_next) == bgb)	break;    }  } else {    bgpsock = 0;  }  if (!(bit_test(parsedflag, C_ROUTERID))) {    if ((bgpIdentifier = get_32id()) == 0)      fatalx("<conf_check>: bgpIdentifier should be defined");  }  if (!(bit_test(parsedflag, C_RIP)))    ripsock = 0;                        /* don't RIP */  /* REACHED */}/* *   "bgp yes {...}" */voidparse_bgp_yes(char *filename){  u_int16_t asnum;  u_int32_t peerid;  extern struct rpcb *bgb;  extern byte         bgpyes;  if (bit_test(parsedflag, C_BGP)) {    syslog(LOG_ERR, "%s:%d %s doubly defined", filename, line, sysatom[C_BGP]);    fatalx("doubly defined");  }  bit_set(parsedflag, C_BGP);  bgb = bgp_new_peer();      /*   Initialized one becomes the head.  */  bgb->rp_next = bgb->rp_prev = bgb;  bnp = bgb;  i += strlen(sysatom[C_BGP]);  SKIP_WHITE(i);  if (strncasecmp(&buf[i], sysatom[C_YES], strlen(sysatom[C_YES]))      == 0)	{    bgpyes = 1;    i += strlen(sysatom[C_YES]);  } else {    if (strncasecmp(&buf[i], sysatom[C_NO], strlen(sysatom[C_NO]))	== 0) {      i += strlen(sysatom[C_NO]);    } else {      syslog(LOG_ERR, "%s:%d syntax error", filename, line);      fatalx("syntax error");    }  }  SKIP_WHITE(i);  if (buf[i++] != '{') {    syslog(LOG_ERR, "%s:%d syntax error, missing \'{\'", filename, line);    fatalx("syntax error");  }  SKIP_WHITE(i);        while(1) {    /*     *   "Group Type"     */    if (strncasecmp(&buf[i], sysatom[C_GROUP], strlen(sysatom[C_GROUP]))	!= 0) {      syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",	     filename, line, sysatom[C_GROUP]);      fatalx("syntax error");    }     i += strlen(sysatom[C_GROUP]);    SKIP_WHITE(i);    if (strncasecmp(&buf[i], sysatom[C_TYPE], strlen(sysatom[C_TYPE]))	!= 0)	{      syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",	     filename, line, sysatom[C_TYPE]);      fatalx("syntax error");    }     i += strlen(sysatom[C_TYPE]);    SKIP_WHITE(i);    /*     *       "External peeras"     */    if (strncasecmp(&buf[i], sysatom[C_EXTERNAL], strlen(sysatom[C_EXTERNAL]))	== 0) {      i += strlen(sysatom[C_EXTERNAL]);      SKIP_WHITE(i);      if (strncasecmp(&buf[i], sysatom[C_PEERAS], strlen(sysatom[C_PEERAS]))	  != 0)	{	syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",	       filename, line, sysatom[C_PEERAS]);	fatalx("syntax error");      }       i += strlen(sysatom[C_PEERAS]);      SKIP_WHITE(i); READ_ATOM(i, j);      if ((asnum = atoi(atom)) == 0) {	syslog(LOG_ERR, "%s:%d invalid AS number", filename, line);	fatalx("invalid AS number");      }      if (find_peer_by_as(asnum)) {	syslog(LOG_ERR, "%s:%d AS %d doubly defined", filename, line, asnum);	fatalx("AS number doubly defined");      }      bnp->rp_as = asnum;    } else {            /*       *       "Internal [routerid ...]"       */      if (strncasecmp(&buf[i], sysatom[C_INTERNAL],strlen(sysatom[C_INTERNAL]))	  == 0) {	i += strlen(sysatom[C_INTERNAL]);	SKIP_WHITE(i);	peerid = 0; /* init */	if (strncasecmp(&buf[i], sysatom[C_ROUTERID], strlen(sysatom[C_ROUTERID]))	  == 0)	{	  i += strlen(sysatom[C_ROUTERID]);	  SKIP_WHITE(i); READ_ATOM(i, j);	  /* IPv4 address format : jinmei */	  if (inet_pton(AF_INET, atom, (void *)&peerid) != 1)	    peerid = htonl(atoi(atom));	  if (peerid == 0) {	    syslog(LOG_ERR, "%s:%d invalid Router ID", filename, line);	    fatalx("invalid Router ID");	  } else if (rpcblookup(bgb, peerid)) {	    syslog(LOG_ERR,		   "%s:%d PEER ID %d doubly defined", filename, line, peerid);	    fatalx("Peer ID doubly defined");	  }	  bnp->rp_mode |= BGPO_IDSTATIC;  /* (1998/5/21) */	}	bnp->rp_id    = peerid; /* net-order */	bnp->rp_mode |= BGPO_IGP;      } else {  /* External nor Internal */	syslog(LOG_ERR, "%s:%d syntax error", filename, line);	fatalx("syntax error");       }    }    SKIP_WHITE(i);    if (buf[i++] != '{') {      syslog(LOG_ERR, "%s:%d syntax error, missing \'{\'", filename, line);      fatalx("syntax error");	      }    SKIP_WHITE(i);    /*     *   "peer|client" ...   [interface ..]     */    if (strncasecmp(&buf[i], sysatom[C_CLIENT], strlen(sysatom[C_CLIENT]))	== 0) {      if (bnp->rp_mode & BGPO_IGP) {	bnp->rp_mode |= BGPO_RRCLIENT;	i += strlen(sysatom[C_CLIENT]);      } else {	syslog(LOG_ERR, "%s:%d External peer (%d) cannot be a RRclient",	       filename, line, bnp->rp_as);	fatalx("External peer cannot be a RRclient");      }    } else {      if (strncasecmp(&buf[i], sysatom[C_PEER], strlen(sysatom[C_PEER]))	  == 0) {	i += strlen(sysatom[C_PEER]);      } else {	syslog(LOG_ERR, "%s:%d syntax error", filename, line);	fatalx("syntax error");      }    }    SKIP_WHITE(i); READ_ATOM(i, j);    bnp->rp_addr.sin6_len      = sizeof(struct sockaddr_in6);    bnp->rp_addr.sin6_family   = AF_INET6;    bnp->rp_addr.sin6_port     = htons(BGP_PORT);    bnp->rp_addr.sin6_flowinfo = 0;    if (inet_pton(AF_INET6, atom, &bnp->rp_addr.sin6_addr) != 1) {      syslog(LOG_ERR, "%s:%d inet_pton() failed", filename, line);      terminate();    }    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;    }    while(1) {      SKIP_WHITE(i);      /*     [interface ..]  (e.x. for link-local address)  */       if (strncasecmp(&buf[i], sysatom[C_INTERFACE], strlen(sysatom[C_INTERFACE]))	  == 0) {	i += strlen(sysatom[C_INTERFACE]);	SKIP_WHITE(i); READ_ATOM(i, j);	if ((bnp->rp_ife = find_if_by_name(atom))) { /* find "ifinfo" */	  bnp->rp_mode |= BGPO_IFSTATIC;	} else {	  syslog(LOG_ERR,		 "%s:%d interface %s misconfigure", filename, line, atom);	  fatalx("interface misconfigure");	}      }       else if (strncasecmp(&buf[i],		      sysatom[C_PREFERENCE], strlen(sysatom[C_PREFERENCE]))	  == 0) {	      /*     [preference ..]  (for this peer)  */ 	      if (bnp->rp_mode & BGPO_IGP) {		      syslog(LOG_ERR,			     "%s:%d %s can only be specified for an EBGP peer",			     filename, line, sysatom[C_PREFERENCE]);		      fatalx("<conf_check>: invalid peer option");	      }	      i += strlen(sysatom[C_PREFERENCE]);	      SKIP_WHITE(i); READ_ATOM(i, j);	      bnp->rp_prefer = htonl(atoi(atom));      }      else if (strncasecmp(&buf[i], sysatom[C_NO], strlen(sysatom[C_NO])) == 0) {	    /*   [no synchronization]  (for this peer)  */ 	    i += strlen(sysatom[C_NO]);	    SKIP_WHITE(i);	    if (strncasecmp(&buf[i], sysatom[C_SYNC], strlen(sysatom[C_SYNC])) == 0) {	      bnp->rp_mode |= BGPO_NOSYNC;	      i += strlen(sysatom[C_SYNC]);	      SKIP_WHITE(i);	    } else {	      syslog(LOG_ERR, "%s:%d syntax error", filename, line);	      fatalx("syntax error");	    }	  }      else if (strncasecmp(&buf[i], sysatom[C_PREPEND], strlen(sysatom[C_PREPEND]))	  == 0) {	      if (bnp->rp_mode & BGPO_IGP) {		      syslog(LOG_ERR,			     "%s:%d %s can only be specified for an EBGP peer",			     filename, line, sysatom[C_PREPEND]);		      fatalx("<conf_check>: invalid peer option");	      }	      i += strlen(sysatom[C_PREPEND]);	      SKIP_WHITE(i);	      if (isdigit(buf[i])) {		      READ_ATOM(i, j);		      bnp->rp_ebgp_as_prepends = atoi(atom);	      }	      else		      bnp->rp_ebgp_as_prepends = BGP_DEF_ASPREPEND;      }      else if (strncasecmp(&buf[i], sysatom[C_NEXTHOPSELF],			   strlen(sysatom[C_NEXTHOPSELF])) == 0) {	      if ((bnp->rp_mode & BGPO_IGP) == 0) {		      syslog(LOG_ERR,			     "%s:%d %s can only be specified for an IBGP peer",			     filename, line, sysatom[C_NEXTHOPSELF]);		      fatalx("<conf_check>: invalid peer option");	      }	      i += strlen(sysatom[C_NEXTHOPSELF]);	      bnp->rp_mode |= BGPO_NEXTHOPSELF;      }      else if (strncasecmp(&buf[i], sysatom[C_LOCALADDR],			   strlen(sysatom[C_LOCALADDR])) == 0) {	      if (!IN6_IS_ADDR_UNSPECIFIED(&bnp->rp_lcladdr.sin6_addr)) {		      syslog(LOG_ERR,			     "%s:%d BGP localaddr doubly defined",			     filename, line);		      fatalx("<conf_check>: perse failed");	      }	      i += strlen(sysatom[C_LOCALADDR]);	      SKIP_WHITE(i); READ_ATOM(i, j);	      memcpy(&bnp->rp_lcladdr.sin6_addr, atom, sizeof(struct in6_addr));	      if (inet_pton(AF_INET6, atom, &bnp->rp_lcladdr.sin6_addr) != 1) {		      syslog(LOG_ERR, "%s:%d inet_pton() failed for %s",			     filename, line, atom);		      fatalx("<conf_check>: perse failed");	      }	      if (IN6_IS_ADDR_LINKLOCAL(&bnp->rp_lcladdr.sin6_addr)) {		      syslog(LOG_ERR,			     "%s:%d BGP local addr must not be a link-local(%s)",			     filename, line, atom);		      fatalx("<conf_check>: perse failed");	      }	      bnp->rp_lcladdr.sin6_len = sizeof(struct sockaddr_in6);	      bnp->rp_lcladdr.sin6_family = AF_INET6;      }      else	      break; /* while */    }    if (IN6_IS_ADDR_LINKLOCAL(&bnp->rp_addr.sin6_addr) &&	bnp->rp_ife == NULL) {      syslog(LOG_ERR,	     "%s:%d link-local address needs it's associating I/F",	     filename, line);      fatalx("interface misconfigure");    }    if (bnp != bgb)      insque(bnp, bgb);    bnp = bgp_new_peer();   /* for next. But the LastOne maybe garbage */    SENTENCE_END(i);    SKIP_WHITE(i);    if (buf[i++] != '}') {      syslog(LOG_ERR, "%s:%d syntax error, missing \'}\'", filename, line);      fatalx("syntax error");    }    SENTENCE_END(i);    SKIP_WHITE(i);    if (buf[i] == '}')      break;  } /* while */  i++;  SKIP_WHITE(i);  SENTENCE_END(i);  if (!bgpyes) {    free(bgb);    bgb = NULL;  }}static intset_filter(struct filtinfo **headp, char *filtstr, char *filename, int line){	struct filtinfo *filter;	char in6txt[INET6_ADDRSTRLEN];	/* At first, check if the string means a special filter */	if (!strncasecmp(filtstr, "default", strlen("default")))		return(1);	/* XXX: adhoc */	memset(in6txt, 0, INET6_ADDRSTRLEN);	MALLOC(filter, struct filtinfo);	memset(filter, 0, sizeof(struct filtinfo));	if (inet_ptox(AF_INET6, filtstr,		      &filter->filtinfo_addr,		      &filter->filtinfo_plen) < 1) {		syslog(LOG_ERR,		       "%s:%d inet_ptox() failed", filename, line);		terminate();	}	mask_nclear(&filter->filtinfo_addr, filter->filtinfo_plen);	if (*headp) {		if (find_filter(*headp, filter)) {			syslog(LOG_ERR,			       "%s:%d route filter doubly defined",			       filename, line);			fatalx("route filter doubly defined");		}		insque(filter, *headp);	} else {		filter->filtinfo_next =			filter->filtinfo_prev = filter;		*headp = filter;	}	return(0);}

⌨️ 快捷键说明

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