📄 ipripng.c
字号:
else prevp->nb_next = plist; prevp = plist; /* For next address in comma list */ } /* while(argptr) */}/* *=========================================================================== * ipripng_initsocks *=========================================================================== * Description: * Parameters: * * Returns: * */IP_GLOBALIp_err ipripng_initsocks(){ int error; const int int0 = 0, int1 = 1, int255 = 255; struct Ip_addrinfo hints, *res; char port[NI_MAXSERV]; ipripng.ifc = (struct ifc *)IP_NULL; ipripng.nifc = 0; ipripng.nindex2ifc = 0; /*initial guess*/ ipripng.index2ifc = IP_NULL; ipcom_snprintf(port, sizeof(port), "%u", RIP6_PORT); if (ipripng.dflag) ipcom_printf("Calling ipripng_initsocks\n"); memset(&hints, 0, sizeof(hints)); hints.ai_family = IP_PF_INET6; hints.ai_socktype = IP_SOCK_DGRAM; hints.ai_protocol = IP_IPPROTO_UDP; hints.ai_flags = IP_AI_PASSIVE | IP_AI_ADDRCONFIG ; error = ipcom_getaddrinfo(IP_NULL, port, &hints, &res); if (error) { IPCOM_LOG1(ERR, "ipripng_initsocks err %d", error); goto initsocks_err; } if (res->ai_next) { IPCOM_LOG0(ERR, ":: resolved to multiple address"); goto initsocks_err; } ipripng.udp_fd = ipcom_socket(IP_PF_INET6, IP_SOCK_DGRAM, IP_IPPROTO_UDP); if (ipripng.udp_fd < 0) { IPCOM_LOG0(ERR, "failed in opening rip socket"); goto initsocks_err; }#ifdef IP_IPV6_V6ONLY if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_V6ONLY, (IP_CONST void *)&int1, sizeof(int1)) < 0) { IPCOM_LOG0(ERR, "failed in setting v6only setsockopt"); goto initsocks_err; }#endif if (ipcom_bind(ipripng.udp_fd, res->ai_addr, res->ai_addrlen) < 0) { IPCOM_LOG0(ERR, "failed in bind"); goto initsocks_err; } if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_MULTICAST_HOPS, (char *)&int255, sizeof(int255)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_MULTICAST_HOPS"); goto initsocks_err; } if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_MULTICAST_LOOP, (char *)&int0, sizeof(int0)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_MULTICAST_LOOP"); goto initsocks_err; }#ifdef IP_IPV6_RECVPKTINFO if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_RECVPKTINFO, (char *)&int1, sizeof(int1)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_RECVPKTINFO"); goto initsocks_err; }#else /* old adv. API */ if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_PKTINFO, (char *)&int1, sizeof(struct Ip_in6_pktinfo)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_PKTINFO"); goto initsocks_err; }#endif /* specify to tell value of hoplimit field of received IP6 hdr */#ifdef IP_IPV6_RECVHOPLIMIT if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_RECVHOPLIMIT, (char *)&int1, sizeof(int1)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_RECVHOPLIMIT"); goto initsocks_err; }#else /* old adv. API */ if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_HOPLIMIT, (char *)&int1, sizeof(int1)) < 0) { IPCOM_LOG0(ERR, "ripng IPV6_HOPLIMIT"); goto initsocks_err; }#endif /* Free addrinfo structure before calling getaddrinfo() again! [KAL] */ ipcom_freeaddrinfo(res); ipcom_memset(&hints, 0, sizeof(hints)); hints.ai_family = IP_PF_INET6; hints.ai_socktype = IP_SOCK_DGRAM; hints.ai_protocol = IP_IPPROTO_UDP; error = ipcom_getaddrinfo(RIP6_DEST, port, &hints, &res); if (error) { IPCOM_LOG1(ERR, "ripng failed in getaddrinfo %d", error); goto initsocks_err; } if (res->ai_next) { IPCOM_LOG1(ERR, "%s resolved to multiple address", RIP6_DEST); goto initsocks_err; } ipcom_memcpy(&ripngsin, res->ai_addr, res->ai_addrlen); if (ipripng.nflag == 0) { if ((ipripng.rt_fd = ipcom_socket(IP_PF_ROUTE, IP_SOCK_RAW, 0)) < 0) { IPCOM_LOG0(ERR, "route socket"); goto initsocks_err; } } /* Free second helping of addrinfo mem */ ipcom_freeaddrinfo(res); return (IPCOM_SUCCESS);initsocks_err: ipcom_freeaddrinfo (res); return (IPCOM_ERR_FAILED);}IP_STATICIp_err setindex2ifc(int idx, struct ifc *ifcp){ int n, nsize; struct ifc **p; if (!ipripng.index2ifc) { ipripng.nindex2ifc = 5; /*initial guess*/ ipripng.index2ifc = (struct ifc **) ipcom_malloc(sizeof(*ipripng.index2ifc) * ipripng.nindex2ifc); if (ipripng.index2ifc == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_malloc failed in setindex2ifc"); return (IPCOM_ERR_NO_MEMORY); } memset(ipripng.index2ifc, 0, sizeof(*ipripng.index2ifc) * ipripng.nindex2ifc); } n = ipripng.nindex2ifc; for (nsize = ipripng.nindex2ifc; nsize <= idx; nsize *= 2) ; if (n != nsize) { p = (struct ifc **)ipcom_realloc(ipripng.index2ifc, sizeof(*ipripng.index2ifc) * nsize); if (p == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_realloc failed in setindex2ifc"); return (IPCOM_ERR_NO_MEMORY); } ipripng.nindex2ifc = nsize; memset(p + n, 0, sizeof(*ipripng.index2ifc) * (ipripng.nindex2ifc - n)); ipripng.index2ifc = p; } ipripng.index2ifc[idx] = ifcp; if (ipripng.dflag) ipcom_printf("setindex2ifc: idx %d, nindex2ifc %d, ipripng.index2ifc[idx] %d\n", idx, ipripng.nindex2ifc, ipripng.index2ifc[idx]); return (IPCOM_SUCCESS);}/* * Check the arrays set up from the command-line for a Split Horizon setting * for this interface. If not explicitly configured with -x/y/z use the default * which is decided by -p/h. * * We set the flag here in the ifc structure. */IP_STATIC void ipripng_horiz_configset (struct ifc * ifcp){ int i; char * iflp; char ifname[IP_IFNAMSIZ]; /* Walk array of interface configuration to find an explicit setting */ for (i = 0; i < ipripng.nifhoriz; i++) { iflp = ipripng.ifhoriz[i]; if ((iflp == IP_NULL) || (*iflp == '\0')) IPCOM_LOG1 (WARNING, "No interface stored for -%c", ipripng.ifhoriztype[i]); /* parse the interface listing portion ("fei0,fei1,elPci0") */ while (iflp) { char * ifoldlp = iflp; if ((iflp = strchr(iflp, ',')) != IP_NULL) { *iflp = '\0'; strcpy (ifname, ifoldlp); *iflp++ = ','; /* Replace the comma for further usages */ } else { /* Last interface in the list */ strcpy (ifname, ifoldlp); } if (strcmp(ifname, ifcp->ifc_name) == 0) { /* Check not already set (i.e. duplicate settings) */ if (ifcp->ifc_horizcfg) IPCOM_LOG1 (WARNING, "Different Split Horizon Settings on %s", ifcp->ifc_name); switch (ipripng.ifhoriztype[i]) { case 'x': ifcp->ifc_horizcfg = IF_POISON; break; case 'y': ifcp->ifc_horizcfg = IF_SPLITH; break; case 'z': ifcp->ifc_horizcfg = IF_NOHORZ; break; default: IPCOM_LOG1 (WARNING, "Bad Split Horizon setting on %s", ifcp->ifc_name); break; } /* switch */ } /* if */ } /* while */ } /* for */ /* If no explicit setting use the default */ if (ifcp->ifc_horizcfg == 0) { if (ipripng.pflag) ifcp->ifc_horizcfg = IF_SPLITH; else if (ipripng.hflag) ifcp->ifc_horizcfg = IF_NOHORZ; else ifcp->ifc_horizcfg = IF_POISON; }}/* * Get information of each interface. */IP_GLOBALIp_err ipripng_ifconfig(){ char buf1[IP_BUFSIZ]; char buf2[IP_BUFSIZ]; struct Ip_ifaddrs *ifap, *ifa; struct ifc *ifcp, *ifcp_next; struct Ip_ipv6_mreq mreq; int s; Ip_err ret; if ((s = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0)) < 0) { IPCOM_LOG0(ERR, "socket"); return (IPCOM_ERR_FAILED); } ret = ipcom_getifaddrs(&ifap); if (ret != 0) { IPCOM_LOG0(ERR, "getifaddrs"); ipcom_socketclose (s); return (ret); } for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != IP_AF_INET6) continue; /* we are interested in multicast-capable interfaces */ if ((ifa->ifa_flags & IP_IFF_MULTICAST) == 0) continue; ifcp = ifc_find(ifa->ifa_name); if (!ifcp) { /* new interface */ if ((ifcp = SIMPLE_MALLOC(struct ifc)) == IP_NULL) { IPCOM_LOG0(ERR, "malloc: struct ifc"); ipcom_socketclose (s); ipcom_freeifaddrs (ifap); return (IPCOM_ERR_NO_MEMORY); } memset(ifcp, 0, sizeof(*ifcp)); ifcp->ifc_index = -1; ifcp->ifc_next = ipripng.ifc; ipripng.ifc = ifcp; ipripng.nifc++; ifcp->ifc_name = ipripng_allocopy(ifa->ifa_name); ifcp->ifc_addr = 0; ifcp->ifc_filter = 0; ifcp->ifc_flags = ifa->ifa_flags; ifflags(ifcp->ifc_flags,buf1); ipripng_horiz_configset (ifcp); IPCOM_LOG2(INFO, "newif %s <%s>", ifcp->ifc_name, buf1); if (!ipcom_strcmp(ifcp->ifc_name, LOOPBACK_IF)) ipripng.loopifcp = ifcp; } else { /* update flag, this may be up again */ if (ifcp->ifc_flags != ifa->ifa_flags) { ifflags(ifcp->ifc_flags,buf1); ifflags(ifa->ifa_flags,buf2); IPCOM_LOG5(INFO, "%s: %.8X <%s> -> %.8X <%s>",ifcp->ifc_name, ifcp->ifc_flags, buf1, ifa->ifa_flags, buf2); ifcp->ifc_cflags |= IFC_CHANGED; } /* Check if interface status has changed */ if (((ifcp->ifc_flags & IP_IFF_UP) == IP_IFF_UP) && ((ifa->ifa_flags & IP_IFF_UP) != IP_IFF_UP)) { /* * Rather than delete RIP learned routes and mark other as * not availabale and not advertise them, we should advertise * these routes over the downed interface with an infinite * metric. They will be marked with an infinite metric in * ifrt() that will be called later by rtrecv(). Those * routes will be aged and deleted normally unless the * interface comes back up and the routes get refreshed ifrt_down (ifcp); */ } else if (((ifcp->ifc_flags & IP_IFF_UP) != IP_IFF_UP) && ((ifa->ifa_flags & IP_IFF_UP) == IP_IFF_UP)) { /* * See the comment above. Since we don't mark the routes * unavailable, we don't have to remove that flag ifrt_up (ifcp); */ ipripng_sendrequest (ifcp); } ifcp->ifc_flags = ifa->ifa_flags; } ret= ipripng_ifconfig1(ifa->ifa_name, ifa->ifa_addr, ifcp, s); if (ret != IPCOM_SUCCESS) { ipcom_socketclose (s); ipcom_freeifaddrs (ifap); return (ret); } if ((ifcp->ifc_flags & (IP_IFF_LOOPBACK | IP_IFF_UP)) == IP_IFF_UP && 0 < ifcp->ifc_index && !ifcp->ifc_joined) { mreq.ipv6mr_multiaddr = ifcp->ifc_ripsin.sin6_addr; mreq.ipv6mr_interface = ifcp->ifc_index; if (ipcom_setsockopt(ipripng.udp_fd, IP_IPPROTO_IPV6, IP_IPV6_JOIN_GROUP, (char *)&mreq, sizeof(mreq)) < 0) { IPCOM_LOG2(ERR, "IPV6_JOIN_GROUP (IF index: %d) %d", ifcp->ifc_index, ipcom_errno); ipcom_socketclose (s); ipcom_freeifaddrs (ifap); return (IPCOM_ERR_FAILED); } IPCOM_LOG2(INFO, "join %s %s", ifcp->ifc_name, RIP6_DEST); ifcp->ifc_joined++; } } /* Check for deleted interfaces */ ifcp_next = ipripng.ifc->ifc_next; ifcp = ipripng.ifc; while (ifcp != IP_NULL) { for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != IP_AF_INET6) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -