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

📄 ipproto.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 3 页
字号:
            else                IF_PREPEND (&pDrvCtrl->idr.ac_if.if_snd, pMblk);            break;            }        else            ++pDrvCtrl->idr.ac_if.if_opackets;          #ifdef IP_DEBUG        if (ipDebug)            logMsg("ipTxStartup done!\n", 1, 2, 3, 4, 5, 6);#endif /* IP_DEBUG */        }    }/********************************************************************************* 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;    int error;                 /* return error status */    int count;    IMPORT int          ipMaxUnits;    int limit = ipMaxUnits;    /* 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 && pDrvCtrl->pIpCookie == pEnd)            break;        }    if (count == limit)        {        /* Device not attached. */        return (ERROR);        }    error = ipShutdownRtn (pDrvCtrl->pIpCookie, pDrvCtrl);    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;    struct sockaddr_in* addr;    register struct in_ifaddr* pIa = 0;    char address[6];    M2_INTERFACETBL mib2Tbl;    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;    END_OBJ * 	pEnd;    pDrvCtrl = (IP_DRV_CTRL *)(ifp->ac_if.pCookie);    pEnd = pDrvCtrl->pIpCookie;    if (pEnd == NULL)        return (EINVAL);    switch (cmd)	{	case SIOCSIFADDR:            for (pIa = in_ifaddr; pIa; pIa = pIa->ia_next)                if ((pIa->ia_ifp == (struct ifnet *)ifp) &&                    (pIa->ia_addr.sin_addr.s_addr == dt_saddr))                    break;            pIa->ia_ifa.ifa_rtrequest = arp_rtrequest;            pIa->ia_ifa.ifa_flags |= RTF_CLONING;	    ifp->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (ifp, &IA_SIN (data)->sin_addr);	    break;        case SIOCGMIB2CNFG:	    error = muxIoctl (pEnd, EIOCGMIB2, (caddr_t)&mib2Tbl);            if (error != OK)                return (EINVAL);            pm2DrvCnfg->ifType = mib2Tbl.ifType;		/* ppp type */            pm2DrvCnfg->ifSpecific.idLength = 0;	/* use default */            break;                    case SIOCGMIB2CNTRS:				/* fill in counters */	    error = muxIoctl (pEnd, 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 SIOCADDMULTI:            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:                  		                    ifr = (struct ifreq *)data;                    addr = ((struct sockaddr_in *)&ifr->ifr_addr);		    pMblk= (struct mBlk*) malloc(sizeof(M_BLK));		    pMblk->mBlkHdr.mFlags |= M_MCAST; 		    ifp->ac_if.if_resolve(NULL,NULL,pMblk,addr,&address);                    free(pMblk);                    error = muxMCastAddrAdd (pEnd, (char *)&address);                    break;                default:                    error = EINVAL;                    break;                }            break;	case SIOCDELMULTI:            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:                  		                    ifr = (struct ifreq *)data;                    addr = ((struct sockaddr_in *)&ifr->ifr_addr);		    pMblk= (struct mBlk*) malloc(sizeof(M_BLK));                    pMblk->mBlkHdr.mFlags |= M_MCAST;                    ifp->ac_if.if_resolve(NULL,NULL,pMblk,addr,&address);                    free(pMblk);                    error = muxMCastAddrDel (pEnd, (char *)&address);                    break;                default:                    error = EINVAL;                    break;                }            break;	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 (pEnd, 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 (pEnd, EIOCSFLAGS, (caddr_t) flagsMask);	    break;	default:	    error = muxIoctl (pEnd, cmd, data);	    break;	}    return (error);    }/******************************************************************************** ipOutput - routine to encapsulate an IP packet.** This routine encapsulates a packet in the link-level frame. It* is roughly equivalent to the Ethernet output routine, but uses* the MUX routines to acheive some link-layer independence for* packets of family AF_INET. The precise behavior depends on* the underlying END driver. This routine will generate Ethernet* frames unless the driver provides a routine to form the appropriate* frame header.* * NOTE: It assumes that ifp is actually a pointer to an arpcom structure.** NOMANUAL*/int ipOutput    (    register struct ifnet *ifp,    struct mbuf *m0,    struct sockaddr *dst,    struct rtentry *rt0    )    {    u_short etype;    int s, error = 0;    u_char edst[6];    register struct mbuf *m = m0;    register struct rtentry *rt;    struct mbuf *mcopy = (struct mbuf *)0;    int off;    struct arpcom *ac = (struct arpcom *)ifp;    struct ether_header* eh;    IP_DRV_CTRL* pDrvCtrl;    END_OBJ* pEnd;    pDrvCtrl = (IP_DRV_CTRL *)ifp->pCookie;    pEnd = pDrvCtrl->pIpCookie;    if (pEnd == NULL)        senderr (EINVAL);    if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))        senderr(ENETDOWN);    ifp->if_lastchange = tickGet();    if ((rt = rt0))        {        if ((rt->rt_flags & RTF_UP) == 0)            {            if ((rt0 = rt = rtalloc1(dst, 1)))                rt->rt_refcnt--;            else                 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);                if ((rt = rt->rt_gwroute) == 0)                    senderr(EHOSTUNREACH);                }            }        if (rt->rt_flags & RTF_REJECT)            if (rt->rt_rmx.rmx_expire == 0 ||                tickGet() < rt->rt_rmx.rmx_expire)                senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);        }    switch (dst->sa_family)        {        case AF_INET:            if (ifp->if_resolve != NULL)                if (!ifp->if_resolve(ac, rt, m, dst, edst))                    return (0);	/* if not yet resolved */            /* If broadcasting on a simplex interface, loopback a copy */            if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))                mcopy = m_copy(m, 0, (int)M_COPYALL);            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.             */            eh = (struct ether_header *)dst->sa_data;            bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));            etype = eh->ether_type;            break;                    default:            logMsg ("%s%d: can't handle af%d\n", (int)ifp->if_name,                    ifp->if_unit, dst->sa_family, 0, 0, 0);            senderr(EAFNOSUPPORT);        }        if (mcopy)        (void) looutput(ifp, mcopy, dst, rt);    etype = htons(etype);    pDrvCtrl->pDst->m_data = (char *)&edst;    pDrvCtrl->pSrc->m_data = (char *)&ac->ac_enaddr;    pDrvCtrl->pDst->mBlkHdr.reserved = etype;    pDrvCtrl->pSrc->mBlkHdr.reserved = etype;    if ((m = muxAddressForm (pEnd, m, pDrvCtrl->pSrc, pDrvCtrl->pDst))        == NULL)        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);        senderr(ENOBUFS);        }    IF_ENQUEUE(&ifp->if_snd, m);        if ((ifp->if_flags & IFF_OACTIVE) == 0)        (*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++;    return (error);        bad:    if (m)        netMblkClChainFree(m);    return (error);}

⌨️ 快捷键说明

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