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

📄 in.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
		in_ifscrub(ifp, ia);		/*		 * Protect from ipintr() traversing address list		 * while we're modifying it.		 */		s = splnet();		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)			ifp->if_addrlist = ifa->ifa_next;		else {			while (ifa->ifa_next &&			       (ifa->ifa_next != (struct ifaddr *)ia))				    ifa = ifa->ifa_next;			if (ifa->ifa_next)				ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;			else				printf("Couldn't unlink inifaddr from ifp\n");		}		oia = ia;		if (oia == (ia = in_ifaddr))			in_ifaddr = ia->ia_next;		else {			while (ia->ia_next && (ia->ia_next != oia))				ia = ia->ia_next;			if (ia->ia_next)				ia->ia_next = oia->ia_next;			else				printf("Didn't unlink inifadr from list\n");		}		if (!oia->ia_multiaddrs.lh_first) {			IFAFREE(&oia->ia_ifa);			FREE(mk, M_IPMADDR);			splx(s);			break;		}		/*		 * Multicast address kludge:		 * If there were any multicast addresses attached to this		 * interface address, either move them to another address		 * on this interface, or save them until such time as this		 * interface is reconfigured for IP.		 */		IFP_TO_IA(oia->ia_ifp, ia);		if (ia) {	/* there is another address */			struct in_multi *inm;			for(inm = oia->ia_multiaddrs.lh_first; inm;			    inm = inm->inm_entry.le_next) {				IFAFREE(&inm->inm_ia->ia_ifa);				ia->ia_ifa.ifa_refcnt++;				inm->inm_ia = ia;				LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm,						 inm_entry);			}			FREE(mk, M_IPMADDR);		} else {	/* last address on this if deleted, save */			struct in_multi *inm;			LIST_INIT(&mk->mk_head);			mk->mk_ifp = ifp;			for(inm = oia->ia_multiaddrs.lh_first; inm;			    inm = inm->inm_entry.le_next) {				LIST_INSERT_HEAD(&mk->mk_head, inm, inm_entry);			}			if (mk->mk_head.lh_first) {				LIST_INSERT_HEAD(&in_mk, mk, mk_entry);			} else {				FREE(mk, M_IPMADDR);			}		}		IFAFREE((&oia->ia_ifa));		splx(s);		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. */static 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. */static 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;	struct multi_kludge *mk;	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);	}	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;	LIST_INIT(&ia->ia_multiaddrs);	/*	 * If the interface supports multicast, join the "all hosts"	 * multicast group on that interface.	 */	if (ifp->if_flags & IFF_MULTICAST) {		struct in_addr addr;		/*		 * Continuation of multicast address hack:		 * If there was a multicast group list previously saved		 * for this interface, then we re-attach it to the first		 * address configured on the i/f.		 */		for(mk = in_mk.lh_first; mk; mk = mk->mk_entry.le_next) {			if(mk->mk_ifp == ifp) {				struct in_multi *inm;				for(inm = mk->mk_head.lh_first; inm;				    inm = inm->inm_entry.le_next) {					IFAFREE(&inm->inm_ia->ia_ifa);					ia->ia_ifa.ifa_refcnt++;					inm->inm_ia = ia;					LIST_INSERT_HEAD(&ia->ia_multiaddrs,							 inm, inm_entry);				}				LIST_REMOVE(mk, mk_entry);				free(mk, M_IPMADDR);				break;			}		}		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);		in_addmulti(&addr, ifp);	}	return (error);}/* * 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) &&		     /*		      * Check for an all one subnetmask. These		      * only exist when an interface gets a secondary		      * address.		      */		     ia->ia_subnetmask != (u_long)0xffffffff)			    return 1;	return (0);#undef ia}/* * Add an address to the list of IP multicast addresses for a given interface. */struct in_multi *in_addmulti(ap, ifp)	register struct in_addr *ap;	register struct ifnet *ifp;{	register struct in_multi *inm;	struct ifreq ifr;	struct in_ifaddr *ia;	int s = splnet();	/*	 * See if address already in list.	 */	IN_LOOKUP_MULTI(*ap, ifp, inm);	if (inm != NULL) {		/*		 * Found it; just increment the reference count.		 */		++inm->inm_refcount;	}	else {		/*		 * New address; allocate a new multicast record		 * and link it into the interface's multicast list.		 */		inm = (struct in_multi *)malloc(sizeof(*inm),		    M_IPMADDR, M_NOWAIT);		if (inm == NULL) {			splx(s);			return (NULL);		}		inm->inm_addr = *ap;		inm->inm_ifp = ifp;		inm->inm_refcount = 1;		IFP_TO_IA(ifp, ia);		if (ia == NULL) {			free(inm, M_IPMADDR);			splx(s);			return (NULL);		}		inm->inm_ia = ia;		ia->ia_ifa.ifa_refcnt++; /* gain a reference */		LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_entry);		/*		 * 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) {			LIST_REMOVE(inm, inm_entry);			IFAFREE(&ia->ia_ifa); /* release reference */			free(inm, M_IPMADDR);			splx(s);			return (NULL);		}		/*		 * Let IGMP know that we have joined a new IP multicast group.		 */		igmp_joingroup(inm);	}	splx(s);	return (inm);}/* * Delete a multicast address record. */voidin_delmulti(inm)	register struct in_multi *inm;{	struct ifreq ifr;	int s = splnet();	if (--inm->inm_refcount == 0) {		/*		 * No remaining claims to this record; let IGMP know that		 * we are leaving the multicast group.		 */		igmp_leavegroup(inm);		/*		 * Unlink from list.		 */		LIST_REMOVE(inm, inm_entry);		IFAFREE(&inm->inm_ia->ia_ifa); /* release reference */		/*		 * 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);		free(inm, M_IPMADDR);	}	splx(s);}

⌨️ 快捷键说明

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