struct ifaddr *ifa;
ipx_control(so, cmd, data, ifp)	struct socket *so;	u_long	cmd;	caddr_t	data;	register struct ifnet *ifp;{	register struct ifreq *ifr = (struct ifreq *)data;	register struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;	register struct ipx_ifaddr *ia;	struct ifaddr *ifa;	int dstIsNew, hostIsNew;	int error = 0;	/*	 * Find address for this interface, if it exists.	 */	if (ifp)		for (ia = ipx_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)			if (ia->ia_ifp == ifp)				break;	switch (cmd) {	case SIOCAIFADDR:	case SIOCDIFADDR:		if (ifra->ifra_addr.sipx_family == AF_IPX)			for (; ia; ia = ia->ia_list.tqe_next) {				if (ia->ia_ifp == ifp  &&				    ipx_neteq(ia->ia_addr.sipx_addr,					      ifra->ifra_addr.sipx_addr))					break;			}		if (cmd == SIOCDIFADDR && ia == 0)			return (EADDRNOTAVAIL);		/* FALLTHROUGH */	case SIOCSIFADDR:	case SIOCSIFDSTADDR:		if ((so->so_state & SS_PRIV) == 0)			return (EPERM);		if (ia == (struct ipx_ifaddr *)NULL) {			ia = (struct ipx_ifaddr *)				malloc(sizeof *ia, M_IFADDR, M_WAITOK);			if (ia == (struct ipx_ifaddr *)NULL)				return (ENOBUFS);			bzero((caddr_t)ia, sizeof(*ia));			TAILQ_INSERT_TAIL(&ifp->if_addrlist,				(struct ifaddr *)ia, ifa_list);			TAILQ_INSERT_TAIL(&ipx_ifaddr, ia, ia_list);			ia->ia_ifp = ifp;			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;			ia->ia_ifa.ifa_netmask =				(struct sockaddr *)&ipx_netmask;			ia->ia_ifa.ifa_dstaddr =				(struct sockaddr *)&ia->ia_dstaddr;			if (ifp->if_flags & IFF_BROADCAST) {				ia->ia_broadaddr.sipx_family = AF_IPX;				ia->ia_broadaddr.sipx_len = sizeof(ia->ia_addr);				ia->ia_broadaddr.sipx_addr.ipx_host = ipx_broadhost;			}			ipx_interfaces++;		}		break;	case SIOCSIFBRDADDR:		if ((so->so_state & SS_PRIV) == 0)			return (EPERM);		/* FALLTHROUGH */	case SIOCGIFADDR:	case SIOCGIFDSTADDR:	case SIOCGIFBRDADDR:		if (ia == (struct ipx_ifaddr *)NULL)			return (EADDRNOTAVAIL);		break;	}	switch (cmd) {	case SIOCGIFADDR:		*(struct sockaddr_ipx *)&ifr->ifr_addr = ia->ia_addr;		return (0);	case SIOCGIFBRDADDR:		if ((ifp->if_flags & IFF_BROADCAST) == 0)			return (EINVAL);		*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_broadaddr;		return (0);	case SIOCGIFDSTADDR:		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)			return (EINVAL);		*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_dstaddr;		return (0);	case SIOCSIFDSTADDR:		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)			return (EINVAL);		if (ia->ia_flags & IFA_ROUTE) {			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);			ia->ia_flags &= ~IFA_ROUTE;		}		if (ifp->if_ioctl) {			error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (void *)ia);			if (error)				return (error);		}		*(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr;		return (0);	case SIOCSIFADDR:		return (ipx_ifinit(ifp, ia,				(struct sockaddr_ipx *)&ifr->ifr_addr, 1));	case SIOCDIFADDR:		ipx_ifscrub(ifp, ia);		TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);		TAILQ_REMOVE(&ipx_ifaddr, ia, ia_list);		IFAFREE((&ia->ia_ifa));		if (0 == --ipx_interfaces) {			/*			 * We reset to virginity and start all over again			 */			ipx_thishost = ipx_zerohost;		}		return (0);		case SIOCAIFADDR:		dstIsNew = 0; hostIsNew = 1;		if (ia->ia_addr.sipx_family == AF_IPX) {			if (ifra->ifra_addr.sipx_len == 0) {				ifra->ifra_addr = ia->ia_addr;				hostIsNew = 0;			} else if (ipx_neteq(ifra->ifra_addr.sipx_addr,					 ia->ia_addr.sipx_addr))				hostIsNew = 0;		}		if ((ifp->if_flags & IFF_POINTOPOINT) &&		    (ifra->ifra_dstaddr.sipx_family == AF_IPX)) {			if (hostIsNew == 0)				ipx_ifscrub(ifp, ia);			ia->ia_dstaddr = ifra->ifra_dstaddr;			dstIsNew  = 1;		}		if (ifra->ifra_addr.sipx_family == AF_IPX &&					    (hostIsNew || dstIsNew))			error = ipx_ifinit(ifp, ia, &ifra->ifra_addr, 0);		return (error);	default:		if (ifp->if_ioctl == 0)			return (EOPNOTSUPP);		return ((*ifp->if_ioctl)(ifp, cmd, data));	}}