⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipripng.c

📁 这是最新的vxWorks6.7协议栈下的RIPng(rip over ipv6)实现
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -