1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * Create a new VC given a list of addresses.
  31  */
  32 
  33 #include <errno.h>
  34 #include <stdio.h>
  35 #include <string.h>
  36 #include <strings.h>
  37 #include <stdlib.h>
  38 #include <unistd.h>
  39 #include <netdb.h>
  40 #include <libintl.h>
  41 #include <xti.h>
  42 #include <assert.h>
  43 
  44 #include <sys/types.h>
  45 #include <sys/time.h>
  46 #include <sys/byteorder.h>
  47 #include <sys/socket.h>
  48 #include <sys/fcntl.h>
  49 
  50 #include <netinet/in.h>
  51 #include <netinet/tcp.h>
  52 #include <arpa/inet.h>
  53 
  54 #include <netsmb/smb.h>
  55 #include <netsmb/smb_lib.h>
  56 #include <netsmb/netbios.h>
  57 #include <netsmb/nb_lib.h>
  58 #include <netsmb/smb_dev.h>
  59 
  60 #include "smb/charsets.h"
  61 #include "smb/private.h"
  62 
  63 /*
  64  * Ask the IOD to create a VC with this IP address.
  65  */
  66 static int
  67 fknewvc(struct smb_ctx *ctx, struct addrinfo *ai)
  68 {
  69         char host[256];
  70         char svc[32];
  71         smbioc_ossn_t *ssn = &ctx->ct_ssn;
  72         int err;
  73 
  74         if (smb_debug) {
  75                 err = getnameinfo(ai->ai_addr, ai->ai_addrlen,
  76                     host, sizeof (host), svc, sizeof (svc),
  77                     AI_NUMERICHOST);
  78                 if (err != 0) {
  79                         strlcpy(host, "(?)", sizeof (host));
  80                         strlcpy(svc, "?", sizeof (host));
  81                 }
  82                 printf("fknewvc: Try AF=%d %s:%s\n",
  83                     ai->ai_family, host, svc);
  84         }
  85 
  86         /*
  87          * Copy the passed address into ssn_srvaddr,
  88          * but first sanity-check lengths.  Also,
  89          * zero it first to avoid trailing junk.
  90          */
  91         if (ai->ai_addrlen > sizeof (ssn->ssn_srvaddr))
  92                 return (EINVAL);
  93         bzero(&ssn->ssn_srvaddr, sizeof (ssn->ssn_srvaddr));
  94         bcopy(ai->ai_addr, &ssn->ssn_srvaddr, ai->ai_addrlen);
  95 
  96         /* Ask the IOD to connect using the info in ctx. */
  97         err = smb_iod_cl_newvc(ctx);
  98         if (smb_debug) {
  99                 printf("fknewvc: iod_cl_newvc err=%d\n", err);
 100         }
 101 
 102         return (err);
 103 }
 104 
 105 /*
 106  * Setup a new VC via the IOD.
 107  * Similar to findvc.c
 108  */
 109 int
 110 smb_ctx_newvc(struct smb_ctx *ctx)
 111 {
 112         struct addrinfo *ai;
 113         int err;
 114 
 115         /* Should already have the address list. */
 116         if ((ctx->ct_flags & SMBCF_RESOLVED) == 0)
 117                 return (EINVAL);
 118 
 119         err = EPROTONOSUPPORT;  /* in case no AF match */
 120         for (ai = ctx->ct_addrinfo; ai; ai = ai->ai_next) {
 121 
 122                 switch (ai->ai_family) {
 123 
 124                 case AF_INET:
 125                 case AF_INET6:
 126                 case AF_NETBIOS:
 127                         err = fknewvc(ctx, ai);
 128                         if (err == 0)
 129                                 goto OK;
 130                         break;
 131 
 132                 default:
 133                         break;
 134                 }
 135         }
 136 
 137         /*
 138          * In the error case, the caller may try again
 139          * with new auth. info, so keep the door open.
 140          * Error return will close in smb_ctx_done.
 141          */
 142         return (err);
 143 
 144 OK:
 145         return (0);
 146 }