1139823Simp/*- 211819Sjulian * Copyright (c) 1984, 1985, 1986, 1987, 1993 3194610Srwatson * The Regents of the University of California. 4194610Srwatson * Copyright (c) 2009 Robert N. M. Watson 5194610Srwatson * All rights reserved. 611819Sjulian * 711819Sjulian * Redistribution and use in source and binary forms, with or without 811819Sjulian * modification, are permitted provided that the following conditions 911819Sjulian * are met: 1011819Sjulian * 1. Redistributions of source code must retain the above copyright 1111819Sjulian * notice, this list of conditions and the following disclaimer. 1211819Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1311819Sjulian * notice, this list of conditions and the following disclaimer in the 1411819Sjulian * documentation and/or other materials provided with the distribution. 15165899Srwatson * 4. Neither the name of the University nor the names of its contributors 16165899Srwatson * may be used to endorse or promote products derived from this software 17165899Srwatson * without specific prior written permission. 18165899Srwatson * 19165899Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20165899Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21165899Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22165899Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23165899Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24165899Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25165899Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26165899Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27165899Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28165899Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29165899Srwatson * SUCH DAMAGE. 30165899Srwatson * 31165899Srwatson * Copyright (c) 1995, Mike Mitchell 32165899Srwatson * 33165899Srwatson * Redistribution and use in source and binary forms, with or without 34165899Srwatson * modification, are permitted provided that the following conditions 35165899Srwatson * are met: 36165899Srwatson * 1. Redistributions of source code must retain the above copyright 37165899Srwatson * notice, this list of conditions and the following disclaimer. 38165899Srwatson * 2. Redistributions in binary form must reproduce the above copyright 39165899Srwatson * notice, this list of conditions and the following disclaimer in the 40165899Srwatson * documentation and/or other materials provided with the distribution. 4111819Sjulian * 3. All advertising materials mentioning features or use of this software 4211819Sjulian * must display the following acknowledgement: 4311819Sjulian * This product includes software developed by the University of 4411819Sjulian * California, Berkeley and its contributors. 4511819Sjulian * 4. Neither the name of the University nor the names of its contributors 4611819Sjulian * may be used to endorse or promote products derived from this software 4711819Sjulian * without specific prior written permission. 4811819Sjulian * 4911819Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5011819Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5111819Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5211819Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 5311819Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5411819Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5511819Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5611819Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5711819Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5811819Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5911819Sjulian * SUCH DAMAGE. 60139584Srwatson * 6112057Sjulian * @(#)ipx.c 6211819Sjulian */ 6311819Sjulian 64116189Sobrien#include <sys/cdefs.h> 65116189Sobrien__FBSDID("$FreeBSD: releng/10.2/sys/netipx/ipx.c 229621 2012-01-05 19:00:36Z jhb $"); 66116189Sobrien 6711819Sjulian#include <sys/param.h> 68134445Srwatson#include <sys/kernel.h> 6911819Sjulian#include <sys/systm.h> 70194608Srwatson#include <sys/lock.h> 7126965Sjhay#include <sys/malloc.h> 72170689Srwatson#include <sys/priv.h> 73194608Srwatson#include <sys/rwlock.h> 7424204Sbde#include <sys/sockio.h> 7511819Sjulian#include <sys/socket.h> 7611819Sjulian 7711819Sjulian#include <net/if.h> 7811819Sjulian#include <net/route.h> 7911819Sjulian 8011819Sjulian#include <netipx/ipx.h> 8111819Sjulian#include <netipx/ipx_if.h> 8225652Sjhay#include <netipx/ipx_var.h> 8311819Sjulian 84134445Srwatson/* 85194608Srwatson * The IPX-layer address list is protected by ipx_ifaddr_rw. 86134445Srwatson */ 87194608Srwatsonstruct rwlock ipx_ifaddr_rw; 88194905Srwatsonstruct ipx_ifaddrhead ipx_ifaddrhead; 8911819Sjulian 90194595Srwatsonstatic void ipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia); 91194595Srwatsonstatic int ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia, 92194595Srwatson struct sockaddr_ipx *sipx, int scrub); 9325652Sjhay 9411819Sjulian/* 9511819Sjulian * Generic internet control operations (ioctl's). 9611819Sjulian */ 9711819Sjulianint 98169463Srwatsonipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, 99169463Srwatson struct thread *td) 10011819Sjulian{ 101169463Srwatson struct ifreq *ifr = (struct ifreq *)data; 102169463Srwatson struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data; 103194905Srwatson struct ipx_ifaddr *ia; 10411819Sjulian struct ifaddr *ifa; 10511819Sjulian int dstIsNew, hostIsNew; 106194857Srwatson int error, priv; 10711819Sjulian 10811819Sjulian /* 10911819Sjulian * Find address for this interface, if it exists. 11011819Sjulian */ 11125652Sjhay if (ifp == NULL) 11211819Sjulian return (EADDRNOTAVAIL); 113194610Srwatson 114194857Srwatson IPX_IFADDR_RLOCK(); 115194905Srwatson TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { 11611819Sjulian if (ia->ia_ifp == ifp) 11711819Sjulian break; 118194905Srwatson } 119194857Srwatson if (ia != NULL) 120194857Srwatson ifa_ref(&ia->ia_ifa); 121194857Srwatson IPX_IFADDR_RUNLOCK(); 12211819Sjulian 123194857Srwatson error = 0; 12411819Sjulian switch (cmd) { 12511819Sjulian case SIOCGIFADDR: 126194610Srwatson if (ia == NULL) { 127194610Srwatson error = EADDRNOTAVAIL; 128194610Srwatson goto out; 129194610Srwatson } 13011819Sjulian *(struct sockaddr_ipx *)&ifr->ifr_addr = ia->ia_addr; 131194610Srwatson goto out; 13211819Sjulian 13311819Sjulian case SIOCGIFBRDADDR: 134194610Srwatson if (ia == NULL) { 135194610Srwatson error = EADDRNOTAVAIL; 136194610Srwatson goto out; 137194610Srwatson } 138194610Srwatson if ((ifp->if_flags & IFF_BROADCAST) == 0) { 139194610Srwatson error = EINVAL; 140194610Srwatson goto out; 141194610Srwatson } 14211819Sjulian *(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_broadaddr; 143194610Srwatson goto out; 14411819Sjulian 14511819Sjulian case SIOCGIFDSTADDR: 146194610Srwatson if (ia == NULL) { 147194610Srwatson error = EADDRNOTAVAIL; 148194610Srwatson goto out; 149194610Srwatson } 150194610Srwatson if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 151194610Srwatson error = EINVAL; 152194610Srwatson goto out; 153194610Srwatson } 15411819Sjulian *(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_dstaddr; 155194610Srwatson goto out; 15611819Sjulian } 15711819Sjulian 15811819Sjulian switch (cmd) { 15911819Sjulian case SIOCAIFADDR: 16011819Sjulian case SIOCDIFADDR: 161183113Sattilio priv = (cmd == SIOCAIFADDR) ? PRIV_NET_ADDIFADDR : 162183113Sattilio PRIV_NET_DELIFADDR; 163183113Sattilio if (td && (error = priv_check(td, priv)) != 0) 164194610Srwatson goto out; 165194857Srwatson 166194857Srwatson IPX_IFADDR_RLOCK(); 167194857Srwatson if (ifra->ifra_addr.sipx_family == AF_IPX) { 168194905Srwatson struct ipx_ifaddr *oia; 169194905Srwatson 170194905Srwatson for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) { 171194857Srwatson if (ia->ia_ifp == ifp && 172194857Srwatson ipx_neteq(ia->ia_addr.sipx_addr, 173194857Srwatson ifra->ifra_addr.sipx_addr)) 174194857Srwatson break; 175194857Srwatson } 176194857Srwatson if (oia != NULL && oia != ia) 177194857Srwatson ifa_free(&oia->ia_ifa); 178194857Srwatson if (ia != NULL && oia != ia) 179194857Srwatson ifa_ref(&ia->ia_ifa); 180194857Srwatson } 181194857Srwatson IPX_IFADDR_RUNLOCK(); 182194610Srwatson if (cmd == SIOCDIFADDR && ia == NULL) { 183194610Srwatson error = EADDRNOTAVAIL; 184194610Srwatson goto out; 185194610Srwatson } 18611819Sjulian /* FALLTHROUGH */ 18711819Sjulian 18811819Sjulian case SIOCSIFADDR: 18911819Sjulian case SIOCSIFDSTADDR: 190183113Sattilio if (td && (error = priv_check(td, PRIV_NET_SETLLADDR)) != 0) 191194610Srwatson goto out; 19225652Sjhay if (ia == NULL) { 193194857Srwatson ia = malloc(sizeof(*ia), M_IFADDR, M_NOWAIT | M_ZERO); 194194857Srwatson if (ia == NULL) { 195194610Srwatson error = ENOBUFS; 196194610Srwatson goto out; 197194610Srwatson } 19820407Swollman ifa = (struct ifaddr *)ia; 199194602Srwatson ifa_init(ifa); 20011819Sjulian ia->ia_ifp = ifp; 20120407Swollman ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; 20220407Swollman ifa->ifa_netmask = (struct sockaddr *)&ipx_netmask; 20320407Swollman ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 20411819Sjulian if (ifp->if_flags & IFF_BROADCAST) { 20511819Sjulian ia->ia_broadaddr.sipx_family = AF_IPX; 206194595Srwatson ia->ia_broadaddr.sipx_len = 207194595Srwatson sizeof(ia->ia_addr); 208194595Srwatson ia->ia_broadaddr.sipx_addr.x_host = 209194595Srwatson ipx_broadhost; 21011819Sjulian } 211194905Srwatson ifa_ref(&ia->ia_ifa); /* ipx_ifaddrhead */ 212194857Srwatson IPX_IFADDR_WLOCK(); 213194905Srwatson TAILQ_INSERT_TAIL(&ipx_ifaddrhead, ia, ia_link); 214194857Srwatson IPX_IFADDR_WUNLOCK(); 215194857Srwatson 216194857Srwatson ifa_ref(&ia->ia_ifa); /* if_addrhead */ 217229621Sjhb IF_ADDR_WLOCK(ifp); 218194606Srwatson TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); 219229621Sjhb IF_ADDR_WUNLOCK(ifp); 22011819Sjulian } 221183113Sattilio break; 222194595Srwatson 223183113Sattilio default: 224183113Sattilio if (td && (error = priv_check(td, PRIV_NET_HWIOCTL)) != 0) 225194610Srwatson goto out; 22611819Sjulian } 22711819Sjulian 22811819Sjulian switch (cmd) { 22911819Sjulian case SIOCSIFDSTADDR: 230194610Srwatson if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 231194610Srwatson error = EINVAL; 232194610Srwatson goto out; 233194610Srwatson } 23411819Sjulian if (ia->ia_flags & IFA_ROUTE) { 23511819Sjulian rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 23611819Sjulian ia->ia_flags &= ~IFA_ROUTE; 23711819Sjulian } 23811819Sjulian if (ifp->if_ioctl) { 239194595Srwatson error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, 240194595Srwatson (void *)ia); 241194857Srwatson if (error) 242194857Srwatson goto out; 24311819Sjulian } 24411819Sjulian *(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr; 245194857Srwatson goto out; 24611819Sjulian 24711819Sjulian case SIOCSIFADDR: 248194610Srwatson error = ipx_ifinit(ifp, ia, 249194610Srwatson (struct sockaddr_ipx *)&ifr->ifr_addr, 1); 250194857Srwatson goto out; 25111819Sjulian 25211819Sjulian case SIOCDIFADDR: 25311819Sjulian ipx_ifscrub(ifp, ia); 25420407Swollman ifa = (struct ifaddr *)ia; 255194857Srwatson 256229621Sjhb IF_ADDR_WLOCK(ifp); 25720407Swollman TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); 258229621Sjhb IF_ADDR_WUNLOCK(ifp); 259194857Srwatson ifa_free(ifa); /* if_addrhead */ 260194857Srwatson 261194857Srwatson IPX_IFADDR_WLOCK(); 262194905Srwatson TAILQ_REMOVE(&ipx_ifaddrhead, ia, ia_link); 263194610Srwatson IPX_IFADDR_WUNLOCK(); 264194905Srwatson ifa_free(&ia->ia_ifa); /* ipx_ifaddrhead */ 265194857Srwatson goto out; 266139584Srwatson 26711819Sjulian case SIOCAIFADDR: 26825652Sjhay dstIsNew = 0; 26925652Sjhay hostIsNew = 1; 27011819Sjulian if (ia->ia_addr.sipx_family == AF_IPX) { 27111819Sjulian if (ifra->ifra_addr.sipx_len == 0) { 27211819Sjulian ifra->ifra_addr = ia->ia_addr; 27311819Sjulian hostIsNew = 0; 27411819Sjulian } else if (ipx_neteq(ifra->ifra_addr.sipx_addr, 27511819Sjulian ia->ia_addr.sipx_addr)) 27611819Sjulian hostIsNew = 0; 27711819Sjulian } 27811819Sjulian if ((ifp->if_flags & IFF_POINTOPOINT) && 27911819Sjulian (ifra->ifra_dstaddr.sipx_family == AF_IPX)) { 28011819Sjulian if (hostIsNew == 0) 28111819Sjulian ipx_ifscrub(ifp, ia); 28211819Sjulian ia->ia_dstaddr = ifra->ifra_dstaddr; 28311819Sjulian dstIsNew = 1; 28411819Sjulian } 28511819Sjulian if (ifra->ifra_addr.sipx_family == AF_IPX && 28611819Sjulian (hostIsNew || dstIsNew)) 28711819Sjulian error = ipx_ifinit(ifp, ia, &ifra->ifra_addr, 0); 288194857Srwatson goto out; 28911819Sjulian 29011819Sjulian default: 291194857Srwatson if (ifp->if_ioctl == NULL) { 292194857Srwatson error = EOPNOTSUPP; 293194857Srwatson goto out; 294194857Srwatson } 295194857Srwatson error = ((*ifp->if_ioctl)(ifp, cmd, data)); 29611819Sjulian } 297194610Srwatson 298194610Srwatsonout: 299194857Srwatson if (ia != NULL) 300194857Srwatson ifa_free(&ia->ia_ifa); 301194610Srwatson return (error); 30211819Sjulian} 30311819Sjulian 30411819Sjulian/* 305194595Srwatson * Delete any previous route for an old address. 306194595Srwatson */ 30725652Sjhaystatic void 308169463Srwatsonipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia) 30911819Sjulian{ 310169463Srwatson 31111819Sjulian if (ia->ia_flags & IFA_ROUTE) { 31211819Sjulian if (ifp->if_flags & IFF_POINTOPOINT) { 31311819Sjulian rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 31411819Sjulian } else 31511819Sjulian rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 31611819Sjulian ia->ia_flags &= ~IFA_ROUTE; 31711819Sjulian } 31811819Sjulian} 319194595Srwatson 32011819Sjulian/* 321194595Srwatson * Initialize an interface's internet address and routing table entry. 32211819Sjulian */ 32325652Sjhaystatic int 324169463Srwatsonipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia, 325169463Srwatson struct sockaddr_ipx *sipx, int scrub) 32611819Sjulian{ 32711819Sjulian struct sockaddr_ipx oldaddr; 32811819Sjulian int s = splimp(), error; 32911819Sjulian 33011819Sjulian /* 33111819Sjulian * Set up new addresses. 33211819Sjulian */ 33311819Sjulian oldaddr = ia->ia_addr; 33411819Sjulian ia->ia_addr = *sipx; 33525652Sjhay 33611819Sjulian /* 337194595Srwatson * The convention we shall adopt for naming is that a supplied 338194595Srwatson * address of zero means that "we don't care". Use the MAC address 339194595Srwatson * of the interface. If it is an interface without a MAC address, 340194595Srwatson * like a serial line, the address must be supplied. 34111819Sjulian * 342194595Srwatson * Give the interface a chance to initialize if this is its first 343194595Srwatson * address, and to validate the address if necessary. 34411819Sjulian */ 34525652Sjhay if (ifp->if_ioctl != NULL && 34625652Sjhay (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (void *)ia))) { 34711819Sjulian ia->ia_addr = oldaddr; 34811819Sjulian splx(s); 34925652Sjhay return (error); 35011819Sjulian } 35125652Sjhay splx(s); 35211819Sjulian ia->ia_ifa.ifa_metric = ifp->if_metric; 353194595Srwatson 35411819Sjulian /* 35511819Sjulian * Add route for the network. 35611819Sjulian */ 35711819Sjulian if (scrub) { 35811819Sjulian ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 35911819Sjulian ipx_ifscrub(ifp, ia); 36011819Sjulian ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 36111819Sjulian } 36211819Sjulian if (ifp->if_flags & IFF_POINTOPOINT) 36311819Sjulian rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 36411819Sjulian else { 36511819Sjulian ia->ia_broadaddr.sipx_addr.x_net = ia->ia_addr.sipx_addr.x_net; 36611819Sjulian rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP); 36711819Sjulian } 36811819Sjulian ia->ia_flags |= IFA_ROUTE; 36911819Sjulian return (0); 37011819Sjulian} 37111819Sjulian 37211819Sjulian/* 37311819Sjulian * Return address info for specified internet network. 37411819Sjulian */ 37511819Sjulianstruct ipx_ifaddr * 376169463Srwatsonipx_iaonnetof(struct ipx_addr *dst) 37711819Sjulian{ 378169463Srwatson struct ipx_ifaddr *ia; 379169463Srwatson struct ipx_addr *compare; 380169463Srwatson struct ifnet *ifp; 38125652Sjhay struct ipx_ifaddr *ia_maybe = NULL; 38211819Sjulian union ipx_net net = dst->x_net; 38311819Sjulian 384194608Srwatson IPX_IFADDR_LOCK_ASSERT(); 385194608Srwatson 386194905Srwatson TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) { 38725652Sjhay if ((ifp = ia->ia_ifp) != NULL) { 38811819Sjulian if (ifp->if_flags & IFF_POINTOPOINT) { 38911819Sjulian compare = &satoipx_addr(ia->ia_dstaddr); 39011819Sjulian if (ipx_hosteq(*dst, *compare)) 39111819Sjulian return (ia); 392194595Srwatson if (ipx_neteqnn(net, 393194595Srwatson ia->ia_addr.sipx_addr.x_net)) 39411819Sjulian ia_maybe = ia; 39511819Sjulian } else { 396194595Srwatson if (ipx_neteqnn(net, 397194595Srwatson ia->ia_addr.sipx_addr.x_net)) 39811819Sjulian return (ia); 39911819Sjulian } 40011819Sjulian } 40111819Sjulian } 40211819Sjulian return (ia_maybe); 40311819Sjulian} 40426965Sjhay 40526965Sjhayvoid 406169463Srwatsonipx_printhost(struct ipx_addr *addr) 40726965Sjhay{ 40826965Sjhay u_short port; 40926965Sjhay struct ipx_addr work = *addr; 410169463Srwatson char *p; u_char *q; 411169463Srwatson char *net = "", *host = ""; 41226965Sjhay char cport[10], chost[15], cnet[15]; 41326965Sjhay 41426965Sjhay port = ntohs(work.x_port); 41526965Sjhay 41626965Sjhay if (ipx_nullnet(work) && ipx_nullhost(work)) { 41726965Sjhay if (port) 41826965Sjhay printf("*.%x", port); 41926965Sjhay else 42026965Sjhay printf("*.*"); 42126965Sjhay 42226965Sjhay return; 42326965Sjhay } 42426965Sjhay 42526965Sjhay if (ipx_wildnet(work)) 42626965Sjhay net = "any"; 42726965Sjhay else if (ipx_nullnet(work)) 42826965Sjhay net = "*"; 42926965Sjhay else { 43026965Sjhay q = work.x_net.c_net; 43141514Sarchie snprintf(cnet, sizeof(cnet), "%x%x%x%x", 43226965Sjhay q[0], q[1], q[2], q[3]); 43326965Sjhay for (p = cnet; *p == '0' && p < cnet + 8; p++) 43426965Sjhay continue; 43526965Sjhay net = p; 43626965Sjhay } 43726965Sjhay 43826965Sjhay if (ipx_wildhost(work)) 43926965Sjhay host = "any"; 44026965Sjhay else if (ipx_nullhost(work)) 44126965Sjhay host = "*"; 44226965Sjhay else { 44326965Sjhay q = work.x_host.c_host; 44441514Sarchie snprintf(chost, sizeof(chost), "%x%x%x%x%x%x", 44526965Sjhay q[0], q[1], q[2], q[3], q[4], q[5]); 44626965Sjhay for (p = chost; *p == '0' && p < chost + 12; p++) 44726965Sjhay continue; 44826965Sjhay host = p; 44926965Sjhay } 45026965Sjhay 45126965Sjhay if (port) { 45226965Sjhay if (strcmp(host, "*") == 0) { 45326965Sjhay host = ""; 45441514Sarchie snprintf(cport, sizeof(cport), "%x", port); 45526965Sjhay } else 45641514Sarchie snprintf(cport, sizeof(cport), ".%x", port); 45726965Sjhay } else 45826965Sjhay *cport = 0; 45926965Sjhay 46026965Sjhay printf("%s.%s%s", net, host, cport); 46126965Sjhay} 462