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

📄 ipripng.c

📁 这是最新的vxWorks6.7协议栈下的RIPng(rip over ipv6)实现
💻 C
📖 第 1 页 / 共 5 页
字号:
            ipripng_send_response(ifcp, &ifcp->ifc_ripsin, 0);        }    /* Request a new update timeout. */    ipripng.rndtmo++;    if (ipripng.rndtmo > (Ip_u32)(ipripng.update_seconds + ipripng.update_deltaseconds))        ipripng.rndtmo = ipripng.update_seconds;    (void)ipcom_tmo_request(&ipripng.update, ipripng_update_timeout, IP_NULL, 1000 * ipripng.rndtmo);    /* Increment the flash instance number. */    ipripng.update_inst++;    /* Cancel flash update since we just had a regular one. */    (void)ipcom_tmo_cancel(&ipripng.flash);    IPRIPNG_UNLOCK();    return 0;}/* *=========================================================================== *                    ipripng_flash_timeout *=========================================================================== * Description:  Transmit a triggered RIPng update containing new and changed *               routes on all interfaces that are non-silent. * Parameters:   tmo   NSTIME timeout structure. * Returns:      . * */IP_STATIC Ip_s32ipripng_flash_timeout(Ipcom_tmo *tmo, void *cookie){    Ip_time_t next_triggertime;    struct ifc *ifcp;    struct Ipripng_rt  *rrt;    if (ripngStopFlag)   return 0;    IPRIPNG_LOCK();    (void)tmo;    (void)cookie;    IPCOM_LOG2(DEBUG2, "+++ flash timeout, %ld interfaces, %ld routes:", ipripng.nifc, ipripng.rt_num);    for (ifcp = ipripng.ifc; ifcp; ifcp = ifcp->ifc_next)        {        if (ifcp->ifc_flags & IP_IFF_UP)            ipripng_send_response(ifcp, &ifcp->ifc_ripsin, RRTF_CHANGED);        }    /* Reset the flag */    for (rrt = ipripng.riprt; rrt; rrt = ((Ipripng_rt *)rrt)->rrt_next)        ((Ipripng_rt *)rrt)->rrt_rflags &= ~RRTF_CHANGED;    /*     * Set the next triggered update to between 1 and 5 seconds away.     */    next_triggertime = ipripng_nexttrigger_time();    (void)ipcom_tmo_request(&ipripng.flash, ipripng_flash_timeout, IP_NULL, 1000 * next_triggertime);    /* Increment the flash instance number. */    ipripng.update_inst++;    IPRIPNG_UNLOCK();    return 0;  /* do not request a new timeout. */}/* *=========================================================================== *                    ipripng_flush *=========================================================================== * Description:   Transmit all RIPng routes in RIPng response packet(s) on a single *                interface. * Parameters:    ifcp   Interface to transmit RIPng response packet(s) on. *                sin6   Destination address. * Returns: * */IP_STATIC voidipripng_flush(struct ifc *ifcp, struct Ip_sockaddr_in6 *sin6){    int i;    int error;    char tmpString[120]; /* Our logger puts in newlines */    char * pstr;    char  buf[IP_INET6_ADDRSTRLEN];    if (ipcom_inet_ntop(IP_AF_INET6, &sin6->sin6_addr, buf, sizeof (buf)) == IP_NULL)        buf[0] = '\0';  /* Won't display garbage */    IPCOM_LOG4(INFO, "Send(%s): info(%d) to %s.%d", ifcp ? ifcp->ifc_name : "?", priv_ripng_nrt, buf[0] ? buf : "?", ip_ntohs(sin6->sin6_port));    if (ipripng.dflag >= 2)        {        priv_ripng_np = ipripng.ripngbuf->rip6_nets;        for (i = 0; i < priv_ripng_nrt; i++, priv_ripng_np++)            {            pstr = tmpString;            if (ipcom_inet_ntop(IP_AF_INET6, &priv_ripng_np->rip6_dest, buf, sizeof (buf)) == IP_NULL)                buf[0] = '\0';  /* So doesn't display garbage */            if (priv_ripng_np->rip6_metric == NEXTHOP_METRIC)                {                if (IP_IN6_IS_ADDR_UNSPECIFIED(&priv_ripng_np->rip6_dest))                    {                    sprintf (pstr, "    NextHop reset");                    pstr = tmpString + strlen (tmpString);                    }                else                    {                    sprintf (pstr, "    NextHop %s", buf);                    pstr = tmpString + strlen (tmpString);                    }                }            else                {                sprintf (pstr, "    %s/%d[%d]", buf, priv_ripng_np->rip6_plen, priv_ripng_np->rip6_metric);                pstr = tmpString + strlen (tmpString);                }            if (priv_ripng_np->rip6_tag)                {                sprintf (pstr, "  tag=0x%04x", ip_ntohs(priv_ripng_np->rip6_tag) & 0xffff);                pstr = tmpString + strlen (tmpString);                }            IPCOM_LOG1(DEBUG, "%s", tmpString);            } /* for */        } /* if */    error = ipripng_sendpacket(sin6, RIPSIZE(priv_ripng_nrt));    if (error == IP_ERRNO_EAFNOSUPPORT)        {        /* Protocol not supported */        if (ipcom_inet_ntop(IP_AF_INET6, &ifcp->ifc_ripsin.sin6_addr, buf, sizeof (buf)) == IP_NULL)            buf[0] = '\0';        IPCOM_LOG2(INFO, "Could not send info to %s on %s", buf[0] ? buf : "?", ifcp ? ifcp->ifc_name : "?");        if (ifcp)            {            IPCOM_LOG1(INFO, "Cleared IFF_UP flag on %s", ifcp->ifc_name);            ifcp->ifc_flags &= ~IP_IFF_UP; /* As if down for AF_INET6 */            }        }    priv_ripng_nrt = 0;    priv_ripng_np = ipripng.ripngbuf->rip6_nets;}/* * Generate RIP6_RESPONSE packets and send them. */IP_STATIC voidipripng_send_response(struct  ifc *ifcp, struct Ip_sockaddr_in6 *sin6, int flag){    Ipripng_rt *rrt;    struct  in6_addr *prevnh, *thisnh;  /* next hop */    int maxrte;    int     tobeadvd;    prevnh = thisnh = IP_NULL;    if (ipripng.qflag)        return;    if (flag & RRTF_CHANGED)        IPCOM_LOG1(INFO, "sending triggered update on: %s", ifcp->ifc_name);    if ((flag & RRTF_SENDANYWAY) == 0 &&        (ipripng.qflag || (ifcp->ifc_flags & IP_IFF_LOOPBACK)))        return;    /* -N: no use */    if (iff_find(ifcp, 'N') != IP_NULL)        return;    /* -T: generate default route only */    if (iff_find(ifcp, 'T') != IP_NULL) {        struct netinfo6 rrt_info[2];        memset(&rrt_info, 0, 2 * sizeof(struct netinfo6));        /* Send the Next Hop RTE first */        rrt_info[0].rip6_dest = ifcp->ifc_mylladdr;        rrt_info[0].rip6_plen = 0;        rrt_info[0].rip6_tag = 0;        rrt_info[0].rip6_metric = NEXTHOP_METRIC;        rrt_info[1].rip6_dest = ip_in6addr_any;        rrt_info[1].rip6_plen = 0;        rrt_info[1].rip6_metric = 1;        rrt_info[1].rip6_metric += ifcp->ifc_metric;        rrt_info[1].rip6_tag = ip_htons(ipripng.routetag & 0xffff);        priv_ripng_np = ipripng.ripngbuf->rip6_nets;        *priv_ripng_np = rrt_info[0];        priv_ripng_np++;        *priv_ripng_np = rrt_info[1];        priv_ripng_nrt = 2;        ipripng_flush(ifcp, sin6);        return;    }    maxrte = (ifcp->ifc_mtu - sizeof(Ipnet_pkt_ip6) -            sizeof(Ipnet_pkt_udp) -            sizeof(struct rip6) + sizeof(struct netinfo6)) /            sizeof(struct netinfo6);    priv_ripng_nrt = 0; priv_ripng_np = ipripng.ripngbuf->rip6_nets; prevnh = IP_NULL;    for (rrt = (Ipripng_rt *)ipripng.riprt; rrt; rrt = (Ipripng_rt *)rrt->rrt_next) {        if (rrt->rrt_rflags & RRTF_NOADVERTISE)            continue;        /* Need to check filter here */        if (out_filter(rrt, ifcp) == 0)                continue;        /* Check split horizon / poison reverse and other conditions */        tobeadvd = tobeadv (rrt, ifcp);        if (tobeadvd == 0)            continue;        /*         * Only considers the routes with flag if specified.         * Also don't send triggered updates if this route is an infinite         * metric (poison reverse).         */        if (flag & RRTF_CHANGED)            {            if (((rrt->rrt_rflags & RRTF_CHANGED) == 0) || (tobeadvd == 2))                continue;            }        /* Calculate Next Hop for this route */        /* We use the actual gateway for the Next Hop for:         *    If the route goes out over the same interface         *    AND the gateway address is specified.         *    AND The gateway address is link-local         *    AND this is not a Poison Reverse route         */        if ((rrt->rrt_index == ifcp->ifc_index) &&            (!IP_IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw)) &&            (IP_IN6_IS_ADDR_LINK_LOCAL(&rrt->rrt_gw)) &&            ((rrt->rrt_flags & RRTF_NH_NOT_LLADDR) == 0) &&            (tobeadvd != 2))            {            thisnh = &rrt->rrt_gw;            }        /* Otherwise we use our own link-local address for the Next Hop */        else            {            thisnh = &ifcp->ifc_mylladdr;            }        /*         * Now check if this was the previous Next Hop or if one has         * ever been sent. If not then we must send a new Next Hop RTE.         */        if ((prevnh == IP_NULL) || !IP_IN6_ARE_ADDR_EQUAL(thisnh, prevnh))            {            /* Flush the packet if we're out of space */            if (priv_ripng_nrt == maxrte - 2)                ipripng_flush(ifcp, sin6);            /* Fill out the Next Hop RTE with the address chosen above */            priv_ripng_np->rip6_dest = *thisnh;            if (IP_IN6_IS_ADDR_LINK_LOCAL(&priv_ripng_np->rip6_dest))                SET_IN6_LINKLOCAL_IFINDEX(priv_ripng_np->rip6_dest, 0);            priv_ripng_np->rip6_plen = 0;            priv_ripng_np->rip6_tag = 0;            priv_ripng_np->rip6_metric = NEXTHOP_METRIC;            prevnh = thisnh;            priv_ripng_np++; priv_ripng_nrt++;            }        /* Put the route to the buffer */        *priv_ripng_np = rrt->rrt_info;        /* Poison Reverse route ? */        if (tobeadvd == 2)            priv_ripng_np->rip6_metric = HOPCNT_INFINITY6;        priv_ripng_np++; priv_ripng_nrt++;        if (priv_ripng_nrt == maxrte) {            ipripng_flush(ifcp, sin6);            prevnh = IP_NULL;        }    }    if (priv_ripng_nrt) /* Send last packet */        ipripng_flush(ifcp, sin6);}/* *=========================================================================== *                    ipripng_process_request *=========================================================================== * Description:   Parse an incoming RIPng request packet and send a response *                if applicable. * Parameters:    ifc   Interface RIPng request arrived on. *                np    RIPng packet output buffer. *                sin6  destination address. * Returns:       IPCOM_SUCCESS or IPCOM_ERR_BAD_PACKET. * */IP_STATIC voidipripng_process_request(struct ifc *ifcp, struct netinfo6 *np, int nn, struct Ip_sockaddr_in6 *sin6){    int i;    Ipripng_rt *rrt;    if (!(nn == 1 && IP_IN6_IS_ADDR_UNSPECIFIED(&np->rip6_dest) &&          np->rip6_plen == 0 && np->rip6_metric == HOPCNT_INFINITY6)) {        /* Specific response, don't split-horizon */        IPCOM_LOG0(INFO, "\tRIPng Process Request");        for (i = 0; i < nn; i++, np++) {            rrt = ipripng_rtlookup(np, IP_NULL);            if (rrt)                np->rip6_metric = rrt->rrt_info.rip6_metric;            else                np->rip6_metric = HOPCNT_INFINITY6;        }        (void)ipripng_sendpacket(sin6, RIPSIZE(nn));        return;    }    /* Whole routing table dump */    /* Used to use RRTF_SENDANYWAY to bypass qflag (listen only)     * but RIPng shouldn't respond to requests either when in listen     * only mode, otherwise other routers will get this router's     * routes even though the user specified listen only.     */    IPCOM_LOG0(INFO, "\tRIPng Request -- whole routing table");    ipripng_send_response(ifcp, sin6, 0);}/* *=========================================================================== *                    ipripng_neighboradd *=========================================================================== * Description:  Add a line from getopt to our linked list of accepted *		 neighbors. * Parameters: * * Returns: * */IP_STATICvoid ipripng_neighboradd (char * optarg){    struct nb_list *    plist = ipripng.nb_list_root;    struct nb_list *    prevp = IP_NULL;    char *              argptr = optarg;    /* Check valid parameters */    if ((argptr == IP_NULL) || (*argptr == '\0'))        IPCOM_LOG0(WARNING, "No neighbors specified");    /* Walk the list to find the last element */    while (plist)        {        prevp = plist;        plist = plist->nb_next;        }    /* Parse the address list ("addr1,addr2") */    while (argptr)        {        char * addr;        addr = argptr;        /* Replace the comma by a NULL for inet_pton() */        if ((argptr = ipcom_strchr (argptr, ',')) != IP_NULL)            *argptr++ = '\0';        /* Create new element for linked list */        plist = (struct nb_list *)ipcom_malloc (sizeof (struct nb_list));        if (plist == IP_NULL)            {            IPCOM_LOG0(ERR, "Error on neighbor list ipcom_malloc");            return;            }        /* Convert to in6_addr and store in element */        if (ipcom_inet_pton(IP_AF_INET6, addr, &plist->nb_addr) != 1)            {            IPCOM_LOG1(ERR, "Bad restricted neighbor address (%s)", addr);            ipcom_free (plist);            return;            }        plist->nb_next = IP_NULL;        /* Put it to the list */        if (prevp == IP_NULL)  /* First one */            ipripng.nb_list_root = plist;

⌨️ 快捷键说明

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