17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
22*98573c19SMarcel Telka
23*98573c19SMarcel Telka /*
24*98573c19SMarcel Telka * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25*98573c19SMarcel Telka */
26*98573c19SMarcel Telka
277c478bd9Sstevel@tonic-gate /*
28a6f0fae9Sgt29601 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
297c478bd9Sstevel@tonic-gate * Use is subject to license terms.
307c478bd9Sstevel@tonic-gate */
31b17f03d7SMarcel Telka /*
32bbaa8b60SDan Kruchinin * Copyright (c) 2012 by Delphix. All rights reserved.
33b17f03d7SMarcel Telka */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
367c478bd9Sstevel@tonic-gate /* All Rights Reserved */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
407c478bd9Sstevel@tonic-gate * The Regents of the University of California
417c478bd9Sstevel@tonic-gate * All Rights Reserved
427c478bd9Sstevel@tonic-gate *
437c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
447c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
457c478bd9Sstevel@tonic-gate * contributors.
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include <stdio.h>
497c478bd9Sstevel@tonic-gate #include <sys/types.h>
507c478bd9Sstevel@tonic-gate #include <stdlib.h>
517c478bd9Sstevel@tonic-gate #include <unistd.h>
527c478bd9Sstevel@tonic-gate #include <string.h>
537c478bd9Sstevel@tonic-gate #include <syslog.h>
547c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
557c478bd9Sstevel@tonic-gate #include <rpcsvc/sm_inter.h>
567c478bd9Sstevel@tonic-gate #include <rpcsvc/nsm_addr.h>
577c478bd9Sstevel@tonic-gate #include <memory.h>
587c478bd9Sstevel@tonic-gate #include <net/if.h>
597c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
607c478bd9Sstevel@tonic-gate #include <sys/socket.h>
617c478bd9Sstevel@tonic-gate #include <netinet/in.h>
627c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
637c478bd9Sstevel@tonic-gate #include <netdb.h>
647c478bd9Sstevel@tonic-gate #include <netdir.h>
657c478bd9Sstevel@tonic-gate #include <synch.h>
667c478bd9Sstevel@tonic-gate #include <thread.h>
67bbaa8b60SDan Kruchinin #include <ifaddrs.h>
68bbaa8b60SDan Kruchinin #include <errno.h>
697c478bd9Sstevel@tonic-gate #include <assert.h>
707c478bd9Sstevel@tonic-gate #include "sm_statd.h"
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate static int local_state; /* fake local sm state */
737c478bd9Sstevel@tonic-gate /* client name-to-address translation table */
747c478bd9Sstevel@tonic-gate static name_addr_entry_t *name_addr = NULL;
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate #define LOGHOST "loghost"
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate static void delete_mon(char *mon_name, my_id *my_idp);
807c478bd9Sstevel@tonic-gate static void insert_mon(mon *monp);
817c478bd9Sstevel@tonic-gate static void pr_mon(char *);
827c478bd9Sstevel@tonic-gate static int statd_call_lockd(mon *monp, int state);
837c478bd9Sstevel@tonic-gate static int hostname_eq(char *host1, char *host2);
847c478bd9Sstevel@tonic-gate static char *get_system_id(char *hostname);
857c478bd9Sstevel@tonic-gate static void add_aliases(struct hostent *phost);
867c478bd9Sstevel@tonic-gate static void *thr_send_notice(void *);
877c478bd9Sstevel@tonic-gate static void delete_onemon(char *mon_name, my_id *my_idp,
887c478bd9Sstevel@tonic-gate mon_entry **monitor_q);
897c478bd9Sstevel@tonic-gate static void send_notice(char *mon_name, int state);
907c478bd9Sstevel@tonic-gate static void add_to_host_array(char *host);
917c478bd9Sstevel@tonic-gate static int in_host_array(char *host);
927c478bd9Sstevel@tonic-gate static void pr_name_addr(name_addr_entry_t *name_addr);
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate extern int self_check(char *hostname);
957c478bd9Sstevel@tonic-gate extern struct lifconf *getmyaddrs(void);
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate /* ARGSUSED */
987c478bd9Sstevel@tonic-gate void
sm_stat_svc(sm_name * namep,sm_stat_res * resp)99bbaa8b60SDan Kruchinin sm_stat_svc(sm_name *namep, sm_stat_res *resp)
1007c478bd9Sstevel@tonic-gate {
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate if (debug)
1037c478bd9Sstevel@tonic-gate (void) printf("proc sm_stat: mon_name = %s\n",
1047c478bd9Sstevel@tonic-gate namep->mon_name);
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate resp->res_stat = stat_succ;
1077c478bd9Sstevel@tonic-gate resp->state = LOCAL_STATE;
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate /* ARGSUSED */
1117c478bd9Sstevel@tonic-gate void
sm_mon_svc(mon * monp,sm_stat_res * resp)112bbaa8b60SDan Kruchinin sm_mon_svc(mon *monp, sm_stat_res *resp)
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate mon_id *monidp;
1157c478bd9Sstevel@tonic-gate monidp = &monp->mon_id;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate rw_rdlock(&thr_rwlock);
1187c478bd9Sstevel@tonic-gate if (debug) {
1197c478bd9Sstevel@tonic-gate (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
1207c478bd9Sstevel@tonic-gate monidp->mon_name, *((int *)monp->priv));
1217c478bd9Sstevel@tonic-gate pr_mon(monp->mon_id.mon_name);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate /* only monitor other hosts */
1257c478bd9Sstevel@tonic-gate if (self_check(monp->mon_id.mon_name) == 0) {
1267c478bd9Sstevel@tonic-gate /* store monitor request into monitor_q */
1277c478bd9Sstevel@tonic-gate insert_mon(monp);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate pr_mon(monp->mon_id.mon_name);
1317c478bd9Sstevel@tonic-gate resp->res_stat = stat_succ;
1327c478bd9Sstevel@tonic-gate resp->state = local_state;
1337c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate /* ARGSUSED */
1377c478bd9Sstevel@tonic-gate void
sm_unmon_svc(mon_id * monidp,sm_stat * resp)138bbaa8b60SDan Kruchinin sm_unmon_svc(mon_id *monidp, sm_stat *resp)
1397c478bd9Sstevel@tonic-gate {
1407c478bd9Sstevel@tonic-gate rw_rdlock(&thr_rwlock);
1417c478bd9Sstevel@tonic-gate if (debug) {
1427c478bd9Sstevel@tonic-gate (void) printf(
1437c478bd9Sstevel@tonic-gate "proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
1447c478bd9Sstevel@tonic-gate monidp->mon_name, monidp->my_id.my_name,
1457c478bd9Sstevel@tonic-gate monidp->my_id.my_prog, monidp->my_id.my_vers,
1467c478bd9Sstevel@tonic-gate monidp->my_id.my_proc);
1477c478bd9Sstevel@tonic-gate pr_mon(monidp->mon_name);
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate delete_mon(monidp->mon_name, &monidp->my_id);
1517c478bd9Sstevel@tonic-gate pr_mon(monidp->mon_name);
1527c478bd9Sstevel@tonic-gate resp->state = local_state;
1537c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate /* ARGSUSED */
1577c478bd9Sstevel@tonic-gate void
sm_unmon_all_svc(my_id * myidp,sm_stat * resp)158bbaa8b60SDan Kruchinin sm_unmon_all_svc(my_id *myidp, sm_stat *resp)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate rw_rdlock(&thr_rwlock);
1617c478bd9Sstevel@tonic-gate if (debug)
1627c478bd9Sstevel@tonic-gate (void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
1637c478bd9Sstevel@tonic-gate myidp->my_name,
1647c478bd9Sstevel@tonic-gate myidp->my_prog, myidp->my_vers,
1657c478bd9Sstevel@tonic-gate myidp->my_proc);
166*98573c19SMarcel Telka delete_mon(NULL, myidp);
1677c478bd9Sstevel@tonic-gate pr_mon(NULL);
1687c478bd9Sstevel@tonic-gate resp->state = local_state;
1697c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate * Notifies lockd specified by name that state has changed for this server.
1747c478bd9Sstevel@tonic-gate */
1757c478bd9Sstevel@tonic-gate void
sm_notify_svc(stat_chge * ntfp)176bbaa8b60SDan Kruchinin sm_notify_svc(stat_chge *ntfp)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate rw_rdlock(&thr_rwlock);
1797c478bd9Sstevel@tonic-gate if (debug)
1807c478bd9Sstevel@tonic-gate (void) printf("sm_notify: %s state =%d\n",
1817c478bd9Sstevel@tonic-gate ntfp->mon_name, ntfp->state);
1827c478bd9Sstevel@tonic-gate send_notice(ntfp->mon_name, ntfp->state);
1837c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /* ARGSUSED */
1877c478bd9Sstevel@tonic-gate void
sm_simu_crash_svc(void * myidp)188bbaa8b60SDan Kruchinin sm_simu_crash_svc(void *myidp)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate int i;
1917c478bd9Sstevel@tonic-gate struct mon_entry *monitor_q;
1927c478bd9Sstevel@tonic-gate int found = 0;
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate if (debug)
1957c478bd9Sstevel@tonic-gate (void) printf("proc sm_simu_crash\n");
196*98573c19SMarcel Telka
197*98573c19SMarcel Telka /* Only one crash should be running at a time. */
198*98573c19SMarcel Telka mutex_lock(&crash_lock);
199*98573c19SMarcel Telka if (in_crash != 0) {
2007c478bd9Sstevel@tonic-gate mutex_unlock(&crash_lock);
2017c478bd9Sstevel@tonic-gate return;
2027c478bd9Sstevel@tonic-gate }
203*98573c19SMarcel Telka in_crash = 1;
2047c478bd9Sstevel@tonic-gate mutex_unlock(&crash_lock);
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_HASHSIZE; i++) {
2077c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[i].lock);
2087c478bd9Sstevel@tonic-gate monitor_q = mon_table[i].sm_monhdp;
209*98573c19SMarcel Telka if (monitor_q != NULL) {
2107c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[i].lock);
2117c478bd9Sstevel@tonic-gate found = 1;
2127c478bd9Sstevel@tonic-gate break;
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[i].lock);
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate /*
2177c478bd9Sstevel@tonic-gate * If there are entries found in the monitor table,
2187c478bd9Sstevel@tonic-gate * initiate a crash, else zero out the in_crash variable.
2197c478bd9Sstevel@tonic-gate */
2207c478bd9Sstevel@tonic-gate if (found) {
2217c478bd9Sstevel@tonic-gate mutex_lock(&crash_lock);
2227c478bd9Sstevel@tonic-gate die = 1;
223*98573c19SMarcel Telka /* Signal sm_try() thread if sleeping. */
2247c478bd9Sstevel@tonic-gate cond_signal(&retrywait);
2257c478bd9Sstevel@tonic-gate mutex_unlock(&crash_lock);
2267c478bd9Sstevel@tonic-gate rw_wrlock(&thr_rwlock);
2277c478bd9Sstevel@tonic-gate sm_crash();
2287c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
2297c478bd9Sstevel@tonic-gate } else {
2307c478bd9Sstevel@tonic-gate mutex_lock(&crash_lock);
2317c478bd9Sstevel@tonic-gate in_crash = 0;
2327c478bd9Sstevel@tonic-gate mutex_unlock(&crash_lock);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate /* ARGSUSED */
2377c478bd9Sstevel@tonic-gate void
nsmaddrproc1_reg(reg1args * regargs,reg1res * regresp)238*98573c19SMarcel Telka nsmaddrproc1_reg(reg1args *regargs, reg1res *regresp)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate nsm_addr_res status;
2417c478bd9Sstevel@tonic-gate name_addr_entry_t *entry;
2427c478bd9Sstevel@tonic-gate char *tmp_n_bytes;
2437c478bd9Sstevel@tonic-gate addr_entry_t *addr;
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate rw_rdlock(&thr_rwlock);
2467c478bd9Sstevel@tonic-gate if (debug) {
2477c478bd9Sstevel@tonic-gate int i;
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate (void) printf("nap1_reg: fam= %d, name= %s, len= %d\n",
250*98573c19SMarcel Telka regargs->family, regargs->name, regargs->address.n_len);
2517c478bd9Sstevel@tonic-gate (void) printf("address is: ");
2527c478bd9Sstevel@tonic-gate for (i = 0; i < regargs->address.n_len; i++) {
2537c478bd9Sstevel@tonic-gate (void) printf("%d.",
2547c478bd9Sstevel@tonic-gate (unsigned char)regargs->address.n_bytes[i]);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate (void) printf("\n");
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate * Locate the entry with the name in the NSM_ADDR_REG request if
2617c478bd9Sstevel@tonic-gate * it exists. If it doesn't, create a new entry to hold this name.
2627c478bd9Sstevel@tonic-gate * The first time through this code, name_addr starts out as NULL.
2637c478bd9Sstevel@tonic-gate */
2647c478bd9Sstevel@tonic-gate mutex_lock(&name_addrlock);
2657c478bd9Sstevel@tonic-gate for (entry = name_addr; entry; entry = entry->next) {
2667c478bd9Sstevel@tonic-gate if (strcmp(regargs->name, entry->name) == 0) {
2677c478bd9Sstevel@tonic-gate if (debug) {
2687c478bd9Sstevel@tonic-gate (void) printf("nap1_reg: matched name %s\n",
2697c478bd9Sstevel@tonic-gate entry->name);
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate break;
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate if (entry == NULL) {
2767c478bd9Sstevel@tonic-gate entry = (name_addr_entry_t *)malloc(sizeof (*entry));
2777c478bd9Sstevel@tonic-gate if (entry == NULL) {
2787c478bd9Sstevel@tonic-gate if (debug) {
2797c478bd9Sstevel@tonic-gate (void) printf(
2807c478bd9Sstevel@tonic-gate "nsmaddrproc1_reg: no memory for entry\n");
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate status = nsm_addr_fail;
2837c478bd9Sstevel@tonic-gate goto done;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate entry->name = strdup(regargs->name);
2877c478bd9Sstevel@tonic-gate if (entry->name == NULL) {
2887c478bd9Sstevel@tonic-gate if (debug) {
2897c478bd9Sstevel@tonic-gate (void) printf(
2907c478bd9Sstevel@tonic-gate "nsmaddrproc1_reg: no memory for name\n");
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate free(entry);
2937c478bd9Sstevel@tonic-gate status = nsm_addr_fail;
2947c478bd9Sstevel@tonic-gate goto done;
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate entry->addresses = NULL;
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate /*
2997c478bd9Sstevel@tonic-gate * Link the new entry onto the *head* of the name_addr
3007c478bd9Sstevel@tonic-gate * table.
3017c478bd9Sstevel@tonic-gate *
3027c478bd9Sstevel@tonic-gate * Note: there is code below in the address maintenance
3037c478bd9Sstevel@tonic-gate * section that assumes this behavior.
3047c478bd9Sstevel@tonic-gate */
3057c478bd9Sstevel@tonic-gate entry->next = name_addr;
3067c478bd9Sstevel@tonic-gate name_addr = entry;
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate /*
3107c478bd9Sstevel@tonic-gate * Try to match the address in the request; if it doesn't match,
3117c478bd9Sstevel@tonic-gate * add it to the entry's address list.
3127c478bd9Sstevel@tonic-gate */
3137c478bd9Sstevel@tonic-gate for (addr = entry->addresses; addr; addr = addr->next) {
3147c478bd9Sstevel@tonic-gate if (addr->family == (sa_family_t)regargs->family &&
3157c478bd9Sstevel@tonic-gate addr->ah.n_len == regargs->address.n_len &&
3167c478bd9Sstevel@tonic-gate memcmp(addr->ah.n_bytes, regargs->address.n_bytes,
3177c478bd9Sstevel@tonic-gate addr->ah.n_len) == 0) {
3187c478bd9Sstevel@tonic-gate if (debug) {
3197c478bd9Sstevel@tonic-gate int i;
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate (void) printf("nap1_reg: matched addr ");
3227c478bd9Sstevel@tonic-gate for (i = 0; i < addr->ah.n_len; i++) {
3237c478bd9Sstevel@tonic-gate (void) printf("%d.",
3247c478bd9Sstevel@tonic-gate (unsigned char)addr->ah.n_bytes[i]);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate (void) printf(" family %d for name %s\n",
327*98573c19SMarcel Telka addr->family, entry->name);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate break;
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate if (addr == NULL) {
3347c478bd9Sstevel@tonic-gate addr = (addr_entry_t *)malloc(sizeof (*addr));
3357c478bd9Sstevel@tonic-gate tmp_n_bytes = (char *)malloc(regargs->address.n_len);
3367c478bd9Sstevel@tonic-gate if (addr == NULL || tmp_n_bytes == NULL) {
3377c478bd9Sstevel@tonic-gate if (debug) {
338*98573c19SMarcel Telka (void) printf("nap1_reg: no memory for addr\n");
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate /*
3427c478bd9Sstevel@tonic-gate * If this name entry was just newly made in the
3437c478bd9Sstevel@tonic-gate * table, back it out now that we can't register
3447c478bd9Sstevel@tonic-gate * an address with it anyway.
3457c478bd9Sstevel@tonic-gate *
3467c478bd9Sstevel@tonic-gate * Note: we are making an assumption about how
3477c478bd9Sstevel@tonic-gate * names are added to (the head of) name_addr here.
3487c478bd9Sstevel@tonic-gate */
3497c478bd9Sstevel@tonic-gate if (entry == name_addr && entry->addresses == NULL) {
3507c478bd9Sstevel@tonic-gate name_addr = name_addr->next;
3517c478bd9Sstevel@tonic-gate free(entry->name);
3527c478bd9Sstevel@tonic-gate free(entry);
3537c478bd9Sstevel@tonic-gate if (tmp_n_bytes)
3547c478bd9Sstevel@tonic-gate free(tmp_n_bytes);
3557c478bd9Sstevel@tonic-gate if (addr)
3567c478bd9Sstevel@tonic-gate free(addr);
3577c478bd9Sstevel@tonic-gate status = nsm_addr_fail;
3587c478bd9Sstevel@tonic-gate goto done;
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate /*
3637c478bd9Sstevel@tonic-gate * Note: this check for address family assumes that we
3647c478bd9Sstevel@tonic-gate * will get something different here someday for
3657c478bd9Sstevel@tonic-gate * other supported address types, such as IPv6.
3667c478bd9Sstevel@tonic-gate */
3677c478bd9Sstevel@tonic-gate addr->ah.n_len = regargs->address.n_len;
3687c478bd9Sstevel@tonic-gate addr->ah.n_bytes = tmp_n_bytes;
3697c478bd9Sstevel@tonic-gate addr->family = regargs->family;
3707c478bd9Sstevel@tonic-gate if (debug) {
371*98573c19SMarcel Telka if ((addr->family != AF_INET) &&
3727c478bd9Sstevel@tonic-gate (addr->family != AF_INET6)) {
3737c478bd9Sstevel@tonic-gate (void) printf(
3747c478bd9Sstevel@tonic-gate "nap1_reg: unknown addr family %d\n",
3757c478bd9Sstevel@tonic-gate addr->family);
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate (void) memcpy(addr->ah.n_bytes, regargs->address.n_bytes,
3797c478bd9Sstevel@tonic-gate addr->ah.n_len);
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate addr->next = entry->addresses;
3827c478bd9Sstevel@tonic-gate entry->addresses = addr;
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate status = nsm_addr_succ;
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate done:
3887c478bd9Sstevel@tonic-gate regresp->status = status;
3897c478bd9Sstevel@tonic-gate if (debug) {
3907c478bd9Sstevel@tonic-gate pr_name_addr(name_addr);
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate mutex_unlock(&name_addrlock);
3937c478bd9Sstevel@tonic-gate rw_unlock(&thr_rwlock);
3947c478bd9Sstevel@tonic-gate }
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate /*
3977c478bd9Sstevel@tonic-gate * Insert an entry into the monitor_q. Space for the entry is allocated
3987c478bd9Sstevel@tonic-gate * here. It is then filled in from the information passed in.
3997c478bd9Sstevel@tonic-gate */
4007c478bd9Sstevel@tonic-gate static void
insert_mon(mon * monp)401*98573c19SMarcel Telka insert_mon(mon *monp)
4027c478bd9Sstevel@tonic-gate {
4037c478bd9Sstevel@tonic-gate mon_entry *new, *found;
4047c478bd9Sstevel@tonic-gate my_id *my_idp, *nl_idp;
4057c478bd9Sstevel@tonic-gate mon_entry *monitor_q;
4067c478bd9Sstevel@tonic-gate unsigned int hash;
4077c478bd9Sstevel@tonic-gate name_addr_entry_t *entry;
4087c478bd9Sstevel@tonic-gate addr_entry_t *addr;
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate /* Allocate entry for new */
4117c478bd9Sstevel@tonic-gate if ((new = (mon_entry *) malloc(sizeof (mon_entry))) == 0) {
4127c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
4137c478bd9Sstevel@tonic-gate "statd: insert_mon: malloc error on mon %s (id=%d)\n",
4147c478bd9Sstevel@tonic-gate monp->mon_id.mon_name, *((int *)monp->priv));
4157c478bd9Sstevel@tonic-gate return;
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate /* Initialize and copy contents of monp to new */
4197c478bd9Sstevel@tonic-gate (void) memset(new, 0, sizeof (mon_entry));
4207c478bd9Sstevel@tonic-gate (void) memcpy(&new->id, monp, sizeof (mon));
4217c478bd9Sstevel@tonic-gate
4227c478bd9Sstevel@tonic-gate /* Allocate entry for new mon_name */
4237c478bd9Sstevel@tonic-gate if ((new->id.mon_id.mon_name = strdup(monp->mon_id.mon_name)) == 0) {
4247c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
4257c478bd9Sstevel@tonic-gate "statd: insert_mon: malloc error on mon %s (id=%d)\n",
4267c478bd9Sstevel@tonic-gate monp->mon_id.mon_name, *((int *)monp->priv));
4277c478bd9Sstevel@tonic-gate free(new);
4287c478bd9Sstevel@tonic-gate return;
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate /* Allocate entry for new my_name */
4337c478bd9Sstevel@tonic-gate if ((new->id.mon_id.my_id.my_name =
4347c478bd9Sstevel@tonic-gate strdup(monp->mon_id.my_id.my_name)) == 0) {
4357c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
4367c478bd9Sstevel@tonic-gate "statd: insert_mon: malloc error on mon %s (id=%d)\n",
4377c478bd9Sstevel@tonic-gate monp->mon_id.mon_name, *((int *)monp->priv));
4387c478bd9Sstevel@tonic-gate free(new->id.mon_id.mon_name);
4397c478bd9Sstevel@tonic-gate free(new);
4407c478bd9Sstevel@tonic-gate return;
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate if (debug)
4447c478bd9Sstevel@tonic-gate (void) printf("add_mon(%x) %s (id=%d)\n",
4457c478bd9Sstevel@tonic-gate (int)new, new->id.mon_id.mon_name, *((int *)new->id.priv));
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate /*
4487c478bd9Sstevel@tonic-gate * Record the name, and all addresses which have been registered
4497c478bd9Sstevel@tonic-gate * for this name, in the filesystem name space.
4507c478bd9Sstevel@tonic-gate */
4517c478bd9Sstevel@tonic-gate record_name(new->id.mon_id.mon_name, 1);
4527c478bd9Sstevel@tonic-gate if (regfiles_only == 0) {
4537c478bd9Sstevel@tonic-gate mutex_lock(&name_addrlock);
4547c478bd9Sstevel@tonic-gate for (entry = name_addr; entry; entry = entry->next) {
4557c478bd9Sstevel@tonic-gate if (strcmp(new->id.mon_id.mon_name, entry->name) != 0) {
4567c478bd9Sstevel@tonic-gate continue;
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate for (addr = entry->addresses; addr; addr = addr->next) {
4607c478bd9Sstevel@tonic-gate record_addr(new->id.mon_id.mon_name,
4617c478bd9Sstevel@tonic-gate addr->family, &addr->ah);
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate break;
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate mutex_unlock(&name_addrlock);
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate SMHASH(new->id.mon_id.mon_name, hash);
4697c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
4707c478bd9Sstevel@tonic-gate monitor_q = mon_table[hash].sm_monhdp;
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gate /* If mon_table hash list is empty. */
473*98573c19SMarcel Telka if (monitor_q == NULL) {
4747c478bd9Sstevel@tonic-gate if (debug)
4757c478bd9Sstevel@tonic-gate (void) printf("\nAdding to monitor_q hash %d\n", hash);
476*98573c19SMarcel Telka new->nxt = new->prev = NULL;
4777c478bd9Sstevel@tonic-gate mon_table[hash].sm_monhdp = new;
4787c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
4797c478bd9Sstevel@tonic-gate return;
4807c478bd9Sstevel@tonic-gate } else {
4817c478bd9Sstevel@tonic-gate found = 0;
4827c478bd9Sstevel@tonic-gate my_idp = &new->id.mon_id.my_id;
483*98573c19SMarcel Telka while (monitor_q != NULL) {
4847c478bd9Sstevel@tonic-gate /*
4857c478bd9Sstevel@tonic-gate * This list is searched sequentially for the
4867c478bd9Sstevel@tonic-gate * tuple (hostname, prog, vers, proc). The tuples
4877c478bd9Sstevel@tonic-gate * are inserted in the beginning of the monitor_q,
4887c478bd9Sstevel@tonic-gate * if the hostname is not already present in the list.
4897c478bd9Sstevel@tonic-gate * If the hostname is found in the list, the incoming
4907c478bd9Sstevel@tonic-gate * tuple is inserted just after all the tuples with the
4917c478bd9Sstevel@tonic-gate * same hostname. However, if the tuple matches exactly
4927c478bd9Sstevel@tonic-gate * with an entry in the list, space allocated for the
4937c478bd9Sstevel@tonic-gate * new entry is released and nothing is inserted in the
4947c478bd9Sstevel@tonic-gate * list.
4957c478bd9Sstevel@tonic-gate */
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate if (str_cmp_unqual_hostname(
4987c478bd9Sstevel@tonic-gate monitor_q->id.mon_id.mon_name,
4997c478bd9Sstevel@tonic-gate new->id.mon_id.mon_name) == 0) {
5007c478bd9Sstevel@tonic-gate /* found */
5017c478bd9Sstevel@tonic-gate nl_idp = &monitor_q->id.mon_id.my_id;
5027c478bd9Sstevel@tonic-gate if ((str_cmp_unqual_hostname(my_idp->my_name,
5037c478bd9Sstevel@tonic-gate nl_idp->my_name) == 0) &&
5047c478bd9Sstevel@tonic-gate my_idp->my_prog == nl_idp->my_prog &&
5057c478bd9Sstevel@tonic-gate my_idp->my_vers == nl_idp->my_vers &&
5067c478bd9Sstevel@tonic-gate my_idp->my_proc == nl_idp->my_proc) {
5077c478bd9Sstevel@tonic-gate /*
5087c478bd9Sstevel@tonic-gate * already exists an identical one,
5097c478bd9Sstevel@tonic-gate * release the space allocated for the
5107c478bd9Sstevel@tonic-gate * mon_entry
5117c478bd9Sstevel@tonic-gate */
5127c478bd9Sstevel@tonic-gate free(new->id.mon_id.mon_name);
5137c478bd9Sstevel@tonic-gate free(new->id.mon_id.my_id.my_name);
5147c478bd9Sstevel@tonic-gate free(new);
5157c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
5167c478bd9Sstevel@tonic-gate return;
5177c478bd9Sstevel@tonic-gate } else {
5187c478bd9Sstevel@tonic-gate /*
5197c478bd9Sstevel@tonic-gate * mark the last callback that is
5207c478bd9Sstevel@tonic-gate * not matching; new is inserted
5217c478bd9Sstevel@tonic-gate * after this
5227c478bd9Sstevel@tonic-gate */
5237c478bd9Sstevel@tonic-gate found = monitor_q;
5247c478bd9Sstevel@tonic-gate }
5257c478bd9Sstevel@tonic-gate } else if (found)
5267c478bd9Sstevel@tonic-gate break;
5277c478bd9Sstevel@tonic-gate monitor_q = monitor_q->nxt;
5287c478bd9Sstevel@tonic-gate }
5297c478bd9Sstevel@tonic-gate if (found) {
5307c478bd9Sstevel@tonic-gate /*
5317c478bd9Sstevel@tonic-gate * insert just after the entry having matching tuple.
5327c478bd9Sstevel@tonic-gate */
5337c478bd9Sstevel@tonic-gate new->nxt = found->nxt;
5347c478bd9Sstevel@tonic-gate new->prev = found;
535*98573c19SMarcel Telka if (found->nxt != NULL)
5367c478bd9Sstevel@tonic-gate found->nxt->prev = new;
5377c478bd9Sstevel@tonic-gate found->nxt = new;
5387c478bd9Sstevel@tonic-gate } else {
5397c478bd9Sstevel@tonic-gate /*
5407c478bd9Sstevel@tonic-gate * not found, insert in front of list.
5417c478bd9Sstevel@tonic-gate */
5427c478bd9Sstevel@tonic-gate new->nxt = mon_table[hash].sm_monhdp;
5437c478bd9Sstevel@tonic-gate new->prev = (mon_entry *) NULL;
5447c478bd9Sstevel@tonic-gate if (new->nxt != (mon_entry *) NULL)
5457c478bd9Sstevel@tonic-gate new->nxt->prev = new;
5467c478bd9Sstevel@tonic-gate mon_table[hash].sm_monhdp = new;
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
5497c478bd9Sstevel@tonic-gate return;
5507c478bd9Sstevel@tonic-gate }
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate
5537c478bd9Sstevel@tonic-gate /*
5547c478bd9Sstevel@tonic-gate * Deletes a specific monitor name or deletes all monitors with same id
5557c478bd9Sstevel@tonic-gate * in hash table.
5567c478bd9Sstevel@tonic-gate */
5577c478bd9Sstevel@tonic-gate static void
delete_mon(char * mon_name,my_id * my_idp)558*98573c19SMarcel Telka delete_mon(char *mon_name, my_id *my_idp)
5597c478bd9Sstevel@tonic-gate {
5607c478bd9Sstevel@tonic-gate unsigned int hash;
5617c478bd9Sstevel@tonic-gate
562*98573c19SMarcel Telka if (mon_name != NULL) {
5637c478bd9Sstevel@tonic-gate record_name(mon_name, 0);
5647c478bd9Sstevel@tonic-gate SMHASH(mon_name, hash);
5657c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
5667c478bd9Sstevel@tonic-gate delete_onemon(mon_name, my_idp, &mon_table[hash].sm_monhdp);
5677c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
5687c478bd9Sstevel@tonic-gate } else {
5697c478bd9Sstevel@tonic-gate for (hash = 0; hash < MAX_HASHSIZE; hash++) {
5707c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
5717c478bd9Sstevel@tonic-gate delete_onemon(mon_name, my_idp,
5727c478bd9Sstevel@tonic-gate &mon_table[hash].sm_monhdp);
5737c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate /*
5797c478bd9Sstevel@tonic-gate * Deletes a monitor in list.
5807c478bd9Sstevel@tonic-gate * IF mon_name is NULL, delete all mon_names that have the same id,
5817c478bd9Sstevel@tonic-gate * else delete specific monitor.
5827c478bd9Sstevel@tonic-gate */
5837c478bd9Sstevel@tonic-gate void
delete_onemon(char * mon_name,my_id * my_idp,mon_entry ** monitor_q)584*98573c19SMarcel Telka delete_onemon(char *mon_name, my_id *my_idp, mon_entry **monitor_q)
5857c478bd9Sstevel@tonic-gate {
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate mon_entry *next, *nl;
5887c478bd9Sstevel@tonic-gate my_id *nl_idp;
5897c478bd9Sstevel@tonic-gate
5907c478bd9Sstevel@tonic-gate next = *monitor_q;
591*98573c19SMarcel Telka while ((nl = next) != NULL) {
5927c478bd9Sstevel@tonic-gate next = next->nxt;
593*98573c19SMarcel Telka if (mon_name == NULL || (mon_name != NULL &&
5947c478bd9Sstevel@tonic-gate str_cmp_unqual_hostname(nl->id.mon_id.mon_name,
5957c478bd9Sstevel@tonic-gate mon_name) == 0)) {
5967c478bd9Sstevel@tonic-gate nl_idp = &nl->id.mon_id.my_id;
5977c478bd9Sstevel@tonic-gate if ((str_cmp_unqual_hostname(my_idp->my_name,
5987c478bd9Sstevel@tonic-gate nl_idp->my_name) == 0) &&
5997c478bd9Sstevel@tonic-gate my_idp->my_prog == nl_idp->my_prog &&
6007c478bd9Sstevel@tonic-gate my_idp->my_vers == nl_idp->my_vers &&
6017c478bd9Sstevel@tonic-gate my_idp->my_proc == nl_idp->my_proc) {
6027c478bd9Sstevel@tonic-gate /* found */
6037c478bd9Sstevel@tonic-gate if (debug)
6047c478bd9Sstevel@tonic-gate (void) printf("delete_mon(%x): %s\n",
6057c478bd9Sstevel@tonic-gate (int)nl, mon_name ?
6067c478bd9Sstevel@tonic-gate mon_name : "<NULL>");
6077c478bd9Sstevel@tonic-gate /*
6087c478bd9Sstevel@tonic-gate * Remove the monitor name from the
6097c478bd9Sstevel@tonic-gate * record_q, if id matches.
6107c478bd9Sstevel@tonic-gate */
6117c478bd9Sstevel@tonic-gate record_name(nl->id.mon_id.mon_name, 0);
6127c478bd9Sstevel@tonic-gate /* if nl is not the first entry on list */
613*98573c19SMarcel Telka if (nl->prev != NULL)
6147c478bd9Sstevel@tonic-gate nl->prev->nxt = nl->nxt;
6157c478bd9Sstevel@tonic-gate else {
6167c478bd9Sstevel@tonic-gate *monitor_q = nl->nxt;
6177c478bd9Sstevel@tonic-gate }
618*98573c19SMarcel Telka if (nl->nxt != NULL)
6197c478bd9Sstevel@tonic-gate nl->nxt->prev = nl->prev;
6207c478bd9Sstevel@tonic-gate free(nl->id.mon_id.mon_name);
6217c478bd9Sstevel@tonic-gate free(nl_idp->my_name);
6227c478bd9Sstevel@tonic-gate free(nl);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate } /* end of if mon */
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate /*
6297c478bd9Sstevel@tonic-gate * Notify lockd of host specified by mon_name that the specified state
6307c478bd9Sstevel@tonic-gate * has changed.
6317c478bd9Sstevel@tonic-gate */
6327c478bd9Sstevel@tonic-gate static void
send_notice(char * mon_name,int state)633*98573c19SMarcel Telka send_notice(char *mon_name, int state)
6347c478bd9Sstevel@tonic-gate {
6357c478bd9Sstevel@tonic-gate struct mon_entry *next;
6367c478bd9Sstevel@tonic-gate mon_entry *monitor_q;
6377c478bd9Sstevel@tonic-gate unsigned int hash;
6387c478bd9Sstevel@tonic-gate moninfo_t *minfop;
6397c478bd9Sstevel@tonic-gate mon *monp;
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate SMHASH(mon_name, hash);
6427c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
6437c478bd9Sstevel@tonic-gate monitor_q = mon_table[hash].sm_monhdp;
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate next = monitor_q;
646*98573c19SMarcel Telka while (next != NULL) {
6477c478bd9Sstevel@tonic-gate if (hostname_eq(next->id.mon_id.mon_name, mon_name)) {
6487c478bd9Sstevel@tonic-gate monp = &next->id;
6497c478bd9Sstevel@tonic-gate /*
6507c478bd9Sstevel@tonic-gate * Prepare the minfop structure to pass to
6517c478bd9Sstevel@tonic-gate * thr_create(). This structure is a copy of
6527c478bd9Sstevel@tonic-gate * mon info and state.
6537c478bd9Sstevel@tonic-gate */
6547c478bd9Sstevel@tonic-gate if ((minfop =
655*98573c19SMarcel Telka (moninfo_t *)xmalloc(sizeof (moninfo_t))) != NULL) {
6567c478bd9Sstevel@tonic-gate (void) memcpy(&minfop->id, monp, sizeof (mon));
6577c478bd9Sstevel@tonic-gate /* Allocate entry for mon_name */
6587c478bd9Sstevel@tonic-gate if ((minfop->id.mon_id.mon_name =
6597c478bd9Sstevel@tonic-gate strdup(monp->mon_id.mon_name)) == 0) {
660*98573c19SMarcel Telka syslog(LOG_ERR, "statd: send_notice: "
661*98573c19SMarcel Telka "malloc error on mon %s (id=%d)\n",
6627c478bd9Sstevel@tonic-gate monp->mon_id.mon_name,
6637c478bd9Sstevel@tonic-gate *((int *)monp->priv));
6647c478bd9Sstevel@tonic-gate free(minfop);
6657c478bd9Sstevel@tonic-gate continue;
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate /* Allocate entry for my_name */
6687c478bd9Sstevel@tonic-gate if ((minfop->id.mon_id.my_id.my_name =
6697c478bd9Sstevel@tonic-gate strdup(monp->mon_id.my_id.my_name)) == 0) {
670*98573c19SMarcel Telka syslog(LOG_ERR, "statd: send_notice: "
671*98573c19SMarcel Telka "malloc error on mon %s (id=%d)\n",
6727c478bd9Sstevel@tonic-gate monp->mon_id.mon_name,
6737c478bd9Sstevel@tonic-gate *((int *)monp->priv));
6747c478bd9Sstevel@tonic-gate free(minfop->id.mon_id.mon_name);
6757c478bd9Sstevel@tonic-gate free(minfop);
6767c478bd9Sstevel@tonic-gate continue;
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate minfop->state = state;
6797c478bd9Sstevel@tonic-gate /*
6807c478bd9Sstevel@tonic-gate * Create detached threads to process each host
6817c478bd9Sstevel@tonic-gate * to notify. If error, print out msg, free
6827c478bd9Sstevel@tonic-gate * resources and continue.
6837c478bd9Sstevel@tonic-gate */
6847c478bd9Sstevel@tonic-gate if (thr_create(NULL, NULL, thr_send_notice,
685*98573c19SMarcel Telka minfop, THR_DETACHED, NULL)) {
686*98573c19SMarcel Telka syslog(LOG_ERR, "statd: unable to "
687*98573c19SMarcel Telka "create thread to send_notice to "
688*98573c19SMarcel Telka "%s.\n", mon_name);
6897c478bd9Sstevel@tonic-gate free(minfop->id.mon_id.mon_name);
6907c478bd9Sstevel@tonic-gate free(minfop->id.mon_id.my_id.my_name);
6917c478bd9Sstevel@tonic-gate free(minfop);
6927c478bd9Sstevel@tonic-gate continue;
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate }
6957c478bd9Sstevel@tonic-gate }
6967c478bd9Sstevel@tonic-gate next = next->nxt;
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate /*
7027c478bd9Sstevel@tonic-gate * Work thread created to do the actual statd_call_lockd
7037c478bd9Sstevel@tonic-gate */
7047c478bd9Sstevel@tonic-gate static void *
thr_send_notice(void * arg)7057c478bd9Sstevel@tonic-gate thr_send_notice(void *arg)
7067c478bd9Sstevel@tonic-gate {
7077c478bd9Sstevel@tonic-gate moninfo_t *minfop;
7087c478bd9Sstevel@tonic-gate
7097c478bd9Sstevel@tonic-gate minfop = (moninfo_t *)arg;
7107c478bd9Sstevel@tonic-gate if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
7117c478bd9Sstevel@tonic-gate if (debug && minfop->id.mon_id.mon_name)
712b17f03d7SMarcel Telka (void) printf("problem with notifying %s failure, "
713b17f03d7SMarcel Telka "give up\n", minfop->id.mon_id.mon_name);
7147c478bd9Sstevel@tonic-gate } else {
7157c478bd9Sstevel@tonic-gate if (debug)
716b17f03d7SMarcel Telka (void) printf("send_notice: %s, %d notified.\n",
7177c478bd9Sstevel@tonic-gate minfop->id.mon_id.mon_name, minfop->state);
7187c478bd9Sstevel@tonic-gate }
7197c478bd9Sstevel@tonic-gate
7207c478bd9Sstevel@tonic-gate free(minfop->id.mon_id.mon_name);
7217c478bd9Sstevel@tonic-gate free(minfop->id.mon_id.my_id.my_name);
7227c478bd9Sstevel@tonic-gate free(minfop);
7237c478bd9Sstevel@tonic-gate
7247c478bd9Sstevel@tonic-gate thr_exit((void *) 0);
7257c478bd9Sstevel@tonic-gate #ifdef lint
7267c478bd9Sstevel@tonic-gate /*NOTREACHED*/
7277c478bd9Sstevel@tonic-gate return ((void *)0);
7287c478bd9Sstevel@tonic-gate #endif
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate /*
7327c478bd9Sstevel@tonic-gate * Contact lockd specified by monp.
7337c478bd9Sstevel@tonic-gate */
7347c478bd9Sstevel@tonic-gate static int
statd_call_lockd(mon * monp,int state)735*98573c19SMarcel Telka statd_call_lockd(mon *monp, int state)
7367c478bd9Sstevel@tonic-gate {
7377c478bd9Sstevel@tonic-gate enum clnt_stat clnt_stat;
7387c478bd9Sstevel@tonic-gate struct timeval tottimeout;
739bbaa8b60SDan Kruchinin struct sm_status stat;
7407c478bd9Sstevel@tonic-gate my_id *my_idp;
7417c478bd9Sstevel@tonic-gate char *mon_name;
7427c478bd9Sstevel@tonic-gate int i;
7437c478bd9Sstevel@tonic-gate int rc = 0;
7447c478bd9Sstevel@tonic-gate CLIENT *clnt;
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate mon_name = monp->mon_id.mon_name;
7477c478bd9Sstevel@tonic-gate my_idp = &monp->mon_id.my_id;
748bbaa8b60SDan Kruchinin (void) memset(&stat, 0, sizeof (stat));
7497c478bd9Sstevel@tonic-gate stat.mon_name = mon_name;
7507c478bd9Sstevel@tonic-gate stat.state = state;
7517c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) {
7527c478bd9Sstevel@tonic-gate stat.priv[i] = monp->priv[i];
7537c478bd9Sstevel@tonic-gate }
7547c478bd9Sstevel@tonic-gate if (debug)
7557c478bd9Sstevel@tonic-gate (void) printf("statd_call_lockd: %s state = %d\n",
7567c478bd9Sstevel@tonic-gate stat.mon_name, stat.state);
7577c478bd9Sstevel@tonic-gate
758a6f0fae9Sgt29601 tottimeout.tv_sec = SM_RPC_TIMEOUT;
759a6f0fae9Sgt29601 tottimeout.tv_usec = 0;
760a6f0fae9Sgt29601
761bbaa8b60SDan Kruchinin clnt = create_client(my_idp->my_name, my_idp->my_prog, my_idp->my_vers,
762bbaa8b60SDan Kruchinin "ticotsord", &tottimeout);
763bbaa8b60SDan Kruchinin if (clnt == NULL) {
7647c478bd9Sstevel@tonic-gate return (-1);
7657c478bd9Sstevel@tonic-gate }
7667c478bd9Sstevel@tonic-gate
767*98573c19SMarcel Telka clnt_stat = clnt_call(clnt, my_idp->my_proc, xdr_sm_status,
768*98573c19SMarcel Telka (char *)&stat, xdr_void, NULL, tottimeout);
7697c478bd9Sstevel@tonic-gate if (debug) {
7707c478bd9Sstevel@tonic-gate (void) printf("clnt_stat=%s(%d)\n",
7717c478bd9Sstevel@tonic-gate clnt_sperrno(clnt_stat), clnt_stat);
7727c478bd9Sstevel@tonic-gate }
7737c478bd9Sstevel@tonic-gate if (clnt_stat != (int)RPC_SUCCESS) {
7747c478bd9Sstevel@tonic-gate syslog(LOG_WARNING,
7757c478bd9Sstevel@tonic-gate "statd: cannot talk to lockd at %s, %s(%d)\n",
7767c478bd9Sstevel@tonic-gate my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
7777c478bd9Sstevel@tonic-gate rc = -1;
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate
7807c478bd9Sstevel@tonic-gate clnt_destroy(clnt);
7817c478bd9Sstevel@tonic-gate return (rc);
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate }
7847c478bd9Sstevel@tonic-gate
7857c478bd9Sstevel@tonic-gate /*
7867c478bd9Sstevel@tonic-gate * Client handle created.
7877c478bd9Sstevel@tonic-gate */
7887c478bd9Sstevel@tonic-gate CLIENT *
create_client(char * host,int prognum,int versnum,char * netid,struct timeval * utimeout)789bbaa8b60SDan Kruchinin create_client(char *host, int prognum, int versnum, char *netid,
790bbaa8b60SDan Kruchinin struct timeval *utimeout)
7917c478bd9Sstevel@tonic-gate {
7927c478bd9Sstevel@tonic-gate int fd;
7937c478bd9Sstevel@tonic-gate struct timeval timeout;
7947c478bd9Sstevel@tonic-gate CLIENT *client;
7957c478bd9Sstevel@tonic-gate struct t_info tinfo;
7967c478bd9Sstevel@tonic-gate
797bbaa8b60SDan Kruchinin if (netid == NULL) {
798bbaa8b60SDan Kruchinin client = clnt_create_timed(host, prognum, versnum,
799bbaa8b60SDan Kruchinin "netpath", utimeout);
800bbaa8b60SDan Kruchinin } else {
801bbaa8b60SDan Kruchinin struct netconfig *nconf;
802bbaa8b60SDan Kruchinin
803bbaa8b60SDan Kruchinin nconf = getnetconfigent(netid);
804bbaa8b60SDan Kruchinin if (nconf == NULL) {
8057c478bd9Sstevel@tonic-gate return (NULL);
8067c478bd9Sstevel@tonic-gate }
807bbaa8b60SDan Kruchinin
808bbaa8b60SDan Kruchinin client = clnt_tp_create_timed(host, prognum, versnum, nconf,
809bbaa8b60SDan Kruchinin utimeout);
810bbaa8b60SDan Kruchinin
811bbaa8b60SDan Kruchinin freenetconfigent(nconf);
812bbaa8b60SDan Kruchinin }
813bbaa8b60SDan Kruchinin
814bbaa8b60SDan Kruchinin if (client == NULL) {
815bbaa8b60SDan Kruchinin return (NULL);
816bbaa8b60SDan Kruchinin }
817bbaa8b60SDan Kruchinin
8187c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
8197c478bd9Sstevel@tonic-gate if (t_getinfo(fd, &tinfo) != -1) {
8207c478bd9Sstevel@tonic-gate if (tinfo.servtype == T_CLTS) {
8217c478bd9Sstevel@tonic-gate /*
8227c478bd9Sstevel@tonic-gate * Set time outs for connectionless case
8237c478bd9Sstevel@tonic-gate */
8247c478bd9Sstevel@tonic-gate timeout.tv_usec = 0;
8257c478bd9Sstevel@tonic-gate timeout.tv_sec = SM_CLTS_TIMEOUT;
8267c478bd9Sstevel@tonic-gate (void) CLNT_CONTROL(client,
8277c478bd9Sstevel@tonic-gate CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate } else
8307c478bd9Sstevel@tonic-gate return (NULL);
8317c478bd9Sstevel@tonic-gate
8327c478bd9Sstevel@tonic-gate return (client);
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate
8357c478bd9Sstevel@tonic-gate /*
8367c478bd9Sstevel@tonic-gate * ONLY for debugging.
8377c478bd9Sstevel@tonic-gate * Debug messages which prints out the monitor table information.
8387c478bd9Sstevel@tonic-gate * If name is specified, just print out the hash list corresponding
8397c478bd9Sstevel@tonic-gate * to name, otherwise print out the entire monitor table.
8407c478bd9Sstevel@tonic-gate */
8417c478bd9Sstevel@tonic-gate static void
pr_mon(char * name)842*98573c19SMarcel Telka pr_mon(char *name)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate mon_entry *nl;
8457c478bd9Sstevel@tonic-gate int hash;
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate if (!debug)
8487c478bd9Sstevel@tonic-gate return;
8497c478bd9Sstevel@tonic-gate
8507c478bd9Sstevel@tonic-gate /* print all */
8517c478bd9Sstevel@tonic-gate if (name == NULL) {
8527c478bd9Sstevel@tonic-gate for (hash = 0; hash < MAX_HASHSIZE; hash++) {
8537c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
8547c478bd9Sstevel@tonic-gate nl = mon_table[hash].sm_monhdp;
855*98573c19SMarcel Telka if (nl == NULL) {
8567c478bd9Sstevel@tonic-gate (void) printf(
857*98573c19SMarcel Telka "*****monitor_q = NULL hash %d\n", hash);
8587c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
8597c478bd9Sstevel@tonic-gate continue;
8607c478bd9Sstevel@tonic-gate }
8617c478bd9Sstevel@tonic-gate (void) printf("*****monitor_q:\n ");
862*98573c19SMarcel Telka while (nl != NULL) {
8637c478bd9Sstevel@tonic-gate (void) printf("%s:(%x), ",
8647c478bd9Sstevel@tonic-gate nl->id.mon_id.mon_name, (int)nl);
8657c478bd9Sstevel@tonic-gate nl = nl->nxt;
8667c478bd9Sstevel@tonic-gate }
8677c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
8687c478bd9Sstevel@tonic-gate (void) printf("\n");
8697c478bd9Sstevel@tonic-gate }
8707c478bd9Sstevel@tonic-gate } else { /* print one hash list */
8717c478bd9Sstevel@tonic-gate SMHASH(name, hash);
8727c478bd9Sstevel@tonic-gate mutex_lock(&mon_table[hash].lock);
8737c478bd9Sstevel@tonic-gate nl = mon_table[hash].sm_monhdp;
874*98573c19SMarcel Telka if (nl == NULL) {
8757c478bd9Sstevel@tonic-gate (void) printf("*****monitor_q = NULL hash %d\n", hash);
8767c478bd9Sstevel@tonic-gate } else {
8777c478bd9Sstevel@tonic-gate (void) printf("*****monitor_q:\n ");
878*98573c19SMarcel Telka while (nl != NULL) {
8797c478bd9Sstevel@tonic-gate (void) printf("%s:(%x), ",
8807c478bd9Sstevel@tonic-gate nl->id.mon_id.mon_name, (int)nl);
8817c478bd9Sstevel@tonic-gate nl = nl->nxt;
8827c478bd9Sstevel@tonic-gate }
8837c478bd9Sstevel@tonic-gate (void) printf("\n");
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate mutex_unlock(&mon_table[hash].lock);
8867c478bd9Sstevel@tonic-gate }
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate /*
8907c478bd9Sstevel@tonic-gate * Only for debugging.
8917c478bd9Sstevel@tonic-gate * Dump the host name-to-address translation table passed in `name_addr'.
8927c478bd9Sstevel@tonic-gate */
8937c478bd9Sstevel@tonic-gate static void
pr_name_addr(name_addr_entry_t * name_addr)8947c478bd9Sstevel@tonic-gate pr_name_addr(name_addr_entry_t *name_addr)
8957c478bd9Sstevel@tonic-gate {
8967c478bd9Sstevel@tonic-gate name_addr_entry_t *entry;
8977c478bd9Sstevel@tonic-gate addr_entry_t *addr;
8987c478bd9Sstevel@tonic-gate struct in_addr ipv4_addr;
8997c478bd9Sstevel@tonic-gate char *ipv6_addr;
9007c478bd9Sstevel@tonic-gate char abuf[INET6_ADDRSTRLEN];
9017c478bd9Sstevel@tonic-gate
9027c478bd9Sstevel@tonic-gate assert(MUTEX_HELD(&name_addrlock));
9037c478bd9Sstevel@tonic-gate (void) printf("name-to-address translation table:\n");
9047c478bd9Sstevel@tonic-gate for (entry = name_addr; entry != NULL; entry = entry->next) {
9057c478bd9Sstevel@tonic-gate (void) printf("\t%s: ",
9067c478bd9Sstevel@tonic-gate (entry->name ? entry->name : "(null)"));
9077c478bd9Sstevel@tonic-gate for (addr = entry->addresses; addr; addr = addr->next) {
9087c478bd9Sstevel@tonic-gate switch (addr->family) {
9097c478bd9Sstevel@tonic-gate case AF_INET:
910b17f03d7SMarcel Telka ipv4_addr = *(struct in_addr *)addr->ah.n_bytes;
9117c478bd9Sstevel@tonic-gate (void) printf(" %s (fam %d)",
912b17f03d7SMarcel Telka inet_ntoa(ipv4_addr), addr->family);
9137c478bd9Sstevel@tonic-gate break;
9147c478bd9Sstevel@tonic-gate case AF_INET6:
9157c478bd9Sstevel@tonic-gate ipv6_addr = (char *)addr->ah.n_bytes;
9167c478bd9Sstevel@tonic-gate (void) printf(" %s (fam %d)",
917b17f03d7SMarcel Telka inet_ntop(addr->family, ipv6_addr, abuf,
918b17f03d7SMarcel Telka sizeof (abuf)), addr->family);
9197c478bd9Sstevel@tonic-gate break;
9207c478bd9Sstevel@tonic-gate default:
9217c478bd9Sstevel@tonic-gate return;
9227c478bd9Sstevel@tonic-gate }
9237c478bd9Sstevel@tonic-gate }
9247c478bd9Sstevel@tonic-gate printf("\n");
9257c478bd9Sstevel@tonic-gate }
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate
9287c478bd9Sstevel@tonic-gate /*
929b17f03d7SMarcel Telka * First, try to compare the hostnames as strings. If the hostnames does not
930b17f03d7SMarcel Telka * match we might deal with the hostname aliases. In this case two different
931b17f03d7SMarcel Telka * aliases for the same machine don't match each other when using strcmp. To
932b17f03d7SMarcel Telka * deal with this, the hostnames must be translated into some sort of universal
933b17f03d7SMarcel Telka * identifier. These identifiers can be compared. Universal network addresses
934b17f03d7SMarcel Telka * are currently used for this identifier because it is general and easy to do.
935b17f03d7SMarcel Telka * Other schemes are possible and this routine could be converted if required.
9367c478bd9Sstevel@tonic-gate *
9377c478bd9Sstevel@tonic-gate * If it can't find an address for some reason, 0 is returned.
9387c478bd9Sstevel@tonic-gate */
9397c478bd9Sstevel@tonic-gate static int
hostname_eq(char * host1,char * host2)9407c478bd9Sstevel@tonic-gate hostname_eq(char *host1, char *host2)
9417c478bd9Sstevel@tonic-gate {
9427c478bd9Sstevel@tonic-gate char *sysid1;
9437c478bd9Sstevel@tonic-gate char *sysid2;
9447c478bd9Sstevel@tonic-gate int rv;
9457c478bd9Sstevel@tonic-gate
946b17f03d7SMarcel Telka /* Compare hostnames as strings */
947b17f03d7SMarcel Telka if (host1 != NULL && host2 != NULL && strcmp(host1, host2) == 0)
948b17f03d7SMarcel Telka return (1);
949b17f03d7SMarcel Telka
950b17f03d7SMarcel Telka /* Try harder if hostnames do not match */
9517c478bd9Sstevel@tonic-gate sysid1 = get_system_id(host1);
9527c478bd9Sstevel@tonic-gate sysid2 = get_system_id(host2);
9537c478bd9Sstevel@tonic-gate if ((sysid1 == NULL) || (sysid2 == NULL))
9547c478bd9Sstevel@tonic-gate rv = 0;
9557c478bd9Sstevel@tonic-gate else
9567c478bd9Sstevel@tonic-gate rv = (strcmp(sysid1, sysid2) == 0);
9577c478bd9Sstevel@tonic-gate free(sysid1);
9587c478bd9Sstevel@tonic-gate free(sysid2);
9597c478bd9Sstevel@tonic-gate return (rv);
9607c478bd9Sstevel@tonic-gate }
9617c478bd9Sstevel@tonic-gate
9627c478bd9Sstevel@tonic-gate /*
9637c478bd9Sstevel@tonic-gate * Convert a hostname character string into its network address.
9647c478bd9Sstevel@tonic-gate * A network address is found by searching through all the entries
9657c478bd9Sstevel@tonic-gate * in /etc/netconfig and doing a netdir_getbyname() for each inet
9667c478bd9Sstevel@tonic-gate * entry found. The netbuf structure returned is converted into
9677c478bd9Sstevel@tonic-gate * a universal address format.
9687c478bd9Sstevel@tonic-gate *
9697c478bd9Sstevel@tonic-gate * If a NULL hostname is given, then the name of the current host
9707c478bd9Sstevel@tonic-gate * is used. If the hostname doesn't map to an address, a NULL
9717c478bd9Sstevel@tonic-gate * pointer is returned.
9727c478bd9Sstevel@tonic-gate *
9737c478bd9Sstevel@tonic-gate * N.B. the character string returned is allocated in taddr2uaddr()
9747c478bd9Sstevel@tonic-gate * and should be freed by the caller using free().
9757c478bd9Sstevel@tonic-gate */
9767c478bd9Sstevel@tonic-gate static char *
get_system_id(char * hostname)9777c478bd9Sstevel@tonic-gate get_system_id(char *hostname)
9787c478bd9Sstevel@tonic-gate {
9797c478bd9Sstevel@tonic-gate void *hp;
9807c478bd9Sstevel@tonic-gate struct netconfig *ncp;
9817c478bd9Sstevel@tonic-gate struct nd_hostserv service;
9827c478bd9Sstevel@tonic-gate struct nd_addrlist *addrs;
9837c478bd9Sstevel@tonic-gate char *uaddr;
9847c478bd9Sstevel@tonic-gate int rv;
9857c478bd9Sstevel@tonic-gate
9867c478bd9Sstevel@tonic-gate if (hostname == NULL)
9877c478bd9Sstevel@tonic-gate service.h_host = HOST_SELF;
9887c478bd9Sstevel@tonic-gate else
9897c478bd9Sstevel@tonic-gate service.h_host = hostname;
9907c478bd9Sstevel@tonic-gate service.h_serv = NULL;
9917c478bd9Sstevel@tonic-gate hp = setnetconfig();
9927c478bd9Sstevel@tonic-gate if (hp == (void *) NULL) {
9937c478bd9Sstevel@tonic-gate return (NULL);
9947c478bd9Sstevel@tonic-gate }
995*98573c19SMarcel Telka while ((ncp = getnetconfig(hp)) != NULL) {
9967c478bd9Sstevel@tonic-gate if ((strcmp(ncp->nc_protofmly, NC_INET) == 0) ||
9977c478bd9Sstevel@tonic-gate (strcmp(ncp->nc_protofmly, NC_INET6) == 0)) {
9987c478bd9Sstevel@tonic-gate addrs = NULL;
9997c478bd9Sstevel@tonic-gate rv = netdir_getbyname(ncp, &service, &addrs);
10007c478bd9Sstevel@tonic-gate if (rv != 0) {
10017c478bd9Sstevel@tonic-gate continue;
10027c478bd9Sstevel@tonic-gate }
10037c478bd9Sstevel@tonic-gate if (addrs) {
10047c478bd9Sstevel@tonic-gate uaddr = taddr2uaddr(ncp, addrs->n_addrs);
10057c478bd9Sstevel@tonic-gate netdir_free(addrs, ND_ADDRLIST);
10067c478bd9Sstevel@tonic-gate endnetconfig(hp);
10077c478bd9Sstevel@tonic-gate return (uaddr);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate }
10107c478bd9Sstevel@tonic-gate else
10117c478bd9Sstevel@tonic-gate continue;
10127c478bd9Sstevel@tonic-gate }
10137c478bd9Sstevel@tonic-gate endnetconfig(hp);
10147c478bd9Sstevel@tonic-gate return (NULL);
10157c478bd9Sstevel@tonic-gate }
10167c478bd9Sstevel@tonic-gate
10177c478bd9Sstevel@tonic-gate void
merge_hosts(void)10187c478bd9Sstevel@tonic-gate merge_hosts(void)
10197c478bd9Sstevel@tonic-gate {
10207c478bd9Sstevel@tonic-gate struct lifconf *lifc = NULL;
10217c478bd9Sstevel@tonic-gate int sock = -1;
10227c478bd9Sstevel@tonic-gate struct lifreq *lifrp;
10237c478bd9Sstevel@tonic-gate struct lifreq lifr;
10247c478bd9Sstevel@tonic-gate int n;
10257c478bd9Sstevel@tonic-gate struct sockaddr_in *sin;
10267c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6;
10277c478bd9Sstevel@tonic-gate struct sockaddr_storage *sa;
10287c478bd9Sstevel@tonic-gate int af;
10297c478bd9Sstevel@tonic-gate struct hostent *phost;
10307c478bd9Sstevel@tonic-gate char *addr;
10317c478bd9Sstevel@tonic-gate size_t alen;
10327c478bd9Sstevel@tonic-gate int errnum;
10337c478bd9Sstevel@tonic-gate
10347c478bd9Sstevel@tonic-gate /*
10357c478bd9Sstevel@tonic-gate * This function will enumerate all the interfaces for
10367c478bd9Sstevel@tonic-gate * this platform, then get the hostent for each i/f.
10377c478bd9Sstevel@tonic-gate * With the hostent structure, we can get all of the
10387c478bd9Sstevel@tonic-gate * aliases for the i/f. Then we'll merge all the aliases
10397c478bd9Sstevel@tonic-gate * with the existing host_name[] list to come up with
10407c478bd9Sstevel@tonic-gate * all of the known names for each interface. This solves
10417c478bd9Sstevel@tonic-gate * the problem of a multi-homed host not knowing which
10427c478bd9Sstevel@tonic-gate * name to publish when statd is started. All the aliases
10437c478bd9Sstevel@tonic-gate * will be stored in the array, host_name.
10447c478bd9Sstevel@tonic-gate *
10457c478bd9Sstevel@tonic-gate * NOTE: Even though we will use all of the aliases we
10467c478bd9Sstevel@tonic-gate * can get from the i/f hostent, the receiving statd
10477c478bd9Sstevel@tonic-gate * will still need to handle aliases with hostname_eq.
10487c478bd9Sstevel@tonic-gate * This is because the sender's aliases may not match
10497c478bd9Sstevel@tonic-gate * those of the receiver.
10507c478bd9Sstevel@tonic-gate */
10517c478bd9Sstevel@tonic-gate lifc = getmyaddrs();
1052*98573c19SMarcel Telka if (lifc == NULL) {
10537c478bd9Sstevel@tonic-gate goto finish;
10547c478bd9Sstevel@tonic-gate }
10557c478bd9Sstevel@tonic-gate lifrp = lifc->lifc_req;
10567c478bd9Sstevel@tonic-gate for (n = lifc->lifc_len / sizeof (struct lifreq); n > 0; n--, lifrp++) {
10577c478bd9Sstevel@tonic-gate
10587c478bd9Sstevel@tonic-gate (void) strncpy(lifr.lifr_name, lifrp->lifr_name,
10597c478bd9Sstevel@tonic-gate sizeof (lifr.lifr_name));
10607c478bd9Sstevel@tonic-gate
10617c478bd9Sstevel@tonic-gate af = lifrp->lifr_addr.ss_family;
10627c478bd9Sstevel@tonic-gate sock = socket(af, SOCK_DGRAM, 0);
10637c478bd9Sstevel@tonic-gate if (sock == -1) {
10647c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "statd: socket failed\n");
10657c478bd9Sstevel@tonic-gate goto finish;
10667c478bd9Sstevel@tonic-gate }
10677c478bd9Sstevel@tonic-gate
10687c478bd9Sstevel@tonic-gate /* If it's the loopback interface, ignore */
10697c478bd9Sstevel@tonic-gate if (ioctl(sock, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
10707c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
10717c478bd9Sstevel@tonic-gate "statd: SIOCGLIFFLAGS failed, error: %m\n");
10727c478bd9Sstevel@tonic-gate goto finish;
10737c478bd9Sstevel@tonic-gate }
10747c478bd9Sstevel@tonic-gate if (lifr.lifr_flags & IFF_LOOPBACK)
10757c478bd9Sstevel@tonic-gate continue;
10767c478bd9Sstevel@tonic-gate
10777c478bd9Sstevel@tonic-gate if (ioctl(sock, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
10787c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
10797c478bd9Sstevel@tonic-gate "statd: SIOCGLIFADDR failed, error: %m\n");
10807c478bd9Sstevel@tonic-gate goto finish;
10817c478bd9Sstevel@tonic-gate }
10827c478bd9Sstevel@tonic-gate sa = (struct sockaddr_storage *)&(lifr.lifr_addr);
10837c478bd9Sstevel@tonic-gate
10847c478bd9Sstevel@tonic-gate if (sa->ss_family == AF_INET) {
10857c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&lifr.lifr_addr;
10867c478bd9Sstevel@tonic-gate addr = (char *)(&sin->sin_addr);
10877c478bd9Sstevel@tonic-gate alen = sizeof (struct in_addr);
10887c478bd9Sstevel@tonic-gate } else if (sa->ss_family == AF_INET6) {
10897c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
10907c478bd9Sstevel@tonic-gate addr = (char *)(&sin6->sin6_addr);
10917c478bd9Sstevel@tonic-gate alen = sizeof (struct in6_addr);
10927c478bd9Sstevel@tonic-gate } else {
10937c478bd9Sstevel@tonic-gate syslog(LOG_WARNING,
10947c478bd9Sstevel@tonic-gate "unexpected address family (%d)",
10957c478bd9Sstevel@tonic-gate sa->ss_family);
10967c478bd9Sstevel@tonic-gate continue;
10977c478bd9Sstevel@tonic-gate }
10987c478bd9Sstevel@tonic-gate
10997c478bd9Sstevel@tonic-gate phost = getipnodebyaddr(addr, alen, sa->ss_family, &errnum);
11007c478bd9Sstevel@tonic-gate
11017c478bd9Sstevel@tonic-gate if (phost)
11027c478bd9Sstevel@tonic-gate add_aliases(phost);
11037c478bd9Sstevel@tonic-gate }
11047c478bd9Sstevel@tonic-gate /*
11057c478bd9Sstevel@tonic-gate * Now, just in case we didn't get them all byaddr,
11067c478bd9Sstevel@tonic-gate * let's look by name.
11077c478bd9Sstevel@tonic-gate */
11087c478bd9Sstevel@tonic-gate phost = getipnodebyname(hostname, AF_INET6, AI_ALL, &errnum);
11097c478bd9Sstevel@tonic-gate
11107c478bd9Sstevel@tonic-gate if (phost)
11117c478bd9Sstevel@tonic-gate add_aliases(phost);
11127c478bd9Sstevel@tonic-gate
11137c478bd9Sstevel@tonic-gate finish:
11147c478bd9Sstevel@tonic-gate if (sock != -1)
11157c478bd9Sstevel@tonic-gate (void) close(sock);
11167c478bd9Sstevel@tonic-gate if (lifc) {
11177c478bd9Sstevel@tonic-gate free(lifc->lifc_buf);
11187c478bd9Sstevel@tonic-gate free(lifc);
11197c478bd9Sstevel@tonic-gate }
11207c478bd9Sstevel@tonic-gate }
11217c478bd9Sstevel@tonic-gate
11227c478bd9Sstevel@tonic-gate /*
11237c478bd9Sstevel@tonic-gate * add_aliases traverses a hostent alias list, compares
11247c478bd9Sstevel@tonic-gate * the aliases to the contents of host_name, and if an
11257c478bd9Sstevel@tonic-gate * alias is not already present, adds it to host_name[].
11267c478bd9Sstevel@tonic-gate */
11277c478bd9Sstevel@tonic-gate
11287c478bd9Sstevel@tonic-gate static void
add_aliases(struct hostent * phost)11297c478bd9Sstevel@tonic-gate add_aliases(struct hostent *phost)
11307c478bd9Sstevel@tonic-gate {
11317c478bd9Sstevel@tonic-gate char **aliases;
11327c478bd9Sstevel@tonic-gate
11337c478bd9Sstevel@tonic-gate if (!in_host_array(phost->h_name)) {
11347c478bd9Sstevel@tonic-gate add_to_host_array(phost->h_name);
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gate if (phost->h_aliases == NULL)
11387c478bd9Sstevel@tonic-gate return; /* no aliases to register */
11397c478bd9Sstevel@tonic-gate
11407c478bd9Sstevel@tonic-gate for (aliases = phost->h_aliases; *aliases != NULL; aliases++) {
11417c478bd9Sstevel@tonic-gate if (!in_host_array(*aliases)) {
11427c478bd9Sstevel@tonic-gate add_to_host_array(*aliases);
11437c478bd9Sstevel@tonic-gate }
11447c478bd9Sstevel@tonic-gate }
11457c478bd9Sstevel@tonic-gate }
11467c478bd9Sstevel@tonic-gate
11477c478bd9Sstevel@tonic-gate /*
11487c478bd9Sstevel@tonic-gate * in_host_array checks if the given hostname exists in the host_name
11497c478bd9Sstevel@tonic-gate * array. Returns 0 if the host doesn't exist, and 1 if it does exist
11507c478bd9Sstevel@tonic-gate */
11517c478bd9Sstevel@tonic-gate static int
in_host_array(char * host)11527c478bd9Sstevel@tonic-gate in_host_array(char *host)
11537c478bd9Sstevel@tonic-gate {
11547c478bd9Sstevel@tonic-gate int i;
11557c478bd9Sstevel@tonic-gate
11567c478bd9Sstevel@tonic-gate if (debug)
11577c478bd9Sstevel@tonic-gate (void) printf("%s ", host);
11587c478bd9Sstevel@tonic-gate
11597c478bd9Sstevel@tonic-gate if ((strcmp(hostname, host) == 0) || (strcmp(LOGHOST, host) == 0))
11607c478bd9Sstevel@tonic-gate return (1);
11617c478bd9Sstevel@tonic-gate
11627c478bd9Sstevel@tonic-gate for (i = 0; i < addrix; i++) {
11637c478bd9Sstevel@tonic-gate if (strcmp(host_name[i], host) == 0)
11647c478bd9Sstevel@tonic-gate return (1);
11657c478bd9Sstevel@tonic-gate }
11667c478bd9Sstevel@tonic-gate
11677c478bd9Sstevel@tonic-gate return (0);
11687c478bd9Sstevel@tonic-gate }
11697c478bd9Sstevel@tonic-gate
11707c478bd9Sstevel@tonic-gate /*
11717c478bd9Sstevel@tonic-gate * add_to_host_array adds a hostname to the host_name array. But if
11727c478bd9Sstevel@tonic-gate * the array is already full, then it first reallocates the array with
11737c478bd9Sstevel@tonic-gate * HOST_NAME_INCR extra elements. If the realloc fails, then it does
11747c478bd9Sstevel@tonic-gate * nothing and leaves host_name the way it was previous to the call.
11757c478bd9Sstevel@tonic-gate */
11767c478bd9Sstevel@tonic-gate static void
add_to_host_array(char * host)11777c478bd9Sstevel@tonic-gate add_to_host_array(char *host) {
11787c478bd9Sstevel@tonic-gate
11797c478bd9Sstevel@tonic-gate void *new_block = NULL;
11807c478bd9Sstevel@tonic-gate
11817c478bd9Sstevel@tonic-gate /* Make sure we don't overrun host_name. */
11827c478bd9Sstevel@tonic-gate if (addrix >= host_name_count) {
11837c478bd9Sstevel@tonic-gate host_name_count += HOST_NAME_INCR;
11847c478bd9Sstevel@tonic-gate new_block = realloc((void *)host_name,
11857c478bd9Sstevel@tonic-gate host_name_count*sizeof (char *));
11867c478bd9Sstevel@tonic-gate if (new_block != NULL)
11877c478bd9Sstevel@tonic-gate host_name = new_block;
11887c478bd9Sstevel@tonic-gate else {
11897c478bd9Sstevel@tonic-gate host_name_count -= HOST_NAME_INCR;
11907c478bd9Sstevel@tonic-gate return;
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate }
11937c478bd9Sstevel@tonic-gate
11947c478bd9Sstevel@tonic-gate if ((host_name[addrix] = strdup(host)) != NULL)
11957c478bd9Sstevel@tonic-gate addrix++;
11967c478bd9Sstevel@tonic-gate }
11977c478bd9Sstevel@tonic-gate
11987c478bd9Sstevel@tonic-gate /*
11997c478bd9Sstevel@tonic-gate * Compares the unqualified hostnames for hosts. Returns 0 if the
12007c478bd9Sstevel@tonic-gate * names match, and 1 if the names fail to match.
12017c478bd9Sstevel@tonic-gate */
12027c478bd9Sstevel@tonic-gate int
str_cmp_unqual_hostname(char * rawname1,char * rawname2)12037c478bd9Sstevel@tonic-gate str_cmp_unqual_hostname(char *rawname1, char *rawname2)
12047c478bd9Sstevel@tonic-gate {
12057c478bd9Sstevel@tonic-gate size_t unq_len1, unq_len2;
12067c478bd9Sstevel@tonic-gate char *domain;
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate if (debug) {
12097c478bd9Sstevel@tonic-gate (void) printf("str_cmp_unqual: rawname1= %s, rawname2= %s\n",
12107c478bd9Sstevel@tonic-gate rawname1, rawname2);
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate
12137c478bd9Sstevel@tonic-gate unq_len1 = strcspn(rawname1, ".");
12147c478bd9Sstevel@tonic-gate unq_len2 = strcspn(rawname2, ".");
12157c478bd9Sstevel@tonic-gate domain = strchr(rawname1, '.');
12167c478bd9Sstevel@tonic-gate if (domain != NULL) {
12177c478bd9Sstevel@tonic-gate if ((strncmp(rawname1, SM_ADDR_IPV4, unq_len1) == 0) ||
12187c478bd9Sstevel@tonic-gate (strncmp(rawname1, SM_ADDR_IPV6, unq_len1) == 0))
12197c478bd9Sstevel@tonic-gate return (1);
12207c478bd9Sstevel@tonic-gate }
12217c478bd9Sstevel@tonic-gate
12227c478bd9Sstevel@tonic-gate if ((unq_len1 == unq_len2) &&
12237c478bd9Sstevel@tonic-gate (strncmp(rawname1, rawname2, unq_len1) == 0)) {
12247c478bd9Sstevel@tonic-gate return (0);
12257c478bd9Sstevel@tonic-gate }
12267c478bd9Sstevel@tonic-gate
12277c478bd9Sstevel@tonic-gate return (1);
12287c478bd9Sstevel@tonic-gate }
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gate /*
12317c478bd9Sstevel@tonic-gate * Compares <family>.<address-specifier> ASCII names for hosts. Returns
12327c478bd9Sstevel@tonic-gate * 0 if the addresses match, and 1 if the addresses fail to match.
12337c478bd9Sstevel@tonic-gate * If the args are indeed specifiers, they should look like this:
12347c478bd9Sstevel@tonic-gate *
12357c478bd9Sstevel@tonic-gate * ipv4.192.9.200.1 or ipv6.::C009:C801
12367c478bd9Sstevel@tonic-gate */
12377c478bd9Sstevel@tonic-gate int
str_cmp_address_specifier(char * specifier1,char * specifier2)12387c478bd9Sstevel@tonic-gate str_cmp_address_specifier(char *specifier1, char *specifier2)
12397c478bd9Sstevel@tonic-gate {
12407c478bd9Sstevel@tonic-gate size_t unq_len1, unq_len2;
12417c478bd9Sstevel@tonic-gate char *rawaddr1, *rawaddr2;
12427c478bd9Sstevel@tonic-gate int af1, af2, len;
12437c478bd9Sstevel@tonic-gate
12447c478bd9Sstevel@tonic-gate if (debug) {
12457c478bd9Sstevel@tonic-gate (void) printf("str_cmp_addr: specifier1= %s, specifier2= %s\n",
12467c478bd9Sstevel@tonic-gate specifier1, specifier2);
12477c478bd9Sstevel@tonic-gate }
12487c478bd9Sstevel@tonic-gate
12497c478bd9Sstevel@tonic-gate /*
12507c478bd9Sstevel@tonic-gate * Verify that:
12517c478bd9Sstevel@tonic-gate * 1. The family tokens match;
12527c478bd9Sstevel@tonic-gate * 2. The IP addresses following the `.' are legal; and
12537c478bd9Sstevel@tonic-gate * 3. These addresses match.
12547c478bd9Sstevel@tonic-gate */
12557c478bd9Sstevel@tonic-gate unq_len1 = strcspn(specifier1, ".");
12567c478bd9Sstevel@tonic-gate unq_len2 = strcspn(specifier2, ".");
12577c478bd9Sstevel@tonic-gate rawaddr1 = strchr(specifier1, '.');
12587c478bd9Sstevel@tonic-gate rawaddr2 = strchr(specifier2, '.');
12597c478bd9Sstevel@tonic-gate
12607c478bd9Sstevel@tonic-gate if (strncmp(specifier1, SM_ADDR_IPV4, unq_len1) == 0) {
12617c478bd9Sstevel@tonic-gate af1 = AF_INET;
12627c478bd9Sstevel@tonic-gate len = 4;
12637c478bd9Sstevel@tonic-gate } else if (strncmp(specifier1, SM_ADDR_IPV6, unq_len1) == 0) {
12647c478bd9Sstevel@tonic-gate af1 = AF_INET6;
12657c478bd9Sstevel@tonic-gate len = 16;
12667c478bd9Sstevel@tonic-gate }
12677c478bd9Sstevel@tonic-gate else
12687c478bd9Sstevel@tonic-gate return (1);
12697c478bd9Sstevel@tonic-gate
12707c478bd9Sstevel@tonic-gate if (strncmp(specifier2, SM_ADDR_IPV4, unq_len2) == 0)
12717c478bd9Sstevel@tonic-gate af2 = AF_INET;
12727c478bd9Sstevel@tonic-gate else if (strncmp(specifier2, SM_ADDR_IPV6, unq_len2) == 0)
12737c478bd9Sstevel@tonic-gate af2 = AF_INET6;
12747c478bd9Sstevel@tonic-gate else
12757c478bd9Sstevel@tonic-gate return (1);
12767c478bd9Sstevel@tonic-gate
12777c478bd9Sstevel@tonic-gate if (af1 != af2)
12787c478bd9Sstevel@tonic-gate return (1);
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gate if (rawaddr1 != NULL && rawaddr2 != NULL) {
12817c478bd9Sstevel@tonic-gate char dst1[16];
12827c478bd9Sstevel@tonic-gate char dst2[16];
12837c478bd9Sstevel@tonic-gate ++rawaddr1;
12847c478bd9Sstevel@tonic-gate ++rawaddr2;
12857c478bd9Sstevel@tonic-gate
12867c478bd9Sstevel@tonic-gate if (inet_pton(af1, rawaddr1, dst1) == 1 &&
12877c478bd9Sstevel@tonic-gate inet_pton(af2, rawaddr1, dst2) == 1 &&
12887c478bd9Sstevel@tonic-gate memcmp(dst1, dst2, len) == 0) {
12897c478bd9Sstevel@tonic-gate return (0);
12907c478bd9Sstevel@tonic-gate }
12917c478bd9Sstevel@tonic-gate }
12927c478bd9Sstevel@tonic-gate return (1);
12937c478bd9Sstevel@tonic-gate }
1294bbaa8b60SDan Kruchinin
1295bbaa8b60SDan Kruchinin /*
1296bbaa8b60SDan Kruchinin * Add IP address strings to the host_name list.
1297bbaa8b60SDan Kruchinin */
1298bbaa8b60SDan Kruchinin void
merge_ips(void)1299bbaa8b60SDan Kruchinin merge_ips(void)
1300bbaa8b60SDan Kruchinin {
1301bbaa8b60SDan Kruchinin struct ifaddrs *ifap, *cifap;
1302bbaa8b60SDan Kruchinin int error;
1303bbaa8b60SDan Kruchinin
1304bbaa8b60SDan Kruchinin error = getifaddrs(&ifap);
1305bbaa8b60SDan Kruchinin if (error) {
1306bbaa8b60SDan Kruchinin syslog(LOG_WARNING, "getifaddrs error: '%s'",
1307bbaa8b60SDan Kruchinin strerror(errno));
1308bbaa8b60SDan Kruchinin return;
1309bbaa8b60SDan Kruchinin }
1310bbaa8b60SDan Kruchinin
1311bbaa8b60SDan Kruchinin for (cifap = ifap; cifap != NULL; cifap = cifap->ifa_next) {
1312bbaa8b60SDan Kruchinin struct sockaddr *sa = cifap->ifa_addr;
1313bbaa8b60SDan Kruchinin char addr_str[INET6_ADDRSTRLEN];
1314bbaa8b60SDan Kruchinin void *addr = NULL;
1315bbaa8b60SDan Kruchinin
1316bbaa8b60SDan Kruchinin switch (sa->sa_family) {
1317bbaa8b60SDan Kruchinin case AF_INET: {
1318bbaa8b60SDan Kruchinin struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1319bbaa8b60SDan Kruchinin
1320bbaa8b60SDan Kruchinin /* Skip loopback addresses. */
1321bbaa8b60SDan Kruchinin if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
1322bbaa8b60SDan Kruchinin continue;
1323bbaa8b60SDan Kruchinin }
1324bbaa8b60SDan Kruchinin
1325bbaa8b60SDan Kruchinin addr = &sin->sin_addr;
1326bbaa8b60SDan Kruchinin break;
1327bbaa8b60SDan Kruchinin }
1328bbaa8b60SDan Kruchinin
1329bbaa8b60SDan Kruchinin case AF_INET6: {
1330bbaa8b60SDan Kruchinin struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
1331bbaa8b60SDan Kruchinin
1332bbaa8b60SDan Kruchinin /* Skip loopback addresses. */
1333bbaa8b60SDan Kruchinin if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
1334bbaa8b60SDan Kruchinin continue;
1335bbaa8b60SDan Kruchinin }
1336bbaa8b60SDan Kruchinin
1337bbaa8b60SDan Kruchinin addr = &sin6->sin6_addr;
1338bbaa8b60SDan Kruchinin break;
1339bbaa8b60SDan Kruchinin }
1340bbaa8b60SDan Kruchinin
1341bbaa8b60SDan Kruchinin default:
1342bbaa8b60SDan Kruchinin syslog(LOG_WARNING, "Unknown address family %d for "
1343bbaa8b60SDan Kruchinin "interface %s", sa->sa_family, cifap->ifa_name);
1344bbaa8b60SDan Kruchinin continue;
1345bbaa8b60SDan Kruchinin }
1346bbaa8b60SDan Kruchinin
1347bbaa8b60SDan Kruchinin if (inet_ntop(sa->sa_family, addr, addr_str, sizeof (addr_str))
1348bbaa8b60SDan Kruchinin == NULL) {
1349bbaa8b60SDan Kruchinin syslog(LOG_WARNING, "Failed to convert address into "
1350bbaa8b60SDan Kruchinin "string representation for interface '%s' "
1351bbaa8b60SDan Kruchinin "address family %d", cifap->ifa_name,
1352bbaa8b60SDan Kruchinin sa->sa_family);
1353bbaa8b60SDan Kruchinin continue;
1354bbaa8b60SDan Kruchinin }
1355bbaa8b60SDan Kruchinin
1356bbaa8b60SDan Kruchinin if (!in_host_array(addr_str)) {
1357bbaa8b60SDan Kruchinin add_to_host_array(addr_str);
1358bbaa8b60SDan Kruchinin }
1359bbaa8b60SDan Kruchinin }
1360bbaa8b60SDan Kruchinin
1361bbaa8b60SDan Kruchinin freeifaddrs(ifap);
1362bbaa8b60SDan Kruchinin }
1363