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