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

📄 ipripng.c

📁 这是最新的vxWorks6.7协议栈下的RIPng(rip over ipv6)实现
💻 C
📖 第 1 页 / 共 5 页
字号:
IP_STATIC voidipripng_rtfree(Ipripng_rt *rt, Ip_bool proto_set){    ip_assert(rt != IP_NULL);    if (IP_BIT_ISSET(rt->rrt_rflags, RRTF_STACKROUTE)) {        ip_assert(ipripng.delete_route != IP_NULL);        if (ipripng.delete_route(&(rt->rrt_info), &(rt->rrt_gw), proto_set) != IPCOM_SUCCESS)        {/*            IPCOM_LOG2(WARNING, "ipripng_rtfree() :: failed to delete stack route %s, errno %d",                       ipripng_routeinfo(rt),                       ipcom_errno);*/        }    }    ipcom_free(rt);}/* *=========================================================================== *                    ipripng_rtinsert *=========================================================================== * Description:   Insert a RIP route, report to the TCP/IP stack *                and schedule a RIP triggered update, i.e. flash. * Parameters:    rt    RIP route entry. * Returns:       IPCOM_SUCESS or error code. * */IP_STATIC Ip_erripripng_rtinsert(Ipripng_rt *rt, struct ifc *ifcp){    Ip_err  retval;    ip_assert(rt != IP_NULL);    if (NOT IP_BIT_ISSET(rt->rrt_rflags, RRTF_INTERFACE + RRTF_RIPNGLEARNED + RRTF_AGGREGATE))    {        /* Add the route with the TCP/IP stack. */        if (ipripng.add_route(rt, &(rt->rrt_gw), ifcp) == IPCOM_SUCCESS)            IP_BIT_SET(rt->rrt_rflags, RRTF_STACKROUTE);        else        {            IPCOM_LOG2(WARNING, "iprip_rtinsert() :: failed to add stack route %s, errno %d",                       ipripng_routeinfo(rt),                       ipcom_errno);            return IPCOM_ERR_FAILED;        }    }    /* Insert route. */    rt->hdr.key  = &rt->rrt_info.rip6_dest;    rt->hdr.mask = rt->keymask;    retval = ipcom_route_add(ipripng.rtab, &rt->hdr);    ip_assert(retval == IPCOM_SUCCESS);    ipcom_list_insert_last(&ipripng.rt_head, &rt->rt_list);    ipripng.rt_num++;    /* New or updated route, flash it. */    ipripng_rtflash(rt);    return retval;}/* *=========================================================================== *                    ipripng_rtremove *=========================================================================== * Description:   Remove a route. * Parameters:    rt    RIPng route entry. * Returns:       IPCOM_SUCESS or error code. * */IP_STATIC voidipripng_rtremove(Ipripng_rt *rt){    Ip_err  retval;    ip_assert(rt != IP_NULL);    ipcom_list_remove(&rt->rt_list);    retval = ipcom_route_remove(ipripng.rtab, &rt->hdr);    ip_assert(retval == IPCOM_SUCCESS);    (void)retval;    ipripng.rt_num--;    ip_assert(ipripng.rt_num >= 0);}/* *=========================================================================== *                    ipripng_rtlookup *=========================================================================== * Description: * Parameters: * Returns: * */IP_STATIC Ipripng_rt *ipripng_rtlookup(struct  netinfo6 *np, Ipripng_rt **prev_rrt){        struct Ipripng_rt   *rrt;        if (prev_rrt)                *prev_rrt = IP_NULL;        for (rrt = ipripng.riprt; rrt; rrt = ((Ipripng_rt *)rrt)->rrt_next) {                if (((Ipripng_rt *)rrt)->rrt_info.rip6_plen == np->rip6_plen &&                    IP_IN6_ARE_ADDR_EQUAL(&((Ipripng_rt *)rrt)->rrt_info.rip6_dest,                                       &np->rip6_dest))                        return (Ipripng_rt *)rrt;                if (prev_rrt)                        *prev_rrt = (Ipripng_rt *)rrt;        }        if (prev_rrt)                *prev_rrt = IP_NULL;        return IP_NULL;}/* *=========================================================================== *                    ipripng_rtnotify *=========================================================================== * Description: Callback that is used each time the status of the route *              table changes. * Parameters:  rtab - The route table that has changed. *              entry - The entry in the route table that was affected. *              code - Code that describes the event. * Returns: * */IP_STATIC voidipripng_rtnotify(Ipcom_route *rtab, Ipcom_route_entry *entry, int code){    (void)rtab;    (void)entry;    if (code == IPCOM_ROUTE_CODE_DUPLICATE)    {        IP_PANIC();    }}/* *=========================================================================== *                    ipripng_rtflash *=========================================================================== * Description:   Trigger a flash update with this route included. Ignore *                scheduling a new flash if there is one already scheduled. * Parameters:    re    RIPng route entry. * Returns:       . * */IP_STATIC voidipripng_rtflash(Ipripng_rt *rt){    ip_assert(rt != IP_NULL);    /* Schedule a flash with thir route included. */    rt->update_inst = ipripng.update_inst;/*    IPCOM_LOG4(DEBUG2, "    ++ route flash: %s/%s -> %s - %s.",               ipcom_inet_ntop(IP_AF_INET, &rt->ipaddr_n, iprip.str, sizeof(iprip.str)),               ipcom_inet_ntop(IP_AF_INET, &rt->mask_n,   iprip.str2, sizeof(iprip.str2)),               ipcom_inet_ntop(IP_AF_INET, &rt->router_n, iprip.str3, sizeof(iprip.str3)),               IPCOM_TMO_PENDING(&iprip.flash) ? "ignored" : "triggered");*/    if (NOT IPCOM_TMO_PENDING(&ipripng.flash))    {        (void)ipcom_tmo_request(&ipripng.flash, ipripng_flash_timeout, IP_NULL, 1000 * ipripng.flash_seconds);    }}/* *=========================================================================== *                    ipripng_sendpacket *=========================================================================== * Description:   Transmit a RIPng packet to address sin6. * Parameters:    sin6     Address to transmit a RIPng packet to. *                len      The length of the packet. * Returns: * */IP_STATIC intipripng_sendpacket(struct  Ip_sockaddr_in6 *sin6, int len){    struct Ip_msghdr m;    struct Ip_cmsghdr *cm;    struct Ip_iovec iov[2];    Ip_u8 cmsgbuf[256];    struct Ip_in6_pktinfo *pi;    int idx;    struct Ip_sockaddr_in6 sin6copy;    /* do not overwrite the given sin6 */    sin6copy = *sin6;    sin6 = &sin6copy;    if (IP_IN6_IS_ADDR_LINK_LOCAL(&sin6->sin6_addr)     || IP_IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {        /* XXX: do not mix the interface index and link index */        idx = IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr);        SET_IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr, 0);        sin6->sin6_scope_id = idx;    } else        idx = 0;    if (ipripng.dflag)        ipcom_printf("ipripng_sendpacket, to format the packet\n");    m.msg_name = (char *)sin6;    m.msg_namelen = sizeof(*sin6);    iov[0].iov_base = (char *)ipripng.ripngbuf;    iov[0].iov_len = len;    m.msg_iov = iov;    m.msg_iovlen = 1;    m.msg_flags = 0;    if (!idx) {        m.msg_control = IP_NULL;        m.msg_controllen = 0;    } else {        memset(cmsgbuf, 0, sizeof(cmsgbuf));        cm = (struct Ip_cmsghdr *)cmsgbuf;        m.msg_control = (char *)cm;        m.msg_controllen = IP_CMSG_SPACE(sizeof(struct Ip_in6_pktinfo));        cm->cmsg_len = IP_CMSG_LEN(sizeof(struct Ip_in6_pktinfo));        cm->cmsg_level = IP_IPPROTO_IPV6;        cm->cmsg_type = IP_IPV6_PKTINFO;        pi = (struct Ip_in6_pktinfo *)IP_CMSG_DATA(cm);        memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*::*/        pi->ipi6_ifindex = idx;    }    if (ipripng.dflag)        ipcom_printf("ipripng_sendpacket, to call ipcom_sendmsg\n");    if ((ipcom_sendmsg(ipripng.udp_fd, &m, 0 /*MSG_DONTROUTE*/)) < 0)        {        IPCOM_LOG1(INFO, "sendmsg: %d", ipcom_errno);        return ipcom_errno;        }    return 0;}/* *=========================================================================== *                    ipripng_sendrequest *=========================================================================== * Description:   Send a RIPng request for all routes on this interface. * Parameters:    ifcp   Interface to send RIPng request on. * Returns: * */IP_GLOBAL voidipripng_sendrequest(struct ifc *ifcp){    struct netinfo6 *np;    int error;    char  buf[IP_INET6_ADDRSTRLEN];    char  buf2[IP_BUFSIZ];    if (ipripng.dflag)        ipcom_printf("Calling ipripng_sendrequest, %s\n", ifcp->ifc_name);    if (ifcp->ifc_flags & IP_IFF_LOOPBACK)        return;    ipripng.ripngbuf->rip6_cmd = RIP6_REQUEST;    np = ipripng.ripngbuf->rip6_nets;    memset(np, 0, sizeof(struct netinfo6));    np->rip6_metric = HOPCNT_INFINITY6;    if (ipcom_inet_ntop(IP_AF_INET6, &ifcp->ifc_ripsin.sin6_addr, buf, sizeof (buf))        == IP_NULL)        buf[0] = '\0';  /* So doesn't display garbage */    IPCOM_LOG2(INFO, "Send rtdump Request to %s (%s)",        ifcp->ifc_name, buf);    if (ipripng.dflag)	ipcom_printf("Send rtdump Request to %s (%s)", ifcp->ifc_name, buf);    error = ipripng_sendpacket(&ifcp->ifc_ripsin, RIPSIZE(1));    if (error == IP_ERRNO_EAFNOSUPPORT) {        /* Protocol not supported */        IPCOM_LOG3(INFO, "%s: Could not send rtdump Request to %s (%s): "            "set IFF_UP to 0", buf2,            ifcp->ifc_name, buf);        ifcp->ifc_flags &= ~IP_IFF_UP; /* As if down for AF_INET6 */    }    ipripng.ripngbuf->rip6_cmd = RIP6_RESPONSE;}/* *=========================================================================== *                    ipripng_update_timeout *=========================================================================== * Description:   Age all RIPng routes and send a regular RIPng update on all RIPng *                interfaces that should transmit. * Parameters:    tmo   NSTIME timeout structure. * Returns:       . * */IP_STATIC Ip_s32ipripng_update_timeout(Ipcom_tmo *tmo, void *cookie){    struct  ifc *ifcp;    Ipripng_rt *rrt, *rrt_prev, *rrt_next;    Ip_time_t  t_lifetime, t_holddown;    if (ripngStopFlag)   return 0;    IPRIPNG_LOCK();    (void)tmo;    (void)cookie;    IPCOM_LOG2(DEBUG2, "+++ update timeout, %ld interfaces, %ld routes:", ipripng.nifc, ipripng.rt_num);    /* age the RIPng routes */    rrt_prev = 0;    t_lifetime = time_offset(IP_NULL) - RIP_LIFETIME;    t_holddown = t_lifetime - RIP_HOLDDOWN;    for (rrt = (Ipripng_rt *)ipripng.riprt; rrt; rrt = rrt_next)        {        rrt_next = (Ipripng_rt *)rrt->rrt_next;        if (rrt->rrt_t == 0)            {            rrt_prev = rrt;            continue;            }        if (rrt->rrt_t < t_holddown)            {            if (rrt_prev)                {                rrt_prev->rrt_next = rrt->rrt_next;                }            else                {                ipripng.riprt = rrt->rrt_next;                }            /*             * Only delete the route if it wasn't already deleted.             * This happens if the user deleted the routes in the kernel             * and RIPng learned of the deleted route via the routing socket.             * It ages the route with metric 16, but after the timeout             * there is of course no need to delete it in the kernel.             */            if ((rrt->rrt_rflags & RRTF_DELETED) == 0)                {                if ((rrt->rrt_rflags & RRTF_RIPNGLEARNED) == 0)                    {                    /*                     * Don't delete static routes unless we've been                     * asked to age them. Normally static routes have                     * their rtt set to 0 unless the ripng_age flag is                     * set, but even in that case, if the interface goes                     * down, we ahe them so that we can advertise an                     * INFINITE metric for them. When we are finished                     * advertising them, we want to delete them from RIPng's                     * internal table but not from the system route table.                     */                    if ((rrt->rrt_flags & IPNET_RTF_STATIC) == 0 ||                        ipripng.aflag != 0)                        {                        IPCOM_LOG0(INFO, "Warning: Ageing a route not learned by RIPng");                        /* delroute() shouldn't use PROTO_SET */                        ipripng.delete_route(&rrt->rrt_info, &rrt->rrt_gw, IP_FALSE);                        }                    }                else                    {                    ipripng.delete_route(&rrt->rrt_info, &rrt->rrt_gw, IP_TRUE);                    }                }            ipcom_free(rrt);            continue;            }            if (rrt->rrt_t < t_lifetime)                {                rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6;                }            rrt_prev = rrt;        }    /* Supply updates */    for (ifcp = ipripng.ifc; ifcp; ifcp = ifcp->ifc_next)        {        if ((ifcp->ifc_index > 0) && (ifcp->ifc_flags & IP_IFF_UP))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -