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

📄 ipproto.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 3 页
字号:
* ipError - a routine to deal with device errors** This routines is called by the lower layer when a device error occurs.** RETURNS: N/A** NOMANUAL*/void ipError    (    END_OBJ* pEnd,    END_ERR* pError,    IP_DRV_CTRL* pDrvCtrl    )    {    if (ipDebug)        {        switch (pError->errCode)            {            case END_ERR_INFO:                if (pError->pMesg != NULL)                    logMsg ("INFO: Device: %s Unit: %d Msg: %s\n",                            (int)pEnd->devObject.name,                            pEnd->devObject.unit,                            (int)pError->pMesg, 4, 5, 6);                break;            case END_ERR_WARN:                if (pError->pMesg != NULL)                    logMsg ("WARN: Device: %s Unit: %d Msg: %s\n",                            (int)pEnd->devObject.name,                            pEnd->devObject.unit,                            (int)pError->pMesg, 4, 5, 6);                break;            case END_ERR_RESET:                if (pError->pMesg != NULL)                    logMsg ("RESET: Device: %s Unit: %d Msg: %s\n",                            (int)pEnd->devObject.name,                            pEnd->devObject.unit,                            (int)pError->pMesg, 4, 5, 6);                pDrvCtrl->idr.ac_if.if_lastchange = tickGet();                break;            case END_ERR_UP:                if (pError->pMesg != NULL)                    logMsg ("UP: Device: %s Unit: %d Msg: %s\n",                            (int)pEnd->devObject.name,                            pEnd->devObject.unit,                            (int)pError->pMesg, 4, 5, 6);                break;            case END_ERR_DOWN:                if (pError->pMesg != NULL)                    logMsg ("DOWN: Device: %s Unit: %d Msg: %s\n",                            (int)pEnd->devObject.name,                            pEnd->devObject.unit,                            (int)pError->pMesg, 4, 5, 6);                pDrvCtrl->idr.ac_if.if_lastchange = tickGet();                ((IFNET *)&pDrvCtrl->idr)->if_flags &= ~(IFF_UP| IFF_RUNNING);                break;            default:            }        }    }/******************************************************************************** ipAttach - a generic attach routine for the TCP/IP network stack** This routine takes the unit number and device name of an END driver* (e.g., "ln0", "ei0", etc.) and attaches the TCP/IP stack to the MUX. * If completed successfully, the IP protocol will begin receiving packets* from that driver.** RETURNS: OK or ERROR*/int ipAttach    (    int unit,                   /* Unit number  */    char *pDevice		/* Device name (i.e. ln, ei etc.). */    )    {    int flags;    M2_INTERFACETBL mib2Tbl;    IP_DRV_CTRL* pDrvCtrl;    IMPORT int          ipMaxUnits;    struct ifnet* pIfp = NULL;    char *pName;    END_OBJ* pEnd;    struct ifaddr *pIfa;    struct sockaddr_dl *pSdl;    int ifHdrLen;    struct ifreq  ifr;    int count;    int limit = ipMaxUnits;    int freeslot = -1;    pEnd = endFindByName (pDevice, unit);    if (pEnd == NULL)        {        logMsg ("Can't attach unknown device %s (unit %d).\n", pDevice, unit,                0, 0, 0, 0);        return (ERROR);        }    for (count = 0; count < limit; count++)        {        pDrvCtrl = &ipDrvCtrl [count];        if (pDrvCtrl->attached)            {            if (pDrvCtrl->pIpCookie == pEnd)     /* Already attached? */                return (OK);            }        else if (freeslot == -1)            freeslot = count;        }    if (freeslot == -1)        {        /* Too many attach attempts. */        logMsg ("Protocol is out of space. Increase IP_MAX_UNITS.\n",                0, 0, 0, 0, 0, 0);        return (ERROR);        }    pDrvCtrl = &ipDrvCtrl [freeslot];    bzero ( (char *)pDrvCtrl, sizeof (IP_DRV_CTRL));    if ((pDrvCtrl->pIpCookie = muxBind(pDevice, unit, (FUNCPTR) ipReceiveRtn,                                      (FUNCPTR) ipShutdownRtn,                                       (FUNCPTR) ipTxRestart,                                      (VOIDFUNCPTR) ipError,                                      0x800, "IP 4.4 TCP/IP",                                      (void *) pDrvCtrl)) == NULL)	{	logMsg("TCP/IP could not bind to the MUX! %s", (int)pDevice,               2, 3, 4, 5, 6);	return (ERROR);	}        if ((pDrvCtrl->pArpCookie = muxBind(pDevice, unit, (FUNCPTR) ipReceiveRtn,                                       (FUNCPTR) arpShutdownRtn,                                        (FUNCPTR) ipTxRestart,                                       NULL,                                       0x806, "IP 4.4 ARP",                                       pDrvCtrl)) == NULL)	{	logMsg("ARP could not bind to the MUX! %s", (int)pDevice,               2, 3, 4, 5, 6);	return (ERROR);	}    pEnd = (END_OBJ*)pDrvCtrl->pIpCookie;    if ((pDrvCtrl->pSrc = netMblkGet (pEnd->pNetPool,                                      M_DONTWAIT, MT_DATA)) == NULL)        return (ERROR);    if ((pDrvCtrl->pDst = netMblkGet (pEnd->pNetPool,                                      M_DONTWAIT, MT_DATA)) == NULL)        {        netMblkFree (pEnd->pNetPool, pDrvCtrl->pSrc);        return (ERROR);        }    pName = malloc (strlen (pDevice) + 1);    /* +1 is for EOS character */    if (pName == NULL)        {        netMblkFree (pEnd->pNetPool, pDrvCtrl->pSrc);	netMblkFree (pEnd->pNetPool, pDrvCtrl->pDst);        return (ERROR);        }    strcpy(pName, pDevice);        /* Get lower level info that we need. */    muxIoctl(pDrvCtrl->pIpCookie, EIOCGADDR,             (caddr_t)&pDrvCtrl->idr.ac_enaddr);    muxIoctl(pDrvCtrl->pIpCookie, EIOCGFLAGS, (caddr_t)&flags);    muxIoctl(pDrvCtrl->pIpCookie, EIOCGMIB2, (caddr_t)&mib2Tbl);    pIfp = (IFNET *)&pDrvCtrl->idr;    /* Hook up the interface pointers etc. */    bzero ((char *) pIfp, sizeof (*pIfp));    pIfp->if_unit   = unit;    pIfp->if_name   = pName;    pIfp->if_mtu    = mib2Tbl.ifMtu;    pIfp->if_baudrate = mib2Tbl.ifSpeed;  /* interface speed */    pIfp->if_init   = NULL;    pIfp->if_ioctl  = (FUNCPTR) ipIoctl;    pIfp->if_output = ipOutput;    pIfp->if_reset  = NULL;    pIfp->if_resolve = muxAddrResFuncGet(mib2Tbl.ifType, 0x800);    pIfp->if_flags  |= IFF_BROADCAST;    pIfp->if_type = mib2Tbl.ifType;    pIfp->if_addrlen = mib2Tbl.ifPhysAddress.addrLength;    pIfp->pCookie = (void *)pDrvCtrl;    pDrvCtrl->pSrc->mBlkHdr.mLen = pIfp->if_addrlen;    pDrvCtrl->pDst->mBlkHdr.mLen = pIfp->if_addrlen;        /* Get the length of the header. */    if (muxIoctl (pDrvCtrl->pIpCookie, EIOCGHDRLEN, 		  (caddr_t) &ifHdrLen) != OK)        pIfp->if_hdrlen = 0;    else	pIfp->if_hdrlen = (short) ifHdrLen;    /*     * Perform common duties while attaching to interface list     */    for (pIfa = pIfp->if_addrlist; pIfa; pIfa = pIfa->ifa_next)        {        if ((pSdl = (struct sockaddr_dl *)pIfa->ifa_addr) &&            pSdl->sdl_family == AF_LINK)            {            pSdl->sdl_type = pIfp->if_type;            pSdl->sdl_alen = pIfp->if_addrlen;            bcopy((caddr_t)((struct arpcom *)pIfp)->ac_enaddr,                  LLADDR(pSdl), pIfp->if_addrlen);            break;            }                }    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)ipTxStartup;        if (muxIoctl(pDrvCtrl->pIpCookie, EIOCGMWIDTH,                 (caddr_t)&pDrvCtrl->memWidth) != OK)        {        pDrvCtrl->memWidth = NONE;        }    /* Find out the size for the first buffer chunk. */    muxIoctl(pDrvCtrl->pIpCookie, EIOCGFBUF, (caddr_t)&pDrvCtrl->minFirstBuf);    pDrvCtrl->idr.ac_if.if_flags = flags;    pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    /* Attach the interface. */    if_attach (pIfp);    ifr.ifr_flags=pIfp->if_flags;    /* Update the driver flag status */    ipIoctl(pIfp, SIOCSIFFLAGS, &ifr);     pDrvCtrl->idr.ac_if.if_type = mib2Tbl.ifType;    pDrvCtrl->attached = TRUE;    return (OK);    }/********************************************************************************* ipTxReStart - restart routine ** NOMANUAL*/LOCAL int ipTxRestart    (    void * pCookie,	/* given by muxRestart */    IP_DRV_CTRL * pDrvCtrl    )    {    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().** Note that this function is ALWAYS called between an splnet() and an splx().* This is true because netTask(), and ether_output() take care of* this when calling this function.  Therefore, no calls to these spl functions* are needed anywhere in this output thread.** NOMANUAL*/void ipTxStartup    (    IP_DRV_CTRL * pDrvCtrl		/* pointer to the drv control */    )    {    M_BLK_ID      pMblk;    STATUS        status = OK;        if (!pDrvCtrl->attached)        {#ifdef IP_DEBUG        if (ipDebug)            logMsg("ipTxStartup not attached!\n", 1, 2, 3, 4, 5, 6);#endif /* IP_DEBUG */        return;        }        /*     * Loop until there are no more packets ready to send or we     * have insufficient resources left to send another one.     */    while (pDrvCtrl->idr.ac_if.if_snd.ifq_head)        {        /* dequeue a packet */        IF_DEQUEUE (&pDrvCtrl->idr.ac_if.if_snd, pMblk);          if ((etherOutputHookRtn != NULL) &&            (* etherOutputHookRtn)            (&pDrvCtrl->idr, (struct ether_header *)pMblk->m_data,             pMblk->m_len))            {            continue;            }#ifdef IP_DEBUG        if (ipDebug)            logMsg("ipTxStartup Transmiting!\n", 1, 2, 3, 4, 5, 6);#endif /* IP_DEBUG */        /* place a transmit request */        status = muxSend (pDrvCtrl->pIpCookie, pMblk);        if (status == END_ERR_BLOCK)            {#ifdef IP_DEBUG            if (ipDebug)                logMsg("Transmit error!\n", 1, 2, 3, 4, 5, 6);#endif /* IP_DEBUG */            /* If we are transmit 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;                          }

⌨️ 快捷键说明

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