2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * This is where we have chosen to combine every useful bit of code for 2N/A * all the Solaris frontends to lookup hosts, services, and netdir information 2N/A * for inet family (udp, tcp) transports. gethostbyYY(), getservbyYY(), and 2N/A * netdir_getbyYY() are all implemented on top of this code. Similarly, 2N/A * netdir_options, taddr2uaddr, and uaddr2taddr for inet transports also 2N/A * If the netconfig structure supplied has NO nametoaddr libs (i.e. a "-" 2N/A * If an administrator chooses to bypass the name service switch by 2N/A * implementation does NOT call the name service switch, it merely loops 2N/A * through the nametoaddr libs. In this case, if this code was called 2N/A * transport independent netbuf or hostserv, and unmarshal the resulting 2N/A * nd_addrlist or hostservlist back into hostent and servent, as the case 2N/A * and netdir_getbyYY are lurking somewhere here. 2N/A * constant values of addresses for HOST_SELF_BIND, HOST_SELF_CONNECT 2N/A * The following variables are static to the extent that they should 2N/A * not be visible outside of this file. 2N/A{
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
NULL};
2N/A{
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001",
NULL};
2N/A/* IPv4 nd_addrlist */ 2N/A/* IPv6 nd_addrlist */ 2N/Astatic int dstcmp(
const void *,
const void *);
2N/A * with nametoaddr libs in nconf, we call netdir_getbyname 2N/A * implementation: __classic_netdir_getbyname, otherwise nsswitch. 2N/A * netdir_getbyname calls this only if nametoaddr libs are NOT 2N/A * specified for inet transports; i.e. it's supposed to follow 2N/A * the name service switch. 2N/A * 1. gethostbyname()/netdir_getbyname() special cases: 2N/A * Worth the performance gain -- assuming a lot of inet apps 2N/A * actively use "localhost". 2N/A * If the caller passed in a dot separated IP notation to 2N/A * gethostbyname, return that back as the address. 2N/A * The nd_addr_lock mutex was added to be truely re-entrant. 2N/A * Handle case of literal address string. 2N/A * If servname is NULL, return 0 as the port number 2N/A * If servname is rpcbind, return 111 as the port number 2N/A * If servname is a number, return it back as the port 2N/A /* i.e. need to call a name service on this */ 2N/A * If the hostname is HOST_SELF_BIND, we return 0.0.0.0 2N/A * so the binding can be contacted through all 2N/A * interfaces. If the hostname is HOST_SELF_CONNECT, 2N/A * we return 127.0.0.1 so the address can be connected 2N/A * to locally. If the hostname is HOST_ANY, we return 2N/A * no addresses because IP doesn't know how to specify 2N/A * a service without a host. And finally if we specify 2N/A * HOST_BROADCAST then we ask a tli fd to tell us what 2N/A * the broadcast addresses are for any udp 2N/A * interfaces on this machine. 2N/A * If the caller passed in a dot separated IP 2N/A * notation to netdir_getbyname, convert that 2N/A * back into address. 2N/A * Now that inaddrs and baddrlist are 2N/A * dynamically allocated, care must be 2N/A * taken in freeing up the 2N/A * memory at each 'return()' point. 2N/A * Early return protection (using 2N/A * FREE_return()) is needed only in NETDIR_BY 2N/A * cases because dynamic allocation is used 2N/A * when args->op_t == NETDIR_BY. 2N/A * Early return protection is not needed in 2N/A * haddrlist==0 conditionals because dynamic 2N/A * allocation guarantees haddrlist!=0. 2N/A * Early return protection is not needed in most 2N/A * servp!=0 conditionals because this is handled 2N/A * (and returned) first. 2N/A /* i.e. need to call a name service on this */ 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, freed using 2N/A * If servname is NULL, return 0 as the port number. 2N/A * If servname is rpcbind, return 111 as the port number 2N/A * If servname is a number, return it back as the port 2N/A /* i.e. need to call a name service on this */ 2N/A * If the hostname is HOST_SELF_BIND, we return ipv6 2N/A * localaddress so the binding can be contacted through 2N/A * If the hostname is HOST_SELF_CONNECT, we return 2N/A * ipv6 loopback address so the address can be connected 2N/A * If the hostname is HOST_ANY, we return no addresses 2N/A * because IP doesn't know how to specify a service 2N/A * And finally if we specify HOST_BROADCAST then we 2N/A * disallow since IPV6 does not have any 2N/A * broadcast concept. 2N/A * If the caller passed in a dot separated IP notation 2N/A * to netdir_getbyname, convert that back into address. 2N/A /* not sure what to return */ 2N/A * Don't support broadcast in 2N/A /* i.e. need to call a name service on this */ 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, freed 2N/A * using netdir_free. 2N/A * Emphasis on improving performance in the "if" part. 2N/A * We go through all this for just one port number, 2N/A * which is most often constant. How about linking in 2N/A * an indexed database of well-known ports in the name 2N/A * Search the ipnodes (v6) path first, 2N/A * search will return the v4 addresses 2N/A * as v4mapped addresses. 2N/A /* Failover case, try hosts db for v4 address */ 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, freed using 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, freed using 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, freed using netdir_free. 2N/A * We go through all this for just 2N/A * which is most often constant. 2N/A * How about linking in 2N/A * an indexed database of well-known 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, 2N/A * freed using netdir_free. 2N/A * Convert h_addr_list into nd_addrlist. 2N/A * malloc's will be done, 2N/A * freed using netdir_free. 2N/A /* haddrlist is no longer used, so clean up */ 2N/A * 3. We come this far only if nametoaddr libs are specified for 2N/A * convert addresses back into sockaddr for gethostbyname. 2N/A * A similar HACK showed up in Solaris 2.3. 2N/A * The caller wild-carded proto -- i.e. will 2N/A * accept a match using tcp or udp for the port 2N/A * number. Since we have no hope of getting 2N/A * directly to a name service switch backend 2N/A * from here that understands this semantics, 2N/A * we try calling the netdir interfaces first 2N/A * with "tcp" and then "udp". 2N/A * Third-parties should optimize their nametoaddr 2N/A * libraries for the HOST_SELF case. 2N/A * convert addresses back into servent for getservbyname. 2N/A * with nametoaddr libs in nconf, we call netdir_getbyaddr 2N/A * implementation __classic_netdir_getbyaddr, otherwise nsswitch. 2N/A * netdir_getbyaddr calls this only if nametoaddr libs are NOT 2N/A * specified for inet transports; i.e. it's supposed to follow 2N/A * the name service switch. 2N/A * 1. gethostbyaddr()/netdir_getbyaddr() special cases: 2N/A * Worth the performance gain: assuming a lot of inet apps 2N/A * actively use "127.0.0.1". 2N/A /* LINTED pointer cast */ 2N/A * Validate the address which was passed 2N/A * Validate the address which was passed 2N/A * Emphasis on improving performance in the "if" part. 2N/A * if NETDIR_BY_NOSRV or port == 0 skip the service 2N/A * We can live with this - i.e. the address 2N/A * belong to a well known service. The caller 2N/A * traditionally accepts a stringified port 2N/A * as the service name. The state of se is used 2N/A * ahead to indicate the same. 2N/A * However, we do not tolerate this nonsense 2N/A * when we cannot get a host name. See below. 2N/A * Since we're going to search the ipnodes (v6) path first, 2N/A * we need to treat the address as a v4mapped address. 2N/A /* Failover case, try hosts db for v4 address */ 2N/A * Convert host names and service names into hostserv 2N/A * pairs. malloc's will be done, freed using 2N/A * Convert host names and service names into hostserv 2N/A * pairs. malloc's will be done, freed using 2N/A * if NETDIR_BY_NOSRV6 or port == 0 skip the service 2N/A * We can live with this - i.e. the address does 2N/A * not * belong to a well known service. The 2N/A * caller traditionally accepts a stringified 2N/A * as the service name. The state of se is used 2N/A * ahead to indicate the same. 2N/A * However, we do not tolerate this nonsense 2N/A * when we cannot get a host name. See below. 2N/A * Convert host names and service names into hostserv 2N/A * pairs. malloc's will be done, freed using netdir_free. 2N/A * 3. We come this far only if nametoaddr libs are specified for 2N/A /* LINTED pointer cast */ 2N/A /* Hopefully, third-parties get this optimization */ 2N/A * convert the host-serv pairs into h_aliases and hent. 2N/A * A similar HACK showed up in Solaris 2.3. 2N/A * The caller wild-carded proto -- i.e. will 2N/A * accept a match on tcp or udp for the port 2N/A * number. Since we have no hope of getting 2N/A * directly to a name service switch backend 2N/A * from here that understands this semantics, 2N/A * we try calling the netdir interfaces first 2N/A * with "tcp" and then "udp". 2N/A * Third-party nametoaddr_libs should be optimized for 2N/A * this case. It also gives a special semantics twist to 2N/A * netdir_getbyaddr. Only for the INADDR_ANY case, it gives 2N/A * higher priority to service lookups (over host lookups). 2N/A * If service lookup fails, the backend returns ND_NOSERV to 2N/A * facilitate lookup in the "next" naming service. 2N/A * convert the host-serv pairs into s_aliases and servent. 2N/A * Part II: Name Service Switch interfacing routines. 2N/A /* no macro-defined success code for h_errno */ 2N/A * The _switch_getXXbyYY_r() routines should be static. They used to 2N/A * be exported in SunOS 5.3, and in fact publicised as work-around 2N/A * their signatures here. Just in case. 2N/A * Return values: 0 = success, 1 = parse error, 2 = erange ... 2N/A * The structure pointer passed in is a structure in the caller's space 2N/A * wherein the field pointers would be set to areas in the buffer if 2N/A * need be. instring and buffer should be separate areas. 2N/A * Defined here because we need it and we (libnsl) cannot have a dependency 2N/A * on libsocket (however, libsocket always depends on libnsl). 2N/A p++;
/* Skip over the canonical name */ 2N/A }
while (*p++ !=
'/');
2N/A /* Syntax error -- supposed number is empty or too long */ 2N/A /* Syntax error -- port number isn't a number */ 2N/A p++;
/* Scan the protocol name */ 2N/A * Although nss_files_XY_all calls us with # stripped, 2N/A * we should be able to deal with it here in order to 2N/A if (p >=
limit || *p ==
'#') {
/* no aliases, no problem */ 2N/A /* hope they don't try to peek in */ 2N/A * Part III: All `n sundry routines that are useful only in this 2N/A * module. In the interest of keeping this source file shorter, 2N/A * we would create them a new module only if the linker allowed 2N/A * "library-static" functions. 2N/A * Routines to order addresses based on local interfaces and netmasks, 2N/A * to get and check reserved ports, and to get broadcast nets. 2N/A * The number of nanoseconds the order_haddrlist_inet() function waits 2N/A * to retreive IP interface information. The default is five minutes. 2N/A * Sort the addresses in haddrlist. Since the sorting algorithms are 2N/A * address-family specific, the work is done in the address-family 2N/A * specific order_haddrlist_<family> functions. 2N/A * Do not sort addresses if SORT_ADDRS variable is set to NO or FALSE 2N/A * the order of addresses returned by the nameserver needs to be 2N/A * maintained. (DNS round robin feature is one example) 2N/A * Check if SORT_ADDRS is set to NO or FALSE in the configuration 2N/A * file. We do not have to sort addresses in that case. 2N/A /* Count the addresses to sort */ 2N/A * If there's only one address or no addresses to sort, then 2N/A * there's nothing for us to do. 2N/A /* Call the address-family specific sorting functions. */ 2N/A * Move any local (on-link) addresses toward the beginning of haddrlist. 2N/A * The order within these two classes is preserved. 2N/A * The interface list is retrieved no more often than every 2N/A * IFINFOTIMEOUT nanoseconds. Access to the interface list is 2N/A * protected by an RW lock. 2N/A * If this function encounters an error, haddrlist is unaltered. 2N/A * The classes in the sortclass array correspond to the class 2N/A * of the address in the haddrlist list of the same index. 2N/A * ADDR_ONLINK on-link address 2N/A * ADDR_OFFLINK off-link address 2N/A /* LINTED pointer cast */ 2N/A /* LINTED pointer cast */ 2N/A * Get a read lock, and check if the interface information 2N/A /* Need to update I/F info. Upgrade to write lock. */ 2N/A * Another thread might have updated "then" between 2N/A * the rw_unlock() and rw_wrlock() calls above, so 2N/A * re-check the timeout. 2N/A /* Downgrade to read lock */ 2N/A * Another thread may have updated the I/F info, 2N/A * so verify that the 'localinfo' pointer still 2N/A * Classify the addresses. We also maintain the classcount 2N/A * array to keep track of the number of addresses in each 2N/A /* Don't need the interface list anymore in this call */ 2N/A * Each element in the classnext array points to the next 2N/A * element for that class in the sorted address list. 'rc' is 2N/A * the running count of elements as we sum the class 2N/A /* Now for the actual rearrangement of the addresses */ 2N/A /* Copy the sorted list to inaddrlist */ 2N/A * This function implements the IPv6 Default Address Selection's 2N/A * destination address ordering mechanism. The algorithm is described 2N/A * in getaddrinfo(3SOCKET). 2N/A /* Initialize the dstinfo array we'll use for SIOCGDSTINFO */ 2N/A /* Sort the dinfo array */ 2N/A /* Copy the addresses back into in6addrlist */ 2N/A * Determine number of leading bits that are common between two addresses. 2N/A * Only consider bits which fall within the prefix length plen. 2N/A for (i = 0; i <
4; i++) {
2N/A * Find number of leading common bits in the word which might 2N/A * have some common bits by searching for the first one from the left 2N/A * in the xor of the two addresses. 2N/A * We don't need to shift and check for the last bit. The 2N/A * check for IPV6_ABITS above would have caught that. 2N/A * The following group of functions named rule_*() are individual 2N/A * sorting rules for the AF_INET6 address sorting algorithm. The 2N/A * functions compare two addresses (described by two dstinforeq 2N/A * structures), and determines if one is "greater" than the other, or 2N/A * if the two are equal according to that rule. 2N/A * These values of these constants are no accident. Since qsort() 2N/A * implements the AF_INET6 address sorting, the comparison function 2N/A * must return an integer less than, equal to, or greater than zero to 2N/A * indicate if the first address is considered "less than", "equal 2N/A * to", or "greater than" the second one. Since we want the best 2N/A * addresses first on the list, "less than" is considered preferrable. 2N/A/* Prefer the addresses that is reachable. */ 2N/A/* Prefer the address whose scope matches that of its source address. */ 2N/A/* Avoid the address with the link local source address. */ 2N/A/* Prefer the address whose source address isn't deprecated. */ 2N/A/* Prefer the address whose label matches that of its source address. */ 2N/A/* Prefer the address with the higher precedence. */ 2N/A/* Prefer the address whose output interface isn't an IP tunnel */ 2N/A /* Get the common case out of the way early */ 2N/A/* Prefer the address with the smaller scope. */ 2N/A * Prefer the address that has the most leading bits in common with its 2N/A * At this point, the order doesn't matter if the two addresses 2N/A * aren't of the same address family. 2N/A * This is the function passed to qsort() that does the AF_INET6 2N/A * address comparisons. It compares two addresses using a list of 2N/A * rules. The rules are applied in order until one prefers one 2N/A * address over the other. 2N/A * Given haddrlist and a port number, mallocs and populates a new 2N/A * nd_addrlist. The new nd_addrlist maintains the order of the addresses 2N/A * in haddrlist, which have already been sorted by order_haddrlist_inet() 2N/A * or order_haddrlist_inet6(). For IPv6 this function filters out 2N/A * IPv4-mapped IPv6 addresses. 2N/A * Exclude IPv4-mapped IPv6 addresses from the count, as 2N/A * these are not included in the nd_addrlist we return. 2N/A * Given a hostent and a servent, mallocs and populates 2N/A * a new nd_hostservlist with host and service names. 2N/A * We could be passed in a NULL servent, in which case stringify port. 2N/A * We initialize the counters to 1 rather than zero because 2N/A * we have to count the "official" name as well as the aliases. 2N/A /* Convert to a number string */ 2N/A * Process results from nd_addrlist ( returned by netdir_getbyname) 2N/A * into a hostent using buf. 2N/A * *** ASSUMES that nd_addrlist->n_addrs->buf contains IP addresses in 2N/A * Build addrlist at start of buffer (after name); store the 2N/A * addresses themselves at the end of the buffer. 2N/A * Process results from nd_addrlist ( returned by netdir_getbyname) 2N/A * into a servent using buf. 2N/A * Process results from nd_hostservlist ( returned by netdir_getbyaddr) 2N/A * into a hostent using buf. 2N/A * *** ASSUMES that nd_buf->buf is a sockaddr_in *** 2N/A /* First, give the lonely address a specious home in h_addr_list. */ 2N/A * Build h_aliases at start of buffer (after addr and h_addr_list); 2N/A * store the alias strings at the end of the buffer (before h_name). 2N/A * Assumption: the netdir nametoaddr_libs 2N/A * sort the vector of (host, serv) pairs in such a way that 2N/A * all pairs with the same host name are contiguous. 2N/A * Process results from nd_hostservlist ( returned by netdir_getbyaddr) 2N/A * into a servent using buf. 2N/A * Build s_aliases at start of buffer; 2N/A * store proto and aliases at the end of the buffer (before h_name). 2N/A * Assumption: the netdir nametoaddr_libs 2N/A * do a host aliases first and serv aliases next 2N/A * enumeration for creating the list of hostserv 2N/A * This is a utility function so that various parts of libnsl can 2N/A * easily send ioctls down to ip. 2N/A * Add a small fudge factor in case interfaces get plumbed between 2N/A * the call to SIOCGLIFNUM and SIOCGLIFCONF. 2N/A * IP returns EINVAL if the buffer was too small to fit 2N/A * all of the entries. If that's the case, go back and 2N/A "ioctl (get interface configuration): %m");
2N/A /* LINTED pointer cast */ 2N/A /* LINTED pointer cast */ 2N/A /* Squirrel away the address */ 2N/A "n2a get_local_info: " 2N/A "ioctl (get interface flags): %m");
2N/A "n2a get_local_info: " 2N/A "ioctl (get interface netmask): %m");
2N/A * Some higher-level routines for determining if an address is 2N/A * on a local network. 2N/A * __inet_get_local_interfaces() - get an opaque handle with 2N/A * with a list of local interfaces 2N/A * __inet_address_is_local() - return 1 if an address is 2N/A * on a local network; 0 otherwise 2N/A * __inet_free_local_interfaces() - free handle that was 2N/A * returned by __inet_get_local_interfaces() 2N/A * A typical calling sequence is: 2N/A * p = __inet_get_local_interfaces(); 2N/A * if (__inet_address_is_local(p, inaddr)) { 2N/A * __inet_free_local_interfaces(p); 2N/A * Return an opaque pointer to a list of configured interfaces. 2N/A * Free memory allocated by inet_local_interfaces(). 2N/A * Determine if an address is on a local network. 2N/A * Might have made sense to use SIOCTONLINK, except that it doesn't 2N/A * handle matching on IPv4 network addresses. 2N/A for (i = 0; i < n; i++) {
2N/A "broadcast: open to get interface configuration: %m");
2N/A * Ideally, this ioctl should also tell me, how many bytes were 2N/A * finally allocated, but it doesnt. 2N/A "broadcast: ioctl (get interface configuration): %m");
2N/A /* LINTED pointer cast */ 2N/A "ioctl (get interface flags): %m");
2N/A /* LINTED pointer cast */ 2N/A /* May not work with other implementation */ 2N/A /* LINTED pointer cast */ 2N/A /* LINTED pointer cast */ 2N/A /* LINTED pointer cast */ 2N/A * Copied here to avoid our dependency on libsocket. More importantly, 2N/A * to make sure partially static apps that use libnsl, but not 2N/A * libsocket, don't get screwed up. 2N/A * If you understand the above paragraph, try to get rid of 2N/A * this copy of inet_makeaddr; if you don;t, leave it alone. 2N/A * Formulate an Internet address from network + host. Used in 2N/A * building addresses stored in the ifnet structure. 2N/A * Routine to read the default configuration file and check if SORT_ADDRS 2N/A * is set to NO or FALSE. This routine is called by order_haddrlist_af() 2N/A * to determine if the addresses need to be sorted.