1*10023SGordon.Ross@Sun.COM /*
2*10023SGordon.Ross@Sun.COM * CDDL HEADER START
3*10023SGordon.Ross@Sun.COM *
4*10023SGordon.Ross@Sun.COM * The contents of this file are subject to the terms of the
5*10023SGordon.Ross@Sun.COM * Common Development and Distribution License (the "License").
6*10023SGordon.Ross@Sun.COM * You may not use this file except in compliance with the License.
7*10023SGordon.Ross@Sun.COM *
8*10023SGordon.Ross@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10023SGordon.Ross@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10023SGordon.Ross@Sun.COM * See the License for the specific language governing permissions
11*10023SGordon.Ross@Sun.COM * and limitations under the License.
12*10023SGordon.Ross@Sun.COM *
13*10023SGordon.Ross@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10023SGordon.Ross@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10023SGordon.Ross@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10023SGordon.Ross@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10023SGordon.Ross@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10023SGordon.Ross@Sun.COM *
19*10023SGordon.Ross@Sun.COM * CDDL HEADER END
20*10023SGordon.Ross@Sun.COM */
21*10023SGordon.Ross@Sun.COM
22*10023SGordon.Ross@Sun.COM /*
23*10023SGordon.Ross@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*10023SGordon.Ross@Sun.COM * Use is subject to license terms.
25*10023SGordon.Ross@Sun.COM */
26*10023SGordon.Ross@Sun.COM
27*10023SGordon.Ross@Sun.COM /*
28*10023SGordon.Ross@Sun.COM * Find existing an VC given a list of addresses.
29*10023SGordon.Ross@Sun.COM */
30*10023SGordon.Ross@Sun.COM
31*10023SGordon.Ross@Sun.COM #include <errno.h>
32*10023SGordon.Ross@Sun.COM #include <stdio.h>
33*10023SGordon.Ross@Sun.COM #include <string.h>
34*10023SGordon.Ross@Sun.COM #include <strings.h>
35*10023SGordon.Ross@Sun.COM #include <stdlib.h>
36*10023SGordon.Ross@Sun.COM #include <unistd.h>
37*10023SGordon.Ross@Sun.COM #include <netdb.h>
38*10023SGordon.Ross@Sun.COM #include <libintl.h>
39*10023SGordon.Ross@Sun.COM #include <xti.h>
40*10023SGordon.Ross@Sun.COM #include <assert.h>
41*10023SGordon.Ross@Sun.COM
42*10023SGordon.Ross@Sun.COM #include <sys/types.h>
43*10023SGordon.Ross@Sun.COM #include <sys/time.h>
44*10023SGordon.Ross@Sun.COM #include <sys/byteorder.h>
45*10023SGordon.Ross@Sun.COM #include <sys/socket.h>
46*10023SGordon.Ross@Sun.COM #include <sys/fcntl.h>
47*10023SGordon.Ross@Sun.COM
48*10023SGordon.Ross@Sun.COM #include <netinet/in.h>
49*10023SGordon.Ross@Sun.COM #include <netinet/tcp.h>
50*10023SGordon.Ross@Sun.COM #include <arpa/inet.h>
51*10023SGordon.Ross@Sun.COM
52*10023SGordon.Ross@Sun.COM #include <netsmb/smb.h>
53*10023SGordon.Ross@Sun.COM #include <netsmb/smb_lib.h>
54*10023SGordon.Ross@Sun.COM #include <netsmb/netbios.h>
55*10023SGordon.Ross@Sun.COM #include <netsmb/nb_lib.h>
56*10023SGordon.Ross@Sun.COM #include <netsmb/smb_dev.h>
57*10023SGordon.Ross@Sun.COM
58*10023SGordon.Ross@Sun.COM #include "charsets.h"
59*10023SGordon.Ross@Sun.COM #include "private.h"
60*10023SGordon.Ross@Sun.COM
61*10023SGordon.Ross@Sun.COM /*
62*10023SGordon.Ross@Sun.COM * Ask the driver if it has a VC with this IP address.
63*10023SGordon.Ross@Sun.COM */
64*10023SGordon.Ross@Sun.COM static int
findvc(struct smb_ctx * ctx,struct addrinfo * ai)65*10023SGordon.Ross@Sun.COM findvc(struct smb_ctx *ctx, struct addrinfo *ai)
66*10023SGordon.Ross@Sun.COM {
67*10023SGordon.Ross@Sun.COM smbioc_ossn_t *ssn = &ctx->ct_ssn;
68*10023SGordon.Ross@Sun.COM
69*10023SGordon.Ross@Sun.COM /*
70*10023SGordon.Ross@Sun.COM * Copy the passed address into ssn_srvaddr,
71*10023SGordon.Ross@Sun.COM * but first sanity-check lengths. Also,
72*10023SGordon.Ross@Sun.COM * zero it first to avoid trailing junk.
73*10023SGordon.Ross@Sun.COM */
74*10023SGordon.Ross@Sun.COM if (ai->ai_addrlen > sizeof (ssn->ssn_srvaddr))
75*10023SGordon.Ross@Sun.COM return (EINVAL);
76*10023SGordon.Ross@Sun.COM bzero(&ssn->ssn_srvaddr, sizeof (ssn->ssn_srvaddr));
77*10023SGordon.Ross@Sun.COM bcopy(ai->ai_addr, &ssn->ssn_srvaddr, ai->ai_addrlen);
78*10023SGordon.Ross@Sun.COM
79*10023SGordon.Ross@Sun.COM if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_FIND, ssn) == -1)
80*10023SGordon.Ross@Sun.COM return (errno);
81*10023SGordon.Ross@Sun.COM
82*10023SGordon.Ross@Sun.COM return (0);
83*10023SGordon.Ross@Sun.COM }
84*10023SGordon.Ross@Sun.COM
85*10023SGordon.Ross@Sun.COM /*
86*10023SGordon.Ross@Sun.COM * Find (and reuse) an existing VC.
87*10023SGordon.Ross@Sun.COM * See also: newvc.c
88*10023SGordon.Ross@Sun.COM */
89*10023SGordon.Ross@Sun.COM int
smb_ctx_findvc(struct smb_ctx * ctx)90*10023SGordon.Ross@Sun.COM smb_ctx_findvc(struct smb_ctx *ctx)
91*10023SGordon.Ross@Sun.COM {
92*10023SGordon.Ross@Sun.COM struct addrinfo *ai;
93*10023SGordon.Ross@Sun.COM int err;
94*10023SGordon.Ross@Sun.COM
95*10023SGordon.Ross@Sun.COM /* Should already have the address list. */
96*10023SGordon.Ross@Sun.COM if ((ctx->ct_flags & SMBCF_RESOLVED) == 0)
97*10023SGordon.Ross@Sun.COM return (EINVAL);
98*10023SGordon.Ross@Sun.COM
99*10023SGordon.Ross@Sun.COM for (ai = ctx->ct_addrinfo; ai; ai = ai->ai_next) {
100*10023SGordon.Ross@Sun.COM
101*10023SGordon.Ross@Sun.COM switch (ai->ai_family) {
102*10023SGordon.Ross@Sun.COM
103*10023SGordon.Ross@Sun.COM case AF_INET:
104*10023SGordon.Ross@Sun.COM case AF_INET6:
105*10023SGordon.Ross@Sun.COM case AF_NETBIOS:
106*10023SGordon.Ross@Sun.COM err = findvc(ctx, ai);
107*10023SGordon.Ross@Sun.COM break;
108*10023SGordon.Ross@Sun.COM
109*10023SGordon.Ross@Sun.COM default:
110*10023SGordon.Ross@Sun.COM DPRINT("skipped family %d", ai->ai_family);
111*10023SGordon.Ross@Sun.COM err = EPROTONOSUPPORT;
112*10023SGordon.Ross@Sun.COM break;
113*10023SGordon.Ross@Sun.COM }
114*10023SGordon.Ross@Sun.COM
115*10023SGordon.Ross@Sun.COM if (err == 0) {
116*10023SGordon.Ross@Sun.COM /* re-use an existing VC */
117*10023SGordon.Ross@Sun.COM ctx->ct_flags |= SMBCF_SSNACTIVE;
118*10023SGordon.Ross@Sun.COM return (0);
119*10023SGordon.Ross@Sun.COM }
120*10023SGordon.Ross@Sun.COM }
121*10023SGordon.Ross@Sun.COM
122*10023SGordon.Ross@Sun.COM return (ENOENT);
123*10023SGordon.Ross@Sun.COM }
124*10023SGordon.Ross@Sun.COM
125*10023SGordon.Ross@Sun.COM /*
126*10023SGordon.Ross@Sun.COM * Forcibly disconnect the current session, even if
127*10023SGordon.Ross@Sun.COM * there are others using it! This is used by the
128*10023SGordon.Ross@Sun.COM * SMB server netlogon when it wants to setup a new
129*10023SGordon.Ross@Sun.COM * logon session and does not want any re-use.
130*10023SGordon.Ross@Sun.COM */
131*10023SGordon.Ross@Sun.COM int
smb_ctx_kill(struct smb_ctx * ctx)132*10023SGordon.Ross@Sun.COM smb_ctx_kill(struct smb_ctx *ctx)
133*10023SGordon.Ross@Sun.COM {
134*10023SGordon.Ross@Sun.COM
135*10023SGordon.Ross@Sun.COM if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_KILL, NULL) == -1)
136*10023SGordon.Ross@Sun.COM return (errno);
137*10023SGordon.Ross@Sun.COM
138*10023SGordon.Ross@Sun.COM return (0);
139*10023SGordon.Ross@Sun.COM }
140