xref: /onnv-gate/usr/src/lib/smbsrv/libsmb/common/smb_nic.c (revision 11963:061945695ce1)
16030Sjb150015 /*
26030Sjb150015  * CDDL HEADER START
36030Sjb150015  *
46030Sjb150015  * The contents of this file are subject to the terms of the
56030Sjb150015  * Common Development and Distribution License (the "License").
66030Sjb150015  * You may not use this file except in compliance with the License.
76030Sjb150015  *
86030Sjb150015  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96030Sjb150015  * or http://www.opensolaris.org/os/licensing.
106030Sjb150015  * See the License for the specific language governing permissions
116030Sjb150015  * and limitations under the License.
126030Sjb150015  *
136030Sjb150015  * When distributing Covered Code, include this CDDL HEADER in each
146030Sjb150015  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156030Sjb150015  * If applicable, add the following below this CDDL HEADER, with the
166030Sjb150015  * fields enclosed by brackets "[]" replaced with your own identifying
176030Sjb150015  * information: Portions Copyright [yyyy] [name of copyright owner]
186030Sjb150015  *
196030Sjb150015  * CDDL HEADER END
206030Sjb150015  */
216030Sjb150015 /*
22*11963SAfshin.Ardakani@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
236030Sjb150015  * Use is subject to license terms.
246030Sjb150015  */
256030Sjb150015 
266030Sjb150015 #include <stdio.h>
276030Sjb150015 #include <stdlib.h>
286030Sjb150015 #include <syslog.h>
296030Sjb150015 #include <libintl.h>
306030Sjb150015 #include <strings.h>
316030Sjb150015 #include <string.h>
326030Sjb150015 #include <unistd.h>
336030Sjb150015 #include <synch.h>
346030Sjb150015 #include <stropts.h>
356030Sjb150015 #include <errno.h>
366030Sjb150015 #include <pthread.h>
376030Sjb150015 
386030Sjb150015 #include <inet/ip.h>
396030Sjb150015 #include <net/if.h>
406030Sjb150015 #include <netinet/in.h>
416030Sjb150015 #include <netdb.h>
426030Sjb150015 #include <net/route.h>
436030Sjb150015 #include <arpa/inet.h>
446030Sjb150015 
456030Sjb150015 #include <sys/socket.h>
466030Sjb150015 #include <sys/sockio.h>
476030Sjb150015 #include <sys/systeminfo.h>
486030Sjb150015 
496030Sjb150015 #include <smbsrv/libsmb.h>
506030Sjb150015 
516030Sjb150015 #define	SMB_NIC_DB_NAME		"/var/smb/smbhosts.db"
526030Sjb150015 #define	SMB_NIC_DB_TIMEOUT	3000		/* in millisecond */
536030Sjb150015 #define	SMB_NIC_DB_VERMAJOR	1
546030Sjb150015 #define	SMB_NIC_DB_VERMINOR	0
556030Sjb150015 #define	SMB_NIC_DB_MAGIC	0x484F5354	/* HOST */
566030Sjb150015 
576030Sjb150015 #define	SMB_NIC_DB_ORD		1		/* open read-only */
586030Sjb150015 #define	SMB_NIC_DB_ORW		2		/* open read/write */
596030Sjb150015 
606030Sjb150015 #define	SMB_NIC_DB_SQL \
616030Sjb150015 	"CREATE TABLE db_info ("				\
626030Sjb150015 	"	ver_major INTEGER,"				\
636030Sjb150015 	"	ver_minor INTEGER,"				\
646030Sjb150015 	"	magic     INTEGER"				\
656030Sjb150015 	");"							\
666030Sjb150015 	""							\
676030Sjb150015 	"CREATE TABLE hosts ("					\
686030Sjb150015 	"	hostname  TEXT PRIMARY KEY,"			\
696030Sjb150015 	"	comment   TEXT,"				\
706030Sjb150015 	"	ifnames   TEXT"					\
716030Sjb150015 	");"
726030Sjb150015 
736030Sjb150015 #define	SMB_NIC_HTBL_NCOL	3
746030Sjb150015 #define	SMB_NIC_HTBL_HOST	0
756030Sjb150015 #define	SMB_NIC_HTBL_CMNT	1
766030Sjb150015 #define	SMB_NIC_HTBL_IFS	2
776030Sjb150015 
786030Sjb150015 #define	NULL_MSGCHK(msg)	((msg) ? (msg) : "NULL")
796030Sjb150015 
806030Sjb150015 #define	SMB_NIC_MAXIFS		256
818334SJose.Borrego@Sun.COM #define	SMB_NIC_MAXEXCLLIST_LEN	512
826030Sjb150015 
836030Sjb150015 typedef struct smb_hostifs {
846030Sjb150015 	list_node_t if_lnd;
856030Sjb150015 	char if_host[MAXHOSTNAMELEN];
866030Sjb150015 	char if_cmnt[SMB_PI_MAX_COMMENT];
876030Sjb150015 	char *if_names[SMB_NIC_MAXIFS];
886030Sjb150015 	int if_num;
896030Sjb150015 } smb_hostifs_t;
906030Sjb150015 
916030Sjb150015 typedef struct smb_hosts {
926030Sjb150015 	list_t h_list;
936030Sjb150015 	int h_num;
946030Sjb150015 	int h_ifnum;
956030Sjb150015 } smb_hosts_t;
966030Sjb150015 
976030Sjb150015 typedef struct {
986030Sjb150015 	smb_nic_t	*nl_nics;
996030Sjb150015 	int		nl_cnt;		/* number of smb_nic_t structures */
1006030Sjb150015 	int		nl_hcnt;	/* number of host names */
1016030Sjb150015 	long		nl_seqnum;	/* a random sequence number */
1026030Sjb150015 	rwlock_t	nl_rwl;
1036030Sjb150015 } smb_niclist_t;
1046030Sjb150015 
1056030Sjb150015 static int smb_nic_list_create(void);
1066030Sjb150015 static void smb_nic_list_destroy(void);
1076030Sjb150015 
1086030Sjb150015 static int smb_nic_hlist_create(smb_hosts_t *);
1096030Sjb150015 static void smb_nic_hlist_destroy(smb_hosts_t *);
1106030Sjb150015 static int smb_nic_hlist_dbget(smb_hosts_t *);
1116030Sjb150015 static int smb_nic_hlist_sysget(smb_hosts_t *);
1126030Sjb150015 
1136030Sjb150015 static void smb_nic_iflist_destroy(smb_hostifs_t *);
114*11963SAfshin.Ardakani@Sun.COM static smb_hostifs_t *smb_nic_iflist_decode(const char **, int *);
1156030Sjb150015 
1166030Sjb150015 static int smb_nic_dbcreate(void);
1176030Sjb150015 static sqlite *smb_nic_dbopen(int);
1186030Sjb150015 static void smb_nic_dbclose(sqlite *);
1196030Sjb150015 static boolean_t smb_nic_dbexists(void);
1206030Sjb150015 static boolean_t smb_nic_dbvalidate(void);
1216030Sjb150015 static int smb_nic_dbaddhost(const char *, const char *, char *);
1226030Sjb150015 static int smb_nic_dbdelhost(const char *);
1236030Sjb150015 static int smb_nic_dbsetinfo(sqlite *);
1246030Sjb150015 
1258670SJose.Borrego@Sun.COM static int smb_nic_getinfo(char *, smb_nic_t *, int);
1268334SJose.Borrego@Sun.COM static boolean_t smb_nic_nbt_exclude(const smb_nic_t *, const char **, int);
1278334SJose.Borrego@Sun.COM static int smb_nic_nbt_get_exclude_list(char *, char **, int);
1286030Sjb150015 
1298670SJose.Borrego@Sun.COM static void smb_close_sockets(int, int);
1308670SJose.Borrego@Sun.COM static boolean_t smb_duplicate_nic(smb_hostifs_t *iflist, struct lifreq *lifrp);
1318670SJose.Borrego@Sun.COM 
1326030Sjb150015 /* This is the list we will monitor */
1336030Sjb150015 static smb_niclist_t smb_niclist;
1346030Sjb150015 
1356030Sjb150015 /*
1366030Sjb150015  * smb_nic_init
1376030Sjb150015  *
1386030Sjb150015  * Initializes the interface list.
1396030Sjb150015  */
1406030Sjb150015 int
smb_nic_init(void)1416030Sjb150015 smb_nic_init(void)
1426030Sjb150015 {
1436030Sjb150015 	int rc;
1446030Sjb150015 
1456030Sjb150015 	(void) rw_wrlock(&smb_niclist.nl_rwl);
1466030Sjb150015 	smb_nic_list_destroy();
1476030Sjb150015 	rc = smb_nic_list_create();
1486030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1496030Sjb150015 
1506030Sjb150015 	return (rc);
1516030Sjb150015 }
1526030Sjb150015 
1536030Sjb150015 /*
1546030Sjb150015  * smb_nic_fini
1556030Sjb150015  *
1566030Sjb150015  * Destroys the interface list.
1576030Sjb150015  */
1586030Sjb150015 void
smb_nic_fini(void)1596030Sjb150015 smb_nic_fini(void)
1606030Sjb150015 {
1616030Sjb150015 	(void) rw_wrlock(&smb_niclist.nl_rwl);
1626030Sjb150015 	smb_nic_list_destroy();
1636030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1646030Sjb150015 }
1656030Sjb150015 
1666030Sjb150015 /*
1676030Sjb150015  * smb_nic_getnum
1686030Sjb150015  *
1696030Sjb150015  * Gets the number of interfaces for the specified host.
1706030Sjb150015  * if host is NULL then total number of interfaces
1716030Sjb150015  * is returned. It's assumed that given name is a NetBIOS
1726030Sjb150015  * encoded name.
1736030Sjb150015  */
1746030Sjb150015 int
smb_nic_getnum(char * nb_hostname)1756030Sjb150015 smb_nic_getnum(char *nb_hostname)
1766030Sjb150015 {
1776030Sjb150015 	int n = 0, i;
1786030Sjb150015 
1796030Sjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
1806030Sjb150015 
1816030Sjb150015 	if (nb_hostname != NULL) {
1826030Sjb150015 		for (i = 0; i < smb_niclist.nl_cnt; i++) {
1836030Sjb150015 			/* ignore the suffix */
1846030Sjb150015 			if (strncasecmp(smb_niclist.nl_nics[i].nic_nbname,
1856030Sjb150015 			    nb_hostname, NETBIOS_NAME_SZ - 1) == 0)
1866030Sjb150015 				n++;
1876030Sjb150015 		}
1886030Sjb150015 	} else {
1896030Sjb150015 		n = smb_niclist.nl_cnt;
1906030Sjb150015 	}
1916030Sjb150015 
1926030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1936030Sjb150015 
1946030Sjb150015 	return (n);
1956030Sjb150015 }
1966030Sjb150015 
1976030Sjb150015 /*
1986030Sjb150015  * smb_nic_getfirst
1996030Sjb150015  *
2006030Sjb150015  * Returns the first NIC in the interface list and
2016030Sjb150015  * initializes the given iterator. To get the rest of
2026030Sjb150015  * NICs smb_nic_getnext() must be called.
2036030Sjb150015  *
204*11963SAfshin.Ardakani@Sun.COM  * Returns SMB_NIC_SUCCESS upon success or the following:
205*11963SAfshin.Ardakani@Sun.COM  *	SMB_NIC_NOT_FOUND - there's no interface available
206*11963SAfshin.Ardakani@Sun.COM  *	SMB_NIC_INVALID_ARG - 'ni' is NULL
2076030Sjb150015  */
2086030Sjb150015 int
smb_nic_getfirst(smb_niciter_t * ni)2096030Sjb150015 smb_nic_getfirst(smb_niciter_t *ni)
2106030Sjb150015 {
211*11963SAfshin.Ardakani@Sun.COM 	int rc = SMB_NIC_SUCCESS;
2126030Sjb150015 
2136030Sjb150015 	if (ni == NULL)
214*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_INVALID_ARG);
2156030Sjb150015 
2166030Sjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2176030Sjb150015 
2186030Sjb150015 	if (smb_niclist.nl_cnt > 0) {
2196030Sjb150015 		ni->ni_nic = smb_niclist.nl_nics[0];
2206030Sjb150015 		ni->ni_cookie = 1;
2216030Sjb150015 		ni->ni_seqnum = smb_niclist.nl_seqnum;
2226030Sjb150015 	} else {
223*11963SAfshin.Ardakani@Sun.COM 		rc = SMB_NIC_NOT_FOUND;
2246030Sjb150015 	}
2256030Sjb150015 
2266030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
2276030Sjb150015 
2286030Sjb150015 	return (rc);
2296030Sjb150015 }
2306030Sjb150015 
2316030Sjb150015 /*
2326030Sjb150015  * smb_nic_getnext
2336030Sjb150015  *
2346030Sjb150015  * Returns the next NIC information based on the passed
2356030Sjb150015  * iterator (ni). The iterator must have previously been
2366030Sjb150015  * initialized by calling smb_nic_getfirst().
2376030Sjb150015  *
238*11963SAfshin.Ardakani@Sun.COM  * Returns SMB_NIC_SUCCESS upon successfully finding the specified NIC
239*11963SAfshin.Ardakani@Sun.COM  * or the following:
240*11963SAfshin.Ardakani@Sun.COM  * 	SMB_NIC_INVALID_ARG - the specified iterator is invalid
241*11963SAfshin.Ardakani@Sun.COM  * 	SMB_NIC_NO_MORE - reaches the end of the NIC list
242*11963SAfshin.Ardakani@Sun.COM  * 	SMB_NIC_CHANGED - sequence number in the iterator is different from
2436030Sjb150015  *	  the sequence number in the NIC list which means
2446030Sjb150015  *	  the list has been changed between getfirst/getnext
2456030Sjb150015  *	  calls.
2466030Sjb150015  */
2476030Sjb150015 int
smb_nic_getnext(smb_niciter_t * ni)2486030Sjb150015 smb_nic_getnext(smb_niciter_t *ni)
2496030Sjb150015 {
250*11963SAfshin.Ardakani@Sun.COM 	int rc = SMB_NIC_SUCCESS;
2516030Sjb150015 
2526030Sjb150015 	if ((ni == NULL) || (ni->ni_cookie < 1))
253*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_INVALID_ARG);
2546030Sjb150015 
2556030Sjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2566030Sjb150015 
2576030Sjb150015 	if ((smb_niclist.nl_cnt > ni->ni_cookie) &&
2586030Sjb150015 	    (smb_niclist.nl_seqnum == ni->ni_seqnum)) {
2596030Sjb150015 		ni->ni_nic = smb_niclist.nl_nics[ni->ni_cookie];
2606030Sjb150015 		ni->ni_cookie++;
2616030Sjb150015 	} else {
262*11963SAfshin.Ardakani@Sun.COM 		if (smb_niclist.nl_seqnum != ni->ni_seqnum)
263*11963SAfshin.Ardakani@Sun.COM 			rc = SMB_NIC_CHANGED;
264*11963SAfshin.Ardakani@Sun.COM 		else
265*11963SAfshin.Ardakani@Sun.COM 			rc = SMB_NIC_NO_MORE;
2666030Sjb150015 	}
2676030Sjb150015 
2686030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
2696030Sjb150015 
2706030Sjb150015 	return (rc);
2716030Sjb150015 }
2726030Sjb150015 
2736030Sjb150015 boolean_t
smb_nic_is_local(smb_inaddr_t * ipaddr)2749021Samw@Sun.COM smb_nic_is_local(smb_inaddr_t *ipaddr)
2756030Sjb150015 {
2766030Sjb150015 	smb_nic_t *cfg;
2776030Sjb150015 	int i;
2786030Sjb150015 
2796030Sjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2806030Sjb150015 
2816030Sjb150015 	for (i = 0; i < smb_niclist.nl_cnt; i++) {
2826030Sjb150015 		cfg = &smb_niclist.nl_nics[i];
2839021Samw@Sun.COM 		if (smb_inet_equal(ipaddr, &cfg->nic_ip)) {
2849021Samw@Sun.COM 			(void) rw_unlock(&smb_niclist.nl_rwl);
2859021Samw@Sun.COM 			return (B_TRUE);
2869021Samw@Sun.COM 		}
2879021Samw@Sun.COM 	}
2889021Samw@Sun.COM 	(void) rw_unlock(&smb_niclist.nl_rwl);
2899021Samw@Sun.COM 	return (B_FALSE);
2909021Samw@Sun.COM }
2919021Samw@Sun.COM 
2929021Samw@Sun.COM boolean_t
smb_nic_is_same_subnet(smb_inaddr_t * ipaddr)2939021Samw@Sun.COM smb_nic_is_same_subnet(smb_inaddr_t *ipaddr)
2949021Samw@Sun.COM {
2959021Samw@Sun.COM 	smb_nic_t *cfg;
2969021Samw@Sun.COM 	int i;
2979021Samw@Sun.COM 
2989021Samw@Sun.COM 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2999021Samw@Sun.COM 
3009021Samw@Sun.COM 	for (i = 0; i < smb_niclist.nl_cnt; i++) {
3019021Samw@Sun.COM 		cfg = &smb_niclist.nl_nics[i];
3029021Samw@Sun.COM 		if (smb_inet_same_subnet(ipaddr, &cfg->nic_ip, cfg->nic_mask)) {
3036030Sjb150015 			(void) rw_unlock(&smb_niclist.nl_rwl);
3046030Sjb150015 			return (B_TRUE);
3056030Sjb150015 		}
3066030Sjb150015 	}
3076030Sjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
3086030Sjb150015 	return (B_FALSE);
3096030Sjb150015 }
3106030Sjb150015 
3116030Sjb150015 /*
3126030Sjb150015  * smb_nic_addhost
3136030Sjb150015  *
3146030Sjb150015  * Adds an association between the given host and the specified interface
3156030Sjb150015  * list (if_names). This function can be called as many times as needed,
3166030Sjb150015  * the associations will be stored in /var/smb/smbhosts.db, which is sqlite
3176030Sjb150015  * database. If this file exists and it's not empty NIC list is generated
3186030Sjb150015  * based on the information stored in this file.
3196030Sjb150015  *
3206030Sjb150015  * host: actual system's name (not Netbios name)
3216030Sjb150015  * cmnt: an optional description for the CIFS server running on
3226030Sjb150015  *       the specified host. Can be NULL.
3236030Sjb150015  * if_num: number of interface names in if_names arg
3246030Sjb150015  * if_names: array of interface names in string format
3256030Sjb150015  *
326*11963SAfshin.Ardakani@Sun.COM  * Returns SMB_NIC_SUCCESS upon success, a nonzero value otherwise.
3276030Sjb150015  */
3286030Sjb150015 int
smb_nic_addhost(const char * host,const char * cmnt,int if_num,const char ** if_names)3296030Sjb150015 smb_nic_addhost(const char *host, const char *cmnt,
3306030Sjb150015     int if_num, const char **if_names)
3316030Sjb150015 {
3326030Sjb150015 	char *if_list;
3336030Sjb150015 	char *ifname;
3346030Sjb150015 	int buflen = 0;
3356030Sjb150015 	int rc, i;
3366030Sjb150015 
3376030Sjb150015 	if ((host == NULL) || (if_num <= 0) || (if_names == NULL))
338*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_INVALID_ARG);
3396030Sjb150015 
3406030Sjb150015 	if (!smb_nic_dbexists() || !smb_nic_dbvalidate()) {
341*11963SAfshin.Ardakani@Sun.COM 		if ((rc = smb_nic_dbcreate()) != SMB_NIC_SUCCESS)
342*11963SAfshin.Ardakani@Sun.COM 			return (rc);
3436030Sjb150015 	}
3446030Sjb150015 
3459832Samw@Sun.COM 	for (i = 0; i < if_num; i++) {
3469832Samw@Sun.COM 		ifname = (char *)if_names[i];
3476030Sjb150015 		if ((ifname == NULL) || (*ifname == '\0'))
348*11963SAfshin.Ardakani@Sun.COM 			return (SMB_NIC_INVALID_ARG);
3496030Sjb150015 		buflen += strlen(ifname) + 1;
3506030Sjb150015 	}
3516030Sjb150015 
3526030Sjb150015 	if ((if_list = malloc(buflen)) == NULL)
353*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
3546030Sjb150015 
3556030Sjb150015 	ifname = if_list;
3566030Sjb150015 	for (i = 0; i < if_num - 1; i++)
3576030Sjb150015 		ifname += snprintf(ifname, buflen, "%s,", if_names[i]);
3586030Sjb150015 
3596030Sjb150015 	(void) snprintf(ifname, buflen, "%s", if_names[i]);
3606030Sjb150015 
3616030Sjb150015 	rc = smb_nic_dbaddhost(host, cmnt, if_list);
3626030Sjb150015 	free(if_list);
3636030Sjb150015 
364*11963SAfshin.Ardakani@Sun.COM 	return (rc);
3656030Sjb150015 }
3666030Sjb150015 
3676030Sjb150015 /*
3686030Sjb150015  * smb_nic_delhost
3696030Sjb150015  *
3706030Sjb150015  * Removes the stored interface association for the specified host
3716030Sjb150015  */
3726030Sjb150015 int
smb_nic_delhost(const char * host)3736030Sjb150015 smb_nic_delhost(const char *host)
3746030Sjb150015 {
3756030Sjb150015 	if ((host == NULL) || (*host == '\0'))
376*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_INVALID_ARG);
3776030Sjb150015 
3786030Sjb150015 	if (!smb_nic_dbexists())
379*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_SUCCESS);
3806030Sjb150015 
3816030Sjb150015 	if (!smb_nic_dbvalidate()) {
3826030Sjb150015 		(void) unlink(SMB_NIC_DB_NAME);
383*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_SUCCESS);
3846030Sjb150015 	}
3856030Sjb150015 
386*11963SAfshin.Ardakani@Sun.COM 	return (smb_nic_dbdelhost(host));
3876030Sjb150015 }
3886030Sjb150015 
3896030Sjb150015 /*
3906030Sjb150015  * smb_nic_list_create
3916030Sjb150015  *
3926030Sjb150015  * Creates a NIC list either based on /var/smb/smbhosts.db or
3936030Sjb150015  * by getting the information from OS.
3946030Sjb150015  *
3956030Sjb150015  * Note that the caller of this function should grab the
3966030Sjb150015  * list lock.
3976030Sjb150015  */
3986030Sjb150015 static int
smb_nic_list_create(void)3996030Sjb150015 smb_nic_list_create(void)
4006030Sjb150015 {
4016030Sjb150015 	smb_hosts_t hlist;
4026030Sjb150015 	smb_hostifs_t *iflist;
4036030Sjb150015 	smb_nic_t *nc;
4046030Sjb150015 	char *ifname;
4058334SJose.Borrego@Sun.COM 	char excludestr[SMB_NIC_MAXEXCLLIST_LEN];
4068334SJose.Borrego@Sun.COM 	char *exclude[SMB_PI_MAX_NETWORKS];
4078334SJose.Borrego@Sun.COM 	int nexclude = 0;
408*11963SAfshin.Ardakani@Sun.COM 	int i, rc;
4096030Sjb150015 
410*11963SAfshin.Ardakani@Sun.COM 	if ((rc = smb_nic_hlist_create(&hlist)) !=  SMB_NIC_SUCCESS)
411*11963SAfshin.Ardakani@Sun.COM 		return (rc);
4126030Sjb150015 
4136030Sjb150015 	smb_niclist.nl_cnt = 0;
4146030Sjb150015 	smb_niclist.nl_seqnum = random();
4156030Sjb150015 	smb_niclist.nl_hcnt = hlist.h_num;
4166030Sjb150015 
4176030Sjb150015 	smb_niclist.nl_nics = calloc(hlist.h_ifnum, sizeof (smb_nic_t));
4186030Sjb150015 	if (smb_niclist.nl_nics == NULL) {
4196030Sjb150015 		smb_nic_hlist_destroy(&hlist);
420*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
4216030Sjb150015 	}
4226030Sjb150015 
4238334SJose.Borrego@Sun.COM 	*excludestr = '\0';
4248334SJose.Borrego@Sun.COM 	(void) smb_config_getstr(SMB_CI_WINS_EXCL,
4258334SJose.Borrego@Sun.COM 	    excludestr, sizeof (excludestr));
4268334SJose.Borrego@Sun.COM 
4278334SJose.Borrego@Sun.COM 	nexclude = smb_nic_nbt_get_exclude_list(excludestr,
4288334SJose.Borrego@Sun.COM 	    exclude, SMB_PI_MAX_NETWORKS);
4296030Sjb150015 
4306030Sjb150015 	nc = smb_niclist.nl_nics;
4316030Sjb150015 	iflist = list_head(&hlist.h_list);
4326030Sjb150015 
4336030Sjb150015 	do {
4346030Sjb150015 		for (i = 0; i < iflist->if_num; i++) {
4356030Sjb150015 			ifname = iflist->if_names[i];
436*11963SAfshin.Ardakani@Sun.COM 			if (smb_nic_getinfo(ifname, nc, AF_INET) !=
437*11963SAfshin.Ardakani@Sun.COM 			    SMB_NIC_SUCCESS) {
4388670SJose.Borrego@Sun.COM 				if (smb_nic_getinfo(ifname, nc,
439*11963SAfshin.Ardakani@Sun.COM 				    AF_INET6) != SMB_NIC_SUCCESS) {
4408670SJose.Borrego@Sun.COM 					continue;
4418670SJose.Borrego@Sun.COM 				}
4428670SJose.Borrego@Sun.COM 			}
4436030Sjb150015 
4446030Sjb150015 			(void) strlcpy(nc->nic_host, iflist->if_host,
4456030Sjb150015 			    sizeof (nc->nic_host));
4466030Sjb150015 			(void) strlcpy(nc->nic_cmnt, iflist->if_cmnt,
4476030Sjb150015 			    sizeof (nc->nic_cmnt));
4486030Sjb150015 
4496030Sjb150015 			smb_tonetbiosname(nc->nic_host, nc->nic_nbname, 0x00);
4506030Sjb150015 
4516030Sjb150015 			if (strchr(ifname, ':'))
4526030Sjb150015 				nc->nic_smbflags |= SMB_NICF_ALIAS;
4536030Sjb150015 
4548334SJose.Borrego@Sun.COM 			if (smb_nic_nbt_exclude(nc,
4558334SJose.Borrego@Sun.COM 			    (const char **)exclude, nexclude))
4566030Sjb150015 				nc->nic_smbflags |= SMB_NICF_NBEXCL;
4576030Sjb150015 
4586030Sjb150015 			smb_niclist.nl_cnt++;
4596030Sjb150015 			nc++;
4606030Sjb150015 		}
4616030Sjb150015 	} while	((iflist = list_next(&hlist.h_list, iflist)) != NULL);
4626030Sjb150015 
4636030Sjb150015 	smb_nic_hlist_destroy(&hlist);
4646030Sjb150015 
465*11963SAfshin.Ardakani@Sun.COM 	return (SMB_NIC_SUCCESS);
4666030Sjb150015 }
4676030Sjb150015 
4686030Sjb150015 static void
smb_nic_list_destroy(void)4696030Sjb150015 smb_nic_list_destroy(void)
4706030Sjb150015 {
4716030Sjb150015 	free(smb_niclist.nl_nics);
4726030Sjb150015 	smb_niclist.nl_nics = NULL;
4736030Sjb150015 	smb_niclist.nl_cnt = 0;
4746030Sjb150015 }
4756030Sjb150015 
4766030Sjb150015 static int
smb_nic_getinfo(char * interface,smb_nic_t * nc,int family)4778670SJose.Borrego@Sun.COM smb_nic_getinfo(char *interface, smb_nic_t *nc, int family)
4786030Sjb150015 {
4796030Sjb150015 	struct lifreq lifrr;
4806030Sjb150015 	int s;
4818670SJose.Borrego@Sun.COM 	boolean_t isv6;
4828670SJose.Borrego@Sun.COM 	struct sockaddr_in6 *sin6;
4838670SJose.Borrego@Sun.COM 	struct sockaddr_in *sin;
4846030Sjb150015 
4858670SJose.Borrego@Sun.COM 	if ((s = socket(family, SOCK_DGRAM, IPPROTO_IP)) < 0) {
486*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_SOCK);
4876030Sjb150015 	}
4886030Sjb150015 
4896030Sjb150015 	(void) strlcpy(lifrr.lifr_name, interface, sizeof (lifrr.lifr_name));
4906030Sjb150015 	if (ioctl(s, SIOCGLIFADDR, &lifrr) < 0) {
4916030Sjb150015 		(void) close(s);
492*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_IOCTL);
4936030Sjb150015 	}
4948670SJose.Borrego@Sun.COM 	isv6 = (lifrr.lifr_addr.ss_family == AF_INET6);
4958670SJose.Borrego@Sun.COM 	if (isv6) {
4968670SJose.Borrego@Sun.COM 		sin6 = (struct sockaddr_in6 *)(&lifrr.lifr_addr);
4978670SJose.Borrego@Sun.COM 		nc->nic_ip.a_ipv6 = sin6->sin6_addr;
4988670SJose.Borrego@Sun.COM 		nc->nic_ip.a_family = AF_INET6;
4998670SJose.Borrego@Sun.COM 	} else {
5008670SJose.Borrego@Sun.COM 		sin = (struct sockaddr_in *)(&lifrr.lifr_addr);
5018670SJose.Borrego@Sun.COM 		nc->nic_ip.a_ipv4 = (in_addr_t)(sin->sin_addr.s_addr);
5028670SJose.Borrego@Sun.COM 		nc->nic_ip.a_family = AF_INET;
5038670SJose.Borrego@Sun.COM 	}
5048670SJose.Borrego@Sun.COM 	if (smb_inet_iszero(&nc->nic_ip)) {
5056030Sjb150015 		(void) close(s);
506*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_BAD_DATA);
5076030Sjb150015 	}
5088670SJose.Borrego@Sun.COM 	/* there is no broadcast or netmask for v6 */
5098670SJose.Borrego@Sun.COM 	if (!isv6) {
5108670SJose.Borrego@Sun.COM 		if (ioctl(s, SIOCGLIFBRDADDR, &lifrr) < 0) {
5118670SJose.Borrego@Sun.COM 			(void) close(s);
512*11963SAfshin.Ardakani@Sun.COM 			return (SMB_NIC_IOCTL);
5138670SJose.Borrego@Sun.COM 		}
5148670SJose.Borrego@Sun.COM 		sin = (struct sockaddr_in *)&lifrr.lifr_broadaddr;
5158670SJose.Borrego@Sun.COM 		nc->nic_bcast = (uint32_t)sin->sin_addr.s_addr;
5166030Sjb150015 
5178670SJose.Borrego@Sun.COM 		if (ioctl(s, SIOCGLIFNETMASK, &lifrr) < 0) {
5188670SJose.Borrego@Sun.COM 			(void) close(s);
519*11963SAfshin.Ardakani@Sun.COM 			return (SMB_NIC_IOCTL);
5208670SJose.Borrego@Sun.COM 		}
5218670SJose.Borrego@Sun.COM 		sin = (struct sockaddr_in *)&lifrr.lifr_addr;
5228670SJose.Borrego@Sun.COM 		nc->nic_mask = (uint32_t)sin->sin_addr.s_addr;
5236030Sjb150015 	}
5246030Sjb150015 	if (ioctl(s, SIOCGLIFFLAGS, &lifrr) < 0) {
5256030Sjb150015 		(void) close(s);
526*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_IOCTL);
5276030Sjb150015 	}
5286030Sjb150015 	nc->nic_sysflags = lifrr.lifr_flags;
5296030Sjb150015 
5306030Sjb150015 	(void) strlcpy(nc->nic_ifname, interface, sizeof (nc->nic_ifname));
5316030Sjb150015 
5326030Sjb150015 	(void) close(s);
533*11963SAfshin.Ardakani@Sun.COM 	return (SMB_NIC_SUCCESS);
5346030Sjb150015 }
5356030Sjb150015 
5366030Sjb150015 /*
5376030Sjb150015  * smb_nic_hlist_create
5386030Sjb150015  *
5396030Sjb150015  * Creates a list of hosts and their associated interfaces.
5406030Sjb150015  * If host database exists the information is retrieved from
5416030Sjb150015  * the database, otherwise it's retrieved from OS.
5426030Sjb150015  *
5436030Sjb150015  * The allocated memories for the returned list should be freed
5446030Sjb150015  * by calling smb_nic_hlist_destroy()
5456030Sjb150015  */
5466030Sjb150015 static int
smb_nic_hlist_create(smb_hosts_t * hlist)5476030Sjb150015 smb_nic_hlist_create(smb_hosts_t *hlist)
5486030Sjb150015 {
5496030Sjb150015 	int rc;
5506030Sjb150015 
5516030Sjb150015 	list_create(&hlist->h_list, sizeof (smb_hostifs_t),
5526030Sjb150015 	    offsetof(smb_hostifs_t, if_lnd));
5536030Sjb150015 	hlist->h_num = 0;
5546030Sjb150015 	hlist->h_ifnum = 0;
5556030Sjb150015 
5566030Sjb150015 	if (smb_nic_dbexists() && smb_nic_dbvalidate()) {
5576030Sjb150015 		rc = smb_nic_hlist_dbget(hlist);
5586030Sjb150015 		errno = EBADF;
5596030Sjb150015 	} else {
5606030Sjb150015 		rc = smb_nic_hlist_sysget(hlist);
5616030Sjb150015 	}
5626030Sjb150015 
563*11963SAfshin.Ardakani@Sun.COM 	if (rc != SMB_NIC_SUCCESS)
5646030Sjb150015 		smb_nic_hlist_destroy(hlist);
5656030Sjb150015 
5666030Sjb150015 	return (rc);
5676030Sjb150015 }
5686030Sjb150015 
5696030Sjb150015 static void
smb_nic_hlist_destroy(smb_hosts_t * hlist)5706030Sjb150015 smb_nic_hlist_destroy(smb_hosts_t *hlist)
5716030Sjb150015 {
5726030Sjb150015 	smb_hostifs_t *iflist;
5736030Sjb150015 
5746030Sjb150015 	if (hlist == NULL)
5756030Sjb150015 		return;
5766030Sjb150015 
5776030Sjb150015 	while ((iflist = list_head(&hlist->h_list)) != NULL) {
5786030Sjb150015 		list_remove(&hlist->h_list, iflist);
5796030Sjb150015 		smb_nic_iflist_destroy(iflist);
5806030Sjb150015 	}
5816030Sjb150015 
5826030Sjb150015 	list_destroy(&hlist->h_list);
5836030Sjb150015 }
5846030Sjb150015 
5858670SJose.Borrego@Sun.COM static void
smb_close_sockets(int s4,int s6)5868670SJose.Borrego@Sun.COM smb_close_sockets(int s4, int s6)
5878670SJose.Borrego@Sun.COM {
5888670SJose.Borrego@Sun.COM 	if (s4)
5898670SJose.Borrego@Sun.COM 		(void) close(s4);
5908670SJose.Borrego@Sun.COM 	if (s6)
5918670SJose.Borrego@Sun.COM 		(void) close(s6);
5928670SJose.Borrego@Sun.COM }
5938670SJose.Borrego@Sun.COM 
5946030Sjb150015 /*
5956030Sjb150015  * smb_nic_hlist_sysget
5966030Sjb150015  *
5976030Sjb150015  * Get the list of currently plumbed and up interface names. The loopback (lo0)
5986030Sjb150015  * port is ignored
5996030Sjb150015  */
6006030Sjb150015 static int
smb_nic_hlist_sysget(smb_hosts_t * hlist)6016030Sjb150015 smb_nic_hlist_sysget(smb_hosts_t *hlist)
6026030Sjb150015 {
6036030Sjb150015 	smb_hostifs_t *iflist;
6048670SJose.Borrego@Sun.COM 	struct lifconf lifc;
6058670SJose.Borrego@Sun.COM 	struct lifreq lifrl;
6068670SJose.Borrego@Sun.COM 	struct lifreq *lifrp;
6076030Sjb150015 	char *ifname;
6086030Sjb150015 	int ifnum;
6096030Sjb150015 	int i;
6108670SJose.Borrego@Sun.COM 	int s4, s6;
6118670SJose.Borrego@Sun.COM 	struct lifnum lifn;
6126030Sjb150015 
6136030Sjb150015 	iflist = malloc(sizeof (smb_hostifs_t));
6146030Sjb150015 	if (iflist == NULL)
615*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
6166030Sjb150015 
6176030Sjb150015 	bzero(iflist, sizeof (smb_hostifs_t));
6186030Sjb150015 
619*11963SAfshin.Ardakani@Sun.COM 	if (smb_gethostname(iflist->if_host, sizeof (iflist->if_host),
620*11963SAfshin.Ardakani@Sun.COM 	    SMB_CASE_PRESERVE) < 0) {
6216030Sjb150015 		free(iflist);
622*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_HOST);
6236030Sjb150015 	}
6246030Sjb150015 
6256030Sjb150015 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, iflist->if_cmnt,
6266030Sjb150015 	    sizeof (iflist->if_cmnt));
6276030Sjb150015 
6288670SJose.Borrego@Sun.COM 	if ((s4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
6296030Sjb150015 		free(iflist);
630*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_SOCK);
6316030Sjb150015 	}
6328670SJose.Borrego@Sun.COM 	s6 = socket(AF_INET6, SOCK_DGRAM, 0);
6336030Sjb150015 
6348670SJose.Borrego@Sun.COM 	lifn.lifn_family = AF_UNSPEC;
6358670SJose.Borrego@Sun.COM 	lifn.lifn_flags = 0;
6368670SJose.Borrego@Sun.COM 	if (ioctl(s4, SIOCGLIFNUM, (char *)&lifn) < 0) {
6378670SJose.Borrego@Sun.COM 		smb_close_sockets(s4, s6);
6386030Sjb150015 		free(iflist);
6398670SJose.Borrego@Sun.COM 		syslog(LOG_ERR, "hlist_sysget: SIOCGLIFNUM errno=%d", errno);
640*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_IOCTL);
6416030Sjb150015 	}
6426030Sjb150015 
6438670SJose.Borrego@Sun.COM 	lifc.lifc_len = lifn.lifn_count * sizeof (struct lifreq);
6448670SJose.Borrego@Sun.COM 	lifc.lifc_buf = malloc(lifc.lifc_len);
6458670SJose.Borrego@Sun.COM 	if (lifc.lifc_buf == NULL) {
6468670SJose.Borrego@Sun.COM 		smb_close_sockets(s4, s6);
6476030Sjb150015 		free(iflist);
648*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
6496030Sjb150015 	}
6508670SJose.Borrego@Sun.COM 	bzero(lifc.lifc_buf, lifc.lifc_len);
6518670SJose.Borrego@Sun.COM 	lifc.lifc_family = AF_UNSPEC;
6528670SJose.Borrego@Sun.COM 	lifc.lifc_flags = 0;
6536030Sjb150015 
6548670SJose.Borrego@Sun.COM 	if (ioctl(s4, SIOCGLIFCONF, (char *)&lifc) < 0) {
6558670SJose.Borrego@Sun.COM 		smb_close_sockets(s4, s6);
6566030Sjb150015 		free(iflist);
6578670SJose.Borrego@Sun.COM 		free(lifc.lifc_buf);
658*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_IOCTL);
6596030Sjb150015 	}
6606030Sjb150015 
6618670SJose.Borrego@Sun.COM 	lifrp = lifc.lifc_req;
6628670SJose.Borrego@Sun.COM 	ifnum = lifc.lifc_len / sizeof (struct lifreq);
6638670SJose.Borrego@Sun.COM 	hlist->h_num = 0;
6648670SJose.Borrego@Sun.COM 	for (i = 0; i < ifnum; i++, lifrp++) {
6656030Sjb150015 
6668670SJose.Borrego@Sun.COM 		if ((iflist->if_num > 0) && smb_duplicate_nic(iflist, lifrp))
6678670SJose.Borrego@Sun.COM 			continue;
6686030Sjb150015 		/*
6696030Sjb150015 		 * Get the flags so that we can skip the loopback interface
6706030Sjb150015 		 */
6718670SJose.Borrego@Sun.COM 		(void) memset(&lifrl, 0, sizeof (lifrl));
6728670SJose.Borrego@Sun.COM 		(void) strlcpy(lifrl.lifr_name, lifrp->lifr_name,
6738670SJose.Borrego@Sun.COM 		    sizeof (lifrl.lifr_name));
6746030Sjb150015 
6758670SJose.Borrego@Sun.COM 		if (ioctl(s4, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0) {
6768670SJose.Borrego@Sun.COM 			if ((s6 < 0) ||
6778670SJose.Borrego@Sun.COM 			    (ioctl(s6, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0)) {
6788670SJose.Borrego@Sun.COM 				smb_close_sockets(s4, s6);
6798670SJose.Borrego@Sun.COM 				free(lifc.lifc_buf);
6808670SJose.Borrego@Sun.COM 				smb_nic_iflist_destroy(iflist);
681*11963SAfshin.Ardakani@Sun.COM 				return (SMB_NIC_IOCTL);
6828670SJose.Borrego@Sun.COM 			}
6838670SJose.Borrego@Sun.COM 		}
6848670SJose.Borrego@Sun.COM 		if (lifrl.lifr_flags & IFF_LOOPBACK) {
6858670SJose.Borrego@Sun.COM 			continue;
6866030Sjb150015 		}
6876030Sjb150015 
6888670SJose.Borrego@Sun.COM 		if ((lifrl.lifr_flags & IFF_UP) == 0) {
6896030Sjb150015 			continue;
6908670SJose.Borrego@Sun.COM 		}
6918670SJose.Borrego@Sun.COM 		ifname = strdup(lifrp->lifr_name);
6926030Sjb150015 		if (ifname == NULL) {
6938670SJose.Borrego@Sun.COM 			smb_close_sockets(s4, s6);
6948670SJose.Borrego@Sun.COM 			free(lifc.lifc_buf);
6956030Sjb150015 			smb_nic_iflist_destroy(iflist);
696*11963SAfshin.Ardakani@Sun.COM 			return (SMB_NIC_NO_MEMORY);
6976030Sjb150015 		}
6986030Sjb150015 		iflist->if_names[iflist->if_num++] = ifname;
6996030Sjb150015 	}
7008670SJose.Borrego@Sun.COM 	hlist->h_ifnum = iflist->if_num;
7016030Sjb150015 	hlist->h_num = 1;
7028670SJose.Borrego@Sun.COM 	smb_close_sockets(s4, s6);
7038670SJose.Borrego@Sun.COM 	free(lifc.lifc_buf);
7046030Sjb150015 	list_insert_tail(&hlist->h_list, iflist);
7056030Sjb150015 
706*11963SAfshin.Ardakani@Sun.COM 	return (SMB_NIC_SUCCESS);
7076030Sjb150015 }
7086030Sjb150015 
7098670SJose.Borrego@Sun.COM static boolean_t
smb_duplicate_nic(smb_hostifs_t * iflist,struct lifreq * lifrp)7108670SJose.Borrego@Sun.COM smb_duplicate_nic(smb_hostifs_t *iflist, struct lifreq *lifrp)
7118670SJose.Borrego@Sun.COM {
7128670SJose.Borrego@Sun.COM 	int j;
7138670SJose.Borrego@Sun.COM 	/*
7148670SJose.Borrego@Sun.COM 	 * throw out duplicate names
7158670SJose.Borrego@Sun.COM 	 */
7168670SJose.Borrego@Sun.COM 	for (j = 0; j < iflist->if_num; j++) {
7178670SJose.Borrego@Sun.COM 		if (strcmp(iflist->if_names[j],
7188670SJose.Borrego@Sun.COM 		    lifrp->lifr_name) == 0)
7198670SJose.Borrego@Sun.COM 			return (B_TRUE);
7208670SJose.Borrego@Sun.COM 	}
7218670SJose.Borrego@Sun.COM 	return (B_FALSE);
7228670SJose.Borrego@Sun.COM }
7238670SJose.Borrego@Sun.COM 
7246030Sjb150015 static int
smb_nic_hlist_dbget(smb_hosts_t * hlist)7256030Sjb150015 smb_nic_hlist_dbget(smb_hosts_t *hlist)
7266030Sjb150015 {
7276030Sjb150015 	smb_hostifs_t *iflist;
7286030Sjb150015 	sqlite *db;
7296030Sjb150015 	sqlite_vm *vm;
730*11963SAfshin.Ardakani@Sun.COM 	int err = SMB_NIC_SUCCESS;
7316030Sjb150015 	const char **values;
7326030Sjb150015 	char *sql;
7336030Sjb150015 	char *errmsg = NULL;
7346030Sjb150015 	int ncol, rc;
7356030Sjb150015 
7366030Sjb150015 	sql = sqlite_mprintf("SELECT * FROM hosts");
7376030Sjb150015 	if (sql == NULL)
738*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
7396030Sjb150015 
7406030Sjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORD);
7416030Sjb150015 	if (db == NULL) {
7426030Sjb150015 		sqlite_freemem(sql);
743*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DBOPEN_FAILED);
7446030Sjb150015 	}
7456030Sjb150015 
7466030Sjb150015 	rc = sqlite_compile(db, sql, NULL, &vm, &errmsg);
7476030Sjb150015 	sqlite_freemem(sql);
7486030Sjb150015 
7496030Sjb150015 	if (rc != SQLITE_OK) {
7506030Sjb150015 		smb_nic_dbclose(db);
751*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to query hosts info from host " \
752*11963SAfshin.Ardakani@Sun.COM 		    "database.  Unable to create virtual machine (%s).",
753*11963SAfshin.Ardakani@Sun.COM 		    NULL_MSGCHK(errmsg));
754*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DB_ERROR);
7556030Sjb150015 	}
7566030Sjb150015 
7576030Sjb150015 	do {
7586030Sjb150015 		rc = sqlite_step(vm, &ncol, &values, NULL);
7596030Sjb150015 		if (rc == SQLITE_ROW) {
7606030Sjb150015 			if (ncol != SMB_NIC_HTBL_NCOL) {
761*11963SAfshin.Ardakani@Sun.COM 				err = SMB_NIC_DB_ERROR;
7626030Sjb150015 				break;
7636030Sjb150015 			}
7646030Sjb150015 
765*11963SAfshin.Ardakani@Sun.COM 			if ((iflist = smb_nic_iflist_decode(values, &err)) ==
766*11963SAfshin.Ardakani@Sun.COM 			    NULL) {
7676030Sjb150015 				break;
7686030Sjb150015 			}
7696030Sjb150015 
7706030Sjb150015 			list_insert_tail(&hlist->h_list, iflist);
7716030Sjb150015 			hlist->h_num++;
7726030Sjb150015 			hlist->h_ifnum += iflist->if_num;
7736030Sjb150015 		}
7746030Sjb150015 	} while (rc == SQLITE_ROW);
7756030Sjb150015 
776*11963SAfshin.Ardakani@Sun.COM 	if (rc != SQLITE_DONE && err == SMB_NIC_SUCCESS) {
777*11963SAfshin.Ardakani@Sun.COM 		/* set this error if no previous error */
778*11963SAfshin.Ardakani@Sun.COM 		err = SMB_LGRP_DBEXEC_FAILED;
779*11963SAfshin.Ardakani@Sun.COM 	}
7806030Sjb150015 
7816030Sjb150015 	rc = sqlite_finalize(vm, &errmsg);
7826030Sjb150015 	if (rc != SQLITE_OK) {
783*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to query hosts info from host " \
784*11963SAfshin.Ardakani@Sun.COM 		    "database.  Unable to destroy virtual machine (%s).",
785*11963SAfshin.Ardakani@Sun.COM 		    NULL_MSGCHK(errmsg));
786*11963SAfshin.Ardakani@Sun.COM 		if (err == SMB_NIC_SUCCESS) {
787*11963SAfshin.Ardakani@Sun.COM 			/* set this error if no previous error */
788*11963SAfshin.Ardakani@Sun.COM 			err = SMB_NIC_DB_ERROR;
789*11963SAfshin.Ardakani@Sun.COM 		}
7906030Sjb150015 	}
7916030Sjb150015 
7926030Sjb150015 	smb_nic_dbclose(db);
7936030Sjb150015 
794*11963SAfshin.Ardakani@Sun.COM 	return (err);
7956030Sjb150015 }
7966030Sjb150015 
7976030Sjb150015 static smb_hostifs_t *
smb_nic_iflist_decode(const char ** values,int * err)798*11963SAfshin.Ardakani@Sun.COM smb_nic_iflist_decode(const char **values, int *err)
7996030Sjb150015 {
8006030Sjb150015 	smb_hostifs_t *iflist;
8016030Sjb150015 	char *host;
8026030Sjb150015 	char *cmnt;
8036030Sjb150015 	char *ifnames;
8046030Sjb150015 	char *lasts;
8056030Sjb150015 	char *ifname;
8066030Sjb150015 	int if_num = 0;
8076030Sjb150015 
8086030Sjb150015 	host = (char *)values[SMB_NIC_HTBL_HOST];
8096030Sjb150015 	cmnt = (char *)values[SMB_NIC_HTBL_CMNT];
8106030Sjb150015 	ifnames = (char *)values[SMB_NIC_HTBL_IFS];
8116030Sjb150015 
812*11963SAfshin.Ardakani@Sun.COM 	if ((host == NULL) || (ifnames == NULL)) {
813*11963SAfshin.Ardakani@Sun.COM 		*err = SMB_NIC_INVALID_ARG;
8146030Sjb150015 		return (NULL);
815*11963SAfshin.Ardakani@Sun.COM 	}
8166030Sjb150015 
8176030Sjb150015 	iflist = malloc(sizeof (smb_hostifs_t));
818*11963SAfshin.Ardakani@Sun.COM 	if (iflist == NULL) {
819*11963SAfshin.Ardakani@Sun.COM 		*err = SMB_NIC_NO_MEMORY;
8206030Sjb150015 		return (NULL);
821*11963SAfshin.Ardakani@Sun.COM 	}
8226030Sjb150015 
8236030Sjb150015 	bzero(iflist, sizeof (smb_hostifs_t));
8246030Sjb150015 
8256030Sjb150015 	(void) strlcpy(iflist->if_host, host, sizeof (iflist->if_host));
8266030Sjb150015 	(void) strlcpy(iflist->if_cmnt, (cmnt) ? cmnt : "",
8276030Sjb150015 	    sizeof (iflist->if_cmnt));
8286030Sjb150015 
829*11963SAfshin.Ardakani@Sun.COM 	if ((ifname = strtok_r(ifnames, ",", &lasts)) == NULL) {
830*11963SAfshin.Ardakani@Sun.COM 		*err = SMB_NIC_BAD_DATA;
8316030Sjb150015 		return (NULL);
832*11963SAfshin.Ardakani@Sun.COM 	}
8336030Sjb150015 
8346030Sjb150015 	iflist->if_names[if_num++] = strdup(ifname);
8356030Sjb150015 
8366030Sjb150015 	while ((ifname = strtok_r(NULL, ",", &lasts)) != NULL)
8376030Sjb150015 		iflist->if_names[if_num++] = strdup(ifname);
8386030Sjb150015 
8396030Sjb150015 	iflist->if_num = if_num;
8406030Sjb150015 
8416030Sjb150015 	for (if_num = 0; if_num < iflist->if_num; if_num++) {
8426030Sjb150015 		if (iflist->if_names[if_num] == NULL) {
8436030Sjb150015 			smb_nic_iflist_destroy(iflist);
844*11963SAfshin.Ardakani@Sun.COM 			*err = SMB_NIC_NO_MEMORY;
8456030Sjb150015 			return (NULL);
8466030Sjb150015 		}
8476030Sjb150015 	}
8486030Sjb150015 
849*11963SAfshin.Ardakani@Sun.COM 	*err = SMB_NIC_SUCCESS;
8506030Sjb150015 	return (iflist);
8516030Sjb150015 }
8526030Sjb150015 
8536030Sjb150015 /*
8546030Sjb150015  * smb_nic_iflist_destroy
8556030Sjb150015  *
8566030Sjb150015  * Frees allocated memory for the given IF names lists.
8576030Sjb150015  */
8586030Sjb150015 static void
smb_nic_iflist_destroy(smb_hostifs_t * iflist)8596030Sjb150015 smb_nic_iflist_destroy(smb_hostifs_t *iflist)
8606030Sjb150015 {
8616030Sjb150015 	int i;
8626030Sjb150015 
8636030Sjb150015 	if (iflist == NULL)
8646030Sjb150015 		return;
8656030Sjb150015 
8666030Sjb150015 	for (i = 0; i < iflist->if_num; i++)
8676030Sjb150015 		free(iflist->if_names[i]);
8686030Sjb150015 
8696030Sjb150015 	free(iflist);
8706030Sjb150015 }
8716030Sjb150015 
8726030Sjb150015 /*
8736030Sjb150015  * Functions to manage host/interface database
8746030Sjb150015  *
8756030Sjb150015  * Each entry in the hosts table associates a hostname with a
8766030Sjb150015  * list of interface names. The host/interface association could
8776030Sjb150015  * be added by calling smb_nic_addhost() and could be removed by
8786030Sjb150015  * calling smb_nic_delhost(). If the database exists and it contains
8796030Sjb150015  * valid information then the inteface list wouldn't be obtained
8806030Sjb150015  * from system using ioctl.
8816030Sjb150015  */
8826030Sjb150015 
8836030Sjb150015 /*
8846030Sjb150015  * smb_nic_dbcreate
8856030Sjb150015  *
8866030Sjb150015  * Creates the host database based on the defined SQL statement.
8876030Sjb150015  * It also initializes db_info table.
8886030Sjb150015  */
8896030Sjb150015 static int
smb_nic_dbcreate(void)8906030Sjb150015 smb_nic_dbcreate(void)
8916030Sjb150015 {
8926030Sjb150015 	sqlite *db = NULL;
8936030Sjb150015 	char *errmsg = NULL;
894*11963SAfshin.Ardakani@Sun.COM 	int rc, err = SMB_NIC_SUCCESS;
8956030Sjb150015 
8966030Sjb150015 	(void) unlink(SMB_NIC_DB_NAME);
8976030Sjb150015 
8986030Sjb150015 	db = sqlite_open(SMB_NIC_DB_NAME, 0600, &errmsg);
8996030Sjb150015 	if (db == NULL) {
900*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to create host database (%s).",
9016030Sjb150015 		    NULL_MSGCHK(errmsg));
9026030Sjb150015 		sqlite_freemem(errmsg);
903*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DBOPEN_FAILED);
9046030Sjb150015 	}
9056030Sjb150015 
9066030Sjb150015 	sqlite_busy_timeout(db, SMB_NIC_DB_TIMEOUT);
9076030Sjb150015 	rc = sqlite_exec(db, "BEGIN TRANSACTION", NULL, NULL, &errmsg);
9086030Sjb150015 	if (rc != SQLITE_OK) {
909*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
910*11963SAfshin.Ardakani@Sun.COM 		    "begin database transaction (%s).", NULL_MSGCHK(errmsg));
9116030Sjb150015 		sqlite_freemem(errmsg);
9126030Sjb150015 		sqlite_close(db);
913*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DBEXEC_FAILED);
9146030Sjb150015 	}
9156030Sjb150015 
9166030Sjb150015 	if (sqlite_exec(db, SMB_NIC_DB_SQL, NULL, NULL, &errmsg) == SQLITE_OK) {
9176030Sjb150015 		rc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
9186030Sjb150015 		    &errmsg);
9196030Sjb150015 		if (rc == SQLITE_OK)
920*11963SAfshin.Ardakani@Sun.COM 			err = smb_nic_dbsetinfo(db);
921*11963SAfshin.Ardakani@Sun.COM 		if (err != SMB_NIC_SUCCESS)
9226030Sjb150015 			rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
9236030Sjb150015 			    &errmsg);
9246030Sjb150015 	} else {
925*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
926*11963SAfshin.Ardakani@Sun.COM 		    "initialize host database (%s).", NULL_MSGCHK(errmsg));
9276030Sjb150015 		sqlite_freemem(errmsg);
9286030Sjb150015 		rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
9296030Sjb150015 		    &errmsg);
9306030Sjb150015 	}
9316030Sjb150015 
9326030Sjb150015 	if (rc != SQLITE_OK) {
9336030Sjb150015 		/* this is bad - database may be left in a locked state */
934*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
935*11963SAfshin.Ardakani@Sun.COM 		    "close a transaction (%s).", NULL_MSGCHK(errmsg));
9366030Sjb150015 		sqlite_freemem(errmsg);
937*11963SAfshin.Ardakani@Sun.COM 		err = SMB_NIC_DBINIT_FAILED;
9386030Sjb150015 	}
9396030Sjb150015 
9406030Sjb150015 	(void) sqlite_close(db);
941*11963SAfshin.Ardakani@Sun.COM 	return (err);
9426030Sjb150015 }
9436030Sjb150015 
9446030Sjb150015 /*
9456030Sjb150015  * smb_nic_dbopen
9466030Sjb150015  *
9476030Sjb150015  * Opens host database with the given mode.
9486030Sjb150015  */
9496030Sjb150015 static sqlite *
smb_nic_dbopen(int mode)9506030Sjb150015 smb_nic_dbopen(int mode)
9516030Sjb150015 {
9526030Sjb150015 	sqlite *db;
9536030Sjb150015 	char *errmsg = NULL;
9546030Sjb150015 
9556030Sjb150015 	db = sqlite_open(SMB_NIC_DB_NAME, mode, &errmsg);
9566030Sjb150015 	if (db == NULL) {
957*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to open host database: %s (%s).",
958*11963SAfshin.Ardakani@Sun.COM 		    SMB_NIC_DB_NAME, NULL_MSGCHK(errmsg));
9596030Sjb150015 		sqlite_freemem(errmsg);
9606030Sjb150015 	}
9616030Sjb150015 
9626030Sjb150015 	return (db);
9636030Sjb150015 }
9646030Sjb150015 
9656030Sjb150015 /*
9666030Sjb150015  * smb_nic_dbclose
9676030Sjb150015  *
9686030Sjb150015  * Closes the given database handle
9696030Sjb150015  */
9706030Sjb150015 static void
smb_nic_dbclose(sqlite * db)9716030Sjb150015 smb_nic_dbclose(sqlite *db)
9726030Sjb150015 {
9736030Sjb150015 	if (db) {
9746030Sjb150015 		sqlite_close(db);
9756030Sjb150015 	}
9766030Sjb150015 }
9776030Sjb150015 
9786030Sjb150015 static boolean_t
smb_nic_dbexists(void)9796030Sjb150015 smb_nic_dbexists(void)
9806030Sjb150015 {
9816030Sjb150015 	return (access(SMB_NIC_DB_NAME, F_OK) == 0);
9826030Sjb150015 }
9836030Sjb150015 
9846030Sjb150015 static boolean_t
smb_nic_dbvalidate(void)9856030Sjb150015 smb_nic_dbvalidate(void)
9866030Sjb150015 {
9876030Sjb150015 	sqlite *db;
9886030Sjb150015 	char *errmsg = NULL;
9896030Sjb150015 	char *sql;
9906030Sjb150015 	char **result;
9916030Sjb150015 	int nrow, ncol;
9926030Sjb150015 	boolean_t check = B_TRUE;
9936030Sjb150015 	int rc;
9946030Sjb150015 
9956030Sjb150015 	sql = sqlite_mprintf("SELECT * FROM db_info");
9966030Sjb150015 	if (sql == NULL)
9976030Sjb150015 		return (B_FALSE);
9986030Sjb150015 
9996030Sjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
10006030Sjb150015 	if (db == NULL) {
10016030Sjb150015 		sqlite_freemem(sql);
10026030Sjb150015 		return (B_FALSE);
10036030Sjb150015 	}
10046030Sjb150015 
10056030Sjb150015 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
10066030Sjb150015 	sqlite_freemem(sql);
10076030Sjb150015 
10086030Sjb150015 	if (rc != SQLITE_OK) {
1009*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to validate host database.  Unable " \
1010*11963SAfshin.Ardakani@Sun.COM 		    "to get database information (%s).", NULL_MSGCHK(errmsg));
10116030Sjb150015 		sqlite_freemem(errmsg);
10126030Sjb150015 		smb_nic_dbclose(db);
10136030Sjb150015 		return (B_FALSE);
10146030Sjb150015 	}
10156030Sjb150015 
10166030Sjb150015 	if (nrow != 1 || ncol != 3) {
1017*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to validate host database:  bad " \
1018*11963SAfshin.Ardakani@Sun.COM 		    "db_info table.");
10196030Sjb150015 		sqlite_free_table(result);
10206030Sjb150015 		smb_nic_dbclose(db);
10216030Sjb150015 		return (B_FALSE);
10226030Sjb150015 	}
10236030Sjb150015 
10246030Sjb150015 	if ((atoi(result[3]) != SMB_NIC_DB_VERMAJOR) ||
10256030Sjb150015 	    (atoi(result[4]) != SMB_NIC_DB_VERMINOR) ||
10266030Sjb150015 	    (atoi(result[5]) != SMB_NIC_DB_MAGIC)) {
1027*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to validate host database: bad " \
1028*11963SAfshin.Ardakani@Sun.COM 		    "db_info content.");
10296030Sjb150015 		sqlite_free_table(result);
10306030Sjb150015 		smb_nic_dbclose(db);
10316030Sjb150015 		return (B_FALSE);
10326030Sjb150015 	}
10336030Sjb150015 	sqlite_free_table(result);
10346030Sjb150015 
10356030Sjb150015 	sql = sqlite_mprintf("SELECT hostname FROM hosts");
10366030Sjb150015 	if (sql == NULL) {
10376030Sjb150015 		smb_nic_dbclose(db);
10386030Sjb150015 		return (B_FALSE);
10396030Sjb150015 	}
10406030Sjb150015 
10416030Sjb150015 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
10426030Sjb150015 	sqlite_freemem(sql);
10436030Sjb150015 
10446030Sjb150015 	if (rc != SQLITE_OK) {
1045*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to validate host database.  Unable " \
1046*11963SAfshin.Ardakani@Sun.COM 		"to query for host (%s).", NULL_MSGCHK(errmsg));
10476030Sjb150015 		sqlite_freemem(errmsg);
10486030Sjb150015 		smb_nic_dbclose(db);
10496030Sjb150015 		return (B_FALSE);
10506030Sjb150015 	}
10516030Sjb150015 
10526030Sjb150015 	sqlite_free_table(result);
10536030Sjb150015 
10546030Sjb150015 	if (nrow == 0)
10556030Sjb150015 		/* No hosts in the database */
10566030Sjb150015 		check = B_FALSE;
10576030Sjb150015 
10586030Sjb150015 	smb_nic_dbclose(db);
10596030Sjb150015 	return (check);
10606030Sjb150015 }
10616030Sjb150015 
10626030Sjb150015 static int
smb_nic_dbaddhost(const char * host,const char * cmnt,char * if_list)10636030Sjb150015 smb_nic_dbaddhost(const char *host, const char *cmnt, char *if_list)
10646030Sjb150015 {
10656030Sjb150015 	sqlite *db;
10666030Sjb150015 	char *sql;
10676030Sjb150015 	char *errmsg;
1068*11963SAfshin.Ardakani@Sun.COM 	int rc, err = SMB_NIC_SUCCESS;
10696030Sjb150015 
10706030Sjb150015 	sql = sqlite_mprintf("REPLACE INTO hosts (hostname, comment, ifnames)"
10716030Sjb150015 	    "VALUES ('%s', '%q', '%s')", host, (cmnt) ? cmnt : "", if_list);
10726030Sjb150015 	if (sql == NULL)
1073*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
10746030Sjb150015 
10756030Sjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
10766030Sjb150015 	if (db == NULL) {
10776030Sjb150015 		sqlite_freemem(sql);
1078*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DBOPEN_FAILED);
10796030Sjb150015 	}
10806030Sjb150015 
10816030Sjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
10826030Sjb150015 	sqlite_freemem(sql);
10836030Sjb150015 	smb_nic_dbclose(db);
10846030Sjb150015 
10856030Sjb150015 	if (rc != SQLITE_OK) {
1086*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to add host %s to host database (%s).",
10876030Sjb150015 		    host, NULL_MSGCHK(errmsg));
10886030Sjb150015 		sqlite_freemem(errmsg);
1089*11963SAfshin.Ardakani@Sun.COM 		err = SMB_NIC_INSERT_FAILED;
10906030Sjb150015 	}
10916030Sjb150015 
1092*11963SAfshin.Ardakani@Sun.COM 	return (err);
10936030Sjb150015 }
10946030Sjb150015 
10956030Sjb150015 static int
smb_nic_dbdelhost(const char * host)10966030Sjb150015 smb_nic_dbdelhost(const char *host)
10976030Sjb150015 {
10986030Sjb150015 	sqlite *db;
10996030Sjb150015 	char *sql;
11006030Sjb150015 	char *errmsg;
1101*11963SAfshin.Ardakani@Sun.COM 	int rc, err = SMB_NIC_SUCCESS;
11026030Sjb150015 
11036030Sjb150015 	sql = sqlite_mprintf("DELETE FROM hosts WHERE hostname = '%s'", host);
11046030Sjb150015 	if (sql == NULL)
1105*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
11066030Sjb150015 
11076030Sjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
11086030Sjb150015 	if (db == NULL) {
11096030Sjb150015 		sqlite_freemem(sql);
1110*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_DBOPEN_FAILED);
11116030Sjb150015 	}
11126030Sjb150015 
11136030Sjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
11146030Sjb150015 	sqlite_freemem(sql);
11156030Sjb150015 	smb_nic_dbclose(db);
11166030Sjb150015 
11176030Sjb150015 	if (rc != SQLITE_OK) {
1118*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to delete host %s from host " \
1119*11963SAfshin.Ardakani@Sun.COM 		    "database (%s).", host, NULL_MSGCHK(errmsg));
11206030Sjb150015 		sqlite_freemem(errmsg);
1121*11963SAfshin.Ardakani@Sun.COM 		err = SMB_NIC_DELETE_FAILED;
11226030Sjb150015 	}
11236030Sjb150015 
1124*11963SAfshin.Ardakani@Sun.COM 	return (err);
11256030Sjb150015 }
11266030Sjb150015 
11276030Sjb150015 /*
11286030Sjb150015  * smb_nic_dbsetinfo
11296030Sjb150015  *
11306030Sjb150015  * Initializes the db_info table upon database creation.
11316030Sjb150015  */
11326030Sjb150015 static int
smb_nic_dbsetinfo(sqlite * db)11336030Sjb150015 smb_nic_dbsetinfo(sqlite *db)
11346030Sjb150015 {
11356030Sjb150015 	char *errmsg = NULL;
11366030Sjb150015 	char *sql;
1137*11963SAfshin.Ardakani@Sun.COM 	int rc, err = SMB_NIC_SUCCESS;
11386030Sjb150015 
11396030Sjb150015 	sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
11406030Sjb150015 	    " magic) VALUES (%d, %d, %d)", SMB_NIC_DB_VERMAJOR,
11416030Sjb150015 	    SMB_NIC_DB_VERMINOR, SMB_NIC_DB_MAGIC);
11426030Sjb150015 
11436030Sjb150015 	if (sql == NULL)
1144*11963SAfshin.Ardakani@Sun.COM 		return (SMB_NIC_NO_MEMORY);
11456030Sjb150015 
11466030Sjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
11476030Sjb150015 	sqlite_freemem(sql);
11486030Sjb150015 	if (rc != SQLITE_OK) {
1149*11963SAfshin.Ardakani@Sun.COM 		syslog(LOG_ERR, "Failed to add database information to " \
1150*11963SAfshin.Ardakani@Sun.COM 		    "host database (%s).", NULL_MSGCHK(errmsg));
11516030Sjb150015 		sqlite_freemem(errmsg);
1152*11963SAfshin.Ardakani@Sun.COM 		err = SMB_NIC_DBINIT_ERROR;
11536030Sjb150015 	}
11546030Sjb150015 
1155*11963SAfshin.Ardakani@Sun.COM 	return (err);
11566030Sjb150015 }
11578334SJose.Borrego@Sun.COM 
11588334SJose.Borrego@Sun.COM /*
11598334SJose.Borrego@Sun.COM  * smb_nic_nbt_get_exclude_list
11608334SJose.Borrego@Sun.COM  *
11618334SJose.Borrego@Sun.COM  * Construct an array containing list of i/f names on which NetBIOS traffic is
11628334SJose.Borrego@Sun.COM  * to be disabled, from a string containing a list of comma separated i/f names.
11638334SJose.Borrego@Sun.COM  *
11648334SJose.Borrego@Sun.COM  * Returns the number of i/f on which NetBIOS traffic is to be disabled.
11658334SJose.Borrego@Sun.COM  */
11668334SJose.Borrego@Sun.COM static int
smb_nic_nbt_get_exclude_list(char * excludestr,char ** iflist,int max_nifs)11678334SJose.Borrego@Sun.COM smb_nic_nbt_get_exclude_list(char *excludestr, char **iflist, int max_nifs)
11688334SJose.Borrego@Sun.COM {
11698334SJose.Borrego@Sun.COM 	int n = 0;
11708334SJose.Borrego@Sun.COM 	char *entry;
11718334SJose.Borrego@Sun.COM 
11728334SJose.Borrego@Sun.COM 	bzero(iflist, SMB_PI_MAX_NETWORKS * sizeof (char *));
11738334SJose.Borrego@Sun.COM 
11748334SJose.Borrego@Sun.COM 	(void) trim_whitespace(excludestr);
11758334SJose.Borrego@Sun.COM 	(void) strcanon(excludestr, ",");
11768334SJose.Borrego@Sun.COM 
11778334SJose.Borrego@Sun.COM 	if (*excludestr == '\0')
11788334SJose.Borrego@Sun.COM 		return (0);
11798334SJose.Borrego@Sun.COM 
11808334SJose.Borrego@Sun.COM 	while (((iflist[n] = strsep(&excludestr, ",")) != NULL) &&
11818334SJose.Borrego@Sun.COM 	    (n < max_nifs)) {
11828334SJose.Borrego@Sun.COM 		entry = iflist[n];
11838334SJose.Borrego@Sun.COM 		if (*entry == '\0')
11848334SJose.Borrego@Sun.COM 			continue;
11858334SJose.Borrego@Sun.COM 		n++;
11868334SJose.Borrego@Sun.COM 	}
11878334SJose.Borrego@Sun.COM 
11888334SJose.Borrego@Sun.COM 	return (n);
11898334SJose.Borrego@Sun.COM }
11908334SJose.Borrego@Sun.COM 
11918334SJose.Borrego@Sun.COM /*
11928334SJose.Borrego@Sun.COM  * smb_nic_nbt_exclude
11938334SJose.Borrego@Sun.COM  *
11948334SJose.Borrego@Sun.COM  * Check to see if the given interface name should send NetBIOS traffic or not.
11958334SJose.Borrego@Sun.COM  *
11968334SJose.Borrego@Sun.COM  * Returns TRUE if NetBIOS traffic is disabled on an interface name.
11978334SJose.Borrego@Sun.COM  * Returns FALSE otherwise.
11988334SJose.Borrego@Sun.COM  */
11998334SJose.Borrego@Sun.COM static boolean_t
smb_nic_nbt_exclude(const smb_nic_t * nc,const char ** exclude_list,int nexclude)12008334SJose.Borrego@Sun.COM smb_nic_nbt_exclude(const smb_nic_t *nc, const char **exclude_list,
12018334SJose.Borrego@Sun.COM     int nexclude)
12028334SJose.Borrego@Sun.COM {
12038334SJose.Borrego@Sun.COM 	char buf[INET6_ADDRSTRLEN];
12048334SJose.Borrego@Sun.COM 	const char *ifname = nc->nic_ifname;
12058334SJose.Borrego@Sun.COM 	int i;
12068334SJose.Borrego@Sun.COM 
12078334SJose.Borrego@Sun.COM 	if (inet_ntop(AF_INET, &nc->nic_ip, buf, INET6_ADDRSTRLEN) == NULL)
12088334SJose.Borrego@Sun.COM 		buf[0] = '\0';
12098334SJose.Borrego@Sun.COM 
12108334SJose.Borrego@Sun.COM 	for (i = 0; i < nexclude; i++) {
12118334SJose.Borrego@Sun.COM 		if (strcmp(ifname, exclude_list[i]) == 0)
12128334SJose.Borrego@Sun.COM 			return (B_TRUE);
12138334SJose.Borrego@Sun.COM 
12148334SJose.Borrego@Sun.COM 		if ((buf[0] != '\0') && (strcmp(buf, exclude_list[i]) == 0))
12158334SJose.Borrego@Sun.COM 			return (B_TRUE);
12168334SJose.Borrego@Sun.COM 	}
12178334SJose.Borrego@Sun.COM 
12188334SJose.Borrego@Sun.COM 	return (B_FALSE);
12198334SJose.Borrego@Sun.COM }
1220