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

📄 riplib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    bzero ( (char *)&zero, 4);    /* Check to see if the packet has the proper info. */    if (bcmp((orig->sa_data + RIP2_MASK_OFFSET), (char *)&zero, 4) == 0)        noMask = TRUE;    if (bcmp((orig->sa_data + RIP2_GATE_OFFSET), (char *)&zero, 4) == 0)        noGate = TRUE;        /*      * Clear the provided storage for packet data. The rtadd routine used     * later requires zero values for all unused fields for correct      * operation of the protocol. Later queries will fail if this condition      * is not met.      */    bzero ( (char *)gateway, sizeof(gateway));    bzero ( (char *)netmask, sizeof(netmask));        /* Duplicate the shared parameters from the current route entry. */    gateway->sa_family = orig->sa_family;    gateway->sa_len = orig->sa_len;        netmask->sa_family = orig->sa_family;    netmask->sa_len = orig->sa_len;    /* Extract the data from the original packet. */    if (noGate)        {        /*          * RFC 1723, Section 3.4: If a value of 0.0.0.0 is given in the next         * hop field, use the originator of the RIP advertisement as the          * gateway.         */        bcopy ( (char *)&(src->sin_addr.s_addr),                (char *)gateway->sa_data + 2, 4);        }    else        bcopy ( (char *)(orig->sa_data + RIP2_GATE_OFFSET),                (char *)gateway->sa_data + 2, 4);    if (noMask)        bcopy ( (char *)&pIfp->int_subnetmask,                (char *)netmask->sa_data + 2, 4);    else        bcopy ( (char *)(orig->sa_data + RIP2_MASK_OFFSET),                (char *)netmask->sa_data + 2, 4);    /*      * Clear the fields in the original data now that the values have been     * copied. This step converts that structure into a format suitable     * for use with the rtadd() function.     */    /* Erase the route tag (sin_port field). */    bzero ( (char *)orig->sa_data, 2); 	    /* Erase the adjacent subnet mask and next hop values (sin_zero field). */    bzero ( (char *)(orig->sa_data + RIP2_MASK_OFFSET), 8);    return;    }/******************************************************************************** ripRouteToAddrs - convert a route entry into separate sockaddr_in structures** This routine takes a pointer to an rt_entry and parses it out into* three sockaddr_in structures.  pDsin contains the destination, pGsin contains* the gateway and pNsin contains the subnetmask.** RETURNS: N/A** NOMANUAL*/void ripRouteToAddrs    (    struct rt_entry* pRoute,    /* Route to convert. */    struct sockaddr_in** ppDsin,  /* Destination sin. */    struct sockaddr_in** ppGsin,  /* Gateway sin. */    struct sockaddr_in** ppNsin  /* Netmask sin. */    )    {    if (ppDsin != NULL)        *ppDsin = (struct sockaddr_in *) &(pRoute->rt_dst);    if (ppGsin != NULL)        *ppGsin = (struct sockaddr_in *) &(pRoute->rt_router);    if (ppNsin != NULL)        *ppNsin = (struct sockaddr_in *) &(pRoute->rt_netmask);    }/******************************************************************************** ripBuildPacket - this routine builds a packet from the route passed** This routine takes the routing entry that we are passed and properly* fills the fields in the packet.  If RIP version 1 packets are requested,* then the sections that must be zero are left alone, otherwise they are * properly filled. The version parameter uses the values for the MIB variable* stored in ripState.ripConf.rip2IfConfSend instead of the actual version* number. This routine is never called if that value is set to disable* transmission.** RETURNS: N/A** NOMANUAL*/void ripBuildPacket    (    RIP2PKT *pPacket,    struct rt_entry* rt,    struct interface * 	pIf,    int version    )    {    UINT32 	routenet = 0; 	/* Network number of route gateway */    UINT32 	destnet = 0; 	/* Network number of route destination */    struct sockaddr_in* dSin;    struct sockaddr_in* gSin;    struct sockaddr_in* nSin;    if (version == M2_rip2IfConfSend_ripVersion1)        {        pPacket->tag = 0;        ripRouteToAddrs(rt, &dSin, &gSin, &nSin);        pPacket->dest = dSin->sin_addr.s_addr;        pPacket->subnet = 0;        pPacket->gateway = 0;        pPacket->metric = htonl(rt->rt_metric);        }    else        {        /*          * Building version 2 packets requires special processing to          * support both RIP-1 and RIP-2 routers in all situations.         */        pPacket->tag = 0;        ripRouteToAddrs(rt, &dSin, &gSin, &nSin);        if (nSin->sin_addr.s_addr)            {            /*              * Don't apply the route's netmask if it is shorter than the              * mask of the outgoing interface. The interface's mask is used             * for those destinations so that an unreachable gateway is not              * sent. The shorter mask could conceal the network mismatch,             * (e.g. - 147.11.151.47/23 and 147.11.150.48/24 would match             * in that case).             */            if ( (nSin->sin_addr.s_addr & htonl (pIf->int_subnetmask)) ==                    pIf->int_subnetmask)                routenet = gSin->sin_addr.s_addr & nSin->sin_addr.s_addr;            else                routenet = gSin->sin_addr.s_addr & pIf->int_subnetmask;            }        else            routenet = gSin->sin_addr.s_addr & pIf->int_subnetmask;        destnet = (*(UINT32 *)(&pIf->int_addr.sa_data[0] + 2) &                                      pIf->int_subnetmask);        /* No special processing is required for the advertised destination. */        pPacket->dest = dSin->sin_addr.s_addr;        /*         * Internally generated entries which substitute for supernets         * still contain the classless netmask so that the border gateway          * filtering can select the correct entry for both directly connected          * and "distant" destinations. That value must be replaced with         * the "natural" (class-based) network mask before the update is         * sent so that the route will be understood by RIP-2 routers. If          * border gateway filtering was disabled, none of the internally          * generated entries will be included in any update, so this         * substitution is (correctly) ignored.         */        if ( (rt->rt_state & (RTS_INTERNAL | RTS_SUBNET)) ==                 (RTS_INTERNAL | RTS_SUBNET))            {            /*             * For internal routes, the route entry's netmask is equal to              * rt->rt_ifp->int_netmask unless it is a substitute for a             * supernet.             */            if (ntohl (nSin->sin_addr.s_addr) != rt->rt_ifp->int_netmask)                {                /*                  * Substitute the class-based value for the                  * supernet mask in the outgoing message.                 */                pPacket->subnet = htonl (rt->rt_ifp->int_netmask);                }            else                {                /*                  * For subnet replacements, use the existing                  * (class-based) value.                 */                pPacket->subnet = nSin->sin_addr.s_addr;                }            }        else            {            /*              * Common case: use mask from actual route entry. This             * case includes the internally generated default route             * created when the gateway flag is set during initialization.             */            pPacket->subnet = nSin->sin_addr.s_addr;            }        /*          * For RIPv2 packets, the network number of the published gateway          * must match the network number of the outgoing interface. Unless         * the host contains multiple interfaces with the same network         * number, the value stored in the RIP routing table generally         * contains an address on a different network. In that case,         * use the interface IP address to include a reachable gateway in          * the route update.         */        if (routenet != destnet)            pPacket->gateway = *(UINT32 *)(&pIf->int_addr.sa_data[0] + 2);        else            pPacket->gateway = gSin->sin_addr.s_addr;        /*          * Unlike the gateway and netmask, the specified metric         * can always be copied directly.          */        pPacket->metric = htonl(rt->rt_metric);        }    }/******************************************************************************** ripRouteShow - display the internal routing table maintained by RIP** This routine prints every entry in the local RIP routing table. The* flags displayed below the destination, gateway, and netmask addresses* indicate the current route status. Entries with the RTS_INTERFACE flag* indicate routes to directly connected networks which are generated * locally. If RTS_SUBNET is set for an entry, it is subject to border* gateway filtering (if enabled). When RTS_INTERNAL is also present, the * corresponding entry is an "artificial" route created to supply distant* networks with legitimate destinations if border filtering excludes the* actual entry. Those entries are not copied to the kernel routing table.* The RTS_CHANGED flag marks entries added or modified in the last timer * interval which will be included in a triggered update.** RETURNS: N/A** ERRNO: N/A*/void ripRouteShow()    {    int doinghost = 1;    register struct rthash *rh;    register struct rt_entry *rt;    struct rthash *base = hosthash;    struct sockaddr_in* dSin;    struct sockaddr_in* gSin;    struct sockaddr_in* nSin;    char address[32];    if (!ripInitFlag)        return;    /* Block all processing to guarantee a stable list of routes. */    semTake (ripLockSem, WAIT_FOREVER);     again:    for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++)        {        rt = rh->rt_forw;        for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)            {            ripRouteToAddrs(rt, &dSin, &gSin, &nSin);            inet_ntoa_b(dSin->sin_addr, (char *)&address);            printf("%s\t", address);            inet_ntoa_b(gSin->sin_addr, (char *)&address);            printf("%s\t", address);            inet_ntoa_b(nSin->sin_addr, (char *)&address);            printf("%s\t", address);            printf("Metric: %d\t", rt->rt_metric);            printf("Timer: %d\n", rt->rt_timer);            /* Now figure out all the state. */            if (rt->rt_state & RTS_CHANGED)                printf("RTS_CHANGED ");            if (rt->rt_state & RTS_EXTERNAL)                printf("RTS_EXTERNAL ");            if (rt->rt_state & RTS_INTERNAL)                printf("RTS_INTERNAL ");            if (rt->rt_state & RTS_PASSIVE)                printf("RTS_PASSIVE ");            if (rt->rt_state & RTS_INTERFACE)                printf("RTS_INTERFACE ");            if (rt->rt_state & RTS_REMOTE)                printf("RTS_REMOTE ");            if (rt->rt_state & RTS_SUBNET)                printf("RTS_SUBNET ");            printf ("\n");            }        }    if (doinghost)        {        doinghost = 0;        base = nethash;        goto again;        }    semGive (ripLockSem);    return;    }/******************************************************************************* ripSetInterfaces - add all multicast interfaces to address group** This routine sets all interfaces that are multicast capable into the* multicast group address passed in as an argument.** RETURNS: N/A** NOMANUAL*/void ripSetInterfaces    (    INT32 sock,    UINT32 mcastAddr                          /* Address to join. */    )    {    struct ip_mreq	ipMreq; /* Multicast structure for version 2 */    struct ifreq ifbuf[32];    struct ifreq *ifrp;    struct ifreq *ifend;    struct ifconf ifc;    int n = 0;    UINT32 addr;    ifc.ifc_buf = (char *)ifbuf;    ifc.ifc_len = sizeof(ifbuf);    if (ioctl(sock, SIOCGIFCONF, (UINT32)(char *)&ifc) < 0)        if (routedDebug)	    logMsg ("SIOCGIFCONF error adding multicast address",                    0, 0, 0, 0, 0, 0);    ifrp = (struct ifreq *)ifbuf;    ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len);    /*     * Loop through all of the interfaces.     */    for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n))        {	n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);	if (n < sizeof(*ifrp))	    n = sizeof(*ifrp);	/*	 * Ignore any interface for an address family other than IP.	 */	if (ifrp->ifr_addr.sa_family != AF_INET)	    continue;	addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;        ipMreq.imr_multiaddr.s_addr = htonl (mcastAddr);        ipMreq.imr_interface.s_addr = addr;                if (setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,                        (char *)&ipMreq, sizeof (ipMreq)) < 0)            {             if (routedDebug)                logMsg ("setsockopt IP_ADD_MEMBERSHIP error:\n",                        0, 0, 0, 0, 0, 0);             }        } }/******************************************************************************* ripClearInterfaces - remove all multicast interfaces from address group** This routine removes all interfaces that are multicast capable from the* multicast group address given by <mcastAddr>. It is called when changing* the receive control switch from RIP-2 only mode with SNMP. Although it * seems acceptable to allow membership in the multicast group unless the * receive switch is set to RIP-1 only mode, ANVL test 16.1 would fail.

⌨️ 快捷键说明

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