📄 parse.c
字号:
/* * 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 + -