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

📄 ipproto.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        if (ifp->ac_if.if_resolve)                {                pDrvCtrl = (IP_DRV_CTRL*)ifp->ac_if.pCookie;                ifr = (struct ifreq *)data;                inetaddr = &ifr->ifr_addr;                pMblk = KHEAP_ALLOC(sizeof(M_BLK));                if (pMblk == NULL)                    {                    error = ENOBUFS;                    break;                    }                bzero ( (char *)pMblk, sizeof (M_BLK));                pMblk->mBlkHdr.mFlags |= M_MCAST;                /*                 * call the registered address resolution function                 * to do the mapping                 */                if (ifp->ac_if.if_resolve (&ipMcastResume, pMblk, inetaddr,                                           &ifp->ac_if, SIOCADDMULTI, &mapMCastBuff) == 0)		    {		    KHEAP_FREE( (char *)pMblk);		    break; /* not yet resolved */		    }                KHEAP_FREE( (char *)pMblk);                /* register the mapped multicast MAC address */                error = muxMCastAddrAdd (pDrvCtrl->pIpCookie,                                         (char *)&mapMCastBuff);                }            break;           /* if no resolve function, return OK */        case SIOCDELMULTI:            /* Don't allow group membership on non-multicast interfaces. */            if ((ifp->ac_if.if_flags & IFF_MULTICAST) == 0)                return EOPNOTSUPP;                        if (ifp->ac_if.if_resolve)                {                pDrvCtrl = ifp->ac_if.pCookie;                ifr = (struct ifreq *)data;                inetaddr = (&ifr->ifr_addr);                                pMblk = KHEAP_ALLOC(sizeof (M_BLK));                if (pMblk == NULL)                    {                    error = ENOBUFS;                    break;                    }                bzero ( (char *)pMblk, sizeof (M_BLK));                pMblk->mBlkHdr.mFlags |= M_MCAST;                /*                 * call the registered address resolution function to do                 * the mapping                 */                                if (ifp->ac_if.if_resolve (&ipMcastResume, pMblk, inetaddr,                                     &ifp->ac_if, SIOCDELMULTI, &mapMCastBuff) == 0)		    {		    KHEAP_FREE( (char *)pMblk);		    break; /* not yet resolved */		    }		KHEAP_FREE( (char *)pMblk);                		/* delete the mapped multicast MAC address */                		error = muxMCastAddrDel (pDrvCtrl->pIpCookie,                                         (char *)&mapMCastBuff);		}            break;            /* if no resolve routine, return OK */            	case SIOCGETMULTI:	    break;            	case SIOCSIFFLAGS:	    ifr = (struct ifreq *) data;			    	    /* 	     * Turn off all flags that are disabled in the request 	     * correcting for the conversion from short to long 	     */	    	    flagsMask = (unsigned short) (~ ifr->ifr_flags);	    /* Two's complement used to disable flags by muxIoctl () */	    	    flagsMask = -flagsMask - 1;	    error = muxIoctl (pDrvCtrl->pIpCookie, EIOCSFLAGS,                              (caddr_t) flagsMask);	    /* 	     * Next set all flags that are set in request correcting for 	     * the conversion from short to long. 	     */	    flagsMask = (unsigned short) ifr->ifr_flags;	    error |= muxIoctl (pDrvCtrl->pIpCookie, EIOCSFLAGS,                               (caddr_t) flagsMask);	    break;        case SIOCGMCASTLIST:            error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMCASTLIST, data);            if (error != OK)                return (EINVAL);            break;	default:	    error = muxIoctl (pDrvCtrl->pIpCookie, cmd, data);	    break;	}    return (error);    }/******************************************************************************** ipOutput - transmit routine for IP packets using END or NPT devices.** This routine handles the final processing before transferring a* network packet (contained in the <m0> argument) to the transmit* device.** For END devices, it encapsulates a packet in the link-level frame* before transferring it to the driver. The output processing constructs* Ethernet frames unless the device provides a custom routine to form the* appropriate frame header.** For NPT devices, the routine just inserts the destination link-level* address at the front of the mBlk chain. Later processing hands that* address to the driver along with an mBlk chain containing the network* packet (with no link-level header).** NOTE: It assumes that ifp is actually a pointer to an arpcom structure.** NOMANUAL*/LOCAL int ipOutput    (    register struct ifnet *ifp,    struct mbuf *m0,    struct sockaddr *dst,    struct rtentry *rt0    )    {    u_short etype = 0;    int s, error = 0;    register struct mbuf *m = m0;    register struct rtentry *rt;    int off;    struct arpcom *ac = (struct arpcom *)ifp;    struct ether_header* eh;    IP_DRV_CTRL* pDrvCtrl;    pDrvCtrl = (IP_DRV_CTRL *)ifp->pCookie;    if (pDrvCtrl->pIpCookie == NULL)        senderr (EINVAL);    if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))        {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 2, 3,                         WV_NETEVENT_ETHEROUT_IFDOWN, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif        senderr(ENETDOWN);        }    ifp->if_lastchange = tickGet();    if ((rt = rt0))        {        if ((rt->rt_flags & RTF_UP) == 0)            {            if ((rt0 = rt = rtalloc1(dst, 1, 1)))                rt->rt_refcnt--;            else                {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */                WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5,                                 WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND,                                ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                senderr(EHOSTUNREACH);                }            }        if (rt->rt_flags & RTF_GATEWAY)            {            if (rt->rt_gwroute == 0)                goto lookup;            if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0)                {                rtfree(rt); rt = rt0;                lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);                if ((rt = rt->rt_gwroute) == 0)                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */                    WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5,                                     WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND,                     ((struct sockaddr_in *)rt->rt_gateway)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                    senderr(EHOSTUNREACH);                    }                }            }        if (rt->rt_flags & RTF_REJECT)            {            if (rt->rt_rmx.rmx_expire == 0 ||                tickGet() < rt->rt_rmx.rmx_expire)                {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */                WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 5, 6,                                 WV_NETEVENT_ETHEROUT_RTREJECT, WV_NET_SEND)#endif  /* INCLUDE_WVNET */#endif                senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);                }            }        } /* if (rt = rt0) */    switch (dst->sa_family)        {        case AF_INET:            if (ifp->if_resolve != NULL)                if (!ifp->if_resolve (&ipOutputResume, m, dst, ifp, rt,                                      pDrvCtrl->pDstAddr))                    return (0);	/* if not yet resolved */#ifdef ROUTER_STACK            /*              * If we are forwarding the packet, check if we need to             * supply the forwarding information to Fastpath. We do not             * want to call Fastpath with a broadcast or multicast address             */            if ((m->m_flags & M_FORWARD) && pIpv4FFRouteCompleteFn != NULL &&                 !(m->m_flags & M_MCAST || m->m_flags & M_BCAST))                (*pIpv4FFRouteCompleteFn) (rt0, pDrvCtrl, ifp, dst);#endif /* ROUTER_STACK */            /* If broadcasting on a simplex interface, loopback a copy */            if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&		!(m->m_flags & M_PROXY))                ip_mloopback (ifp, m, (struct sockaddr_in *)dst,                              (struct rtentry*)rt);            off = m->m_pkthdr.len - m->m_len;            etype = ETHERTYPE_IP;            break;        case AF_UNSPEC:            /*             * WARNING: At the moment this code ONLY handles 14 byte             * headers of the type like Ethernet.             */            switch (ifp->if_type)                {                case M2_ifType_ethernet_csmacd:                case M2_ifType_fastEther:                case M2_ifType_gigabitEthernet:                case M2_ifType_iso88023_csmacd:                case M2_ifType_iso88024_tokenBus:                case M2_ifType_iso88025_tokenRing:                case M2_ifType_iso88026_man:                case M2_ifType_fddi:                    eh = (struct ether_header *)dst->sa_data;		    bcopy((caddr_t)eh->ether_dhost, 		          (caddr_t)pDrvCtrl->pDstAddr, ifp->if_addrlen);                    etype = eh->ether_type;                    break;                default:                    error=ERROR;		}                          if(!error)                 break;             /* fall-through */        default:            logMsg ("%s%d: can't handle af%d\n", (int)ifp->if_name,                    ifp->if_unit, dst->sa_family, 0, 0, 0);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_ERROR, 3, 7,                             WV_NETEVENT_ETHEROUT_AFNOTSUPP, WV_NET_SEND,                            dst->sa_family)#endif  /* INCLUDE_WVNET */#endif            senderr(EAFNOSUPPORT);        }        etype = htons(etype);    if (pDrvCtrl->nptFlag)        {        /*         * For NPT devices, insert the destination address (if any) and         * network protocol type at the beginning of the network packet         * for later use.         */        if (ifp->if_addrlen)            {            M_PREPEND(m, ifp->if_addrlen, M_DONTWAIT);            if (m == NULL)                {                senderr(ENOBUFS);                }            ((M_BLK_ID)m)->mBlkPktHdr.rcvif = 0;            /* Store the destination address. */            bcopy (pDrvCtrl->pDstAddr, m->m_data, ifp->if_addrlen);            }            /* Save the network protocol type. */        ((M_BLK_ID)m)->mBlkHdr.reserved = etype;        }    else        {        /*         * For END devices, build and prepend the complete frame instead.         * NOTE: currently, the ac_enaddr field is only valid for specific         * device types. (See the ipAttach routine).         */        pDrvCtrl->pSrc->m_data = (char *)&ac->ac_enaddr;        pDrvCtrl->pDst->mBlkHdr.reserved = etype;        pDrvCtrl->pSrc->mBlkHdr.reserved = etype;        m = muxAddressForm (pDrvCtrl->pIpCookie, m,                            pDrvCtrl->pSrc, pDrvCtrl->pDst);        if (m == NULL)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 3, 4,                             WV_NETEVENT_ETHEROUT_NOBUFS, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif            senderr(ENOBUFS);            }        }    s = splimp();    /*     * Queue message on interface, and start output if interface     * not yet active.     */    if (IF_QFULL(&ifp->if_snd))        {        IF_DROP(&ifp->if_snd);        splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 3, 4,                         WV_NETEVENT_ETHEROUT_NOBUFS, WV_NET_SEND, ifp)#endif  /* INCLUDE_WVNET */#endif        senderr(ENOBUFS);        }    IF_ENQUEUE(&ifp->if_snd, m);    (*ifp->if_start)(ifp);    splx(s);    ifp->if_obytes += m->mBlkHdr.mLen;    if (m->m_flags & M_MCAST || m->m_flags & M_BCAST)        ifp->if_omcasts++;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */    WV_NET_EVENT_2 (NET_CORE_EVENT, WV_NET_NOTICE, 3, 12,                     WV_NETEVENT_ETHEROUT_FINISH, WV_NET_SEND, ifp, error)#endif  /* INCLUDE_WVNET */#endif    return (error);        bad:    if (m)        netMblkClChainFree(m);    return (error);    }/********************************************************************************* ipOutputResume - transmit routine called after delayed address resolution** When sending an IP packet, all address resolution functions responsible* for converting an IP address to a link-layer address receive a pointer 

⌨️ 快捷键说明

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