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

📄 iso.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
				return (ENOBUFS);			bzero((caddr_t)nia, sizeof(*nia));			if (ia = iso_ifaddr) {				for ( ; ia->ia_next; ia = ia->ia_next)					;				ia->ia_next = nia;			} else				iso_ifaddr = nia;			ia = nia;			if (ifa = ifp->if_addrlist) {				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)					;				ifa->ifa_next = (struct ifaddr *) ia;			} else				ifp->if_addrlist = (struct ifaddr *) ia;			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;			ia->ia_ifa.ifa_dstaddr					= (struct sockaddr *)&ia->ia_dstaddr;			ia->ia_ifa.ifa_netmask					= (struct sockaddr *)&ia->ia_sockmask;			ia->ia_ifp = ifp;			if (ifp != &loif)				iso_interfaces++;		}		break;#define cmdbyte(x)	(((x) >> 8) & 0xff)	default:		if (cmdbyte(cmd) == 'a')			return (snpac_ioctl(so, cmd, data));		if (ia == (struct iso_ifaddr *)0)			return (EADDRNOTAVAIL);		break;	}	switch (cmd) {	case SIOCGIFADDR_ISO:		ifr->ifr_Addr = ia->ia_addr;		break;	case SIOCGIFDSTADDR_ISO:		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)			return (EINVAL);		ifr->ifr_Addr = ia->ia_dstaddr;		break;	case SIOCGIFNETMASK_ISO:		ifr->ifr_Addr = ia->ia_sockmask;		break;	case SIOCAIFADDR_ISO:		maskIsNew = 0; hostIsNew = 1; error = 0;		if (ia->ia_addr.siso_family == AF_ISO) {			if (ifra->ifra_addr.siso_len == 0) {				ifra->ifra_addr = ia->ia_addr;				hostIsNew = 0;			} else if (SAME_ISOADDR(&ia->ia_addr, &ifra->ifra_addr))				hostIsNew = 0;		}		if (ifra->ifra_mask.siso_len) {			iso_ifscrub(ifp, ia);			ia->ia_sockmask = ifra->ifra_mask;			maskIsNew = 1;		}		if ((ifp->if_flags & IFF_POINTOPOINT) &&		    (ifra->ifra_dstaddr.siso_family == AF_ISO)) {			iso_ifscrub(ifp, ia);			ia->ia_dstaddr = ifra->ifra_dstaddr;			maskIsNew  = 1; /* We lie; but the effect's the same */		}		if (ifra->ifra_addr.siso_family == AF_ISO &&					    (hostIsNew || maskIsNew)) {			error = iso_ifinit(ifp, ia, &ifra->ifra_addr, 0);		}		if (ifra->ifra_snpaoffset)			ia->ia_snpaoffset = ifra->ifra_snpaoffset;		return (error);	case SIOCDIFADDR_ISO:		iso_ifscrub(ifp, ia);		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 isoifaddr from ifp\n");		}		oia = ia;		if (oia == (ia = iso_ifaddr)) {			iso_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 isoifadr from list\n");		}		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. */iso_ifscrub(ifp, ia)	register struct ifnet *ifp;	register struct iso_ifaddr *ia;{	int nsellength = ia->ia_addr.siso_tlen;	if ((ia->ia_flags & IFA_ROUTE) == 0)		return;	ia->ia_addr.siso_tlen = 0;	if (ifp->if_flags & IFF_LOOPBACK)		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);	else if (ifp->if_flags & IFF_POINTOPOINT)		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);	else {		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);	}	ia->ia_addr.siso_tlen = nsellength;	ia->ia_flags &= ~IFA_ROUTE;}/* * Initialize an interface's internet address * and routing table entry. */iso_ifinit(ifp, ia, siso, scrub)	register struct ifnet *ifp;	register struct iso_ifaddr *ia;	struct sockaddr_iso *siso;{	struct sockaddr_iso oldaddr;	int s = splimp(), error, nsellength;	oldaddr = ia->ia_addr;	ia->ia_addr = *siso;	/*	 * 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 (scrub) {		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;		iso_ifscrub(ifp, ia);		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;	}	/* XXX -- The following is here temporarily out of laziness	   in not changing every ethernet driver's if_ioctl routine */	if (ifp->if_output == ether_output) {		ia->ia_ifa.ifa_rtrequest = llc_rtrequest;		ia->ia_ifa.ifa_flags |= RTF_CLONING;	}	/*	 * Add route for the network.	 */	nsellength = ia->ia_addr.siso_tlen;	ia->ia_addr.siso_tlen = 0;	if (ifp->if_flags & IFF_LOOPBACK) {		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;		error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);	} else if (ifp->if_flags & IFF_POINTOPOINT &&		 ia->ia_dstaddr.siso_family == AF_ISO)		error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);	else {		rt_maskedcopy(ia->ia_ifa.ifa_addr, ia->ia_ifa.ifa_dstaddr,			ia->ia_ifa.ifa_netmask);		ia->ia_dstaddr.siso_nlen =			min(ia->ia_addr.siso_nlen, (ia->ia_sockmask.siso_len - 6));		error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);	}	ia->ia_addr.siso_tlen = nsellength;	ia->ia_flags |= IFA_ROUTE;	splx(s);	return (error);}#ifdef notdefstruct ifaddr *iso_ifwithidi(addr)	register struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	register u_int af = addr->sa_family;	if (af != AF_ISO)		return (0);	IFDEBUG(D_ROUTE)		printf(">>> iso_ifwithidi addr\n");		dump_isoaddr( (struct sockaddr_iso *)(addr));		printf("\n");	ENDDEBUG	for (ifp = ifnet; ifp; ifp = ifp->if_next) {		IFDEBUG(D_ROUTE)			printf("iso_ifwithidi ifnet %s\n", ifp->if_name);		ENDDEBUG		for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {			IFDEBUG(D_ROUTE)				printf("iso_ifwithidi address ");				dump_isoaddr( (struct sockaddr_iso *)(ifa->ifa_addr));			ENDDEBUG			if (ifa->ifa_addr->sa_family != addr->sa_family)				continue;#define	IFA_SIS(ifa)\	((struct sockaddr_iso *)((ifa)->ifa_addr))			IFDEBUG(D_ROUTE)				printf(" af same, args to iso_eqtype:\n");				printf("0x%x ", IFA_SIS(ifa)->siso_addr);				printf(" 0x%x\n",				&(((struct sockaddr_iso *)addr)->siso_addr));			ENDDEBUG			if (iso_eqtype(&(IFA_SIS(ifa)->siso_addr), 				&(((struct sockaddr_iso *)addr)->siso_addr))) {				IFDEBUG(D_ROUTE)					printf("ifa_ifwithidi: ifa found\n");				ENDDEBUG				return (ifa);			}			IFDEBUG(D_ROUTE)				printf(" iso_eqtype failed\n");			ENDDEBUG		}	}	return ((struct ifaddr *)0);}#endif /* notdef *//* * FUNCTION:		iso_ck_addr * * PURPOSE:			return true if the iso_addr passed is  *					within the legal size limit for an iso address. * * RETURNS:			true or false * * SIDE EFFECTS:	 * */iso_ck_addr(isoa)struct iso_addr	*isoa;	/* address to check */{	return (isoa->isoa_len <= 20);}#ifdef notdef/* * FUNCTION:		iso_eqtype * * PURPOSE:			Determine if two iso addresses are of the same type. *  This is flaky.  Really we should consider all type 47 addrs to be the *  same - but there do exist different structures for 47 addrs. *  Gosip adds a 3rd. * * RETURNS:			true if the addresses are the same type * * SIDE EFFECTS:	 * * NOTES:			By type, I mean rfc986, t37, or osinet * *					This will first compare afis. If they match, then *					if the addr is not t37, the idis must be compared. */iso_eqtype(isoaa, isoab)struct iso_addr	*isoaa;		/* first addr to check */struct iso_addr	*isoab;		/* other addr to check */{	if (isoaa->isoa_afi == isoab->isoa_afi) {		if (isoaa->isoa_afi == AFI_37)			return(1);		else 			return (!bcmp(&isoaa->isoa_u, &isoab->isoa_u, 2));	}	return(0);}#endif /* notdef *//* * FUNCTION:		iso_localifa() * * PURPOSE:			Find an interface addresss having a given destination *					or at least matching the net. * * RETURNS:			ptr to an interface address  * * SIDE EFFECTS:	 * * NOTES:			 */struct iso_ifaddr *iso_localifa(siso)	register struct sockaddr_iso *siso;{	register struct iso_ifaddr *ia;	register char *cp1, *cp2, *cp3;	register struct ifnet *ifp;	struct iso_ifaddr *ia_maybe = 0;	/*	 * We make one pass looking for both net matches and an exact	 * dst addr.	 */	for (ia = iso_ifaddr; ia; ia = ia->ia_next) {		if ((ifp = ia->ia_ifp) == 0 || ((ifp->if_flags & IFF_UP) == 0))			continue;		if (ifp->if_flags & IFF_POINTOPOINT) {			if ((ia->ia_dstaddr.siso_family == AF_ISO) &&				SAME_ISOADDR(&ia->ia_dstaddr, siso))				return (ia);			else				if (SAME_ISOADDR(&ia->ia_addr, siso))					ia_maybe = ia;			continue;		}		if (ia->ia_sockmask.siso_len) {			char *cplim = ia->ia_sockmask.siso_len + (char *)&ia->ia_sockmask;			cp1 = ia->ia_sockmask.siso_data;			cp2 = siso->siso_data;			cp3 = ia->ia_addr.siso_data;			while (cp1 < cplim)				if (*cp1++ & (*cp2++ ^ *cp3++))					goto next;			ia_maybe = ia;		}		if (SAME_ISOADDR(&ia->ia_addr, siso))			return ia;	next:;	}	return ia_maybe;}#ifdef	TPCONS#include <netiso/cons.h>#endif	/* TPCONS *//* * FUNCTION:		iso_nlctloutput * * PURPOSE:			Set options at the network level * * RETURNS:			E* * * SIDE EFFECTS:	 * * NOTES:			This could embody some of the functions of *					rclnp_ctloutput and cons_ctloutput. */iso_nlctloutput(cmd, optname, pcb, m)int			cmd;		/* command:set or get */int			optname;	/* option of interest */caddr_t		pcb;		/* nl pcb */struct mbuf	*m;			/* data for set, buffer for get */{	struct isopcb	*isop = (struct isopcb *)pcb;	int				error = 0;	/* return value */	caddr_t			data;		/* data for option */	int				data_len;	/* data's length */	IFDEBUG(D_ISO)		printf("iso_nlctloutput: cmd %x, opt %x, pcb %x, m %x\n",			cmd, optname, pcb, m);	ENDDEBUG	if ((cmd != PRCO_GETOPT) && (cmd != PRCO_SETOPT))		return(EOPNOTSUPP);	data = mtod(m, caddr_t);	data_len = (m)->m_len;	IFDEBUG(D_ISO)		printf("iso_nlctloutput: data is:\n");		dump_buf(data, data_len);	ENDDEBUG	switch (optname) {#ifdef	TPCONS		case CONSOPT_X25CRUD:			if (cmd == PRCO_GETOPT) {				error = EOPNOTSUPP;				break;			}			if (data_len > MAXX25CRUDLEN) {				error = EINVAL;				break;			}			IFDEBUG(D_ISO)				printf("iso_nlctloutput: setting x25 crud\n");			ENDDEBUG			bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);			isop->isop_x25crud_len = data_len;			break;#endif	/* TPCONS */		default:			error = EOPNOTSUPP;	}	if (cmd == PRCO_SETOPT)		m_freem(m);	return error;}#endif /* ISO */#ifdef ARGO_DEBUG/* * FUNCTION:		dump_isoaddr * * PURPOSE:			debugging * * RETURNS:			nada  * */dump_isoaddr(s)	struct sockaddr_iso *s;{	char *clnp_saddr_isop();	register int i;	if( s->siso_family == AF_ISO) {		printf("ISO address: suffixlen %d, %s\n",			s->siso_tlen, clnp_saddr_isop(s));	} else if( s->siso_family == AF_INET) {		/* hack */		struct sockaddr_in *sin = (struct sockaddr_in *)s;		printf("%d.%d.%d.%d: %d", 			(sin->sin_addr.s_addr>>24)&0xff,			(sin->sin_addr.s_addr>>16)&0xff,			(sin->sin_addr.s_addr>>8)&0xff,			(sin->sin_addr.s_addr)&0xff,			sin->sin_port);	}}#endif /* ARGO_DEBUG */

⌨️ 快捷键说明

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