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

📄 parse.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1998 WIDE Project. * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "include.h"#include "bgp.h"#include "router.h"#include "task.h"#include "rt_table.h"#include "aspath.h"#include "bgp_var.h"#include "parse.h"#include "ripng.h"#include "ripng_var.h"#include "in6.h"/*  parsed bitmap   */#define C_MYASNUM        1#define C_ROUTERID       2   /*  BGP id  */#define C_HOLDTIME       3#define C_PROTO          4#define C_BGP            5#define C_RIP            6#define C_DIRECT         7#define C_INTERFACE      8#define C_YES            9#define C_NO             10#define C_GROUP          11#define C_TYPE           12#define C_EXTERNAL       13#define C_INTERNAL       14#define C_PEERAS         15#define C_PEER           16#define C_AS             17#define C_PREFERENCE     18#define C_EXPORT         19#define C_NORIPIN        20#define C_NORIPOUT       21#define C_DEFAULT        22#define C_RESTRICTIN     23#define C_ALL            24#define C_IBGP           25#define C_RR             26#define C_CLIENT         27#define C_CLUSTERID      28#define C_AGGREGATE      29#define C_EXPLICIT       30#define C_SYNC           31#define C_ORIGINATE      32#define C_PREPEND	 33#define C_METRICIN	 34#define C_RESTRICTOUT	35#define C_FILTERIN	36#define C_FILTEROUT	37#define C_DUMPFILE	38#define C_NEXTHOPSELF	39#define C_LOCALADDR	40#define C_SITELOCAL	41#define C_BGP_SBSIZE	42#define PARSE_MAX_BITS   C_BGP_SBSIZE/*  possiblly compatiblized with gated.conf */char *sysatom[] = {  "",  "autonomoussystem",  "routerid",  "holdtime",  "proto",  "bgp",  "rip",  "direct",  "interface",  "yes",  "no",  "group",  "type",  "external",  "internal",  "peeras",  "peer",  "as",  "preference",  "export",  "noripin",  "noripout",  "default",  "restrictin",  "all",  "ibgp",  "iamroutereflector",  "client",  "clusterid",  "aggregate",  "explicit",  "synchronization",  "originate",  "prepend",  "metricin",  "restrictout",  "filterin",  "filterout",  "dumpfile",  "nexthopself",  "lcladdr",  "sitelocal",  "bgpsbsize"};static int          i, j, line;static FILE        *fp;static struct rpcb *bnp;static char         buf[LINE_MAX];static char         atom[LINE_MAX];static bitstr_t     bit_decl(parsedflag, PARSE_MAX_BITS);static int	    set_filter(struct filtinfo **headp, char *filtstr,			       char *filename, int line);/* *  conf_check() *   ARGUMENT *      filename: config file's name *   DESCRIPTION *      only called at initialization. */voidconf_check(char *filename){  struct rpcb                *ibgpbnp;  /* global variables */  extern byte             bgpyes, ripyes;  extern int              bgpsock;  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;  extern fd_set           fdmask;  extern int              ripsock;  extern struct rt_entry *aggregations;  bit_nclear(parsedflag, 0, PARSE_MAX_BITS-1);  line = 0;  if ((fp = fopen(filename, "r")) == NULL) {    fatal("<conf_check>: fopen");  }  while (memset(buf,0,LINE_MAX), ++line,	 fgets(buf, LINE_MAX, fp) != NULL	 ) {    if (buf[0] == '#' || buf[0] == '\n') continue;    i = 0;    SKIP_WHITE(i);    /*     *	"dumpfile FILENAME"     */    if (strncasecmp(&buf[i], sysatom[C_DUMPFILE], strlen(sysatom[C_DUMPFILE]))	== 0) {	    extern char *dumpfile; /* defined in dump.c */	    i += strlen(sysatom[C_DUMPFILE]);	    SKIP_WHITE(i); READ_ATOM(i, j);	    if ((dumpfile = malloc(strlen(atom) + 1)) == NULL) /* XXX */		    fatalx("malloc");	    strcpy(dumpfile, atom);	    SENTENCE_END(i);	    continue;    }    /*     * socket buffer size     */    if (strncasecmp(&buf[i], sysatom[C_BGP_SBSIZE], strlen(sysatom[C_BGP_SBSIZE]))	== 0) {      if (bit_test(parsedflag, C_BGP_SBSIZE)) {	syslog(LOG_ERR, "%s:%d %s doubly defined",	       filename, line, sysatom[C_BGP_SBSIZE]);	fatalx("<conf_check>: doubly defined");      }      bit_set(parsedflag, C_BGP_SBSIZE);      i += strlen(sysatom[C_BGP_SBSIZE]);      SKIP_WHITE(i); READ_ATOM(i, j);      bgpsbsize = atoi(atom);  /* XXX: need validation? */      SENTENCE_END(i);      continue;    }    /*     *   "bgp yes {...}"     */    if (strncasecmp(&buf[i], sysatom[C_BGP], strlen(sysatom[C_BGP]))	== 0) {      parse_bgp_yes(filename);      continue;    }    /*     *   "aggregate prfx/plen {...}"     */    if (strncasecmp(&buf[i], sysatom[C_AGGREGATE],strlen(sysatom[C_AGGREGATE]))	== 0) {      struct rt_entry *aggregated;      char in6txt[INET6_ADDRSTRLEN];      memset(in6txt, 0, INET6_ADDRSTRLEN);      MALLOC(aggregated, struct rt_entry);      aggregated->rt_proto.rtp_type = RTPROTO_AGGR;      i += strlen(sysatom[C_AGGREGATE]);      SKIP_WHITE(i); READ_ATOM(i, j);      if (inet_ptox(AF_INET6, atom,		    &aggregated->rt_ripinfo.rip6_dest,		    &aggregated->rt_ripinfo.rip6_plen) < 1) {	syslog(LOG_ERR, "%s:%d inet_ptox() failed", filename, line);	terminate();      }      mask_nclear(&aggregated->rt_ripinfo.rip6_dest, 		  aggregated->rt_ripinfo.rip6_plen);      SKIP_WHITE(i);      if (buf[i++] != '{') {	syslog(LOG_ERR,	       "%s:%d syntax error, missing \'{\'", filename, line);	fatalx("<conf_check>: syntax error");      }      while(1) {	SKIP_WHITE(i);	if (strncasecmp(&buf[i], sysatom[C_EXPLICIT],strlen(sysatom[C_EXPLICIT]))	    == 0) {	  SKIP_WHITE(i);	  if (buf[i++] != '{') {	    syslog(LOG_ERR,		   "%s:%d syntax error, missing \'{\'", filename, line);	    fatalx("<conf_check>: syntax error");	  }	  while(11) {	    struct rt_entry *explt;	    SKIP_WHITE(i); READ_ATOM(i, j);	    if (*atom == '}') break;	    MALLOC(explt, struct rt_entry);	    if (inet_ptox(AF_INET6, atom,			  &explt->rt_ripinfo.rip6_dest,			  &explt->rt_ripinfo.rip6_plen) < 1) {	      syslog(LOG_ERR, "%s:%d inet_ptox() failed", filename, line);	      terminate();	    }	    /* aggregatablity check */	  	    if (aggregated != aggregatable(explt)) {	      syslog(LOG_ERR, "%s:%d NOT aggregatable", filename, line);	      fatalx("<conf_check>: NOT aggregatable");	    }	    if (aggregated->rt_aggr.ag_explt != NULL) {	      if (find_rte(explt, aggregated->rt_aggr.ag_explt)) {		syslog(LOG_ERR,		       "%s:%d explicit route doubly defined", filename,line);		fatalx("<conf_check>: explicit route doubly defined");	      }	      insque(explt, aggregated->rt_aggr.ag_explt);	    } else {	      explt->rt_next = explt;	      explt->rt_prev = explt;	      aggregated->rt_aggr.ag_explt = explt;	    }	    SENTENCE_END(i);	  } /* while(11) */	  SENTENCE_END(i);		  continue;	  /* End-of-"explicit" */	}	/*	 *   "proto" ..?	 */	if (strncasecmp(&buf[i], sysatom[C_PROTO], strlen(sysatom[C_PROTO]))	    == 0) {	  struct rtproto  *rtp;	  MALLOC(rtp, struct rtproto);	  	  i += strlen(sysatom[C_PROTO]);	  SKIP_WHITE(i);	  /*	   *   "direct"	   */	  if (strncasecmp(&buf[i], sysatom[C_DIRECT], strlen(sysatom[C_DIRECT]))	      == 0) {	    struct ifinfo *ifp;	    i += strlen(sysatom[C_DIRECT]);	    SKIP_WHITE(i);	    /*     "interface .."    */ 	    if (strncasecmp(&buf[i], sysatom[C_INTERFACE], strlen(sysatom[C_INTERFACE]))		!= 0) {	      syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",		     filename, line, sysatom[C_INTERFACE]);	      fatalx("<conf_check>: syntax error");	    }	    i += strlen(sysatom[C_INTERFACE]);	    SKIP_WHITE(i); READ_ATOM(i, j);	    if ((ifp = find_if_by_name(atom)) == NULL) {/* find  "ifinfo" */	      syslog(LOG_ERR, "%s:%d interface \'%s\' not found",		     filename, line, atom);	      fatalx("<conf_check>: interface not found");	    }	    	    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]);	    	    rtp->rtp_type = RTPROTO_IF;	    rtp->rtp_if   = ifp;	    if (aggregated->rt_aggr.ag_rtp != NULL) {	      if (find_rtp(rtp, aggregated->rt_aggr.ag_rtp)) {		syslog(LOG_ERR,		       "%s:%d protocol I/F doubly defined", filename,line);		fatalx("<conf_check>: protocol I/F doubly defined");	      }	      insque(rtp, aggregated->rt_aggr.ag_rtp);	    } else {	      rtp->rtp_next = rtp;	      rtp->rtp_prev = rtp;	      aggregated->rt_aggr.ag_rtp = rtp;	    }	    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);	    /* End-of-"direct" */	  }	  /*	   * BGP	   * XXX: this must be placed after bgp{} statements...	   */	  else if (strncasecmp(&buf[i], sysatom[C_BGP], strlen(sysatom[C_BGP]))		   == 0) {	    struct rpcb   *asp = NULL;	    u_int16_t  easnum;	    i += strlen(sysatom[C_BGP]);	    SKIP_WHITE(i);	    if (strncasecmp(&buf[i], sysatom[C_AS], strlen(sysatom[C_AS]))		!= 0) {	      syslog(LOG_ERR, "%s:%d syntax error, missing \'%s\'",		     filename, line, sysatom[C_AS]);	      fatalx("<conf_check>: syntax error");	    }	    i += strlen(sysatom[C_AS]);	    SKIP_WHITE(i); READ_ATOM(i, j);	    if ((easnum = atoi(atom)) == 0) {	      syslog(LOG_ERR, "%s:%d invalid AS number", filename, line);	      fatalx("<conf_check>: invalid AS number");	    }	    if (easnum == my_as_number) {	/* IBGP peer */	      /* XXX currently the address for the peer is always required. */	      struct sockaddr_in6 sa6_peer;	      memset(&sa6_peer, 0, sizeof(sa6_peer));	      SKIP_WHITE(i); READ_ATOM(i, j);	      /* TODO: support scoped addresses */	      if (get_in6_addr(atom, &sa6_peer) ||		  (asp = find_apeer_by_addr(&sa6_peer.sin6_addr)) == NULL) {		syslog(LOG_ERR, "%s:%d invalid peer address", filename, line);		fatalx("<conf_check>: invalid peer address");	      }	    }	    else if ((asp = find_peer_by_as(easnum)) == NULL) {  /* already ? */	      syslog(LOG_ERR, "%s:%d AS %d not defined",		     filename, line, easnum);	      fatalx("<conf_check>: AS not defined");	    }	    /* XXX: duplicated code...(see above) */	    rtp->rtp_type = RTPROTO_BGP;	    rtp->rtp_bgp = asp;	    if (aggregated->rt_aggr.ag_rtp != NULL) {	      if (find_rtp(rtp, aggregated->rt_aggr.ag_rtp)) {		syslog(LOG_ERR,		       "%s:%d BGP peer doubly defined", filename,line);		fatalx("<conf_check>: BGP peer for aggregation doubly defined");	      }	      insque(rtp, aggregated->rt_aggr.ag_rtp);	    } else {	      rtp->rtp_next = rtp;	      rtp->rtp_prev = rtp;	      aggregated->rt_aggr.ag_rtp = rtp;	    }	    SENTENCE_END(i);	  }	  else {	    syslog(LOG_ERR, "%s:%d syntax error", filename, line);	    fatalx("<conf_check>: syntax error");	      	  }	  continue;	  /* End-of-"proto" */	}	break;  /* while(1) */      }  /* End-of-while(1) */      if (buf[i++] != '}') {	syslog(LOG_ERR,	       "%s:%d syntax error, missing \'}\'", filename, line);	fatalx("<conf_check>: syntax error");      }      SENTENCE_END(i);      if (aggregations) {	if (find_rte(aggregated, aggregations)) {	  syslog(LOG_ERR,		 "%s:%d aggregate route doubly defined", filename,line);	  fatalx("<conf_check>: aggregate route doubly defined");	}	insque(aggregated, aggregations);      } else {	aggregated->rt_next = aggregated;	aggregated->rt_prev = aggregated;	aggregations = aggregated;      }      continue;    }    /*     *   "autonomoussystem"     */    if (strncasecmp(&buf[i], sysatom[C_MYASNUM], strlen(sysatom[C_MYASNUM]))	== 0) {      if (bit_test(parsedflag, C_MYASNUM)) {	syslog(LOG_ERR, "%s:%d %s doubly defined",	       filename, line, sysatom[C_MYASNUM]);	fatalx("<conf_check>: doubly defined");      }      bit_set(parsedflag, C_MYASNUM);      i += strlen(sysatom[C_MYASNUM]);      SKIP_WHITE(i); READ_ATOM(i, j);      my_as_number = atoi(atom);  /* (global) */      SENTENCE_END(i);      continue;    }    /*     *   "routerid" (my BGP-ID)     */    if (strncasecmp(&buf[i], sysatom[C_ROUTERID], strlen(sysatom[C_ROUTERID])) == 0)       {	if (bit_test(parsedflag, C_ROUTERID)) {	  syslog(LOG_ERR, "<conf_check>: %s:%d %s doubly defined",		 filename, line, sysatom[C_ROUTERID]);	  fatalx("<conf_check>: doubly defined");	}	bit_set(parsedflag ,C_ROUTERID);	i += strlen(sysatom[C_ROUTERID]);	SKIP_WHITE(i); READ_ATOM(i, j);	if (inet_pton(AF_INET, atom, (void *)&bgpIdentifier) != 1)	  bgpIdentifier = htonl(atoi(atom));  /* (global) */	SENTENCE_END(i);	continue;      }

⌨️ 快捷键说明

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