📄 ipripng_util.c
字号:
p = ia->s6_addr; for (i = 0; i < 16; i++) { if (plen <= 0) *p = 0; else if (plen < 8) *p &= plent[plen]; p++, plen -= 8; }}/* * This function is required to add an offset to the time() call. * VxWorks returns time since bootup, but RIPng subtracts RIP_LIFETIME and * RIP_HOLDDOWN from this. If RIPng is started early after boot, then the * result of the subtraction is a negative number. Unfortunately time_t is an * unsigned long so the result is considered a high number in comparisons. * * The offset time returned from this ensures that time_t will never be * subtracted past zero. * * All calls to time() in this code are replaced by time_offset() calls. */IP_GLOBAL Ip_time_t time_offset(Ip_time_t *tod){ return (ipcom_time(tod) + RIP_LIFETIME + RIP_HOLDDOWN);}IP_GLOBAL Ip_time_t ipripng_nexttrigger_time(){ Ip_time_t t; long r = ipcom_random(); t = (int)(RIP_TRIG_INT6_MIN + (RIP_TRIG_INT6_MAX - RIP_TRIG_INT6_MIN) * (r / IP_RAND_MAX )); return t;}IP_GLOBAL intsin6mask2len(const struct Ip_sockaddr_in6 *sin6){ return mask2len(&sin6->sin6_addr, sin6->sin6_len - ip_offsetof(struct Ip_sockaddr_in6, sin6_addr));}IP_GLOBAL voidrtflags(struct Ipnet_rt_msghdr *rtm, char *ripng_rt_buf){ /* * letter conflict should be okay. painful when *BSD diverges... */ ipcom_strcpy(ripng_rt_buf, "");#define RTFLAG(s, f) \do { \ if (rtm->rtm_flags & (f)) \ ipcom_strcat(ripng_rt_buf, (s)); \} while (0) RTFLAG("U", IPNET_RTF_UP); RTFLAG("G", IPNET_RTF_GATEWAY); RTFLAG("H", IPNET_RTF_HOST); RTFLAG("R", IPNET_RTF_REJECT); RTFLAG("D", IPNET_RTF_DYNAMIC); RTFLAG("M", IPNET_RTF_MODIFIED); RTFLAG("d", IPNET_RTF_DONE);#ifdef IPNET_RTF_MASK RTFLAG("m", IPNET_RTF_MASK);#endif RTFLAG("C", IPNET_RTF_CLONING);#ifdef IPNET_RTF_CLONED RTFLAG("c", IPNET_RTF_CLONED);#endif#ifdef IPNET_RTF_PRCLONING RTFLAG("c", IPNET_RTF_PRCLONING);#endif#ifdef IPNET_RTF_WASCLONED RTFLAG("W", IPNET_RTF_WASCLONED);#endif RTFLAG("X", IPNET_RTF_XRESOLVE); RTFLAG("L", IPNET_RTF_LLINFO); RTFLAG("S", IPNET_RTF_STATIC); RTFLAG("B", IPNET_RTF_BLACKHOLE);#ifdef IPNET_RTF_PROTO3 RTFLAG("3", IPNET_RTF_PROTO3);#endif RTFLAG("2", IPNET_RTF_PROTO2); RTFLAG("1", IPNET_RTF_PROTO1);#ifdef IPNET_RTF_BROADCAST RTFLAG("b", IPNET_RTF_BROADCAST);#endif#ifdef IPNET_RTF_DEFAULT RTFLAG("d", IPNET_RTF_DEFAULT);#endif#ifdef IPNET_RTF_ISAROUTER RTFLAG("r", IPNET_RTF_ISAROUTER);#endif#ifdef IPNET_RTF_TUNNEL RTFLAG("T", IPNET_RTF_TUNNEL);#endif#ifdef IPNET_RTF_AUTH RTFLAG("A", IPNET_RTF_AUTH);#endif#ifdef IPNET_RTF_CRYPT RTFLAG("E", IPNET_RTF_CRYPT);#endif#undef RTFLAG}/* * outbound filter logic, per-route/interface. */IP_PUBLIC intout_filter(Ipripng_rt *rrt, struct ifc *ifcp){ struct iff *iffp; struct in6_addr ia; int ok; /* * -A: filter out less specific routes, if we have aggregated * route configured. */ for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) { if (iffp->iff_type != 'A') continue; if (rrt->rrt_info.rip6_plen <= iffp->iff_plen) continue; ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IP_IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) return 0; } /* * if it is an aggregated route, advertise it only to the * interfaces specified on -A. */ if ((rrt->rrt_rflags & RRTF_AGGREGATE) != 0) { ok = 0; for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) { if (iffp->iff_type != 'A') continue; if (rrt->rrt_info.rip6_plen == iffp->iff_plen && IP_IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest, &iffp->iff_addr)) { ok = 1; break; } } if (!ok) return 0; } /* * -O: advertise only if prefix matches the configured prefix. */ if (iff_find(ifcp, 'O')) { ok = 0; for (iffp = ifcp->ifc_filter; iffp; iffp = iffp->iff_next) { if (iffp->iff_type != 'O') continue; if (rrt->rrt_info.rip6_plen < iffp->iff_plen) continue; ia = rrt->rrt_info.rip6_dest; applyplen(&ia, iffp->iff_plen); if (IP_IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { ok = 1; break; } } if (!ok) return 0; } /* the prefix should be advertised */ return 1;}/* * Determine if the route is to be advertised on the specified interface. * It checks options specified in the arguments and the split horizon rule. * Returns: * 0 - if the route shouldn't be advertised. * 1 - if route should be advertised. * 2 - if route should be advd with infinite hopcount (poison rev) * * RIPng-learned routes are advertised depending on -p/h/x/y/z settings * Static routes are advertised depending on the -s/S setting. * Interface routes are not advertised for poison reverse or split horizon. * They are only advertised if Split Horizon is disabled. */IP_GLOBAL inttobeadv(Ipripng_rt *rrt, struct ifc *ifcp){ /* Special care for static routes */ if (rrt->rrt_flags & IPNET_RTF_STATIC) { /* XXX don't advertise reject/blackhole routes */ if (rrt->rrt_flags & (IPNET_RTF_REJECT | IPNET_RTF_BLACKHOLE)) return 0; if (ipripng_Sflag()) /* Yes, advertise it anyway */ return 1; if (ipripng_sflag() && rrt->rrt_index != ifcp->ifc_index) return 1; return 0; } /* Split Horizon & Poison Reverse Config for this interface */ if (ifcp->ifc_horizcfg == IF_SPLITH && (rrt->rrt_index == ifcp->ifc_index)) return 0; if (ifcp->ifc_horizcfg == IF_POISON && (rrt->rrt_index == ifcp->ifc_index)) { /* If RIPng-learned, send route with metric 16. Otherwise don't send */ if (rrt->rrt_rflags & RRTF_RIPNGLEARNED) return 2; else return 0; } return 1;}IP_GLOBAL Ip_boolipripng_neighbor_verify(struct in6_addr * nb_addr){ struct nb_list * plist = ipripng_nb_list_root(); struct in6_addr noindex_addr; while (plist) { struct in6_addr * incoming_addr; /* If link-local take the interface index out of the address */ if (IP_IN6_IS_ADDR_LINK_LOCAL(nb_addr)) { noindex_addr = *nb_addr; SET_IN6_LINKLOCAL_IFINDEX (noindex_addr, 0); incoming_addr = &noindex_addr; } else incoming_addr = nb_addr; if (IP_IN6_ARE_ADDR_EQUAL(incoming_addr, &plist->nb_addr)) return (IP_TRUE); plist = plist->nb_next; } /* None found */ return (IP_FALSE);}IP_STATIC const int pl2m[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};IP_GLOBAL struct in6_addr *plen2mask(int n){ static struct in6_addr ia; Ip_u8 *p; int i; memset(&ia, 0, sizeof(struct in6_addr)); p = (Ip_u8 *)&ia; for (i = 0; i < 16; i++, p++, n -= 8) { if (n >= 8) { *p = 0xff; continue; } *p = pl2m[n]; break; } return &ia;}/* **************************************************************************** * END OF FILE **************************************************************************** */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -