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

📄 ipproto.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    }/********************************************************************************* ipTkTxRestart - restart routine registered with a toolkit driver. ** NOMANUAL*/LOCAL int ipTkTxRestart    (    void * ipCallbackId       /* Sent down in muxTkBind call. */    )    {    IP_DRV_CTRL * pDrvCtrl = (IP_DRV_CTRL *)ipCallbackId;    if (pDrvCtrl == NULL)        return (ERROR);    ipTxStartup (pDrvCtrl);    return (OK);    }/********************************************************************************* ipTxStartup - start output on the lower layer** Looks for any action on the queue, and begins output if there is anything* there.  This routine is called from several possible threads.  Each will be* described below.** The first, and most common thread, is when a user task requests the* transmission of data.  This will cause muxSend() to be called, which will* cause ether_output() to be called, which will cause this routine to be* called (usually).  This routine will not be called if ether_output() finds* that our interface output queue is full.  In this case, the outgoing data* will be thrown out.** The second, and most obscure thread, is when the reception of certain* packets causes an immediate (attempted) response.  For example, ICMP echo* packets (ping), and ICMP "no listener on that port" notifications.  All* functions in this driver that handle the reception side are executed in the* context of netTask().  Always.  So, in the case being discussed, netTask() * will receive these certain packets, cause IP to be stimulated, and cause the* generation of a response to be sent.  We then find ourselves following the* thread explained in the second example, with the important distinction that* the context is that of netTask().** This routine is also called from ipTxRestart() and ipTkTxRestart().** NOMANUAL*/void ipTxStartup    (    IP_DRV_CTRL * pDrvCtrl		/* pointer to the drv control */    )    {    M_BLK_ID      pMblk;    STATUS        status = OK;    struct ifnet * 	pIf;    BOOL 		nptFlag;    USHORT netType = 0;    char dstAddrBuf [MAX_ADDRLEN];    M_BLK_ID pNetPkt = NULL;    int s;    if (pDrvCtrl == NULL)        return;    if (!pDrvCtrl->attached)        {#ifdef IP_DEBUG        if (ipDebug)            logMsg ("ipTxStartup not attached!\n", 0, 0, 0, 0, 0, 0);#endif /* IP_DEBUG */        return;        }    s = splnet();    nptFlag = pDrvCtrl->nptFlag;    pIf = (struct ifnet *)&pDrvCtrl->idr;    /*     * Loop until there are no more packets ready to send or we     * have insufficient resources left to send another one.     */    while (pIf->if_snd.ifq_head)        {        /* Dequeue a packet. */        IF_DEQUEUE (&pIf->if_snd, pMblk);  #ifdef ETHER_OUTPUT_HOOKS        if ((etherOutputHookRtn != NULL) &&            (* etherOutputHookRtn)          (&pDrvCtrl->idr, (struct ether_header *)pMblk->m_data,pMblk->m_len))            {            continue;            }#endif /* ETHER_OUTPUT_HOOKS */        if (nptFlag)            {            /*             * For NPT devices, the output processing adds the network packet             * type (and the link-level destination address, if any) to the             * start of the packet. Retrieve that information and pass it to             * the NPT transmit routine.             */            netType = pMblk->mBlkHdr.reserved;            bzero (dstAddrBuf, MAX_ADDRLEN);            pNetPkt = pMblk;            if (pIf->if_addrlen)                {                /* Save the dest. address to protect it from driver changes. */                bcopy (pMblk->mBlkHdr.mData, dstAddrBuf, pIf->if_addrlen);                /* Restore original network packet data pointers and length. */                m_adj (pMblk, pIf->if_addrlen);                if (pMblk->mBlkHdr.mLen == 0)                    {                    /*                     * The destination address used a new mBlk in the chain.                     * Access the next entry containing the network packet                     * and restore the header flag setting.                     */                    pNetPkt = pMblk->mBlkHdr.mNext;                    if (pMblk->mBlkHdr.mFlags & M_PKTHDR)                        {                        pNetPkt->mBlkHdr.mFlags |= M_PKTHDR;                        }                    }                }            /* Attempt to send the packet. */            status = muxTkSend (pDrvCtrl->pIpCookie, pNetPkt, dstAddrBuf,                                netType, NULL);            }        else            {            /*             * For END devices, the transmit queue contains a complete             * link-level frame. Attempt to send that data.             */            status = muxSend (pDrvCtrl->pIpCookie, pMblk);            }        if (status == END_ERR_BLOCK)            {            /*             * The device is currently unable to transmit. Return the             * packet or frame to the queue to retry later.             */#ifdef IP_DEBUG            if (ipDebug)                logMsg ("Transmit error!\n", 0, 0, 0, 0, 0, 0);#endif /* IP_DEBUG */            if (nptFlag && pIf->if_addrlen)                {                /*                 * For NPT devices, restore the link-level destination                 * address, in case the driver processing altered it.                 */                if (pMblk == pNetPkt)                    {                    /*                     * The destination address used the initial mBlk in the                     * chain. Change the data pointer to provide copy space.                     */                    pMblk->mBlkHdr.mData -= pIf->if_addrlen;                    }                bcopy (dstAddrBuf, pMblk->mBlkHdr.mData, pIf->if_addrlen);                pMblk->mBlkHdr.mLen += pIf->if_addrlen;                if (pMblk->mBlkHdr.mFlags & M_PKTHDR)                    pMblk->mBlkPktHdr.len += pIf->if_addrlen;                }	    /* If we are transmitting make a new copy and PREPEND it. */	    if (IF_QFULL(&pDrvCtrl->idr.ac_if.if_snd))	        {	        IF_DROP(&pDrvCtrl->idr.ac_if.if_snd);	        netMblkClChainFree (pMblk);	        ++pDrvCtrl->idr.ac_if.if_oerrors;                          }	    else	        IF_PREPEND (&pDrvCtrl->idr.ac_if.if_snd, pMblk);            break;            }        else     /* Successful handoff to driver for transmission. */           {           ++pDrvCtrl->idr.ac_if.if_opackets;            /* For NPT devices, free any Mblk prepended for the link-level             * destination address.  */           if (nptFlag && (pMblk != pNetPkt))               {               netMblkClFree(pMblk);               }           }        #ifdef IP_DEBUG        if (ipDebug)            logMsg("ipTxStartup done!\n", 0, 0, 0, 0, 0, 0);#endif /* IP_DEBUG */        }    splx(s);    }/********************************************************************************* ipDetach - a generic detach routine for the TCP/IP network stack** This routine removes the TCP/IP stack from the MUX. If completed* successfully, the IP protocol will no longer receive packets* from the named END driver. ** RETURNS: OK or ERROR*/STATUS ipDetach    (    int unit,                   /* Unit number  */    char *pDevice		/* Device name (i.e. ln, ei etc.). */    )    {    END_OBJ * 	pEnd;    IP_DRV_CTRL* pDrvCtrl = NULL;    int error;                 /* return error status */    int count;#ifndef VIRTUAL_STACK    IMPORT int          ipMaxUnits;#endif    int limit = ipMaxUnits;    char        ifName[IFNAMSIZ];               /* if name, e.g. "en0" */    /* Check if device is valid. */    pEnd = endFindByName (pDevice, unit);    if (pEnd == NULL)        return (ERROR);    for (count = 0; count < limit; count++)        {        pDrvCtrl = &ipDrvCtrl [count];        if (pDrvCtrl->attached &&                PCOOKIE_TO_ENDOBJ (pDrvCtrl->pIpCookie) == pEnd)            break;        }    if (count == limit)        {        /* Device not attached. */        return (ERROR);        }    /* Now bring down the interface */     sprintf (ifName,"%s%d",pDevice, unit);    ifFlagChange(ifName, IFF_UP, 0);     /* Now remove the interface route */     ifRouteDelete(pDevice, unit);        if (pDrvCtrl->nptFlag)       /* npt device, call npt routines */        {        error = ipTkShutdownRtn (pDrvCtrl);        if (pDrvCtrl->pArpCookie)            error |= arpTkShutdownRtn (pDrvCtrl);        }    else        {        error = ipShutdownRtn (pDrvCtrl->pIpCookie, pDrvCtrl);        if (pDrvCtrl->pArpCookie)            error |= arpShutdownRtn (pDrvCtrl->pArpCookie, pDrvCtrl);        }        return (error);    }/********************************************************************************* ipIoctl - the IP I/O control routine** Process an ioctl request.** NOMANUAL*/LOCAL int ipIoctl    (    IDR  *ifp,    int            cmd,    caddr_t        data    )    {    int error = OK;    struct ifreq *ifr;    IP_DRV_CTRL* pDrvCtrl;    register struct in_ifaddr* pIa = 0;    M2_INTERFACETBL mib2Tbl;    struct sockaddr* inetaddr;    char   mapMCastBuff[128];    long flagsMask;    register M2_NETDRVCNFG *pm2DrvCnfg = (M2_NETDRVCNFG *)data;    register M2_NETDRVCNTRS *pm2DrvCntr = (M2_NETDRVCNTRS *)data;    u_long dt_saddr = ((struct in_ifaddr *)data)->ia_addr.sin_addr.s_addr;    struct mBlk* pMblk;    pDrvCtrl = (IP_DRV_CTRL *)(ifp->ac_if.pCookie);    if (pDrvCtrl->pIpCookie == NULL)        return (EINVAL);    switch ((u_int) cmd)	{	case SIOCSIFADDR:#ifdef VIRTUAL_STACK            for (pIa = _in_ifaddr; pIa; pIa = pIa->ia_next)#else            for (pIa = in_ifaddr; pIa; pIa = pIa->ia_next)#endif /* VIRTUAL_STACK */                if ((pIa->ia_ifp == (struct ifnet *)ifp) &&                    (pIa->ia_addr.sin_addr.s_addr == dt_saddr))                    break;            /*             * For devices with 802.x addressing, setup ARP processing             * for the IP address.             */            switch (ifp->ac_if.if_type)                {                case M2_ifType_ethernet_csmacd:                case M2_ifType_iso88023_csmacd:                case M2_ifType_iso88024_tokenBus:                case M2_ifType_iso88025_tokenRing:                case M2_ifType_iso88026_man:                case M2_ifType_fddi:#ifdef ROUTER_STACK		/* UNNUMBERED_SUPPORT */ 	            if (pIa->ia_ifp->if_flags & IFF_UNNUMBERED)		        {		        pIa->ia_ifa.ifa_rtrequest = NULL;		        pIa->ia_ifa.ifa_flags &= ~RTF_CLONING;		        ifp->ac_ipaddr = IA_SIN (data)->sin_addr;		        break;		        }#endif /* ROUTER_STACK */                    pIa->ia_ifa.ifa_rtrequest = arp_rtrequest;                    pIa->ia_ifa.ifa_flags |= RTF_CLONING;                    ifp->ac_ipaddr = IA_SIN (data)->sin_addr;                    /* Generate gratuitous ARP requests only for ethernet devices. */                    arpwhohas ((struct arpcom*) ifp, &IA_SIN (data)->sin_addr);                    break;                default:                    break;                }	    break;        case SIOCGMIB2CNFG:	    error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMIB2,                              (caddr_t)&mib2Tbl);            if (error != OK)                return (EINVAL);            pm2DrvCnfg->ifType = mib2Tbl.ifType;		/* ppp type */            if (mib2Tbl.ifSpecific.idLength)                {                pm2DrvCnfg->ifSpecific.idLength = mib2Tbl.ifSpecific.idLength;                memcpy (&pm2DrvCnfg->ifSpecific.idArray[0],                            &mib2Tbl.ifSpecific.idArray[0],                            mib2Tbl.ifSpecific.idLength * sizeof (long));                }            else                pm2DrvCnfg->ifSpecific.idLength = 0;            break;                    case SIOCGMIB2CNTRS:				/* fill in counters */	    error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMIB2,                              (caddr_t)&mib2Tbl);            if (error != OK)                return (EINVAL);	    pm2DrvCntr->ifSpeed = mib2Tbl.ifSpeed;

⌨️ 快捷键说明

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