1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "mdns_common.h" 28 29 /* 30 * gethostby* functions for the ipnodes database. The ipnodes 31 * database stores both IPv4 and IPv6 address information. 32 * mDNS query functions to perform the host lookup are 33 * in mdns/common/mdns_common.c file. 34 * _nss_mdns_ipnodes_constr is called to initialize 35 * the nsswitch backend data structures. 36 */ 37 38 static nss_status_t 39 getbyname(be, a) 40 mdns_backend_ptr_t be; 41 void *a; 42 { 43 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 44 int af = argp->key.ipnode.af_family; 45 char *hname = (char *)argp->key.ipnode.name; 46 struct mdns_querydata qdata; 47 48 (void) memset(&qdata, 0, sizeof (struct mdns_querydata)); 49 qdata.argp = argp; 50 51 _nss_mdns_updatecfg(be); 52 return (_nss_mdns_querybyname(be, hname, af, &qdata)); 53 } 54 55 static nss_status_t 56 getbyaddr(be, a) 57 mdns_backend_ptr_t be; 58 void *a; 59 { 60 int i; 61 char ch; 62 char *chptr; 63 uint8_t *p; 64 struct in6_addr *addr; 65 struct mdns_querydata qdata; 66 char addrqryname[ sizeof ("f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f") + \ 67 sizeof (".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.ip6.arpa.")]; 68 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 69 70 (void) memset(&qdata, 0, sizeof (struct mdns_querydata)); 71 qdata.argp = argp; 72 argp->h_errno = 0; 73 74 if ((argp->key.hostaddr.type != AF_INET6) || 75 (argp->key.hostaddr.len != sizeof (*addr))) 76 return (NSS_NOTFOUND); 77 78 /* LINTED E_BAD_PTR_CAST_ALIGN */ 79 addr = (struct in6_addr *)(argp->key.hostaddr.addr); 80 81 if (IN6_IS_ADDR_V4MAPPED(addr)) { 82 struct in_addr ipv4addr; 83 84 IN6_V4MAPPED_TO_INADDR(addr, &ipv4addr); 85 if (inet_ntop(AF_INET, (void *) &ipv4addr.s_addr, 86 (void *)qdata.paddrbuf, sizeof (qdata.paddrbuf)) == NULL) 87 return (NSS_NOTFOUND); 88 qdata.af = AF_INET; 89 p = (uint8_t *)&ipv4addr.s_addr; 90 (void) snprintf(addrqryname, sizeof (addrqryname), 91 "%u.%u.%u.%u.in-addr.arpa.", p[3], p[2], p[1], p[0]); 92 } else { 93 if (inet_ntop(AF_INET6, (void *)addr, 94 (void *)qdata.paddrbuf, 95 sizeof (qdata.paddrbuf)) == NULL) 96 return (NSS_NOTFOUND); 97 qdata.af = AF_INET6; 98 chptr = addrqryname; 99 for (i = 0; i < 16; i++) 100 { 101 ch = ((char *)addr)[15-i]; 102 chptr += snprintf(chptr, sizeof (addrqryname)-i*4, 103 "%X.%X.", ch&0x0f, (ch>>4)&0x0f); 104 } 105 (void) strlcpy(chptr, "ip6.arpa.", sizeof (addrqryname)-64); 106 } 107 108 _nss_mdns_updatecfg(be); 109 return (_nss_mdns_querybyaddr(be, addrqryname, qdata.af, &qdata)); 110 } 111 112 /*ARGSUSED*/ 113 static nss_status_t 114 _nss_mdns_getent(be, args) 115 mdns_backend_ptr_t be; 116 void *args; 117 { 118 return (NSS_UNAVAIL); 119 } 120 121 /*ARGSUSED*/ 122 static nss_status_t 123 _nss_mdns_setent(be, dummy) 124 mdns_backend_ptr_t be; 125 void *dummy; 126 { 127 return (NSS_UNAVAIL); 128 } 129 130 /*ARGSUSED*/ 131 static nss_status_t 132 _nss_mdns_endent(be, dummy) 133 mdns_backend_ptr_t be; 134 void *dummy; 135 { 136 return (NSS_UNAVAIL); 137 } 138 139 /*ARGSUSED*/ 140 static nss_status_t 141 _nss_mdns_ipnodes_destr(be, dummy) 142 mdns_backend_ptr_t be; 143 void *dummy; 144 { 145 _nss_mdns_destr(be); 146 return (NSS_SUCCESS); 147 } 148 149 static mdns_backend_op_t ipnodes_ops[] = { 150 _nss_mdns_ipnodes_destr, 151 _nss_mdns_endent, 152 _nss_mdns_setent, 153 _nss_mdns_getent, 154 getbyname, 155 getbyaddr, 156 }; 157 158 /*ARGSUSED*/ 159 nss_backend_t * 160 _nss_mdns_ipnodes_constr(dummy1, dummy2, dummy3) 161 const char *dummy1, *dummy2, *dummy3; 162 { 163 return (_nss_mdns_constr(ipnodes_ops, 164 sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]))); 165 } 166 167 /*ARGSUSED*/ 168 nss_status_t 169 _nss_get_mdns_ipnodes_name(mdns_backend_ptr_t *be, void **bufp, size_t *sizep) 170 { 171 return (_nss_mdns_gethost_withttl(*bufp, *sizep, 1)); 172 } 173