📄 ipripng.c
字号:
if (strcmp(ifa->ifa_name, ifcp->ifc_name) == 0) break; } if (ifa == IP_NULL) /* None found - Interface was detached from v6 */ { IPCOM_LOG1(DEBUG, "Interface %s was deleted", ifcp->ifc_name); ipripng_ifdel (ifcp); } /* Fix for SPR# 88575 - Begin */ else if ((ifcp->ifc_index) < 0) { /* * The interface doesn't have a valid Link-Local addr so RIPng * can't use it and it must be removed from RIPng interfaces * list (RFC 2080: each RIPng intarface must have * at least one valid LL addr). */ IPCOM_LOG1(DEBUG, "No ifindex found at %s " "(no link-local address?)", ifcp->ifc_name); ipripng_ifdel (ifcp); } /* Fix for SPR# 88575 - End */ else if (ifcp == ipripng.loopifcp) { /* remove loopback interface from RIPng interface list */ IPCOM_LOG1(DEBUG, "Remove loopback interface %s", ifcp->ifc_name); ipripng_ifdel (ifcp); } ifcp = ifcp_next; if (ifcp_next != IP_NULL) ifcp_next = ifcp_next->ifc_next; } for (ifcp = ipripng.ifc; ifcp; ifcp = ifcp->ifc_next) { if (ifcp->ifc_index < 0) { IPCOM_LOG1(ERR, "No ifindex found at %s " "(no link-local address?)", ifcp->ifc_name); ipcom_socketclose (s); ipcom_freeifaddrs (ifap); return (IPCOM_ERR_NOT_FOUND); } } if (ipripng.loopifcp == IP_NULL) { IPCOM_LOG0 (ERR, "No loopback found"); ipcom_socketclose (s); ipcom_freeifaddrs (ifap); return (IPCOM_ERR_NOT_FOUND); } ipcom_socketclose(s); ipcom_freeifaddrs(ifap); return (IPCOM_SUCCESS);}IP_STATICIp_err ipripng_ifconfig1(const char *name, const struct Ip_sockaddr *sa, struct ifc *ifcp, int s){ struct Ip_in6_ifreq ifr; struct Ip_ifreq ifr4; struct Ip_sockaddr_in6 *sin6; struct ifac *ifa; int plen; char buf[IP_INET6_ADDRSTRLEN]; char buf2[IP_INET6_ADDRSTRLEN]; sin6 = (struct Ip_sockaddr_in6 *)sa; if (IP_IN6_IS_ADDR_SITE_LOCAL(&sin6->sin6_addr) && !ipripng.lflag) return IPCOM_SUCCESS; ifr.ifr_ifru.ifru_addr = *sin6; strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); strncpy(ifr4.ifr_name, name, sizeof(ifr4.ifr_name)); if (ipcom_socketioctl(s, IP_SIOCGIFPREFIX_IN6, &ifr) < 0) { IPCOM_LOG0(ERR, "ioctl: IP_SIOCGIFPREFIX_IN6"); return (IPCOM_ERR_FAILED); } plen = ifr.ifr_ifru.ifru_prefixlen; if ((ifa = ifa_match(ifcp, &sin6->sin6_addr, plen)) != IP_NULL) { /* same interface found */ /* need check if something changed */ /* XXX not yet implemented */ return (IPCOM_SUCCESS); } /* * New address is found */ if ((ifa = SIMPLE_MALLOC(struct ifac)) == IP_NULL) { IPCOM_LOG0(ERR, "malloc: struct ifac"); return (IPCOM_ERR_NO_MEMORY); } memset(ifa, 0, sizeof(*ifa)); ifa->ifa_conf = ifcp; ifa->ifa_next = ifcp->ifc_addr; ifcp->ifc_addr = ifa; ifa->ifa_addr = sin6->sin6_addr; ifa->ifa_plen = plen; if (ipcom_inet_ntop(IP_AF_INET6, &ifa->ifa_addr, buf2, sizeof (buf2)) == IP_NULL) buf2[0] = '\0'; /* So doesn't display garbage */ if (ifcp->ifc_flags & IP_IFF_POINTOPOINT) { ifr.ifr_ifru.ifru_addr = *sin6; if (ipcom_socketioctl(s, IP_SIOCGIFDSTADDR_IN6, &ifr) < 0) { IPCOM_LOG0(ERR, "ioctl: SIOCGIFDSTADDR_IN6"); return (IPCOM_ERR_FAILED); } ifa->ifa_raddr = ifr.ifr_ifru.ifru_dstaddr.sin6_addr; if (ipcom_inet_ntop(IP_AF_INET6, (void *)&ifa->ifa_raddr, buf, sizeof(buf)) == IP_NULL) buf[0] = '\0'; /* So doesn't display garbage */ IPCOM_LOG3(INFO, "found address %s/%d -- %s", buf2, ifa->ifa_plen, buf); } else { IPCOM_LOG2(INFO, "found address %s/%d", buf2, ifa->ifa_plen); } if (ifcp->ifc_index < 0 && IP_IN6_IS_ADDR_LINK_LOCAL(&ifa->ifa_addr)) { ifcp->ifc_mylladdr = ifa->ifa_addr; ifcp->ifc_index = ipcom_if_nametoindex(name); ipcom_memcpy(&ifcp->ifc_ripsin, &ripngsin, ripngsin.sa_len); SET_IN6_LINKLOCAL_IFINDEX(ifcp->ifc_ripsin.sin6_addr, ifcp->ifc_index); if (setindex2ifc(ifcp->ifc_index, ifcp) != IPCOM_SUCCESS) return (IPCOM_ERR_FAILED); ifcp->ifc_mtu = getifmtu(ifcp->ifc_index); if (ifcp->ifc_mtu == -1) return (IPCOM_ERR_FAILED); if (ifcp->ifc_mtu > RIP6_MAXMTU) ifcp->ifc_mtu = RIP6_MAXMTU; if (ipcom_socketioctl(s, IP_SIOCGIFMETRIC, &ifr4) < 0) { IPCOM_LOG0(ERR, "ioctl: SIOCGIFMETRIC"); return (IPCOM_ERR_FAILED); } ifcp->ifc_metric = ifr4.ifr_ifru.ifru_metric; IPCOM_LOG3(INFO, "\tindex: %d, mtu: %d, metric: %d", ifcp->ifc_index, ifcp->ifc_mtu, ifcp->ifc_metric); } else ifcp->ifc_cflags |= IFC_CHANGED; return (IPCOM_SUCCESS);}/* * Delete all routes and interface information when an interface is deleted * or detached from IPv6. */IP_STATIC void ipripng_ifdel (struct ifc * ifcp_todel){ struct Ipripng_rt *rrt, *rrt_prev, *rrt_next; struct ifc *ifcp, *ifcp_prev, *ifcp_next; struct iff *iffp, *iffp_done; struct ifac *ifap, *ifap_done; /* * Delete all routes over this interface from the internal RIPng * routing table. */ rrt_prev = IP_NULL; for (rrt = ipripng.riprt; rrt; rrt = rrt_next) { rrt_next = ((Ipripng_rt *)rrt)->rrt_next; if (((Ipripng_rt *)rrt)->rrt_index == ifcp_todel->ifc_index) { if (rrt_prev) { ((Ipripng_rt *)rrt_prev)->rrt_next = ((Ipripng_rt *)rrt)->rrt_next; } else { ipripng.riprt = ((Ipripng_rt *)rrt)->rrt_next; } IPCOM_LOG1(DEBUG, "Deleting a route on deleted interface %s", ifcp_todel->ifc_name); ipcom_free(rrt); continue; } rrt_prev = rrt; } /* Delete the interface from the interface list */ ifcp_prev = IP_NULL; for (ifcp = ipripng.ifc; ifcp; ifcp = ifcp_next) { ifcp_next = ifcp->ifc_next; if (ifcp->ifc_index == ifcp_todel->ifc_index) { if (ifcp_prev) { ifcp_prev->ifc_next = ifcp->ifc_next; } else { ipripng.ifc = ifcp->ifc_next; } IPCOM_LOG1(DEBUG, "Deleting interface %s", ifcp->ifc_name); /* Free the internal allocations */ if (ifcp->ifc_name) ipcom_free (ifcp->ifc_name); iffp = ifcp->ifc_filter; while (iffp) { iffp_done = iffp; iffp = iffp->iff_next; ipcom_free (iffp_done); } ifap = ifcp->ifc_addr; while (ifap) { ifap_done = ifap; ifap = ifap->ifa_next; ipcom_free (ifap_done); } ipripng.nifc--; if ((ifcp->ifc_index) >= 0) ipripng.index2ifc[ifcp->ifc_index] = IP_NULL; ipcom_free (ifcp); break; } ifcp_prev = ifcp; }}/* * Parse the -A (and -O) options and put corresponding filter object to the * specified interface structures. Each of the -A/O option has the following * syntax: -A 5f09:c400::/32,ef0,ef1 (aggregate) * -O 5f09:c400::/32,ef0,ef1 (only when match) */IP_GLOBAL Ip_err ipripng_filterconfig(){ int i; char *p, *ap, *iflp, *ifname, *ep; struct iff ftmp, *iff_obj; struct ifc *ifcp; Ipripng_rt *rrt; Ip_u32 plen; char buf[IP_INET6_ADDRSTRLEN]; /* * Replaced all index() calls by strchr() as this will already be * pulled in for other functions within RIPng. */ for (i = 0; i < ipripng.nfilter; i++) { ap = ipripng.filter[i]; iflp = IP_NULL; ifcp = IP_NULL; if (ipripng.filtertype[i] == 'N' || ipripng.filtertype[i] == 'T') { iflp = ap; goto ifonly; } if ((p = strchr(ap, ',')) != IP_NULL) { *p++ = '\0'; iflp = p; } if ((p = strchr(ap, '/')) == IP_NULL) { IPCOM_LOG1(ERR, "no prefixlen specified for '%s'", ap); return (IPCOM_ERR_FAILED); } *p++ = '\0'; if (ipcom_inet_pton(IP_AF_INET6, ap, &ftmp.iff_addr) != 1) { IPCOM_LOG1(ERR, "invalid prefix specified for '%s'", ap); return (IPCOM_ERR_FAILED); } ep = IP_NULL; plen = strtoul(p, &ep, 10); if (!*p || *ep || plen > sizeof(ftmp.iff_addr) * 8) { IPCOM_LOG1(ERR, "invalid prefix length specified for '%s'", ap); return (IPCOM_ERR_FAILED); } ftmp.iff_plen = plen; ftmp.iff_next = IP_NULL; applyplen(&ftmp.iff_addr, ftmp.iff_plen);ifonly: ftmp.iff_type = ipripng.filtertype[i]; if (iflp == IP_NULL || *iflp == '\0') { IPCOM_LOG1(ERR, "no interface specified for '%s'", ap); return (IPCOM_ERR_NOT_FOUND); } /* parse the interface listing portion */ while (iflp) { ifname = iflp; if ((iflp = strchr(iflp, ',')) != IP_NULL) *iflp++ = '\0'; ifcp = ifc_find(ifname); if (ifcp == IP_NULL) { IPCOM_LOG1(ERR, "no interface %s exists", ifname); return (IPCOM_ERR_NOT_FOUND); } iff_obj = (struct iff *)ipcom_malloc(sizeof(struct iff)); if (iff_obj == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_malloc of iff_obj in filterconfig"); return (IPCOM_ERR_NO_MEMORY); } memcpy((void *)iff_obj, (void *)&ftmp, sizeof(struct iff)); /* link it to the interface filter */ iff_obj->iff_next = ifcp->ifc_filter; ifcp->ifc_filter = iff_obj; } /* * -A: aggregate configuration. */ if (ipripng.filtertype[i] != 'A') continue; /* put the aggregate to the kernel routing table */ rrt = (Ipripng_rt *)ipcom_malloc(sizeof(Ipripng_rt)); if (rrt == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_malloc: rrt in filterconfig"); return (IPCOM_ERR_NO_MEMORY); } memset(rrt, 0, sizeof(Ipripng_rt)); rrt->rrt_info.rip6_dest = ftmp.iff_addr; rrt->rrt_info.rip6_plen = ftmp.iff_plen; rrt->rrt_info.rip6_metric = 1; rrt->rrt_info.rip6_tag = ip_htons(ipripng.routetag & 0xffff); rrt->rrt_gw = ip_in6addr_loopback; rrt->rrt_flags = IPNET_RTF_UP | IPNET_RTF_REJECT; /* Show this is a RIPng route */ rrt->rrt_rflags = RRTF_AGGREGATE | RRTF_RIPNGLEARNED; rrt->rrt_t = 0; rrt->rrt_index = ipripng.loopifcp->ifc_index; /* Put the route to the list */ rrt->rrt_next = ipripng.riprt; ipripng.riprt = (struct Ipripng_rt *)rrt; if (ipcom_inet_ntop(IP_AF_INET6, &ftmp.iff_addr, buf, sizeof (buf)) == IP_NULL) buf[0] = '\0'; /* So doesn't display garbage */ IPCOM_LOG3(INFO, "Aggregate: %s/%d for %s", buf, ftmp.iff_plen, ifcp->ifc_name); /* Add this route to the kernel */ if (ipripng.nflag) /* do not modify kernel routing table */ continue; ipripng.add_route(rrt, &ip_in6addr_loopback, ipripng.loopifcp); IP_BIT_SET(rrt->rrt_rflags, RRTF_STACKROUTE); } return (IPCOM_SUCCESS);}/* * Receive and process RIPng packets. Update the routes/kernel forwarding * table if necessary. */IP_GLOBAL Ip_err ipripng_riprecv(){ struct ifc *ifcp; struct Ip_sockaddr_in6 fsock; struct Ip_in6_addr nh; /* next hop */ struct rip6 *rp; struct netinfo6 *np, *nq; Ipripng_rt *rrt = IP_NULL; int len, nn; unsigned int need_trigger, idx; char buf[4 * RIP6_MAXMTU]; Ip_time_t t; struct Ip_msghdr m; st
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -