8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
32
33 /*
34 * University Copyright- Copyright (c) 1982, 1986, 1988
35 * The Regents of the University of California
36 * All Rights Reserved
37 *
38 * University Acknowledgment- Portions of this document are derived from
39 * software developed by the University of California, Berkeley, and its
40 * contributors.
41 */
42
43 #include <stdio.h>
44 #include <sys/types.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <syslog.h>
49 #include <rpc/rpc.h>
50 #include <rpcsvc/sm_inter.h>
51 #include <rpcsvc/nsm_addr.h>
52 #include <memory.h>
53 #include <net/if.h>
54 #include <sys/sockio.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58 #include <netdb.h>
59 #include <netdir.h>
60 #include <synch.h>
61 #include <thread.h>
62 #include <assert.h>
63 #include "sm_statd.h"
64
65 static int local_state; /* fake local sm state */
66 /* client name-to-address translation table */
67 static name_addr_entry_t *name_addr = NULL;
68
69
70 #define LOGHOST "loghost"
71
72 static void delete_mon(char *mon_name, my_id *my_idp);
73 static void insert_mon(mon *monp);
74 static void pr_mon(char *);
75 static int statd_call_lockd(mon *monp, int state);
76 static int hostname_eq(char *host1, char *host2);
77 static char *get_system_id(char *hostname);
78 static void add_aliases(struct hostent *phost);
79 static void *thr_send_notice(void *);
80 static void delete_onemon(char *mon_name, my_id *my_idp,
81 mon_entry **monitor_q);
82 static void send_notice(char *mon_name, int state);
83 static void add_to_host_array(char *host);
84 static int in_host_array(char *host);
85 static void pr_name_addr(name_addr_entry_t *name_addr);
86
87 extern int self_check(char *hostname);
88 extern struct lifconf *getmyaddrs(void);
89
90 /* ARGSUSED */
91 void
92 sm_status(namep, resp)
93 sm_name *namep;
94 sm_stat_res *resp;
95 {
96
97 if (debug)
98 (void) printf("proc sm_stat: mon_name = %s\n",
99 namep->mon_name);
100
101 resp->res_stat = stat_succ;
102 resp->state = LOCAL_STATE;
103 }
104
105 /* ARGSUSED */
106 void
107 sm_mon(monp, resp)
108 mon *monp;
109 sm_stat_res *resp;
110 {
111 mon_id *monidp;
112 monidp = &monp->mon_id;
113
114 rw_rdlock(&thr_rwlock);
115 if (debug) {
116 (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
117 monidp->mon_name, * ((int *)monp->priv));
118 pr_mon(monp->mon_id.mon_name);
119 }
120
121 /* only monitor other hosts */
122 if (self_check(monp->mon_id.mon_name) == 0) {
123 /* store monitor request into monitor_q */
124 insert_mon(monp);
125 }
126
127 pr_mon(monp->mon_id.mon_name);
128 resp->res_stat = stat_succ;
129 resp->state = local_state;
130 rw_unlock(&thr_rwlock);
131 }
132
133 /* ARGSUSED */
134 void
135 sm_unmon(monidp, resp)
136 mon_id *monidp;
137 sm_stat *resp;
138 {
139 rw_rdlock(&thr_rwlock);
140 if (debug) {
141 (void) printf(
142 "proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
143 monidp->mon_name, monidp->my_id.my_name,
144 monidp->my_id.my_prog, monidp->my_id.my_vers,
145 monidp->my_id.my_proc);
146 pr_mon(monidp->mon_name);
147 }
148
149 delete_mon(monidp->mon_name, &monidp->my_id);
150 pr_mon(monidp->mon_name);
151 resp->state = local_state;
152 rw_unlock(&thr_rwlock);
153 }
154
155 /* ARGSUSED */
156 void
157 sm_unmon_all(myidp, resp)
158 my_id *myidp;
159 sm_stat *resp;
160 {
161 rw_rdlock(&thr_rwlock);
162 if (debug)
163 (void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
164 myidp->my_name,
165 myidp->my_prog, myidp->my_vers,
166 myidp->my_proc);
167 delete_mon((char *)NULL, myidp);
168 pr_mon(NULL);
169 resp->state = local_state;
170 rw_unlock(&thr_rwlock);
171 }
172
173 /*
174 * Notifies lockd specified by name that state has changed for this server.
175 */
176 void
177 sm_notify(ntfp)
178 stat_chge *ntfp;
179 {
180 rw_rdlock(&thr_rwlock);
181 if (debug)
182 (void) printf("sm_notify: %s state =%d\n",
183 ntfp->mon_name, ntfp->state);
184 send_notice(ntfp->mon_name, ntfp->state);
185 rw_unlock(&thr_rwlock);
186 }
187
188 /* ARGSUSED */
189 void
190 sm_simu_crash(myidp)
191 void *myidp;
192 {
193 int i;
194 struct mon_entry *monitor_q;
195 int found = 0;
196
197 /* Only one crash should be running at a time. */
198 mutex_lock(&crash_lock);
199 if (debug)
200 (void) printf("proc sm_simu_crash\n");
201 if (in_crash) {
202 cond_wait(&crash_finish, &crash_lock);
203 mutex_unlock(&crash_lock);
204 return;
205 } else {
206 in_crash = 1;
207 }
208 mutex_unlock(&crash_lock);
209
210 for (i = 0; i < MAX_HASHSIZE; i++) {
211 mutex_lock(&mon_table[i].lock);
710 free(minfop->id.mon_id.my_id.my_name);
711 free(minfop);
712 continue;
713 }
714 }
715 }
716 next = next->nxt;
717 }
718 mutex_unlock(&mon_table[hash].lock);
719 }
720
721 /*
722 * Work thread created to do the actual statd_call_lockd
723 */
724 static void *
725 thr_send_notice(void *arg)
726 {
727 moninfo_t *minfop;
728
729 minfop = (moninfo_t *)arg;
730
731 if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
732 if (debug && minfop->id.mon_id.mon_name)
733 (void) printf("problem with notifying %s failure, "
734 "give up\n", minfop->id.mon_id.mon_name);
735 } else {
736 if (debug)
737 (void) printf("send_notice: %s, %d notified.\n",
738 minfop->id.mon_id.mon_name, minfop->state);
739 }
740
741 free(minfop->id.mon_id.mon_name);
742 free(minfop->id.mon_id.my_id.my_name);
743 free(minfop);
744
745 thr_exit((void *) 0);
746 #ifdef lint
747 /*NOTREACHED*/
748 return ((void *)0);
749 #endif
750 }
751
752 /*
753 * Contact lockd specified by monp.
754 */
755 static int
756 statd_call_lockd(monp, state)
757 mon *monp;
758 int state;
759 {
760 enum clnt_stat clnt_stat;
761 struct timeval tottimeout;
762 struct status stat;
763 my_id *my_idp;
764 char *mon_name;
765 int i;
766 int rc = 0;
767 CLIENT *clnt;
768
769 mon_name = monp->mon_id.mon_name;
770 my_idp = &monp->mon_id.my_id;
771 (void) memset(&stat, 0, sizeof (struct status));
772 stat.mon_name = mon_name;
773 stat.state = state;
774 for (i = 0; i < 16; i++) {
775 stat.priv[i] = monp->priv[i];
776 }
777 if (debug)
778 (void) printf("statd_call_lockd: %s state = %d\n",
779 stat.mon_name, stat.state);
780
781 tottimeout.tv_sec = SM_RPC_TIMEOUT;
782 tottimeout.tv_usec = 0;
783
784 if ((clnt = create_client(my_idp->my_name, my_idp->my_prog,
785 my_idp->my_vers, &tottimeout)) == (CLIENT *) NULL) {
786 return (-1);
787 }
788
789 clnt_stat = clnt_call(clnt, my_idp->my_proc, xdr_status, (char *)&stat,
790 xdr_void, NULL, tottimeout);
791 if (debug) {
792 (void) printf("clnt_stat=%s(%d)\n",
793 clnt_sperrno(clnt_stat), clnt_stat);
794 }
795 if (clnt_stat != (int)RPC_SUCCESS) {
796 syslog(LOG_WARNING,
797 "statd: cannot talk to lockd at %s, %s(%d)\n",
798 my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
799 rc = -1;
800 }
801
802 clnt_destroy(clnt);
803 return (rc);
804
805 }
806
807 /*
808 * Client handle created.
809 */
810 CLIENT *
811 create_client(host, prognum, versnum, utimeout)
812 char *host;
813 int prognum;
814 int versnum;
815 struct timeval *utimeout;
816 {
817 int fd;
818 struct timeval timeout;
819 CLIENT *client;
820 struct t_info tinfo;
821
822 if ((client = clnt_create_timed(host, prognum, versnum,
823 "netpath", utimeout)) == NULL) {
824 return (NULL);
825 }
826 (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
827 if (t_getinfo(fd, &tinfo) != -1) {
828 if (tinfo.servtype == T_CLTS) {
829 /*
830 * Set time outs for connectionless case
831 */
832 timeout.tv_usec = 0;
833 timeout.tv_sec = SM_CLTS_TIMEOUT;
834 (void) CLNT_CONTROL(client,
835 CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
836 }
837 } else
838 return (NULL);
839
840 return (client);
841 }
842
843 /*
844 * ONLY for debugging.
845 * Debug messages which prints out the monitor table information.
1283 af2 = AF_INET6;
1284 else
1285 return (1);
1286
1287 if (af1 != af2)
1288 return (1);
1289
1290 if (rawaddr1 != NULL && rawaddr2 != NULL) {
1291 char dst1[16];
1292 char dst2[16];
1293 ++rawaddr1;
1294 ++rawaddr2;
1295
1296 if (inet_pton(af1, rawaddr1, dst1) == 1 &&
1297 inet_pton(af2, rawaddr1, dst2) == 1 &&
1298 memcmp(dst1, dst2, len) == 0) {
1299 return (0);
1300 }
1301 }
1302 return (1);
1303 }
|
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 * Copyright (c) 2012 by Delphix. All rights reserved.
29 */
30
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
33
34 /*
35 * University Copyright- Copyright (c) 1982, 1986, 1988
36 * The Regents of the University of California
37 * All Rights Reserved
38 *
39 * University Acknowledgment- Portions of this document are derived from
40 * software developed by the University of California, Berkeley, and its
41 * contributors.
42 */
43
44 #include <stdio.h>
45 #include <sys/types.h>
46 #include <stdlib.h>
47 #include <unistd.h>
48 #include <string.h>
49 #include <syslog.h>
50 #include <rpc/rpc.h>
51 #include <rpcsvc/sm_inter.h>
52 #include <rpcsvc/nsm_addr.h>
53 #include <memory.h>
54 #include <net/if.h>
55 #include <sys/sockio.h>
56 #include <sys/socket.h>
57 #include <netinet/in.h>
58 #include <arpa/inet.h>
59 #include <netdb.h>
60 #include <netdir.h>
61 #include <synch.h>
62 #include <thread.h>
63 #include <ifaddrs.h>
64 #include <errno.h>
65 #include <assert.h>
66 #include "sm_statd.h"
67
68 static int local_state; /* fake local sm state */
69 /* client name-to-address translation table */
70 static name_addr_entry_t *name_addr = NULL;
71
72
73 #define LOGHOST "loghost"
74
75 static void delete_mon(char *mon_name, my_id *my_idp);
76 static void insert_mon(mon *monp);
77 static void pr_mon(char *);
78 static int statd_call_lockd(mon *monp, int state);
79 static int hostname_eq(char *host1, char *host2);
80 static char *get_system_id(char *hostname);
81 static void add_aliases(struct hostent *phost);
82 static void *thr_send_notice(void *);
83 static void delete_onemon(char *mon_name, my_id *my_idp,
84 mon_entry **monitor_q);
85 static void send_notice(char *mon_name, int state);
86 static void add_to_host_array(char *host);
87 static int in_host_array(char *host);
88 static void pr_name_addr(name_addr_entry_t *name_addr);
89
90 extern int self_check(char *hostname);
91 extern struct lifconf *getmyaddrs(void);
92
93 /* ARGSUSED */
94 void
95 sm_stat_svc(sm_name *namep, sm_stat_res *resp)
96 {
97
98 if (debug)
99 (void) printf("proc sm_stat: mon_name = %s\n",
100 namep->mon_name);
101
102 resp->res_stat = stat_succ;
103 resp->state = LOCAL_STATE;
104 }
105
106 /* ARGSUSED */
107 void
108 sm_mon_svc(mon *monp, sm_stat_res *resp)
109 {
110 mon_id *monidp;
111 monidp = &monp->mon_id;
112
113 rw_rdlock(&thr_rwlock);
114 if (debug) {
115 (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
116 monidp->mon_name, * ((int *)monp->priv));
117 pr_mon(monp->mon_id.mon_name);
118 }
119
120 /* only monitor other hosts */
121 if (self_check(monp->mon_id.mon_name) == 0) {
122 /* store monitor request into monitor_q */
123 insert_mon(monp);
124 }
125
126 pr_mon(monp->mon_id.mon_name);
127 resp->res_stat = stat_succ;
128 resp->state = local_state;
129 rw_unlock(&thr_rwlock);
130 }
131
132 /* ARGSUSED */
133 void
134 sm_unmon_svc(mon_id *monidp, sm_stat *resp)
135 {
136 rw_rdlock(&thr_rwlock);
137 if (debug) {
138 (void) printf(
139 "proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
140 monidp->mon_name, monidp->my_id.my_name,
141 monidp->my_id.my_prog, monidp->my_id.my_vers,
142 monidp->my_id.my_proc);
143 pr_mon(monidp->mon_name);
144 }
145
146 delete_mon(monidp->mon_name, &monidp->my_id);
147 pr_mon(monidp->mon_name);
148 resp->state = local_state;
149 rw_unlock(&thr_rwlock);
150 }
151
152 /* ARGSUSED */
153 void
154 sm_unmon_all_svc(my_id *myidp, sm_stat *resp)
155 {
156 rw_rdlock(&thr_rwlock);
157 if (debug)
158 (void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
159 myidp->my_name,
160 myidp->my_prog, myidp->my_vers,
161 myidp->my_proc);
162 delete_mon((char *)NULL, myidp);
163 pr_mon(NULL);
164 resp->state = local_state;
165 rw_unlock(&thr_rwlock);
166 }
167
168 /*
169 * Notifies lockd specified by name that state has changed for this server.
170 */
171 void
172 sm_notify_svc(stat_chge *ntfp)
173 {
174 rw_rdlock(&thr_rwlock);
175 if (debug)
176 (void) printf("sm_notify: %s state =%d\n",
177 ntfp->mon_name, ntfp->state);
178 send_notice(ntfp->mon_name, ntfp->state);
179 rw_unlock(&thr_rwlock);
180 }
181
182 /* ARGSUSED */
183 void
184 sm_simu_crash_svc(void *myidp)
185 {
186 int i;
187 struct mon_entry *monitor_q;
188 int found = 0;
189
190 /* Only one crash should be running at a time. */
191 mutex_lock(&crash_lock);
192 if (debug)
193 (void) printf("proc sm_simu_crash\n");
194 if (in_crash) {
195 cond_wait(&crash_finish, &crash_lock);
196 mutex_unlock(&crash_lock);
197 return;
198 } else {
199 in_crash = 1;
200 }
201 mutex_unlock(&crash_lock);
202
203 for (i = 0; i < MAX_HASHSIZE; i++) {
204 mutex_lock(&mon_table[i].lock);
703 free(minfop->id.mon_id.my_id.my_name);
704 free(minfop);
705 continue;
706 }
707 }
708 }
709 next = next->nxt;
710 }
711 mutex_unlock(&mon_table[hash].lock);
712 }
713
714 /*
715 * Work thread created to do the actual statd_call_lockd
716 */
717 static void *
718 thr_send_notice(void *arg)
719 {
720 moninfo_t *minfop;
721
722 minfop = (moninfo_t *)arg;
723 if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
724 if (debug && minfop->id.mon_id.mon_name)
725 (void) printf("problem with notifying %s failure, "
726 "give up\n", minfop->id.mon_id.mon_name);
727 } else {
728 if (debug)
729 (void) printf("send_notice: %s, %d notified.\n",
730 minfop->id.mon_id.mon_name, minfop->state);
731 }
732
733 free(minfop->id.mon_id.mon_name);
734 free(minfop->id.mon_id.my_id.my_name);
735 free(minfop);
736
737 thr_exit((void *) 0);
738 #ifdef lint
739 /*NOTREACHED*/
740 return ((void *)0);
741 #endif
742 }
743
744 /*
745 * Contact lockd specified by monp.
746 */
747 static int
748 statd_call_lockd(monp, state)
749 mon *monp;
750 int state;
751 {
752 enum clnt_stat clnt_stat;
753 struct timeval tottimeout;
754 struct sm_status stat;
755 my_id *my_idp;
756 char *mon_name;
757 int i;
758 int rc = 0;
759 CLIENT *clnt;
760
761 mon_name = monp->mon_id.mon_name;
762 my_idp = &monp->mon_id.my_id;
763 (void) memset(&stat, 0, sizeof (stat));
764 stat.mon_name = mon_name;
765 stat.state = state;
766 for (i = 0; i < 16; i++) {
767 stat.priv[i] = monp->priv[i];
768 }
769 if (debug)
770 (void) printf("statd_call_lockd: %s state = %d\n",
771 stat.mon_name, stat.state);
772
773 tottimeout.tv_sec = SM_RPC_TIMEOUT;
774 tottimeout.tv_usec = 0;
775
776 clnt = create_client(my_idp->my_name, my_idp->my_prog, my_idp->my_vers,
777 "ticotsord", &tottimeout);
778 if (clnt == NULL) {
779 return (-1);
780 }
781
782 clnt_stat = clnt_call(clnt, my_idp->my_proc,
783 xdr_sm_status, (char *)&stat,
784 xdr_void, NULL, tottimeout);
785 if (debug) {
786 (void) printf("clnt_stat=%s(%d)\n",
787 clnt_sperrno(clnt_stat), clnt_stat);
788 }
789 if (clnt_stat != (int)RPC_SUCCESS) {
790 syslog(LOG_WARNING,
791 "statd: cannot talk to lockd at %s, %s(%d)\n",
792 my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
793 rc = -1;
794 }
795
796 clnt_destroy(clnt);
797 return (rc);
798
799 }
800
801 /*
802 * Client handle created.
803 */
804 CLIENT *
805 create_client(char *host, int prognum, int versnum, char *netid,
806 struct timeval *utimeout)
807 {
808 int fd;
809 struct timeval timeout;
810 CLIENT *client;
811 struct t_info tinfo;
812
813 if (netid == NULL) {
814 client = clnt_create_timed(host, prognum, versnum,
815 "netpath", utimeout);
816 } else {
817 struct netconfig *nconf;
818
819 nconf = getnetconfigent(netid);
820 if (nconf == NULL) {
821 return (NULL);
822 }
823
824 client = clnt_tp_create_timed(host, prognum, versnum, nconf,
825 utimeout);
826
827 freenetconfigent(nconf);
828 }
829
830 if (client == NULL) {
831 return (NULL);
832 }
833
834 (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
835 if (t_getinfo(fd, &tinfo) != -1) {
836 if (tinfo.servtype == T_CLTS) {
837 /*
838 * Set time outs for connectionless case
839 */
840 timeout.tv_usec = 0;
841 timeout.tv_sec = SM_CLTS_TIMEOUT;
842 (void) CLNT_CONTROL(client,
843 CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
844 }
845 } else
846 return (NULL);
847
848 return (client);
849 }
850
851 /*
852 * ONLY for debugging.
853 * Debug messages which prints out the monitor table information.
1291 af2 = AF_INET6;
1292 else
1293 return (1);
1294
1295 if (af1 != af2)
1296 return (1);
1297
1298 if (rawaddr1 != NULL && rawaddr2 != NULL) {
1299 char dst1[16];
1300 char dst2[16];
1301 ++rawaddr1;
1302 ++rawaddr2;
1303
1304 if (inet_pton(af1, rawaddr1, dst1) == 1 &&
1305 inet_pton(af2, rawaddr1, dst2) == 1 &&
1306 memcmp(dst1, dst2, len) == 0) {
1307 return (0);
1308 }
1309 }
1310 return (1);
1311 }
1312
1313 /*
1314 * Add IP address strings to the host_name list.
1315 */
1316 void
1317 merge_ips(void)
1318 {
1319 struct ifaddrs *ifap, *cifap;
1320 int error;
1321
1322 error = getifaddrs(&ifap);
1323 if (error) {
1324 syslog(LOG_WARNING, "getifaddrs error: '%s'",
1325 strerror(errno));
1326 return;
1327 }
1328
1329 for (cifap = ifap; cifap != NULL; cifap = cifap->ifa_next) {
1330 struct sockaddr *sa = cifap->ifa_addr;
1331 char addr_str[INET6_ADDRSTRLEN];
1332 void *addr = NULL;
1333
1334 switch (sa->sa_family) {
1335 case AF_INET: {
1336 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1337
1338 /* Skip loopback addresses. */
1339 if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
1340 continue;
1341 }
1342
1343 addr = &sin->sin_addr;
1344 break;
1345 }
1346
1347 case AF_INET6: {
1348 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
1349
1350 /* Skip loopback addresses. */
1351 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
1352 continue;
1353 }
1354
1355 addr = &sin6->sin6_addr;
1356 break;
1357 }
1358
1359 default:
1360 syslog(LOG_WARNING, "Unknown address family %d for "
1361 "interface %s", sa->sa_family, cifap->ifa_name);
1362 continue;
1363 }
1364
1365 if (inet_ntop(sa->sa_family, addr, addr_str, sizeof (addr_str))
1366 == NULL) {
1367 syslog(LOG_WARNING, "Failed to convert address into "
1368 "string representation for interface '%s' "
1369 "address family %d", cifap->ifa_name,
1370 sa->sa_family);
1371 continue;
1372 }
1373
1374 if (!in_host_array(addr_str)) {
1375 add_to_host_array(addr_str);
1376 }
1377 }
1378
1379 freeifaddrs(ifap);
1380 }
|