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

📄 in.c

📁 vxworks下的实现网络TCPIP协议的原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				logMsg("Didn't unlink inifadr from list\n",				       0,0,0,0,0,0);		}		IFAFREE((&oia->ia_ifa));		break;	default:		if (ifp == 0 || ifp->if_ioctl == 0)			return (EOPNOTSUPP);		return ((*ifp->if_ioctl)(ifp, cmd, data));	}	return (0);}/* * Delete any existing route for an interface. */voidin_ifscrub(ifp, ia)	register struct ifnet *ifp;	register struct in_ifaddr *ia;{	if ((ia->ia_flags & IFA_ROUTE) == 0)		return;	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);	else		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);	ia->ia_flags &= ~IFA_ROUTE;}/* * Initialize an interface's internet address * and routing table entry. */intin_ifinit(ifp, ia, sin, scrub)	register struct ifnet *ifp;	register struct in_ifaddr *ia;	struct sockaddr_in *sin;	int scrub;{	register u_long i = ntohl(sin->sin_addr.s_addr);	struct sockaddr_in oldaddr;	int s = splimp(), flags = RTF_UP, error, ether_output();	oldaddr = ia->ia_addr;	ia->ia_addr = *sin;	/*	 * Give the interface a chance to initialize	 * if this is its first address,	 * and to validate the address if necessary.	 */	if (ifp->if_ioctl &&	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {		splx(s);		ia->ia_addr = oldaddr;		return (error);	}	if (ifp->if_output == ether_output) { /* XXX: Another Kludge */		ia->ia_ifa.ifa_rtrequest = arp_rtrequest;		ia->ia_ifa.ifa_flags |= RTF_CLONING;	}	splx(s);	if (scrub) {		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;		in_ifscrub(ifp, ia);		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;	}	if (IN_CLASSA(i))		ia->ia_netmask = IN_CLASSA_NET;	else if (IN_CLASSB(i))		ia->ia_netmask = IN_CLASSB_NET;	else		ia->ia_netmask = IN_CLASSC_NET;	/*	 * The subnet mask usually includes at least the standard network part,	 * but may may be smaller in the case of supernetting.	 * If it is set, we believe it.	 */	if (ia->ia_subnetmask == 0) {		ia->ia_subnetmask = ia->ia_netmask;		ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);	} else		ia->ia_netmask &= ia->ia_subnetmask;	ia->ia_net = i & ia->ia_netmask;	ia->ia_subnet = i & ia->ia_subnetmask;	in_socktrim(&ia->ia_sockmask);	/*	 * Add route for the network.	 */	ia->ia_ifa.ifa_metric = ifp->if_metric;	if (ifp->if_flags & IFF_BROADCAST) {		ia->ia_broadaddr.sin_addr.s_addr =			htonl(ia->ia_subnet | ~ia->ia_subnetmask);		ia->ia_netbroadcast.s_addr =			htonl(ia->ia_net | ~ ia->ia_netmask);	} else if (ifp->if_flags & IFF_LOOPBACK) {		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;		flags |= RTF_HOST;	} else if (ifp->if_flags & IFF_POINTOPOINT) {		if (ia->ia_dstaddr.sin_family != AF_INET)			return (0);		flags |= RTF_HOST;	}	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)		ia->ia_flags |= IFA_ROUTE;	/*	 * If the interface supports multicast, join the "all hosts"	 * multicast group on that interface.	 */	if ( ifp->if_flags & IFF_MULTICAST ) {		struct in_addr addr;		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);                in_addmulti (&addr, ifp, NULL);                 ifp->pInmMblk = NULL;	}	return (error);}/********************************************************************************* in_ifaddr_remove - remove an interface from the in_ifaddr list** This function removes the internet interface address given as an input* parameter, from the global linked-list of internet interface addresses* pointed by in_ifaddr. This function is called before dettaching an interface* This function also removes all the internet multicast addresses hooked to * the in_ifaddr. It calls in_delmulti() which in turn calls the ioctl for the* driver to remove the ethernet multicast addresses.* * NOMANUAL* * RETURNS: N/A*/ void in_ifaddr_remove     (    struct ifaddr * pIfAddr		/* pointer to interface address */    )     {    struct in_ifaddr ** pPtrInIfAddr; 	/* pointer to pointer to in_ifaddr */    struct in_ifaddr *  pInIfAddr; 	/* pointer to in_ifaddr */     pPtrInIfAddr = &in_ifaddr; 		/* global variable */    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;	int s = splnet();	/*	 * See if address already in list.	 */	IN_LOOKUP_MULTI(*ap, ifp, inm);	if (inm != NULL) {#if 0		/*		 * Found it; duplicate the mBlk, increment reference count.		 */        	if ((pInmMblk = mBlkGet (_pNetSysPool, M_DONTWAIT, MT_IPMADDR))                    == NULL)                    goto inAddMultiError;                netMblkDup (DATA_TO_MBLK (inm), pInmMblk);#endif                ++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)                    goto inAddMultiError;                pInmMblk = DATA_TO_MBLK (inm);                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)                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 ifreq ifr;	int s = splnet();        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);	}        /* 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;	for (ia = in_ifaddr; ia; ia = ia->ia_next)		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 + -