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

📄 ipproto.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* 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*/LOCAL 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);     /*     * The if_dettach routine within the shutdown routines removes the     * route entries associated with the interface addresses and generates     * the corresponding routing socket and callback events.     */        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);        }        /* Delete any remaining static routes which use the interface. */    ifRouteCleanup (&pDrvCtrl->idr.ac_if);    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_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:#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;                    /*                     * Only generate gratuitous ARP requests 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;            pm2DrvCntr->ifInOctets = mib2Tbl.ifInOctets;            pm2DrvCntr->ifInNUcastPkts = mib2Tbl.ifInNUcastPkts;            pm2DrvCntr->ifInDiscards = mib2Tbl.ifInDiscards;            pm2DrvCntr->ifInUnknownProtos = mib2Tbl.ifInUnknownProtos;            pm2DrvCntr->ifOutOctets = mib2Tbl.ifOutOctets;            pm2DrvCntr->ifOutNUcastPkts = mib2Tbl.ifOutNUcastPkts;            pm2DrvCntr->ifOutDiscards = mib2Tbl.ifOutDiscards;            break;        case SIOCGMIB2233:            error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMIB2233, data);            if (error != OK)                return (EINVAL);            break;        case SIOCSMIB2233:            error = muxIoctl (pDrvCtrl->pIpCookie, EIOCSMIB2233, data);            if (error != OK)                return (EINVAL);            break;                    case SIOCADDMULTI:            /* Don't allow group membership on non-multicast               interfaces. */            if ((ifp->ac_if.if_flags & IFF_MULTICAST) == 0)                return EOPNOTSUPP;

⌨️ 快捷键说明

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