/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include "mdns_common.h"
struct mdns_querydata *data);
static void _nss_mdns_get_svcstatetimestamp(struct timeval *);
static void _nss_mdns_loadsmfcfg(mdns_backend_ptr_t);
static void _nss_mdns_freesmfcfg(mdns_backend_ptr_t);
static int searchdomain(mdns_backend_ptr_t, char *, int, char **);
/*
* This file includes the functions to query for host name
* information via Multicast DNS (mDNS). The function
* _nss_mdns_queryrecord queries for the host information via
* Multicast DNS. _nss_mdns_querybyname and _nss_mdns_querybyaddr
* and PTR DNS resource records respectively. DNSServiceQueryRecord
* in libdns_sd sends a request to the mDNS daemon (mdnsd) to place
* the DNS query via multicast and return the results.
*
* gethostent.c and gethostent6.c implement the nsswitch 'hosts'
* backend module getXbyY functions: getbyname and getbyaddr.
* getby* functions in gethostent.c supports only IPv4 and
* getby* functions in gethostent6.c returns both IPv4 and
* IPv6 results. Functions in gethostent.c and gethostent6.c
* call the _nss_mdns_queryby* functions in mdns_common.c to
* query for host information via mDNS.
*
* Configuration for mdns is stored in SMF and is accessed using
* includes the list of valid DNS domains checked before querying host
* information via mDNS and the search list to use for host lookup via
* mDNS. The default valid domain list in the mDNS service supports host
* lookups for hostnames in the ".local" domain and hostname queries
* for link-local IPv4 and IPv6 addresses. _nss_mdns_loadsmfcfg
* loads the nss_mdns configuration from SMF and the function
* _nss_mdns_updatecfg checks for any updates in nss_mdns configuration.
*/
static int
struct mdns_querydata *data)
{
int sockfd;
int ret;
#ifdef DEBUG
#endif
return (NSS_UNAVAIL);
}
do {
/* Wait until response received from mDNS daemon */
}
int stat;
}
if (stat == NSS_STR_PARSE_SUCCESS) {
} else {
if (stat == NSS_STR_PARSE_ERANGE)
}
} else {
}
}
}
static void
/* LINTED E_FUNC_ARG_UNUSED */
/* LINTED E_FUNC_ARG_UNUSED */
/* LINTED E_FUNC_ARG_UNUSED */
void *context)
{
int firstent = 0;
int af;
char *buffer;
int len;
int remlen;
if (errorCode != kDNSServiceErr_NoError) {
return;
}
if ((flags & kDNSServiceFlagsMoreComing))
else
if (!(flags & kDNSServiceFlagsAdd))
return;
if (rrclass != kDNSServiceClass_IN)
return;
if (rrtype == kDNSServiceType_A)
else if (rrtype == kDNSServiceType_AAAA)
else
return;
if (qdata->withttlbsize > 0) {
} else {
} else {
/* Return in file format */
0, remlen);
}
}
firstent = 1;
} else {
}
#ifdef DEBUG
#endif
if (firstent)
else
return;
}
#ifdef DEBUG
#endif
} else {
}
}
int
{
int rrtype;
int rrclass;
int srchidx = 0;
int rc;
char *name;
char *sname;
else {
return (NSS_NOTFOUND);
}
return (NSS_UNAVAIL);
}
else
#ifdef DEBUG
#endif
return (rc);
}
}
return (NSS_NOTFOUND);
}
static void
/* LINTED E_FUNC_ARG_UNUSED */
/* LINTED E_FUNC_ARG_UNUSED */
/* LINTED E_FUNC_ARG_UNUSED */
void *context)
{
int firstent = 0;
char *buffer;
int len;
int remlen;
if (errorCode != kDNSServiceErr_NoError) {
return;
}
if ((flags & kDNSServiceFlagsMoreComing))
else
if (!(flags & kDNSServiceFlagsAdd))
return;
if (rrclass != kDNSServiceClass_IN)
return;
if (rrtype != kDNSServiceType_PTR)
return;
} else {
/* Return in file format */
}
firstent = 1;
} else {
}
return;
}
#ifdef DEBUG
#endif
if (firstent)
else
return;
}
}
int
/* LINTED E_FUNC_ARG_UNUSED */
struct mdns_querydata *data)
{
int rrtype;
int rrclass;
#ifdef DEBUG
#endif
return (NSS_NOTFOUND);
}
}
/*
* Converts the encoded name in RData returned
* by mDNS query to name in file format
*/
static char *
{
char *end;
int domainlen = 0;
/* first byte is len */
*ptr++ = '\\';
}
}
/*
* Check if we copied entire domain str. and
* if space is still remaining for '.' separator
*/
return (NULL);
*ptr++ = '.';
}
*ptr = '\0';
return (ptr);
}
{
return (NULL);
return ((nss_backend_t *)be);
}
void
{
}
}
static int
{
int trailing_dot = 0;
char *ch;
if ((*ch) == '.')
trailing_dot++;
if (trailing_dot && srchidx > 0)
/*
* If there is a trailing dot in the query
* name, do not perform any additional queries
* with search domains.
*/
return (-1);
if (srchidx == 0) {
/*
* If there is a trailing dot in the query
* or atleast one dot in the query name then
* perform a query as-is once first.
*/
++srchidx;
return (srchidx);
else if (trailing_dot)
return (-1);
}
}
if ((srchidx > NSSMDNS_MAXSRCHDMNS) ||
return (-1);
return (++srchidx);
}
/*
* This function determines if the domain name in the query
* matches any of the valid & search domains in the nss_mdns
* configuration.
*/
static boolean_t
{
char *nameptr;
/* Remove any trailing and leading dots in the name */
nameptr--;
*(++nameptr) = '\0';
nameptr++;
if (*nameptr == '\0')
return (B_FALSE);
/* Compare with search domains */
NSSMDNS_MAXSRCHDMNS) == B_TRUE))
return (B_TRUE);
/* Compare with valid domains */
}
static boolean_t
{
char *vptr;
int vdlen;
char *cptr;
int nlen;
int i;
for (i = 0; (i < maxdmns) &&
continue;
return (B_TRUE);
}
return (B_FALSE);
}
static void
{
scf_handle_t *h;
h = scf_handle_create(SCF_VERSION);
if (h == NULL)
return;
if (scf_handle_bind(h) == -1) {
return;
}
&nsec));
}
if (h != NULL)
}
void
{
/*
* Update configuration if current svc state timestamp
* is different from last known svc state timestamp
*/
" service timestamp");
return;
}
}
static void
{
char *tchr;
char *pchr;
int tlen;
int cnt = 0;
return;
/* Remove beginning & trailing '.' chars */
tchr++;
pchr--;
*(++pchr) = '\0';
cnt++;
}
}
}
static void
{
scf_handle_t *h;
h = scf_handle_create(SCF_VERSION);
if (h == NULL)
return;
if (scf_handle_bind(h) == -1) {
return;
}
if (h != NULL)
}
static void
{
int idx;
return;
}
}
}
}
}
/*
* Performs lookup for IP address by hostname via mDNS and returns
* results along with the TTL value from the mDNS resource records.
* Called by nscd wth a ptr to packed buffer and packed buffer size.
*/
{
int dbop;
int af;
int len;
int blen;
char *dbname;
char *hname;
/*
* Retrieve withttl buffer and size from the passed packed buffer.
* Results are returned along with ttl in this buffer.
*/
if (sret != NSS_SUCCESS)
return (NSS_ERROR);
if (ipnode) {
return (NSS_ERROR);
} else {
}
return (NSS_ERROR);
/* Zero out the withttl buffer prior to use */
#ifdef DEBUG
#endif
return (NSS_ERROR);
}
/* Return ttl in the packed buffer at ext_off */
return (NSS_SUCCESS);
}
return (NSS_ERROR);
}