10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1676Sjpk * Common Development and Distribution License (the "License"). 6*1676Sjpk * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*1676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* SunOS */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <stdio.h> 29*1676Sjpk #include <stdlib.h> 300Sstevel@tonic-gate #include <ctype.h> 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/socket.h> 330Sstevel@tonic-gate #include <sys/sockio.h> 340Sstevel@tonic-gate #include <net/if.h> 350Sstevel@tonic-gate #include <netinet/in_systm.h> 360Sstevel@tonic-gate #include <netinet/in.h> 370Sstevel@tonic-gate #include <netinet/if_ether.h> 380Sstevel@tonic-gate #include <netinet/ip.h> 390Sstevel@tonic-gate #include <netdb.h> 400Sstevel@tonic-gate #include <string.h> 410Sstevel@tonic-gate #include <signal.h> 420Sstevel@tonic-gate #include <setjmp.h> 43*1676Sjpk #include <arpa/inet.h> 44*1676Sjpk #include "snoop.h" 450Sstevel@tonic-gate 46*1676Sjpk static sigjmp_buf nisjmp; 470Sstevel@tonic-gate 480Sstevel@tonic-gate #define MAXHASH 1024 /* must be a power of 2 */ 490Sstevel@tonic-gate 500Sstevel@tonic-gate #define SEPARATORS " \t\n" 510Sstevel@tonic-gate 520Sstevel@tonic-gate struct hostdata { 530Sstevel@tonic-gate struct hostdata *h_next; 540Sstevel@tonic-gate char *h_hostname; 550Sstevel@tonic-gate int h_pktsout; 560Sstevel@tonic-gate int h_pktsin; 570Sstevel@tonic-gate }; 580Sstevel@tonic-gate 590Sstevel@tonic-gate struct hostdata4 { 600Sstevel@tonic-gate struct hostdata4 *h4_next; 610Sstevel@tonic-gate char *h4_hostname; 620Sstevel@tonic-gate int h4_pktsout; 630Sstevel@tonic-gate int h4_pktsin; 640Sstevel@tonic-gate struct in_addr h4_addr; 650Sstevel@tonic-gate }; 660Sstevel@tonic-gate 670Sstevel@tonic-gate struct hostdata6 { 680Sstevel@tonic-gate struct hostdata6 *h6_next; 690Sstevel@tonic-gate char *h6_hostname; 700Sstevel@tonic-gate int h6_pktsout; 710Sstevel@tonic-gate int h6_pktsin; 720Sstevel@tonic-gate struct in6_addr h6_addr; 730Sstevel@tonic-gate }; 740Sstevel@tonic-gate 75*1676Sjpk static struct hostdata *addhost(int, const void *, const char *, char **); 760Sstevel@tonic-gate 77*1676Sjpk static struct hostdata4 *h_table4[MAXHASH]; 78*1676Sjpk static struct hostdata6 *h_table6[MAXHASH]; 790Sstevel@tonic-gate 800Sstevel@tonic-gate #define iphash(e) ((e) & (MAXHASH-1)) 810Sstevel@tonic-gate 82*1676Sjpk /* ARGSUSED */ 830Sstevel@tonic-gate static void 84*1676Sjpk wakeup(int n) 850Sstevel@tonic-gate { 860Sstevel@tonic-gate siglongjmp(nisjmp, 1); 870Sstevel@tonic-gate } 880Sstevel@tonic-gate 890Sstevel@tonic-gate extern char *inet_ntoa(); 900Sstevel@tonic-gate extern boolean_t rflg; 910Sstevel@tonic-gate 920Sstevel@tonic-gate static struct hostdata * 930Sstevel@tonic-gate iplookup(struct in_addr ipaddr) 940Sstevel@tonic-gate { 950Sstevel@tonic-gate register struct hostdata4 *h; 960Sstevel@tonic-gate struct hostent *hp = NULL; 970Sstevel@tonic-gate struct netent *np; 980Sstevel@tonic-gate int error_num; 990Sstevel@tonic-gate struct hostdata *retval; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate for (h = h_table4[iphash(ipaddr.s_addr)]; h; h = h->h4_next) { 1020Sstevel@tonic-gate if (h->h4_addr.s_addr == ipaddr.s_addr) 1030Sstevel@tonic-gate return ((struct hostdata *)h); 1040Sstevel@tonic-gate } 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate /* not found. Put it in */ 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate if (ipaddr.s_addr == htonl(INADDR_BROADCAST)) 1090Sstevel@tonic-gate return (addhost(AF_INET, &ipaddr, "BROADCAST", NULL)); 1100Sstevel@tonic-gate if (ipaddr.s_addr == htonl(INADDR_ANY)) 1110Sstevel@tonic-gate return (addhost(AF_INET, &ipaddr, "OLD-BROADCAST", NULL)); 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate /* 1140Sstevel@tonic-gate * Set an alarm here so we don't get held up by 1150Sstevel@tonic-gate * an unresponsive name server. 1160Sstevel@tonic-gate * Give it 3 sec to do its work. 1170Sstevel@tonic-gate */ 1180Sstevel@tonic-gate if (! rflg && sigsetjmp(nisjmp, 1) == 0) { 1190Sstevel@tonic-gate (void) snoop_alarm(3, wakeup); 1200Sstevel@tonic-gate hp = getipnodebyaddr((char *)&ipaddr, sizeof (int), 1210Sstevel@tonic-gate AF_INET, &error_num); 1220Sstevel@tonic-gate if (hp == NULL && inet_lnaof(ipaddr) == 0) { 1230Sstevel@tonic-gate np = getnetbyaddr(inet_netof(ipaddr), AF_INET); 1240Sstevel@tonic-gate if (np) 1250Sstevel@tonic-gate return (addhost(AF_INET, &ipaddr, np->n_name, 1260Sstevel@tonic-gate np->n_aliases)); 1270Sstevel@tonic-gate } 1280Sstevel@tonic-gate (void) snoop_alarm(0, wakeup); 1290Sstevel@tonic-gate } 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate retval = addhost(AF_INET, &ipaddr, 1320Sstevel@tonic-gate hp ? hp->h_name : inet_ntoa(ipaddr), 1330Sstevel@tonic-gate hp ? hp->h_aliases : NULL); 1340Sstevel@tonic-gate if (hp != NULL) 1350Sstevel@tonic-gate freehostent(hp); 1360Sstevel@tonic-gate return (retval); 1370Sstevel@tonic-gate } 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate static struct hostdata * 140*1676Sjpk ip6lookup(const struct in6_addr *ip6addr) 1410Sstevel@tonic-gate { 1420Sstevel@tonic-gate struct hostdata6 *h; 1430Sstevel@tonic-gate struct hostent *hp = NULL; 1440Sstevel@tonic-gate int error_num; 1450Sstevel@tonic-gate char addrstr[INET6_ADDRSTRLEN]; 146410Skcpoon char *addname; 1470Sstevel@tonic-gate struct hostdata *retval; 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate for (h = h_table6[iphash(((uint32_t *)ip6addr)[3])]; h; 1500Sstevel@tonic-gate h = h->h6_next) { 1510Sstevel@tonic-gate if (IN6_ARE_ADDR_EQUAL(&h->h6_addr, ip6addr)) 1520Sstevel@tonic-gate return ((struct hostdata *)h); 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate /* not in the hash table, put it in */ 1560Sstevel@tonic-gate if (IN6_IS_ADDR_UNSPECIFIED(ip6addr)) 1570Sstevel@tonic-gate return (addhost(AF_INET6, ip6addr, "UNSPECIFIED", NULL)); 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate /* 1600Sstevel@tonic-gate * Set an alarm here so we don't get held up by 1610Sstevel@tonic-gate * an unresponsive name server. 1620Sstevel@tonic-gate * Give it 3 sec to do its work. 1630Sstevel@tonic-gate */ 1640Sstevel@tonic-gate if (! rflg && sigsetjmp(nisjmp, 1) == 0) { 1650Sstevel@tonic-gate (void) snoop_alarm(3, wakeup); 1660Sstevel@tonic-gate hp = getipnodebyaddr(ip6addr, sizeof (struct in6_addr), 1670Sstevel@tonic-gate AF_INET6, &error_num); 1680Sstevel@tonic-gate (void) snoop_alarm(0, wakeup); 1690Sstevel@tonic-gate } else { 1700Sstevel@tonic-gate hp = NULL; 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate if (hp != NULL) 1740Sstevel@tonic-gate addname = hp->h_name; 1750Sstevel@tonic-gate else { 1760Sstevel@tonic-gate (void) inet_ntop(AF_INET6, ip6addr, addrstr, INET6_ADDRSTRLEN); 1770Sstevel@tonic-gate addname = addrstr; 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate retval = addhost(AF_INET6, ip6addr, addname, hp ? hp->h_aliases : NULL); 1810Sstevel@tonic-gate if (hp != NULL) 1820Sstevel@tonic-gate freehostent(hp); 1830Sstevel@tonic-gate return (retval); 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate static struct hostdata * 187*1676Sjpk addhost(int family, const void *ipaddr, const char *name, char **aliases) 1880Sstevel@tonic-gate { 189*1676Sjpk struct hostdata **hp, *n = NULL; 1900Sstevel@tonic-gate extern FILE *namefile; 1910Sstevel@tonic-gate int hashval; 1920Sstevel@tonic-gate static char aname[128]; 1930Sstevel@tonic-gate char *np; 1940Sstevel@tonic-gate static struct hostdata h; 1950Sstevel@tonic-gate int ind; 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate switch (family) { 1980Sstevel@tonic-gate case AF_INET: 1990Sstevel@tonic-gate n = (struct hostdata *)malloc(sizeof (struct hostdata4)); 2000Sstevel@tonic-gate if (n == NULL) 2010Sstevel@tonic-gate goto alloc_failed; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate memset(n, 0, sizeof (struct hostdata4)); 2040Sstevel@tonic-gate n->h_hostname = strdup(name); 2050Sstevel@tonic-gate if (n->h_hostname == NULL) 2060Sstevel@tonic-gate goto alloc_failed; 2070Sstevel@tonic-gate 208*1676Sjpk ((struct hostdata4 *)n)->h4_addr = 209*1676Sjpk *(const struct in_addr *)ipaddr; 2100Sstevel@tonic-gate hashval = ((struct in_addr *)ipaddr)->s_addr; 2110Sstevel@tonic-gate hp = (struct hostdata **)&h_table4[iphash(hashval)]; 2120Sstevel@tonic-gate break; 2130Sstevel@tonic-gate case AF_INET6: 2140Sstevel@tonic-gate n = (struct hostdata *)malloc(sizeof (struct hostdata6)); 2150Sstevel@tonic-gate if (n == NULL) 2160Sstevel@tonic-gate goto alloc_failed; 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate memset(n, 0, sizeof (struct hostdata6)); 2190Sstevel@tonic-gate n->h_hostname = strdup(name); 2200Sstevel@tonic-gate if (n->h_hostname == NULL) 2210Sstevel@tonic-gate goto alloc_failed; 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate memcpy(&((struct hostdata6 *)n)->h6_addr, ipaddr, 2240Sstevel@tonic-gate sizeof (struct in6_addr)); 225*1676Sjpk hashval = ((const int *)ipaddr)[3]; 2260Sstevel@tonic-gate hp = (struct hostdata **)&h_table6[iphash(hashval)]; 2270Sstevel@tonic-gate break; 2280Sstevel@tonic-gate default: 2290Sstevel@tonic-gate fprintf(stderr, "snoop: ERROR: Unknown address family: %d", 2300Sstevel@tonic-gate family); 2310Sstevel@tonic-gate exit(1); 2320Sstevel@tonic-gate } 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate n->h_next = *hp; 2350Sstevel@tonic-gate *hp = n; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate if (namefile != NULL) { 2380Sstevel@tonic-gate if (family == AF_INET) { 239*1676Sjpk np = inet_ntoa(*(const struct in_addr *)ipaddr); 2400Sstevel@tonic-gate if (np) { 2410Sstevel@tonic-gate (void) fprintf(namefile, "%s\t%s", np, name); 2420Sstevel@tonic-gate if (aliases) { 2430Sstevel@tonic-gate for (ind = 0; 2440Sstevel@tonic-gate aliases[ind] != NULL; 2450Sstevel@tonic-gate ind++) { 2460Sstevel@tonic-gate (void) fprintf(namefile, " %s", 2470Sstevel@tonic-gate aliases[ind]); 2480Sstevel@tonic-gate } 2490Sstevel@tonic-gate } 2500Sstevel@tonic-gate (void) fprintf(namefile, "\n"); 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate } else if (family == AF_INET6) { 2530Sstevel@tonic-gate np = (char *)inet_ntop(AF_INET6, (void *)ipaddr, aname, 2540Sstevel@tonic-gate sizeof (aname)); 2550Sstevel@tonic-gate if (np) { 2560Sstevel@tonic-gate (void) fprintf(namefile, "%s\t%s", np, name); 2570Sstevel@tonic-gate if (aliases) { 2580Sstevel@tonic-gate for (ind = 0; 2590Sstevel@tonic-gate aliases[ind] != NULL; 2600Sstevel@tonic-gate ind++) { 2610Sstevel@tonic-gate (void) fprintf(namefile, " %s", 2620Sstevel@tonic-gate aliases[ind]); 2630Sstevel@tonic-gate } 2640Sstevel@tonic-gate } 2650Sstevel@tonic-gate (void) fprintf(namefile, "\n"); 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate } else { 2680Sstevel@tonic-gate (void) fprintf(stderr, "addhost: unknown family %d\n", 2690Sstevel@tonic-gate family); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate return (n); 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate alloc_failed: 2750Sstevel@tonic-gate if (n) 2760Sstevel@tonic-gate free(n); 2770Sstevel@tonic-gate (void) fprintf(stderr, "addhost: no mem\n"); 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate aname[0] = '\0'; 2800Sstevel@tonic-gate memset(&h, 0, sizeof (struct hostdata)); 2810Sstevel@tonic-gate h.h_hostname = aname; 2820Sstevel@tonic-gate return (&h); 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate char * 286*1676Sjpk addrtoname(int family, const void *ipaddr) 2870Sstevel@tonic-gate { 2880Sstevel@tonic-gate switch (family) { 2890Sstevel@tonic-gate case AF_INET: 290*1676Sjpk return (iplookup(*(const struct in_addr *)ipaddr)->h_hostname); 2910Sstevel@tonic-gate case AF_INET6: 292*1676Sjpk return (ip6lookup((const struct in6_addr *)ipaddr)->h_hostname); 2930Sstevel@tonic-gate } 294*1676Sjpk (void) fprintf(stderr, "snoop: ERROR: unknown address family: %d\n", 295*1676Sjpk family); 296*1676Sjpk exit(1); 297*1676Sjpk /* NOTREACHED */ 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate void 3010Sstevel@tonic-gate load_names(fname) 3020Sstevel@tonic-gate char *fname; 3030Sstevel@tonic-gate { 3040Sstevel@tonic-gate char buf[1024]; 3050Sstevel@tonic-gate char *addr, *name, *alias; 3060Sstevel@tonic-gate FILE *f; 3070Sstevel@tonic-gate unsigned int addrv4; 3080Sstevel@tonic-gate struct in6_addr addrv6; 3090Sstevel@tonic-gate int family; 3100Sstevel@tonic-gate void *naddr; 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate (void) fprintf(stderr, "Loading name file %s\n", fname); 3130Sstevel@tonic-gate f = fopen(fname, "r"); 3140Sstevel@tonic-gate if (f == NULL) { 3150Sstevel@tonic-gate perror(fname); 3160Sstevel@tonic-gate return; 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate while (fgets(buf, 1024, f) != NULL) { 3200Sstevel@tonic-gate addr = strtok(buf, SEPARATORS); 3210Sstevel@tonic-gate if (addr == NULL || *addr == '#') 3220Sstevel@tonic-gate continue; 3230Sstevel@tonic-gate if (inet_pton(AF_INET6, addr, (void *)&addrv6) == 1) { 3240Sstevel@tonic-gate family = AF_INET6; 3250Sstevel@tonic-gate naddr = (void *)&addrv6; 326*1676Sjpk } else if ((addrv4 = inet_addr(addr)) != (ulong_t)-1) { 3270Sstevel@tonic-gate family = AF_INET; 3280Sstevel@tonic-gate naddr = (void *)&addrv4; 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate name = strtok(NULL, SEPARATORS); 3310Sstevel@tonic-gate if (name == NULL) 3320Sstevel@tonic-gate continue; 333*1676Sjpk while ((alias = strtok(NULL, SEPARATORS)) != NULL && 334*1676Sjpk (*alias != '#')) { 3350Sstevel@tonic-gate (void) addhost(family, naddr, alias, NULL); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate (void) addhost(family, naddr, name, NULL); 3380Sstevel@tonic-gate /* Note: certain addresses such as broadcast are skipped */ 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate (void) fclose(f); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate /* 3450Sstevel@tonic-gate * lgetipnodebyname: looks up hostname in cached address data. This allows 3460Sstevel@tonic-gate * filtering on hostnames from the .names file to work properly, and 3470Sstevel@tonic-gate * avoids name clashes between domains. Note that only the first of the 3480Sstevel@tonic-gate * ipv4, ipv6, or v4mapped address will be returned, because the 3490Sstevel@tonic-gate * cache does not contain information on multi-homed hosts. 3500Sstevel@tonic-gate */ 3510Sstevel@tonic-gate /*ARGSUSED*/ 3520Sstevel@tonic-gate struct hostent * 3530Sstevel@tonic-gate lgetipnodebyname(const char *name, int af, int flags, int *error_num) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate int i; 3560Sstevel@tonic-gate struct hostdata4 *h; 3570Sstevel@tonic-gate struct hostdata6 *h6; 3580Sstevel@tonic-gate static struct hostent he; /* host entry */ 3590Sstevel@tonic-gate static struct in6_addr h46_addr[MAXADDRS]; /* v4mapped address */ 3600Sstevel@tonic-gate static char h_name[MAXHOSTNAMELEN]; /* hostname */ 3610Sstevel@tonic-gate static char *list[MAXADDRS]; /* addr_list array */ 3620Sstevel@tonic-gate struct hostent *hp = &he; 3630Sstevel@tonic-gate int ind; 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate (void) memset((char *)hp, 0, sizeof (struct hostent)); 3660Sstevel@tonic-gate hp->h_name = h_name; 3670Sstevel@tonic-gate h_name[0] = '\0'; 3680Sstevel@tonic-gate strcpy(h_name, name); 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate hp->h_addrtype = AF_INET6; 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate hp->h_addr_list = list; 3730Sstevel@tonic-gate for (i = 0; i < MAXADDRS; i++) 3740Sstevel@tonic-gate hp->h_addr_list[i] = NULL; 3750Sstevel@tonic-gate ind = 0; 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate /* ipv6 lookup */ 3780Sstevel@tonic-gate if (af == AF_INET6) { 3790Sstevel@tonic-gate hp->h_length = sizeof (struct in6_addr); 3800Sstevel@tonic-gate for (i = 0; i < MAXHASH; i++) { 3810Sstevel@tonic-gate for (h6 = h_table6[i]; h6; h6 = h6->h6_next) { 3820Sstevel@tonic-gate if (strcmp(name, h6->h6_hostname) == 0) { 3830Sstevel@tonic-gate if (ind >= MAXADDRS - 1) { 3840Sstevel@tonic-gate /* too many addresses */ 3850Sstevel@tonic-gate return (hp); 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate /* found ipv6 addr */ 3880Sstevel@tonic-gate hp->h_addr_list[ind] = 3890Sstevel@tonic-gate (char *)&h6->h6_addr; 3900Sstevel@tonic-gate ind++; 3910Sstevel@tonic-gate } 3920Sstevel@tonic-gate } 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate /* ipv4 or v4mapped lookup */ 3960Sstevel@tonic-gate if (af == AF_INET || (flags & AI_ALL)) { 3970Sstevel@tonic-gate for (i = 0; i < MAXHASH; i++) { 3980Sstevel@tonic-gate for (h = h_table4[i]; h; h = h->h4_next) { 3990Sstevel@tonic-gate if (strcmp(name, h->h4_hostname) == 0) { 4000Sstevel@tonic-gate if (ind >= MAXADDRS - 1) { 4010Sstevel@tonic-gate /* too many addresses */ 4020Sstevel@tonic-gate return (hp); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate if (af == AF_INET) { 4050Sstevel@tonic-gate /* found ipv4 addr */ 4060Sstevel@tonic-gate hp->h_addrtype = AF_INET; 4070Sstevel@tonic-gate hp->h_length = 4080Sstevel@tonic-gate sizeof (struct in_addr); 4090Sstevel@tonic-gate hp->h_addr_list[ind] = 4100Sstevel@tonic-gate (char *)&h->h4_addr; 4110Sstevel@tonic-gate ind++; 4120Sstevel@tonic-gate } else { 4130Sstevel@tonic-gate /* found v4mapped addr */ 4140Sstevel@tonic-gate hp->h_length = 4150Sstevel@tonic-gate sizeof (struct in6_addr); 4160Sstevel@tonic-gate hp->h_addr_list[ind] = 4170Sstevel@tonic-gate (char *)&h46_addr[ind]; 4180Sstevel@tonic-gate IN6_INADDR_TO_V4MAPPED( 4190Sstevel@tonic-gate &h->h4_addr, 4200Sstevel@tonic-gate &h46_addr[ind]); 4210Sstevel@tonic-gate ind++; 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate } 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate } 4270Sstevel@tonic-gate return (ind > 0 ? hp : NULL); 4280Sstevel@tonic-gate } 429