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

📄 in.c

📁 vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef VIRTUAL_STACK    pPtrInIfAddr = &_in_ifaddr; 	/* global variable */#else    pPtrInIfAddr = &in_ifaddr; 		/* global variable */#endif /* VIRTUAL_STACK */    while (*pPtrInIfAddr != NULL)	{	if (*pPtrInIfAddr == (struct in_ifaddr *)pIfAddr)	    {	    pInIfAddr = *pPtrInIfAddr; 	    *pPtrInIfAddr = (*pPtrInIfAddr)->ia_next; 	/* delete from list */	    IFAFREE (&pInIfAddr->ia_ifa);		/* free address */	    break; 	    }	pPtrInIfAddr = &(*pPtrInIfAddr)->ia_next; 	}    } /* * Return 1 if the address might be a local broadcast address. */intin_broadcast(in, ifp)	struct in_addr in;        struct ifnet *ifp;{	register struct ifaddr *ifa;	u_long t;	if (in.s_addr == INADDR_BROADCAST ||	    in.s_addr == INADDR_ANY)		return 1;	if ((ifp->if_flags & IFF_BROADCAST) == 0)		return 0;	t = ntohl(in.s_addr);	/*	 * Look through the list of addresses for a match	 * with a broadcast address.	 */#define ia ((struct in_ifaddr *)ifa)	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if (ifa->ifa_addr->sa_family == AF_INET &&		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||		     in.s_addr == ia->ia_netbroadcast.s_addr ||		     /*		      * Check for old-style (host 0) broadcast.		      */		     t == ia->ia_subnet || t == ia->ia_net))			    return 1;	return (0);#undef ia}/* * Add an address to the list of IP multicast addresses for a given interface. */struct mBlk *in_addmulti(ap, ifp, pInPcb)	register struct in_addr *ap;	register struct ifnet *ifp;	register struct inpcb * pInPcb;{	register struct in_multi *inm;	struct ifreq ifr;        struct mBlk * pInPcbMblk = NULL;        struct mBlk * pInmMblk = NULL;	struct mBlk * pInmFirstMblk = NULL;	int s = splnet();#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */    WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_VERBOSE, 58, 11,                      WV_NETEVENT_INADDMULT_START, ifp, ap->s_addr)#endif  /* INCLUDE_WVNET */#endif	/*	 * See if address already in list.	 */	IN_LOOKUP_MULTI(*ap, ifp, inm);	if (inm != NULL) {		/*		 * Found it; duplicate the mBlk, increment reference count.		 */        	if ((pInmMblk = mBlkGet (_pNetSysPool, M_DONTWAIT, MT_IPMADDR))                    == NULL)                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_EMERGENCY, 12, 3,                              WV_NETEVENT_INADDMULT_NOBUFS, ifp, ap->s_addr)#endif  /* INCLUDE_WVNET */#endif                    goto inAddMultiError;                    }                /*		 * XXX - The in_multi structures are stored in Mblk chains		 * instead of arrays like in BSD. Therefore when a second 		 * socket joins a multicast group, the Mblk for the in_multi		 * structure is duplicated for this new member. The Mblk		 * address for the in_multi is obtained by using a pointer		 * to the start of the Mblk. This pointer is located just		 * before the structure and is retrieved using DATA_TO_MBLK.		 * This poses a problem when there is more than one Mblk		 * accessing the in_multi structure (like in this case) since		 * Mblk information for the second Mblk is lost. To fix this		 * (SPR #67536), we use the mNextPkt field of the first Mblk		 * to store the Mblk address for the second Mblk. When the 		 * first Mblk is deleted (leaving group), the address of		 * second Mblk can be still be retrieved through the pointer.		 * Though this is not the best way to fix this problem, we		 * leave it this way since the entire design needs to be 		 * rethought (using the Mblk back-ptr is not a good idea).		 */                pInmFirstMblk = DATA_TO_MBLK (inm);                netMblkDup (pInmFirstMblk, pInmMblk);		pInmFirstMblk->mBlkHdr.mNextPkt = pInmMblk;		pInmMblk->mBlkHdr.mNextPkt = NULL;                ++inm->inm_refcount;	}	else {		/*		 * New address; allocate a new multicast record		 * and link it into the interface's multicast list.		 */	        MALLOC(inm, struct in_multi *, sizeof(*inm), MT_IPMADDR,                       M_DONTWAIT);                if (inm == NULL)                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_EMERGENCY, 12, 3,                              WV_NETEVENT_INADDMULT_NOBUFS, ifp, ap->s_addr)#endif  /* INCLUDE_WVNET */#endif                    goto inAddMultiError;                    }                pInmMblk = DATA_TO_MBLK (inm);		pInmMblk->mBlkHdr.mNextPkt = NULL;                bzero ((char *)inm, sizeof (*inm));  /* zero the structure */		inm->inm_addr = *ap;		inm->inm_ifp = ifp;		inm->inm_refcount = 1;                /* insert the multicast address into the hash table */                if (mcastHashTblInsert (inm) != OK)                    goto inAddMultiError;		/*		 * Ask the network driver to update its multicast reception		 * filter appropriately for the new address.		 */		((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;		((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;		if ((ifp->if_ioctl == NULL) ||		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {                	mcastHashTblDelete (inm);                        goto inAddMultiError;		}		/*		 * Let IGMP know that we have joined a new IP multicast group.		 */		if (_igmpJoinGrpHook != NULL)		    (*_igmpJoinGrpHook) (inm); 	}        /*         * insert the protocol control block into inm pcb list         * this is done to get to the list of pcbs which have joined a         * multicast group. When the hash table is looked up the inm         * returned should have a list of pcbs which the datagram         * should be delivered to. refer udp_usrreq.c where the pcb         * list is used.         */        if (pInPcb != NULL)            {            if ((pInPcbMblk = mBlkGet (_pNetSysPool, M_DONTWAIT, MT_PCB))                == NULL)                {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_EMERGENCY, 12, 3,                              WV_NETEVENT_INADDMULT_NOBUFS, ifp, ap->s_addr)#endif  /* INCLUDE_WVNET */#endif                goto inAddMultiError;                }            netMblkDup (DATA_TO_MBLK (pInPcb), pInPcbMblk);            pInPcbMblk->mBlkHdr.mNext = inm->pInPcbMblk;            inm->pInPcbMblk = pInPcbMblk;            }        	splx(s);	return (pInmMblk);	/* return the mBlk pointing to the inm */inAddMultiError:        splx (s);        if (pInmMblk)            m_free (pInmMblk);        return (NULL);}/* * Delete a multicast address record. * deletes all pcbs if pInPcb is NULL.  */intin_delmulti(pInmMblk, pInPcb)    	register struct mBlk * pInmMblk;	register struct inpcb * pInPcb;{	register struct in_multi *inm;        M_BLK_ID *		 ppMblk;        M_BLK_ID		 pInPcbMblk; 	struct mBlk **           ppInmMblk;	struct ifreq ifr;	int s = splnet();#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_VERBOSE, 22, 12,                      WV_NETEVENT_INDELMULT_START)#endif  /* INCLUDE_WVNET */#endif        inm = mtod (pInmMblk, struct in_multi *);        /* delete the pcb from the list */        ppMblk = &inm->pInPcbMblk;        if (pInPcb != NULL)            {            while ((pInPcbMblk = *ppMblk))                {                if (pInPcb == mtod (pInPcbMblk, struct inpcb *))                    {                    *ppMblk = (*ppMblk)->mBlkHdr.mNext;                    m_free (pInPcbMblk);                    break;		/* jump out of the while loop */                    }                ppMblk = &(*ppMblk)->mBlkHdr.mNext;                }            }        else if (inm->pInPcbMblk != NULL)            m_freem (inm->pInPcbMblk);	/* free up all pcbs */	if (--inm->inm_refcount == 0) {		/*		 * No remaining claims to this record; let IGMP know that		 * we are leaving the multicast group.		 */		if (_igmpLeaveGrpHook != NULL)		    (*_igmpLeaveGrpHook) (inm); 		/*		 * Notify the network driver to update its multicast reception		 * filter.		 */		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =								inm->inm_addr;		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,							     (caddr_t)&ifr);                /* time to delete entry from hash table */                mcastHashTblDelete (inm);	}        /*	 * If there is another socket listening to this group, replace	 * inm's back-ptr to its Mblk (currently that of socket leaving	 * the group) with the pointer to the Mblk of the other socket	 */        if ((inm != NULL) && (pInmMblk->mBlkHdr.mNextPkt != NULL))	    {	    ppInmMblk = (struct mbuf **)((char *)inm - sizeof (struct mbuf **));	    *ppInmMblk = pInmMblk->mBlkHdr.mNextPkt;	    (*ppInmMblk)->mBlkHdr.mNextPkt = NULL;	    }        /* free the mblk & inm, actual free only clRefCnt is 1 */        m_free (pInmMblk); 		splx(s);	return (OK);}/* * Return address info for specified internet network. */struct in_ifaddr *in_iaonnetof(net)	u_long net;{	register struct in_ifaddr *ia;#ifdef VIRTUAL_STACK	for (ia = _in_ifaddr; ia; ia = ia->ia_next)#else	for (ia = in_ifaddr; ia; ia = ia->ia_next)#endif /* VIRTUAL_STACK */		if (ia->ia_subnet == net)			return (ia);	return ((struct in_ifaddr *)0);}/* multicast hashing functions */void mcastHashInit ()    {    /* initialize the mcast hash table */    mCastHashInfo.hashBase =  hashinit (mCastHashTblSize,                                        MT_IPMADDR,                                        &mCastHashInfo.hashMask);    }STATUS mcastHashTblInsert    (    struct in_multi * 	pInMulti    )    {    IN_MULTI_HEAD * 	inMultiHead;    int 		s;     s = splnet();    inMultiHead = &mCastHashInfo.hashBase[MCAST_HASH(pInMulti->inm_addr.s_addr,                                                     pInMulti->inm_ifp,                                                     mCastHashInfo.hashMask)];    /* insert a multicast address structure into the hash table */    LIST_INSERT_HEAD(inMultiHead, pInMulti, inm_hash);        splx(s);    return (OK);     }STATUS mcastHashTblDelete    (    struct in_multi * pInMulti    )    {    int 		s;     s = splnet();    LIST_REMOVE(pInMulti, inm_hash);    splx(s);    return (OK);     }struct in_multi * mcastHashTblLookup    (    int			mcastAddr,	/* multicast Address always in NBO */    struct ifnet * 	pIf		/* interface pointer */    )    {    IN_MULTI_HEAD * 	inMultiHead;    IN_MULTI	* 	pInMulti;    int 		s;    s = splnet();    /* search a hash table for the appropriate multicast address tied to       a particular network interface     */    inMultiHead = &mCastHashInfo.hashBase[MCAST_HASH(mcastAddr, pIf,                                                     mCastHashInfo.hashMask)];    for (pInMulti = inMultiHead->lh_first; pInMulti != NULL;         pInMulti = pInMulti->inm_hash.le_next)        {        if (pInMulti->inm_addr.s_addr == mcastAddr &&            pInMulti->inm_ifp == pIf)            goto found;        }    splx(s);    return (NULL);    found:    /*     * Move IN_MULTI to head of this hash chain so that it can be     * found more quickly in the future.     * XXX - this is a pessimization on machines with few     * concurrent connections.     */    if (pInMulti != inMultiHead->lh_first)        {        LIST_REMOVE(pInMulti, inm_hash);        LIST_INSERT_HEAD(inMultiHead, pInMulti, inm_hash);        }    splx(s);    return (pInMulti);    }#endif

⌨️ 快捷键说明

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