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

📄 ipripng.c

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