xref: /titanic_52/usr/src/lib/smbsrv/libsmb/common/smb_nic.c (revision b819cea2f73f98c5662230cc9affc8cc84f77fcf)
17b59d02dSjb150015 /*
27b59d02dSjb150015  * CDDL HEADER START
37b59d02dSjb150015  *
47b59d02dSjb150015  * The contents of this file are subject to the terms of the
57b59d02dSjb150015  * Common Development and Distribution License (the "License").
67b59d02dSjb150015  * You may not use this file except in compliance with the License.
77b59d02dSjb150015  *
87b59d02dSjb150015  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97b59d02dSjb150015  * or http://www.opensolaris.org/os/licensing.
107b59d02dSjb150015  * See the License for the specific language governing permissions
117b59d02dSjb150015  * and limitations under the License.
127b59d02dSjb150015  *
137b59d02dSjb150015  * When distributing Covered Code, include this CDDL HEADER in each
147b59d02dSjb150015  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157b59d02dSjb150015  * If applicable, add the following below this CDDL HEADER, with the
167b59d02dSjb150015  * fields enclosed by brackets "[]" replaced with your own identifying
177b59d02dSjb150015  * information: Portions Copyright [yyyy] [name of copyright owner]
187b59d02dSjb150015  *
197b59d02dSjb150015  * CDDL HEADER END
207b59d02dSjb150015  */
217b59d02dSjb150015 /*
229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237b59d02dSjb150015  * Use is subject to license terms.
24*b819cea2SGordon Ross  *
25*b819cea2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
267b59d02dSjb150015  */
277b59d02dSjb150015 
287b59d02dSjb150015 #include <stdio.h>
297b59d02dSjb150015 #include <stdlib.h>
307b59d02dSjb150015 #include <syslog.h>
317b59d02dSjb150015 #include <libintl.h>
327b59d02dSjb150015 #include <strings.h>
337b59d02dSjb150015 #include <string.h>
347b59d02dSjb150015 #include <unistd.h>
357b59d02dSjb150015 #include <synch.h>
367b59d02dSjb150015 #include <stropts.h>
377b59d02dSjb150015 #include <errno.h>
387b59d02dSjb150015 #include <pthread.h>
397b59d02dSjb150015 
407b59d02dSjb150015 #include <inet/ip.h>
417b59d02dSjb150015 #include <net/if.h>
427b59d02dSjb150015 #include <netinet/in.h>
437b59d02dSjb150015 #include <netdb.h>
447b59d02dSjb150015 #include <net/route.h>
457b59d02dSjb150015 #include <arpa/inet.h>
467b59d02dSjb150015 
477b59d02dSjb150015 #include <sys/socket.h>
487b59d02dSjb150015 #include <sys/sockio.h>
497b59d02dSjb150015 #include <sys/systeminfo.h>
507b59d02dSjb150015 
517b59d02dSjb150015 #include <smbsrv/libsmb.h>
5291d7f85eSGordon Ross #include <sqlite-sys/sqlite.h>
537b59d02dSjb150015 
547b59d02dSjb150015 #define	SMB_NIC_DB_NAME		"/var/smb/smbhosts.db"
557b59d02dSjb150015 #define	SMB_NIC_DB_TIMEOUT	3000		/* in millisecond */
567b59d02dSjb150015 #define	SMB_NIC_DB_VERMAJOR	1
577b59d02dSjb150015 #define	SMB_NIC_DB_VERMINOR	0
587b59d02dSjb150015 #define	SMB_NIC_DB_MAGIC	0x484F5354	/* HOST */
597b59d02dSjb150015 
607b59d02dSjb150015 #define	SMB_NIC_DB_ORD		1		/* open read-only */
617b59d02dSjb150015 #define	SMB_NIC_DB_ORW		2		/* open read/write */
627b59d02dSjb150015 
637b59d02dSjb150015 #define	SMB_NIC_DB_SQL \
647b59d02dSjb150015 	"CREATE TABLE db_info ("				\
657b59d02dSjb150015 	"	ver_major INTEGER,"				\
667b59d02dSjb150015 	"	ver_minor INTEGER,"				\
677b59d02dSjb150015 	"	magic     INTEGER"				\
687b59d02dSjb150015 	");"							\
697b59d02dSjb150015 	""							\
707b59d02dSjb150015 	"CREATE TABLE hosts ("					\
717b59d02dSjb150015 	"	hostname  TEXT PRIMARY KEY,"			\
727b59d02dSjb150015 	"	comment   TEXT,"				\
737b59d02dSjb150015 	"	ifnames   TEXT"					\
747b59d02dSjb150015 	");"
757b59d02dSjb150015 
767b59d02dSjb150015 #define	SMB_NIC_HTBL_NCOL	3
777b59d02dSjb150015 #define	SMB_NIC_HTBL_HOST	0
787b59d02dSjb150015 #define	SMB_NIC_HTBL_CMNT	1
797b59d02dSjb150015 #define	SMB_NIC_HTBL_IFS	2
807b59d02dSjb150015 
817b59d02dSjb150015 #define	NULL_MSGCHK(msg)	((msg) ? (msg) : "NULL")
827b59d02dSjb150015 
837b59d02dSjb150015 #define	SMB_NIC_MAXIFS		256
848d7e4166Sjose borrego #define	SMB_NIC_MAXEXCLLIST_LEN	512
857b59d02dSjb150015 
867b59d02dSjb150015 typedef struct smb_hostifs {
877b59d02dSjb150015 	list_node_t if_lnd;
887b59d02dSjb150015 	char if_host[MAXHOSTNAMELEN];
897b59d02dSjb150015 	char if_cmnt[SMB_PI_MAX_COMMENT];
907b59d02dSjb150015 	char *if_names[SMB_NIC_MAXIFS];
917b59d02dSjb150015 	int if_num;
927b59d02dSjb150015 } smb_hostifs_t;
937b59d02dSjb150015 
947b59d02dSjb150015 typedef struct smb_hosts {
957b59d02dSjb150015 	list_t h_list;
967b59d02dSjb150015 	int h_num;
977b59d02dSjb150015 	int h_ifnum;
987b59d02dSjb150015 } smb_hosts_t;
997b59d02dSjb150015 
1007b59d02dSjb150015 typedef struct {
1017b59d02dSjb150015 	smb_nic_t	*nl_nics;
1027b59d02dSjb150015 	int		nl_cnt;		/* number of smb_nic_t structures */
1037b59d02dSjb150015 	int		nl_hcnt;	/* number of host names */
1047b59d02dSjb150015 	long		nl_seqnum;	/* a random sequence number */
1057b59d02dSjb150015 	rwlock_t	nl_rwl;
1067b59d02dSjb150015 } smb_niclist_t;
1077b59d02dSjb150015 
1087b59d02dSjb150015 static int smb_nic_list_create(void);
1097b59d02dSjb150015 static void smb_nic_list_destroy(void);
1107b59d02dSjb150015 
1117b59d02dSjb150015 static int smb_nic_hlist_create(smb_hosts_t *);
1127b59d02dSjb150015 static void smb_nic_hlist_destroy(smb_hosts_t *);
1137b59d02dSjb150015 static int smb_nic_hlist_dbget(smb_hosts_t *);
1147b59d02dSjb150015 static int smb_nic_hlist_sysget(smb_hosts_t *);
1157b59d02dSjb150015 
1167b59d02dSjb150015 static void smb_nic_iflist_destroy(smb_hostifs_t *);
1179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static smb_hostifs_t *smb_nic_iflist_decode(const char **, int *);
1187b59d02dSjb150015 
1197b59d02dSjb150015 static int smb_nic_dbcreate(void);
1207b59d02dSjb150015 static sqlite *smb_nic_dbopen(int);
1217b59d02dSjb150015 static void smb_nic_dbclose(sqlite *);
1227b59d02dSjb150015 static boolean_t smb_nic_dbexists(void);
1237b59d02dSjb150015 static boolean_t smb_nic_dbvalidate(void);
1247b59d02dSjb150015 static int smb_nic_dbaddhost(const char *, const char *, char *);
1257b59d02dSjb150015 static int smb_nic_dbdelhost(const char *);
1267b59d02dSjb150015 static int smb_nic_dbsetinfo(sqlite *);
1277b59d02dSjb150015 
1287f667e74Sjose borrego static int smb_nic_getinfo(char *, smb_nic_t *, int);
1298d7e4166Sjose borrego static boolean_t smb_nic_nbt_exclude(const smb_nic_t *, const char **, int);
1308d7e4166Sjose borrego static int smb_nic_nbt_get_exclude_list(char *, char **, int);
1317b59d02dSjb150015 
1327f667e74Sjose borrego static void smb_close_sockets(int, int);
1337f667e74Sjose borrego static boolean_t smb_duplicate_nic(smb_hostifs_t *iflist, struct lifreq *lifrp);
1347f667e74Sjose borrego 
1357b59d02dSjb150015 /* This is the list we will monitor */
1367b59d02dSjb150015 static smb_niclist_t smb_niclist;
1377b59d02dSjb150015 
1387b59d02dSjb150015 /*
1397b59d02dSjb150015  * smb_nic_init
1407b59d02dSjb150015  *
1417b59d02dSjb150015  * Initializes the interface list.
1427b59d02dSjb150015  */
1437b59d02dSjb150015 int
1447b59d02dSjb150015 smb_nic_init(void)
1457b59d02dSjb150015 {
1467b59d02dSjb150015 	int rc;
1477b59d02dSjb150015 
1487b59d02dSjb150015 	(void) rw_wrlock(&smb_niclist.nl_rwl);
1497b59d02dSjb150015 	smb_nic_list_destroy();
1507b59d02dSjb150015 	rc = smb_nic_list_create();
1517b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1527b59d02dSjb150015 
1537b59d02dSjb150015 	return (rc);
1547b59d02dSjb150015 }
1557b59d02dSjb150015 
1567b59d02dSjb150015 /*
1577b59d02dSjb150015  * smb_nic_fini
1587b59d02dSjb150015  *
1597b59d02dSjb150015  * Destroys the interface list.
1607b59d02dSjb150015  */
1617b59d02dSjb150015 void
1627b59d02dSjb150015 smb_nic_fini(void)
1637b59d02dSjb150015 {
1647b59d02dSjb150015 	(void) rw_wrlock(&smb_niclist.nl_rwl);
1657b59d02dSjb150015 	smb_nic_list_destroy();
1667b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1677b59d02dSjb150015 }
1687b59d02dSjb150015 
1697b59d02dSjb150015 /*
1707b59d02dSjb150015  * smb_nic_getnum
1717b59d02dSjb150015  *
1727b59d02dSjb150015  * Gets the number of interfaces for the specified host.
1737b59d02dSjb150015  * if host is NULL then total number of interfaces
1747b59d02dSjb150015  * is returned. It's assumed that given name is a NetBIOS
1757b59d02dSjb150015  * encoded name.
1767b59d02dSjb150015  */
1777b59d02dSjb150015 int
1787b59d02dSjb150015 smb_nic_getnum(char *nb_hostname)
1797b59d02dSjb150015 {
1807b59d02dSjb150015 	int n = 0, i;
1817b59d02dSjb150015 
1827b59d02dSjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
1837b59d02dSjb150015 
1847b59d02dSjb150015 	if (nb_hostname != NULL) {
1857b59d02dSjb150015 		for (i = 0; i < smb_niclist.nl_cnt; i++) {
1867b59d02dSjb150015 			/* ignore the suffix */
1877b59d02dSjb150015 			if (strncasecmp(smb_niclist.nl_nics[i].nic_nbname,
1887b59d02dSjb150015 			    nb_hostname, NETBIOS_NAME_SZ - 1) == 0)
1897b59d02dSjb150015 				n++;
1907b59d02dSjb150015 		}
1917b59d02dSjb150015 	} else {
1927b59d02dSjb150015 		n = smb_niclist.nl_cnt;
1937b59d02dSjb150015 	}
1947b59d02dSjb150015 
1957b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
1967b59d02dSjb150015 
1977b59d02dSjb150015 	return (n);
1987b59d02dSjb150015 }
1997b59d02dSjb150015 
2007b59d02dSjb150015 /*
2017b59d02dSjb150015  * smb_nic_getfirst
2027b59d02dSjb150015  *
2037b59d02dSjb150015  * Returns the first NIC in the interface list and
2047b59d02dSjb150015  * initializes the given iterator. To get the rest of
2057b59d02dSjb150015  * NICs smb_nic_getnext() must be called.
2067b59d02dSjb150015  *
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns SMB_NIC_SUCCESS upon success or the following:
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	SMB_NIC_NOT_FOUND - there's no interface available
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	SMB_NIC_INVALID_ARG - 'ni' is NULL
2107b59d02dSjb150015  */
2117b59d02dSjb150015 int
2127b59d02dSjb150015 smb_nic_getfirst(smb_niciter_t *ni)
2137b59d02dSjb150015 {
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc = SMB_NIC_SUCCESS;
2157b59d02dSjb150015 
2167b59d02dSjb150015 	if (ni == NULL)
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_INVALID_ARG);
2187b59d02dSjb150015 
2197b59d02dSjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2207b59d02dSjb150015 
2217b59d02dSjb150015 	if (smb_niclist.nl_cnt > 0) {
2227b59d02dSjb150015 		ni->ni_nic = smb_niclist.nl_nics[0];
2237b59d02dSjb150015 		ni->ni_cookie = 1;
2247b59d02dSjb150015 		ni->ni_seqnum = smb_niclist.nl_seqnum;
2257b59d02dSjb150015 	} else {
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = SMB_NIC_NOT_FOUND;
2277b59d02dSjb150015 	}
2287b59d02dSjb150015 
2297b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
2307b59d02dSjb150015 
2317b59d02dSjb150015 	return (rc);
2327b59d02dSjb150015 }
2337b59d02dSjb150015 
2347b59d02dSjb150015 /*
2357b59d02dSjb150015  * smb_nic_getnext
2367b59d02dSjb150015  *
2377b59d02dSjb150015  * Returns the next NIC information based on the passed
2387b59d02dSjb150015  * iterator (ni). The iterator must have previously been
2397b59d02dSjb150015  * initialized by calling smb_nic_getfirst().
2407b59d02dSjb150015  *
2419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns SMB_NIC_SUCCESS upon successfully finding the specified NIC
2429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or the following:
2439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 	SMB_NIC_INVALID_ARG - the specified iterator is invalid
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 	SMB_NIC_NO_MORE - reaches the end of the NIC list
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 	SMB_NIC_CHANGED - sequence number in the iterator is different from
2467b59d02dSjb150015  *	  the sequence number in the NIC list which means
2477b59d02dSjb150015  *	  the list has been changed between getfirst/getnext
2487b59d02dSjb150015  *	  calls.
2497b59d02dSjb150015  */
2507b59d02dSjb150015 int
2517b59d02dSjb150015 smb_nic_getnext(smb_niciter_t *ni)
2527b59d02dSjb150015 {
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc = SMB_NIC_SUCCESS;
2547b59d02dSjb150015 
2557b59d02dSjb150015 	if ((ni == NULL) || (ni->ni_cookie < 1))
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_INVALID_ARG);
2577b59d02dSjb150015 
2587b59d02dSjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2597b59d02dSjb150015 
2607b59d02dSjb150015 	if ((smb_niclist.nl_cnt > ni->ni_cookie) &&
2617b59d02dSjb150015 	    (smb_niclist.nl_seqnum == ni->ni_seqnum)) {
2627b59d02dSjb150015 		ni->ni_nic = smb_niclist.nl_nics[ni->ni_cookie];
2637b59d02dSjb150015 		ni->ni_cookie++;
2647b59d02dSjb150015 	} else {
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (smb_niclist.nl_seqnum != ni->ni_seqnum)
2669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = SMB_NIC_CHANGED;
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = SMB_NIC_NO_MORE;
2697b59d02dSjb150015 	}
2707b59d02dSjb150015 
2717b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
2727b59d02dSjb150015 
2737b59d02dSjb150015 	return (rc);
2747b59d02dSjb150015 }
2757b59d02dSjb150015 
2767b59d02dSjb150015 boolean_t
277fc724630SAlan Wright smb_nic_is_local(smb_inaddr_t *ipaddr)
2787b59d02dSjb150015 {
2797b59d02dSjb150015 	smb_nic_t *cfg;
2807b59d02dSjb150015 	int i;
2817b59d02dSjb150015 
2827b59d02dSjb150015 	(void) rw_rdlock(&smb_niclist.nl_rwl);
2837b59d02dSjb150015 
2847b59d02dSjb150015 	for (i = 0; i < smb_niclist.nl_cnt; i++) {
2857b59d02dSjb150015 		cfg = &smb_niclist.nl_nics[i];
286fc724630SAlan Wright 		if (smb_inet_equal(ipaddr, &cfg->nic_ip)) {
287fc724630SAlan Wright 			(void) rw_unlock(&smb_niclist.nl_rwl);
288fc724630SAlan Wright 			return (B_TRUE);
289fc724630SAlan Wright 		}
290fc724630SAlan Wright 	}
291fc724630SAlan Wright 	(void) rw_unlock(&smb_niclist.nl_rwl);
292fc724630SAlan Wright 	return (B_FALSE);
293fc724630SAlan Wright }
294fc724630SAlan Wright 
295fc724630SAlan Wright boolean_t
296fc724630SAlan Wright smb_nic_is_same_subnet(smb_inaddr_t *ipaddr)
297fc724630SAlan Wright {
298fc724630SAlan Wright 	smb_nic_t *cfg;
299fc724630SAlan Wright 	int i;
300fc724630SAlan Wright 
301fc724630SAlan Wright 	(void) rw_rdlock(&smb_niclist.nl_rwl);
302fc724630SAlan Wright 
303fc724630SAlan Wright 	for (i = 0; i < smb_niclist.nl_cnt; i++) {
304fc724630SAlan Wright 		cfg = &smb_niclist.nl_nics[i];
305fc724630SAlan Wright 		if (smb_inet_same_subnet(ipaddr, &cfg->nic_ip, cfg->nic_mask)) {
3067b59d02dSjb150015 			(void) rw_unlock(&smb_niclist.nl_rwl);
3077b59d02dSjb150015 			return (B_TRUE);
3087b59d02dSjb150015 		}
3097b59d02dSjb150015 	}
3107b59d02dSjb150015 	(void) rw_unlock(&smb_niclist.nl_rwl);
3117b59d02dSjb150015 	return (B_FALSE);
3127b59d02dSjb150015 }
3137b59d02dSjb150015 
3147b59d02dSjb150015 /*
3157b59d02dSjb150015  * smb_nic_addhost
3167b59d02dSjb150015  *
3177b59d02dSjb150015  * Adds an association between the given host and the specified interface
3187b59d02dSjb150015  * list (if_names). This function can be called as many times as needed,
3197b59d02dSjb150015  * the associations will be stored in /var/smb/smbhosts.db, which is sqlite
3207b59d02dSjb150015  * database. If this file exists and it's not empty NIC list is generated
3217b59d02dSjb150015  * based on the information stored in this file.
3227b59d02dSjb150015  *
3237b59d02dSjb150015  * host: actual system's name (not Netbios name)
3247b59d02dSjb150015  * cmnt: an optional description for the CIFS server running on
3257b59d02dSjb150015  *       the specified host. Can be NULL.
3267b59d02dSjb150015  * if_num: number of interface names in if_names arg
3277b59d02dSjb150015  * if_names: array of interface names in string format
3287b59d02dSjb150015  *
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns SMB_NIC_SUCCESS upon success, a nonzero value otherwise.
3307b59d02dSjb150015  */
3317b59d02dSjb150015 int
3327b59d02dSjb150015 smb_nic_addhost(const char *host, const char *cmnt,
3337b59d02dSjb150015     int if_num, const char **if_names)
3347b59d02dSjb150015 {
3357b59d02dSjb150015 	char *if_list;
3367b59d02dSjb150015 	char *ifname;
3377b59d02dSjb150015 	int buflen = 0;
3387b59d02dSjb150015 	int rc, i;
3397b59d02dSjb150015 
3407b59d02dSjb150015 	if ((host == NULL) || (if_num <= 0) || (if_names == NULL))
3419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_INVALID_ARG);
3427b59d02dSjb150015 
3437b59d02dSjb150015 	if (!smb_nic_dbexists() || !smb_nic_dbvalidate()) {
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((rc = smb_nic_dbcreate()) != SMB_NIC_SUCCESS)
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (rc);
3467b59d02dSjb150015 	}
3477b59d02dSjb150015 
34829bd2886SAlan Wright 	for (i = 0; i < if_num; i++) {
34929bd2886SAlan Wright 		ifname = (char *)if_names[i];
3507b59d02dSjb150015 		if ((ifname == NULL) || (*ifname == '\0'))
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_NIC_INVALID_ARG);
3527b59d02dSjb150015 		buflen += strlen(ifname) + 1;
3537b59d02dSjb150015 	}
3547b59d02dSjb150015 
3557b59d02dSjb150015 	if ((if_list = malloc(buflen)) == NULL)
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
3577b59d02dSjb150015 
3587b59d02dSjb150015 	ifname = if_list;
3597b59d02dSjb150015 	for (i = 0; i < if_num - 1; i++)
3607b59d02dSjb150015 		ifname += snprintf(ifname, buflen, "%s,", if_names[i]);
3617b59d02dSjb150015 
3627b59d02dSjb150015 	(void) snprintf(ifname, buflen, "%s", if_names[i]);
3637b59d02dSjb150015 
3647b59d02dSjb150015 	rc = smb_nic_dbaddhost(host, cmnt, if_list);
3657b59d02dSjb150015 	free(if_list);
3667b59d02dSjb150015 
3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
3687b59d02dSjb150015 }
3697b59d02dSjb150015 
3707b59d02dSjb150015 /*
3717b59d02dSjb150015  * smb_nic_delhost
3727b59d02dSjb150015  *
3737b59d02dSjb150015  * Removes the stored interface association for the specified host
3747b59d02dSjb150015  */
3757b59d02dSjb150015 int
3767b59d02dSjb150015 smb_nic_delhost(const char *host)
3777b59d02dSjb150015 {
3787b59d02dSjb150015 	if ((host == NULL) || (*host == '\0'))
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_INVALID_ARG);
3807b59d02dSjb150015 
3817b59d02dSjb150015 	if (!smb_nic_dbexists())
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_SUCCESS);
3837b59d02dSjb150015 
3847b59d02dSjb150015 	if (!smb_nic_dbvalidate()) {
3857b59d02dSjb150015 		(void) unlink(SMB_NIC_DB_NAME);
3869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_SUCCESS);
3877b59d02dSjb150015 	}
3887b59d02dSjb150015 
3899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_nic_dbdelhost(host));
3907b59d02dSjb150015 }
3917b59d02dSjb150015 
3927b59d02dSjb150015 /*
3937b59d02dSjb150015  * smb_nic_list_create
3947b59d02dSjb150015  *
3957b59d02dSjb150015  * Creates a NIC list either based on /var/smb/smbhosts.db or
3967b59d02dSjb150015  * by getting the information from OS.
3977b59d02dSjb150015  *
3987b59d02dSjb150015  * Note that the caller of this function should grab the
3997b59d02dSjb150015  * list lock.
4007b59d02dSjb150015  */
4017b59d02dSjb150015 static int
4027b59d02dSjb150015 smb_nic_list_create(void)
4037b59d02dSjb150015 {
4047b59d02dSjb150015 	smb_hosts_t hlist;
4057b59d02dSjb150015 	smb_hostifs_t *iflist;
4067b59d02dSjb150015 	smb_nic_t *nc;
4077b59d02dSjb150015 	char *ifname;
4088d7e4166Sjose borrego 	char excludestr[SMB_NIC_MAXEXCLLIST_LEN];
4098d7e4166Sjose borrego 	char *exclude[SMB_PI_MAX_NETWORKS];
4108d7e4166Sjose borrego 	int nexclude = 0;
4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int i, rc;
4127b59d02dSjb150015 
4139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_nic_hlist_create(&hlist)) !=  SMB_NIC_SUCCESS)
4149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (rc);
4157b59d02dSjb150015 
4167b59d02dSjb150015 	smb_niclist.nl_cnt = 0;
4177b59d02dSjb150015 	smb_niclist.nl_seqnum = random();
4187b59d02dSjb150015 	smb_niclist.nl_hcnt = hlist.h_num;
4197b59d02dSjb150015 
4207b59d02dSjb150015 	smb_niclist.nl_nics = calloc(hlist.h_ifnum, sizeof (smb_nic_t));
4217b59d02dSjb150015 	if (smb_niclist.nl_nics == NULL) {
4227b59d02dSjb150015 		smb_nic_hlist_destroy(&hlist);
4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
4247b59d02dSjb150015 	}
4257b59d02dSjb150015 
4268d7e4166Sjose borrego 	*excludestr = '\0';
4278d7e4166Sjose borrego 	(void) smb_config_getstr(SMB_CI_WINS_EXCL,
4288d7e4166Sjose borrego 	    excludestr, sizeof (excludestr));
4298d7e4166Sjose borrego 
4308d7e4166Sjose borrego 	nexclude = smb_nic_nbt_get_exclude_list(excludestr,
4318d7e4166Sjose borrego 	    exclude, SMB_PI_MAX_NETWORKS);
4327b59d02dSjb150015 
4337b59d02dSjb150015 	nc = smb_niclist.nl_nics;
4347b59d02dSjb150015 	iflist = list_head(&hlist.h_list);
4357b59d02dSjb150015 
4367b59d02dSjb150015 	do {
4377b59d02dSjb150015 		for (i = 0; i < iflist->if_num; i++) {
4387b59d02dSjb150015 			ifname = iflist->if_names[i];
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (smb_nic_getinfo(ifname, nc, AF_INET) !=
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    SMB_NIC_SUCCESS) {
4417f667e74Sjose borrego 				if (smb_nic_getinfo(ifname, nc,
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				    AF_INET6) != SMB_NIC_SUCCESS) {
4437b59d02dSjb150015 					continue;
4447f667e74Sjose borrego 				}
4457f667e74Sjose borrego 			}
4467b59d02dSjb150015 
4477b59d02dSjb150015 			(void) strlcpy(nc->nic_host, iflist->if_host,
4487b59d02dSjb150015 			    sizeof (nc->nic_host));
4497b59d02dSjb150015 			(void) strlcpy(nc->nic_cmnt, iflist->if_cmnt,
4507b59d02dSjb150015 			    sizeof (nc->nic_cmnt));
4517b59d02dSjb150015 
4527b59d02dSjb150015 			smb_tonetbiosname(nc->nic_host, nc->nic_nbname, 0x00);
4537b59d02dSjb150015 
4547b59d02dSjb150015 			if (strchr(ifname, ':'))
4557b59d02dSjb150015 				nc->nic_smbflags |= SMB_NICF_ALIAS;
4567b59d02dSjb150015 
4578d7e4166Sjose borrego 			if (smb_nic_nbt_exclude(nc,
4588d7e4166Sjose borrego 			    (const char **)exclude, nexclude))
4597b59d02dSjb150015 				nc->nic_smbflags |= SMB_NICF_NBEXCL;
4607b59d02dSjb150015 
4617b59d02dSjb150015 			smb_niclist.nl_cnt++;
4627b59d02dSjb150015 			nc++;
4637b59d02dSjb150015 		}
4647b59d02dSjb150015 	} while	((iflist = list_next(&hlist.h_list, iflist)) != NULL);
4657b59d02dSjb150015 
4667b59d02dSjb150015 	smb_nic_hlist_destroy(&hlist);
4677b59d02dSjb150015 
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (SMB_NIC_SUCCESS);
4697b59d02dSjb150015 }
4707b59d02dSjb150015 
4717b59d02dSjb150015 static void
4727b59d02dSjb150015 smb_nic_list_destroy(void)
4737b59d02dSjb150015 {
4747b59d02dSjb150015 	free(smb_niclist.nl_nics);
4757b59d02dSjb150015 	smb_niclist.nl_nics = NULL;
4767b59d02dSjb150015 	smb_niclist.nl_cnt = 0;
4777b59d02dSjb150015 }
4787b59d02dSjb150015 
4797b59d02dSjb150015 static int
4807f667e74Sjose borrego smb_nic_getinfo(char *interface, smb_nic_t *nc, int family)
4817b59d02dSjb150015 {
4827b59d02dSjb150015 	struct lifreq lifrr;
4837b59d02dSjb150015 	int s;
4847f667e74Sjose borrego 	boolean_t isv6;
4857f667e74Sjose borrego 	struct sockaddr_in6 *sin6;
4867f667e74Sjose borrego 	struct sockaddr_in *sin;
4877b59d02dSjb150015 
4887f667e74Sjose borrego 	if ((s = socket(family, SOCK_DGRAM, IPPROTO_IP)) < 0) {
4899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_SOCK);
4907b59d02dSjb150015 	}
4917b59d02dSjb150015 
4927b59d02dSjb150015 	(void) strlcpy(lifrr.lifr_name, interface, sizeof (lifrr.lifr_name));
4937b59d02dSjb150015 	if (ioctl(s, SIOCGLIFADDR, &lifrr) < 0) {
4947b59d02dSjb150015 		(void) close(s);
4959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_IOCTL);
4967b59d02dSjb150015 	}
4977f667e74Sjose borrego 	isv6 = (lifrr.lifr_addr.ss_family == AF_INET6);
4987f667e74Sjose borrego 	if (isv6) {
4997f667e74Sjose borrego 		sin6 = (struct sockaddr_in6 *)(&lifrr.lifr_addr);
5007f667e74Sjose borrego 		nc->nic_ip.a_ipv6 = sin6->sin6_addr;
5017f667e74Sjose borrego 		nc->nic_ip.a_family = AF_INET6;
5027f667e74Sjose borrego 	} else {
5037f667e74Sjose borrego 		sin = (struct sockaddr_in *)(&lifrr.lifr_addr);
5047f667e74Sjose borrego 		nc->nic_ip.a_ipv4 = (in_addr_t)(sin->sin_addr.s_addr);
5057f667e74Sjose borrego 		nc->nic_ip.a_family = AF_INET;
5067f667e74Sjose borrego 	}
5077f667e74Sjose borrego 	if (smb_inet_iszero(&nc->nic_ip)) {
5087b59d02dSjb150015 		(void) close(s);
5099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_BAD_DATA);
5107b59d02dSjb150015 	}
5117f667e74Sjose borrego 	/* there is no broadcast or netmask for v6 */
5127f667e74Sjose borrego 	if (!isv6) {
5137b59d02dSjb150015 		if (ioctl(s, SIOCGLIFBRDADDR, &lifrr) < 0) {
5147b59d02dSjb150015 			(void) close(s);
5159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_NIC_IOCTL);
5167b59d02dSjb150015 		}
5177f667e74Sjose borrego 		sin = (struct sockaddr_in *)&lifrr.lifr_broadaddr;
5187f667e74Sjose borrego 		nc->nic_bcast = (uint32_t)sin->sin_addr.s_addr;
5197b59d02dSjb150015 
5207b59d02dSjb150015 		if (ioctl(s, SIOCGLIFNETMASK, &lifrr) < 0) {
5217b59d02dSjb150015 			(void) close(s);
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_NIC_IOCTL);
5237b59d02dSjb150015 		}
5247f667e74Sjose borrego 		sin = (struct sockaddr_in *)&lifrr.lifr_addr;
5257f667e74Sjose borrego 		nc->nic_mask = (uint32_t)sin->sin_addr.s_addr;
5267f667e74Sjose borrego 	}
5277b59d02dSjb150015 	if (ioctl(s, SIOCGLIFFLAGS, &lifrr) < 0) {
5287b59d02dSjb150015 		(void) close(s);
5299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_IOCTL);
5307b59d02dSjb150015 	}
5317b59d02dSjb150015 	nc->nic_sysflags = lifrr.lifr_flags;
5327b59d02dSjb150015 
5337b59d02dSjb150015 	(void) strlcpy(nc->nic_ifname, interface, sizeof (nc->nic_ifname));
5347b59d02dSjb150015 
5357b59d02dSjb150015 	(void) close(s);
5369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (SMB_NIC_SUCCESS);
5377b59d02dSjb150015 }
5387b59d02dSjb150015 
5397b59d02dSjb150015 /*
5407b59d02dSjb150015  * smb_nic_hlist_create
5417b59d02dSjb150015  *
5427b59d02dSjb150015  * Creates a list of hosts and their associated interfaces.
5437b59d02dSjb150015  * If host database exists the information is retrieved from
5447b59d02dSjb150015  * the database, otherwise it's retrieved from OS.
5457b59d02dSjb150015  *
5467b59d02dSjb150015  * The allocated memories for the returned list should be freed
5477b59d02dSjb150015  * by calling smb_nic_hlist_destroy()
5487b59d02dSjb150015  */
5497b59d02dSjb150015 static int
5507b59d02dSjb150015 smb_nic_hlist_create(smb_hosts_t *hlist)
5517b59d02dSjb150015 {
5527b59d02dSjb150015 	int rc;
5537b59d02dSjb150015 
5547b59d02dSjb150015 	list_create(&hlist->h_list, sizeof (smb_hostifs_t),
5557b59d02dSjb150015 	    offsetof(smb_hostifs_t, if_lnd));
5567b59d02dSjb150015 	hlist->h_num = 0;
5577b59d02dSjb150015 	hlist->h_ifnum = 0;
5587b59d02dSjb150015 
5597b59d02dSjb150015 	if (smb_nic_dbexists() && smb_nic_dbvalidate()) {
5607b59d02dSjb150015 		rc = smb_nic_hlist_dbget(hlist);
5617b59d02dSjb150015 		errno = EBADF;
5627b59d02dSjb150015 	} else {
5637b59d02dSjb150015 		rc = smb_nic_hlist_sysget(hlist);
5647b59d02dSjb150015 	}
5657b59d02dSjb150015 
5669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != SMB_NIC_SUCCESS)
5677b59d02dSjb150015 		smb_nic_hlist_destroy(hlist);
5687b59d02dSjb150015 
5697b59d02dSjb150015 	return (rc);
5707b59d02dSjb150015 }
5717b59d02dSjb150015 
5727b59d02dSjb150015 static void
5737b59d02dSjb150015 smb_nic_hlist_destroy(smb_hosts_t *hlist)
5747b59d02dSjb150015 {
5757b59d02dSjb150015 	smb_hostifs_t *iflist;
5767b59d02dSjb150015 
5777b59d02dSjb150015 	if (hlist == NULL)
5787b59d02dSjb150015 		return;
5797b59d02dSjb150015 
5807b59d02dSjb150015 	while ((iflist = list_head(&hlist->h_list)) != NULL) {
5817b59d02dSjb150015 		list_remove(&hlist->h_list, iflist);
5827b59d02dSjb150015 		smb_nic_iflist_destroy(iflist);
5837b59d02dSjb150015 	}
5847b59d02dSjb150015 
5857b59d02dSjb150015 	list_destroy(&hlist->h_list);
5867b59d02dSjb150015 }
5877b59d02dSjb150015 
5887f667e74Sjose borrego static void
5897f667e74Sjose borrego smb_close_sockets(int s4, int s6)
5907f667e74Sjose borrego {
5917f667e74Sjose borrego 	if (s4)
5927f667e74Sjose borrego 		(void) close(s4);
5937f667e74Sjose borrego 	if (s6)
5947f667e74Sjose borrego 		(void) close(s6);
5957f667e74Sjose borrego }
5967f667e74Sjose borrego 
5977b59d02dSjb150015 /*
5987b59d02dSjb150015  * smb_nic_hlist_sysget
5997b59d02dSjb150015  *
6007b59d02dSjb150015  * Get the list of currently plumbed and up interface names. The loopback (lo0)
6017b59d02dSjb150015  * port is ignored
6027b59d02dSjb150015  */
6037b59d02dSjb150015 static int
6047b59d02dSjb150015 smb_nic_hlist_sysget(smb_hosts_t *hlist)
6057b59d02dSjb150015 {
6067b59d02dSjb150015 	smb_hostifs_t *iflist;
6077f667e74Sjose borrego 	struct lifconf lifc;
6087f667e74Sjose borrego 	struct lifreq lifrl;
6097f667e74Sjose borrego 	struct lifreq *lifrp;
6107b59d02dSjb150015 	char *ifname;
6117b59d02dSjb150015 	int ifnum;
6127b59d02dSjb150015 	int i;
6137f667e74Sjose borrego 	int s4, s6;
6147f667e74Sjose borrego 	struct lifnum lifn;
6157b59d02dSjb150015 
6167b59d02dSjb150015 	iflist = malloc(sizeof (smb_hostifs_t));
6177b59d02dSjb150015 	if (iflist == NULL)
6189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
6197b59d02dSjb150015 
6207b59d02dSjb150015 	bzero(iflist, sizeof (smb_hostifs_t));
6217b59d02dSjb150015 
6229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_gethostname(iflist->if_host, sizeof (iflist->if_host),
6239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    SMB_CASE_PRESERVE) < 0) {
6247b59d02dSjb150015 		free(iflist);
6259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_HOST);
6267b59d02dSjb150015 	}
6277b59d02dSjb150015 
6287b59d02dSjb150015 	(void) smb_config_getstr(SMB_CI_SYS_CMNT, iflist->if_cmnt,
6297b59d02dSjb150015 	    sizeof (iflist->if_cmnt));
6307b59d02dSjb150015 
6317f667e74Sjose borrego 	if ((s4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
6327b59d02dSjb150015 		free(iflist);
6339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_SOCK);
6347b59d02dSjb150015 	}
6357f667e74Sjose borrego 	s6 = socket(AF_INET6, SOCK_DGRAM, 0);
6367b59d02dSjb150015 
6377f667e74Sjose borrego 	lifn.lifn_family = AF_UNSPEC;
6387f667e74Sjose borrego 	lifn.lifn_flags = 0;
6397f667e74Sjose borrego 	if (ioctl(s4, SIOCGLIFNUM, (char *)&lifn) < 0) {
6407f667e74Sjose borrego 		smb_close_sockets(s4, s6);
6417b59d02dSjb150015 		free(iflist);
6427f667e74Sjose borrego 		syslog(LOG_ERR, "hlist_sysget: SIOCGLIFNUM errno=%d", errno);
6439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_IOCTL);
6447b59d02dSjb150015 	}
6457b59d02dSjb150015 
6467f667e74Sjose borrego 	lifc.lifc_len = lifn.lifn_count * sizeof (struct lifreq);
6477f667e74Sjose borrego 	lifc.lifc_buf = malloc(lifc.lifc_len);
6487f667e74Sjose borrego 	if (lifc.lifc_buf == NULL) {
6497f667e74Sjose borrego 		smb_close_sockets(s4, s6);
6507b59d02dSjb150015 		free(iflist);
6519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
6527b59d02dSjb150015 	}
6537f667e74Sjose borrego 	bzero(lifc.lifc_buf, lifc.lifc_len);
6547f667e74Sjose borrego 	lifc.lifc_family = AF_UNSPEC;
6557f667e74Sjose borrego 	lifc.lifc_flags = 0;
6567b59d02dSjb150015 
6577f667e74Sjose borrego 	if (ioctl(s4, SIOCGLIFCONF, (char *)&lifc) < 0) {
6587f667e74Sjose borrego 		smb_close_sockets(s4, s6);
6597b59d02dSjb150015 		free(iflist);
6607f667e74Sjose borrego 		free(lifc.lifc_buf);
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_IOCTL);
6627b59d02dSjb150015 	}
6637b59d02dSjb150015 
6647f667e74Sjose borrego 	lifrp = lifc.lifc_req;
6657f667e74Sjose borrego 	ifnum = lifc.lifc_len / sizeof (struct lifreq);
6667f667e74Sjose borrego 	hlist->h_num = 0;
6677f667e74Sjose borrego 	for (i = 0; i < ifnum; i++, lifrp++) {
6687b59d02dSjb150015 
6697f667e74Sjose borrego 		if ((iflist->if_num > 0) && smb_duplicate_nic(iflist, lifrp))
6707f667e74Sjose borrego 			continue;
6717b59d02dSjb150015 		/*
6727b59d02dSjb150015 		 * Get the flags so that we can skip the loopback interface
6737b59d02dSjb150015 		 */
6747f667e74Sjose borrego 		(void) memset(&lifrl, 0, sizeof (lifrl));
6757f667e74Sjose borrego 		(void) strlcpy(lifrl.lifr_name, lifrp->lifr_name,
6767f667e74Sjose borrego 		    sizeof (lifrl.lifr_name));
6777b59d02dSjb150015 
6787f667e74Sjose borrego 		if (ioctl(s4, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0) {
6797f667e74Sjose borrego 			if ((s6 < 0) ||
6807f667e74Sjose borrego 			    (ioctl(s6, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0)) {
6817f667e74Sjose borrego 				smb_close_sockets(s4, s6);
6827f667e74Sjose borrego 				free(lifc.lifc_buf);
6837b59d02dSjb150015 				smb_nic_iflist_destroy(iflist);
6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				return (SMB_NIC_IOCTL);
6857b59d02dSjb150015 			}
6867f667e74Sjose borrego 		}
6877f667e74Sjose borrego 		if (lifrl.lifr_flags & IFF_LOOPBACK) {
6887b59d02dSjb150015 			continue;
6897f667e74Sjose borrego 		}
6907b59d02dSjb150015 
6917f667e74Sjose borrego 		if ((lifrl.lifr_flags & IFF_UP) == 0) {
6927b59d02dSjb150015 			continue;
6937f667e74Sjose borrego 		}
6947f667e74Sjose borrego 		ifname = strdup(lifrp->lifr_name);
6957b59d02dSjb150015 		if (ifname == NULL) {
6967f667e74Sjose borrego 			smb_close_sockets(s4, s6);
6977f667e74Sjose borrego 			free(lifc.lifc_buf);
6987b59d02dSjb150015 			smb_nic_iflist_destroy(iflist);
6999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_NIC_NO_MEMORY);
7007b59d02dSjb150015 		}
7017b59d02dSjb150015 		iflist->if_names[iflist->if_num++] = ifname;
7027b59d02dSjb150015 	}
7037b59d02dSjb150015 	hlist->h_ifnum = iflist->if_num;
7047f667e74Sjose borrego 	hlist->h_num = 1;
7057f667e74Sjose borrego 	smb_close_sockets(s4, s6);
7067f667e74Sjose borrego 	free(lifc.lifc_buf);
7077b59d02dSjb150015 	list_insert_tail(&hlist->h_list, iflist);
7087b59d02dSjb150015 
7099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (SMB_NIC_SUCCESS);
7107b59d02dSjb150015 }
7117b59d02dSjb150015 
7127f667e74Sjose borrego static boolean_t
7137f667e74Sjose borrego smb_duplicate_nic(smb_hostifs_t *iflist, struct lifreq *lifrp)
7147f667e74Sjose borrego {
7157f667e74Sjose borrego 	int j;
7167f667e74Sjose borrego 	/*
7177f667e74Sjose borrego 	 * throw out duplicate names
7187f667e74Sjose borrego 	 */
7197f667e74Sjose borrego 	for (j = 0; j < iflist->if_num; j++) {
7207f667e74Sjose borrego 		if (strcmp(iflist->if_names[j],
7217f667e74Sjose borrego 		    lifrp->lifr_name) == 0)
7227f667e74Sjose borrego 			return (B_TRUE);
7237f667e74Sjose borrego 	}
7247f667e74Sjose borrego 	return (B_FALSE);
7257f667e74Sjose borrego }
7267f667e74Sjose borrego 
7277b59d02dSjb150015 static int
7287b59d02dSjb150015 smb_nic_hlist_dbget(smb_hosts_t *hlist)
7297b59d02dSjb150015 {
7307b59d02dSjb150015 	smb_hostifs_t *iflist;
7317b59d02dSjb150015 	sqlite *db;
7327b59d02dSjb150015 	sqlite_vm *vm;
7339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int err = SMB_NIC_SUCCESS;
7347b59d02dSjb150015 	const char **values;
7357b59d02dSjb150015 	char *sql;
7367b59d02dSjb150015 	char *errmsg = NULL;
7377b59d02dSjb150015 	int ncol, rc;
7387b59d02dSjb150015 
7397b59d02dSjb150015 	sql = sqlite_mprintf("SELECT * FROM hosts");
7407b59d02dSjb150015 	if (sql == NULL)
7419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
7427b59d02dSjb150015 
7437b59d02dSjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORD);
7447b59d02dSjb150015 	if (db == NULL) {
7457b59d02dSjb150015 		sqlite_freemem(sql);
7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DBOPEN_FAILED);
7477b59d02dSjb150015 	}
7487b59d02dSjb150015 
7497b59d02dSjb150015 	rc = sqlite_compile(db, sql, NULL, &vm, &errmsg);
7507b59d02dSjb150015 	sqlite_freemem(sql);
7517b59d02dSjb150015 
7527b59d02dSjb150015 	if (rc != SQLITE_OK) {
7537b59d02dSjb150015 		smb_nic_dbclose(db);
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to query hosts info from host " \
7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "database.  Unable to create virtual machine (%s).",
7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    NULL_MSGCHK(errmsg));
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DB_ERROR);
7587b59d02dSjb150015 	}
7597b59d02dSjb150015 
7607b59d02dSjb150015 	do {
7617b59d02dSjb150015 		rc = sqlite_step(vm, &ncol, &values, NULL);
7627b59d02dSjb150015 		if (rc == SQLITE_ROW) {
7637b59d02dSjb150015 			if (ncol != SMB_NIC_HTBL_NCOL) {
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				err = SMB_NIC_DB_ERROR;
7657b59d02dSjb150015 				break;
7667b59d02dSjb150015 			}
7677b59d02dSjb150015 
7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if ((iflist = smb_nic_iflist_decode(values, &err)) ==
7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    NULL) {
7707b59d02dSjb150015 				break;
7717b59d02dSjb150015 			}
7727b59d02dSjb150015 
7737b59d02dSjb150015 			list_insert_tail(&hlist->h_list, iflist);
7747b59d02dSjb150015 			hlist->h_num++;
7757b59d02dSjb150015 			hlist->h_ifnum += iflist->if_num;
7767b59d02dSjb150015 		}
7777b59d02dSjb150015 	} while (rc == SQLITE_ROW);
7787b59d02dSjb150015 
7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != SQLITE_DONE && err == SMB_NIC_SUCCESS) {
7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* set this error if no previous error */
7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = SMB_LGRP_DBEXEC_FAILED;
7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7837b59d02dSjb150015 
7847b59d02dSjb150015 	rc = sqlite_finalize(vm, &errmsg);
7857b59d02dSjb150015 	if (rc != SQLITE_OK) {
7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to query hosts info from host " \
7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "database.  Unable to destroy virtual machine (%s).",
7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    NULL_MSGCHK(errmsg));
7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (err == SMB_NIC_SUCCESS) {
7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			/* set this error if no previous error */
7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			err = SMB_NIC_DB_ERROR;
7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
7937b59d02dSjb150015 	}
7947b59d02dSjb150015 
7957b59d02dSjb150015 	smb_nic_dbclose(db);
7967b59d02dSjb150015 
7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (err);
7987b59d02dSjb150015 }
7997b59d02dSjb150015 
8007b59d02dSjb150015 static smb_hostifs_t *
8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_nic_iflist_decode(const char **values, int *err)
8027b59d02dSjb150015 {
8037b59d02dSjb150015 	smb_hostifs_t *iflist;
8047b59d02dSjb150015 	char *host;
8057b59d02dSjb150015 	char *cmnt;
8067b59d02dSjb150015 	char *ifnames;
8077b59d02dSjb150015 	char *lasts;
8087b59d02dSjb150015 	char *ifname;
8097b59d02dSjb150015 	int if_num = 0;
8107b59d02dSjb150015 
8117b59d02dSjb150015 	host = (char *)values[SMB_NIC_HTBL_HOST];
8127b59d02dSjb150015 	cmnt = (char *)values[SMB_NIC_HTBL_CMNT];
8137b59d02dSjb150015 	ifnames = (char *)values[SMB_NIC_HTBL_IFS];
8147b59d02dSjb150015 
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((host == NULL) || (ifnames == NULL)) {
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*err = SMB_NIC_INVALID_ARG;
8177b59d02dSjb150015 		return (NULL);
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
8197b59d02dSjb150015 
8207b59d02dSjb150015 	iflist = malloc(sizeof (smb_hostifs_t));
8219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (iflist == NULL) {
8229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*err = SMB_NIC_NO_MEMORY;
8237b59d02dSjb150015 		return (NULL);
8249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
8257b59d02dSjb150015 
8267b59d02dSjb150015 	bzero(iflist, sizeof (smb_hostifs_t));
8277b59d02dSjb150015 
8287b59d02dSjb150015 	(void) strlcpy(iflist->if_host, host, sizeof (iflist->if_host));
8297b59d02dSjb150015 	(void) strlcpy(iflist->if_cmnt, (cmnt) ? cmnt : "",
8307b59d02dSjb150015 	    sizeof (iflist->if_cmnt));
8317b59d02dSjb150015 
8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((ifname = strtok_r(ifnames, ",", &lasts)) == NULL) {
8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*err = SMB_NIC_BAD_DATA;
8347b59d02dSjb150015 		return (NULL);
8359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
8367b59d02dSjb150015 
8377b59d02dSjb150015 	iflist->if_names[if_num++] = strdup(ifname);
8387b59d02dSjb150015 
8397b59d02dSjb150015 	while ((ifname = strtok_r(NULL, ",", &lasts)) != NULL)
8407b59d02dSjb150015 		iflist->if_names[if_num++] = strdup(ifname);
8417b59d02dSjb150015 
8427b59d02dSjb150015 	iflist->if_num = if_num;
8437b59d02dSjb150015 
8447b59d02dSjb150015 	for (if_num = 0; if_num < iflist->if_num; if_num++) {
8457b59d02dSjb150015 		if (iflist->if_names[if_num] == NULL) {
8467b59d02dSjb150015 			smb_nic_iflist_destroy(iflist);
8479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			*err = SMB_NIC_NO_MEMORY;
8487b59d02dSjb150015 			return (NULL);
8497b59d02dSjb150015 		}
8507b59d02dSjb150015 	}
8517b59d02dSjb150015 
8529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	*err = SMB_NIC_SUCCESS;
8537b59d02dSjb150015 	return (iflist);
8547b59d02dSjb150015 }
8557b59d02dSjb150015 
8567b59d02dSjb150015 /*
8577b59d02dSjb150015  * smb_nic_iflist_destroy
8587b59d02dSjb150015  *
8597b59d02dSjb150015  * Frees allocated memory for the given IF names lists.
8607b59d02dSjb150015  */
8617b59d02dSjb150015 static void
8627b59d02dSjb150015 smb_nic_iflist_destroy(smb_hostifs_t *iflist)
8637b59d02dSjb150015 {
8647b59d02dSjb150015 	int i;
8657b59d02dSjb150015 
8667b59d02dSjb150015 	if (iflist == NULL)
8677b59d02dSjb150015 		return;
8687b59d02dSjb150015 
8697b59d02dSjb150015 	for (i = 0; i < iflist->if_num; i++)
8707b59d02dSjb150015 		free(iflist->if_names[i]);
8717b59d02dSjb150015 
8727b59d02dSjb150015 	free(iflist);
8737b59d02dSjb150015 }
8747b59d02dSjb150015 
8757b59d02dSjb150015 /*
8767b59d02dSjb150015  * Functions to manage host/interface database
8777b59d02dSjb150015  *
8787b59d02dSjb150015  * Each entry in the hosts table associates a hostname with a
8797b59d02dSjb150015  * list of interface names. The host/interface association could
8807b59d02dSjb150015  * be added by calling smb_nic_addhost() and could be removed by
8817b59d02dSjb150015  * calling smb_nic_delhost(). If the database exists and it contains
8827b59d02dSjb150015  * valid information then the inteface list wouldn't be obtained
8837b59d02dSjb150015  * from system using ioctl.
8847b59d02dSjb150015  */
8857b59d02dSjb150015 
8867b59d02dSjb150015 /*
8877b59d02dSjb150015  * smb_nic_dbcreate
8887b59d02dSjb150015  *
8897b59d02dSjb150015  * Creates the host database based on the defined SQL statement.
8907b59d02dSjb150015  * It also initializes db_info table.
8917b59d02dSjb150015  */
8927b59d02dSjb150015 static int
8937b59d02dSjb150015 smb_nic_dbcreate(void)
8947b59d02dSjb150015 {
8957b59d02dSjb150015 	sqlite *db = NULL;
8967b59d02dSjb150015 	char *errmsg = NULL;
8979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc, err = SMB_NIC_SUCCESS;
8987b59d02dSjb150015 
8997b59d02dSjb150015 	(void) unlink(SMB_NIC_DB_NAME);
9007b59d02dSjb150015 
9017b59d02dSjb150015 	db = sqlite_open(SMB_NIC_DB_NAME, 0600, &errmsg);
9027b59d02dSjb150015 	if (db == NULL) {
9039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to create host database (%s).",
9047b59d02dSjb150015 		    NULL_MSGCHK(errmsg));
9057b59d02dSjb150015 		sqlite_freemem(errmsg);
9069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DBOPEN_FAILED);
9077b59d02dSjb150015 	}
9087b59d02dSjb150015 
9097b59d02dSjb150015 	sqlite_busy_timeout(db, SMB_NIC_DB_TIMEOUT);
9107b59d02dSjb150015 	rc = sqlite_exec(db, "BEGIN TRANSACTION", NULL, NULL, &errmsg);
9117b59d02dSjb150015 	if (rc != SQLITE_OK) {
9129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
9139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "begin database transaction (%s).", NULL_MSGCHK(errmsg));
9147b59d02dSjb150015 		sqlite_freemem(errmsg);
9157b59d02dSjb150015 		sqlite_close(db);
9169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DBEXEC_FAILED);
9177b59d02dSjb150015 	}
9187b59d02dSjb150015 
9197b59d02dSjb150015 	if (sqlite_exec(db, SMB_NIC_DB_SQL, NULL, NULL, &errmsg) == SQLITE_OK) {
9207b59d02dSjb150015 		rc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
9217b59d02dSjb150015 		    &errmsg);
9227b59d02dSjb150015 		if (rc == SQLITE_OK)
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			err = smb_nic_dbsetinfo(db);
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (err != SMB_NIC_SUCCESS)
9257b59d02dSjb150015 			rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
9267b59d02dSjb150015 			    &errmsg);
9277b59d02dSjb150015 	} else {
9289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
9299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "initialize host database (%s).", NULL_MSGCHK(errmsg));
9307b59d02dSjb150015 		sqlite_freemem(errmsg);
9317b59d02dSjb150015 		rc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
9327b59d02dSjb150015 		    &errmsg);
9337b59d02dSjb150015 	}
9347b59d02dSjb150015 
9357b59d02dSjb150015 	if (rc != SQLITE_OK) {
9367b59d02dSjb150015 		/* this is bad - database may be left in a locked state */
9379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to create host database.  Unable to " \
9389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "close a transaction (%s).", NULL_MSGCHK(errmsg));
9397b59d02dSjb150015 		sqlite_freemem(errmsg);
9409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = SMB_NIC_DBINIT_FAILED;
9417b59d02dSjb150015 	}
9427b59d02dSjb150015 
9437b59d02dSjb150015 	(void) sqlite_close(db);
9449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (err);
9457b59d02dSjb150015 }
9467b59d02dSjb150015 
9477b59d02dSjb150015 /*
9487b59d02dSjb150015  * smb_nic_dbopen
9497b59d02dSjb150015  *
9507b59d02dSjb150015  * Opens host database with the given mode.
9517b59d02dSjb150015  */
9527b59d02dSjb150015 static sqlite *
9537b59d02dSjb150015 smb_nic_dbopen(int mode)
9547b59d02dSjb150015 {
9557b59d02dSjb150015 	sqlite *db;
9567b59d02dSjb150015 	char *errmsg = NULL;
9577b59d02dSjb150015 
9587b59d02dSjb150015 	db = sqlite_open(SMB_NIC_DB_NAME, mode, &errmsg);
9597b59d02dSjb150015 	if (db == NULL) {
9609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to open host database: %s (%s).",
9619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    SMB_NIC_DB_NAME, NULL_MSGCHK(errmsg));
9627b59d02dSjb150015 		sqlite_freemem(errmsg);
9637b59d02dSjb150015 	}
9647b59d02dSjb150015 
9657b59d02dSjb150015 	return (db);
9667b59d02dSjb150015 }
9677b59d02dSjb150015 
9687b59d02dSjb150015 /*
9697b59d02dSjb150015  * smb_nic_dbclose
9707b59d02dSjb150015  *
9717b59d02dSjb150015  * Closes the given database handle
9727b59d02dSjb150015  */
9737b59d02dSjb150015 static void
9747b59d02dSjb150015 smb_nic_dbclose(sqlite *db)
9757b59d02dSjb150015 {
9767b59d02dSjb150015 	if (db) {
9777b59d02dSjb150015 		sqlite_close(db);
9787b59d02dSjb150015 	}
9797b59d02dSjb150015 }
9807b59d02dSjb150015 
9817b59d02dSjb150015 static boolean_t
9827b59d02dSjb150015 smb_nic_dbexists(void)
9837b59d02dSjb150015 {
9847b59d02dSjb150015 	return (access(SMB_NIC_DB_NAME, F_OK) == 0);
9857b59d02dSjb150015 }
9867b59d02dSjb150015 
9877b59d02dSjb150015 static boolean_t
9887b59d02dSjb150015 smb_nic_dbvalidate(void)
9897b59d02dSjb150015 {
9907b59d02dSjb150015 	sqlite *db;
9917b59d02dSjb150015 	char *errmsg = NULL;
9927b59d02dSjb150015 	char *sql;
9937b59d02dSjb150015 	char **result;
9947b59d02dSjb150015 	int nrow, ncol;
9957b59d02dSjb150015 	boolean_t check = B_TRUE;
9967b59d02dSjb150015 	int rc;
9977b59d02dSjb150015 
9987b59d02dSjb150015 	sql = sqlite_mprintf("SELECT * FROM db_info");
9997b59d02dSjb150015 	if (sql == NULL)
10007b59d02dSjb150015 		return (B_FALSE);
10017b59d02dSjb150015 
10027b59d02dSjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
10037b59d02dSjb150015 	if (db == NULL) {
10047b59d02dSjb150015 		sqlite_freemem(sql);
10057b59d02dSjb150015 		return (B_FALSE);
10067b59d02dSjb150015 	}
10077b59d02dSjb150015 
10087b59d02dSjb150015 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
10097b59d02dSjb150015 	sqlite_freemem(sql);
10107b59d02dSjb150015 
10117b59d02dSjb150015 	if (rc != SQLITE_OK) {
10129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to validate host database.  Unable " \
10139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "to get database information (%s).", NULL_MSGCHK(errmsg));
10147b59d02dSjb150015 		sqlite_freemem(errmsg);
10157b59d02dSjb150015 		smb_nic_dbclose(db);
10167b59d02dSjb150015 		return (B_FALSE);
10177b59d02dSjb150015 	}
10187b59d02dSjb150015 
10197b59d02dSjb150015 	if (nrow != 1 || ncol != 3) {
10209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to validate host database:  bad " \
10219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "db_info table.");
10227b59d02dSjb150015 		sqlite_free_table(result);
10237b59d02dSjb150015 		smb_nic_dbclose(db);
10247b59d02dSjb150015 		return (B_FALSE);
10257b59d02dSjb150015 	}
10267b59d02dSjb150015 
10277b59d02dSjb150015 	if ((atoi(result[3]) != SMB_NIC_DB_VERMAJOR) ||
10287b59d02dSjb150015 	    (atoi(result[4]) != SMB_NIC_DB_VERMINOR) ||
10297b59d02dSjb150015 	    (atoi(result[5]) != SMB_NIC_DB_MAGIC)) {
10309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to validate host database: bad " \
10319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "db_info content.");
10327b59d02dSjb150015 		sqlite_free_table(result);
10337b59d02dSjb150015 		smb_nic_dbclose(db);
10347b59d02dSjb150015 		return (B_FALSE);
10357b59d02dSjb150015 	}
10367b59d02dSjb150015 	sqlite_free_table(result);
10377b59d02dSjb150015 
10387b59d02dSjb150015 	sql = sqlite_mprintf("SELECT hostname FROM hosts");
10397b59d02dSjb150015 	if (sql == NULL) {
10407b59d02dSjb150015 		smb_nic_dbclose(db);
10417b59d02dSjb150015 		return (B_FALSE);
10427b59d02dSjb150015 	}
10437b59d02dSjb150015 
10447b59d02dSjb150015 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
10457b59d02dSjb150015 	sqlite_freemem(sql);
10467b59d02dSjb150015 
10477b59d02dSjb150015 	if (rc != SQLITE_OK) {
10489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to validate host database.  Unable " \
10499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"to query for host (%s).", NULL_MSGCHK(errmsg));
10507b59d02dSjb150015 		sqlite_freemem(errmsg);
10517b59d02dSjb150015 		smb_nic_dbclose(db);
10527b59d02dSjb150015 		return (B_FALSE);
10537b59d02dSjb150015 	}
10547b59d02dSjb150015 
10557b59d02dSjb150015 	sqlite_free_table(result);
10567b59d02dSjb150015 
10577b59d02dSjb150015 	if (nrow == 0)
10587b59d02dSjb150015 		/* No hosts in the database */
10597b59d02dSjb150015 		check = B_FALSE;
10607b59d02dSjb150015 
10617b59d02dSjb150015 	smb_nic_dbclose(db);
10627b59d02dSjb150015 	return (check);
10637b59d02dSjb150015 }
10647b59d02dSjb150015 
10657b59d02dSjb150015 static int
10667b59d02dSjb150015 smb_nic_dbaddhost(const char *host, const char *cmnt, char *if_list)
10677b59d02dSjb150015 {
10687b59d02dSjb150015 	sqlite *db;
10697b59d02dSjb150015 	char *sql;
10707b59d02dSjb150015 	char *errmsg;
10719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc, err = SMB_NIC_SUCCESS;
10727b59d02dSjb150015 
10737b59d02dSjb150015 	sql = sqlite_mprintf("REPLACE INTO hosts (hostname, comment, ifnames)"
10747b59d02dSjb150015 	    "VALUES ('%s', '%q', '%s')", host, (cmnt) ? cmnt : "", if_list);
10757b59d02dSjb150015 	if (sql == NULL)
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
10777b59d02dSjb150015 
10787b59d02dSjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
10797b59d02dSjb150015 	if (db == NULL) {
10807b59d02dSjb150015 		sqlite_freemem(sql);
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DBOPEN_FAILED);
10827b59d02dSjb150015 	}
10837b59d02dSjb150015 
10847b59d02dSjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
10857b59d02dSjb150015 	sqlite_freemem(sql);
10867b59d02dSjb150015 	smb_nic_dbclose(db);
10877b59d02dSjb150015 
10887b59d02dSjb150015 	if (rc != SQLITE_OK) {
10899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to add host %s to host database (%s).",
10907b59d02dSjb150015 		    host, NULL_MSGCHK(errmsg));
10917b59d02dSjb150015 		sqlite_freemem(errmsg);
10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = SMB_NIC_INSERT_FAILED;
10937b59d02dSjb150015 	}
10947b59d02dSjb150015 
10959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (err);
10967b59d02dSjb150015 }
10977b59d02dSjb150015 
10987b59d02dSjb150015 static int
10997b59d02dSjb150015 smb_nic_dbdelhost(const char *host)
11007b59d02dSjb150015 {
11017b59d02dSjb150015 	sqlite *db;
11027b59d02dSjb150015 	char *sql;
11037b59d02dSjb150015 	char *errmsg;
11049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc, err = SMB_NIC_SUCCESS;
11057b59d02dSjb150015 
11067b59d02dSjb150015 	sql = sqlite_mprintf("DELETE FROM hosts WHERE hostname = '%s'", host);
11077b59d02dSjb150015 	if (sql == NULL)
11089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
11097b59d02dSjb150015 
11107b59d02dSjb150015 	db = smb_nic_dbopen(SMB_NIC_DB_ORW);
11117b59d02dSjb150015 	if (db == NULL) {
11127b59d02dSjb150015 		sqlite_freemem(sql);
11139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_DBOPEN_FAILED);
11147b59d02dSjb150015 	}
11157b59d02dSjb150015 
11167b59d02dSjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
11177b59d02dSjb150015 	sqlite_freemem(sql);
11187b59d02dSjb150015 	smb_nic_dbclose(db);
11197b59d02dSjb150015 
11207b59d02dSjb150015 	if (rc != SQLITE_OK) {
11219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to delete host %s from host " \
11229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "database (%s).", host, NULL_MSGCHK(errmsg));
11237b59d02dSjb150015 		sqlite_freemem(errmsg);
11249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = SMB_NIC_DELETE_FAILED;
11257b59d02dSjb150015 	}
11267b59d02dSjb150015 
11279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (err);
11287b59d02dSjb150015 }
11297b59d02dSjb150015 
11307b59d02dSjb150015 /*
11317b59d02dSjb150015  * smb_nic_dbsetinfo
11327b59d02dSjb150015  *
11337b59d02dSjb150015  * Initializes the db_info table upon database creation.
11347b59d02dSjb150015  */
11357b59d02dSjb150015 static int
11367b59d02dSjb150015 smb_nic_dbsetinfo(sqlite *db)
11377b59d02dSjb150015 {
11387b59d02dSjb150015 	char *errmsg = NULL;
11397b59d02dSjb150015 	char *sql;
11409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc, err = SMB_NIC_SUCCESS;
11417b59d02dSjb150015 
11427b59d02dSjb150015 	sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
11437b59d02dSjb150015 	    " magic) VALUES (%d, %d, %d)", SMB_NIC_DB_VERMAJOR,
11447b59d02dSjb150015 	    SMB_NIC_DB_VERMINOR, SMB_NIC_DB_MAGIC);
11457b59d02dSjb150015 
11467b59d02dSjb150015 	if (sql == NULL)
11479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_NIC_NO_MEMORY);
11487b59d02dSjb150015 
11497b59d02dSjb150015 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
11507b59d02dSjb150015 	sqlite_freemem(sql);
11517b59d02dSjb150015 	if (rc != SQLITE_OK) {
11529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "Failed to add database information to " \
11539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    "host database (%s).", NULL_MSGCHK(errmsg));
11547b59d02dSjb150015 		sqlite_freemem(errmsg);
11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = SMB_NIC_DBINIT_ERROR;
11567b59d02dSjb150015 	}
11577b59d02dSjb150015 
11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (err);
11597b59d02dSjb150015 }
11608d7e4166Sjose borrego 
11618d7e4166Sjose borrego /*
11628d7e4166Sjose borrego  * smb_nic_nbt_get_exclude_list
11638d7e4166Sjose borrego  *
11648d7e4166Sjose borrego  * Construct an array containing list of i/f names on which NetBIOS traffic is
11658d7e4166Sjose borrego  * to be disabled, from a string containing a list of comma separated i/f names.
11668d7e4166Sjose borrego  *
11678d7e4166Sjose borrego  * Returns the number of i/f on which NetBIOS traffic is to be disabled.
11688d7e4166Sjose borrego  */
11698d7e4166Sjose borrego static int
11708d7e4166Sjose borrego smb_nic_nbt_get_exclude_list(char *excludestr, char **iflist, int max_nifs)
11718d7e4166Sjose borrego {
11728d7e4166Sjose borrego 	int n = 0;
11738d7e4166Sjose borrego 	char *entry;
11748d7e4166Sjose borrego 
11758d7e4166Sjose borrego 	bzero(iflist, SMB_PI_MAX_NETWORKS * sizeof (char *));
11768d7e4166Sjose borrego 
11778d7e4166Sjose borrego 	(void) trim_whitespace(excludestr);
11788d7e4166Sjose borrego 	(void) strcanon(excludestr, ",");
11798d7e4166Sjose borrego 
11808d7e4166Sjose borrego 	if (*excludestr == '\0')
11818d7e4166Sjose borrego 		return (0);
11828d7e4166Sjose borrego 
11838d7e4166Sjose borrego 	while (((iflist[n] = strsep(&excludestr, ",")) != NULL) &&
11848d7e4166Sjose borrego 	    (n < max_nifs)) {
11858d7e4166Sjose borrego 		entry = iflist[n];
11868d7e4166Sjose borrego 		if (*entry == '\0')
11878d7e4166Sjose borrego 			continue;
11888d7e4166Sjose borrego 		n++;
11898d7e4166Sjose borrego 	}
11908d7e4166Sjose borrego 
11918d7e4166Sjose borrego 	return (n);
11928d7e4166Sjose borrego }
11938d7e4166Sjose borrego 
11948d7e4166Sjose borrego /*
11958d7e4166Sjose borrego  * smb_nic_nbt_exclude
11968d7e4166Sjose borrego  *
11978d7e4166Sjose borrego  * Check to see if the given interface name should send NetBIOS traffic or not.
11988d7e4166Sjose borrego  *
11998d7e4166Sjose borrego  * Returns TRUE if NetBIOS traffic is disabled on an interface name.
12008d7e4166Sjose borrego  * Returns FALSE otherwise.
12018d7e4166Sjose borrego  */
12028d7e4166Sjose borrego static boolean_t
12038d7e4166Sjose borrego smb_nic_nbt_exclude(const smb_nic_t *nc, const char **exclude_list,
12048d7e4166Sjose borrego     int nexclude)
12058d7e4166Sjose borrego {
12068d7e4166Sjose borrego 	char buf[INET6_ADDRSTRLEN];
12078d7e4166Sjose borrego 	const char *ifname = nc->nic_ifname;
12088d7e4166Sjose borrego 	int i;
12098d7e4166Sjose borrego 
12108d7e4166Sjose borrego 	if (inet_ntop(AF_INET, &nc->nic_ip, buf, INET6_ADDRSTRLEN) == NULL)
12118d7e4166Sjose borrego 		buf[0] = '\0';
12128d7e4166Sjose borrego 
12138d7e4166Sjose borrego 	for (i = 0; i < nexclude; i++) {
12148d7e4166Sjose borrego 		if (strcmp(ifname, exclude_list[i]) == 0)
12158d7e4166Sjose borrego 			return (B_TRUE);
12168d7e4166Sjose borrego 
12178d7e4166Sjose borrego 		if ((buf[0] != '\0') && (strcmp(buf, exclude_list[i]) == 0))
12188d7e4166Sjose borrego 			return (B_TRUE);
12198d7e4166Sjose borrego 	}
12208d7e4166Sjose borrego 
12218d7e4166Sjose borrego 	return (B_FALSE);
12228d7e4166Sjose borrego }
1223