xref: /titanic_44/usr/src/cmd/fs.d/smbclnt/test/srvinfo.c (revision 85e6b6747d07050e01ec91acef2453655821f9ab)
1*85e6b674SGordon Ross /*
2*85e6b674SGordon Ross  * CDDL HEADER START
3*85e6b674SGordon Ross  *
4*85e6b674SGordon Ross  * The contents of this file are subject to the terms of the
5*85e6b674SGordon Ross  * Common Development and Distribution License (the "License").
6*85e6b674SGordon Ross  * You may not use this file except in compliance with the License.
7*85e6b674SGordon Ross  *
8*85e6b674SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*85e6b674SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10*85e6b674SGordon Ross  * See the License for the specific language governing permissions
11*85e6b674SGordon Ross  * and limitations under the License.
12*85e6b674SGordon Ross  *
13*85e6b674SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14*85e6b674SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*85e6b674SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16*85e6b674SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17*85e6b674SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18*85e6b674SGordon Ross  *
19*85e6b674SGordon Ross  * CDDL HEADER END
20*85e6b674SGordon Ross  */
21*85e6b674SGordon Ross 
22*85e6b674SGordon Ross /*
23*85e6b674SGordon Ross  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*85e6b674SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
25*85e6b674SGordon Ross  */
26*85e6b674SGordon Ross 
27*85e6b674SGordon Ross /*
28*85e6b674SGordon Ross  * Test program for the smbfs named pipe API.
29*85e6b674SGordon Ross  */
30*85e6b674SGordon Ross 
31*85e6b674SGordon Ross #include <sys/types.h>
32*85e6b674SGordon Ross #include <errno.h>
33*85e6b674SGordon Ross #include <fcntl.h>
34*85e6b674SGordon Ross #include <stdio.h>
35*85e6b674SGordon Ross #include <stdlib.h>
36*85e6b674SGordon Ross #include <string.h>
37*85e6b674SGordon Ross #include <unistd.h>
38*85e6b674SGordon Ross #include <libintl.h>
39*85e6b674SGordon Ross 
40*85e6b674SGordon Ross #include <netsmb/smbfs_api.h>
41*85e6b674SGordon Ross 
42*85e6b674SGordon Ross /*
43*85e6b674SGordon Ross  * This is a quick hack for testing client-side named pipes.
44*85e6b674SGordon Ross  * Its purpose is to test the ability to connect to a server,
45*85e6b674SGordon Ross  * open a pipe, send and receive data.  The "hack" aspect is
46*85e6b674SGordon Ross  * the use of hand-crafted RPC messages, which allows testing
47*85e6b674SGordon Ross  * of the named pipe API separately from the RPC libraries.
48*85e6b674SGordon Ross  *
49*85e6b674SGordon Ross  * I captured the two small name pipe messages sent when
50*85e6b674SGordon Ross  * requesting a server info via RPC over /pipe/srvsvc and
51*85e6b674SGordon Ross  * dropped them into the arrays below (bind and info).
52*85e6b674SGordon Ross  * This program sends the two messages (with adjustments)
53*85e6b674SGordon Ross  * and just dumps whatever comes back over the pipe.
54*85e6b674SGordon Ross  * Use wireshark if you want to see decoded messages.
55*85e6b674SGordon Ross  */
56*85e6b674SGordon Ross 
57*85e6b674SGordon Ross extern char *optarg;
58*85e6b674SGordon Ross extern int optind, opterr, optopt;
59*85e6b674SGordon Ross 
60*85e6b674SGordon Ross /* This is a DCE/RPC bind call for "srvsvc". */
61*85e6b674SGordon Ross static const uchar_t
62*85e6b674SGordon Ross srvsvc_bind[] = {
63*85e6b674SGordon Ross 	0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
64*85e6b674SGordon Ross 	0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
65*85e6b674SGordon Ross 	0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
66*85e6b674SGordon Ross 	0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
67*85e6b674SGordon Ross 	0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01,
68*85e6b674SGordon Ross 	0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88,
69*85e6b674SGordon Ross 	0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
70*85e6b674SGordon Ross 	0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
71*85e6b674SGordon Ross 	0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 };
72*85e6b674SGordon Ross 
73*85e6b674SGordon Ross /* This is a srvsvc "get server info" call, in two parts */
74*85e6b674SGordon Ross static const uchar_t
75*85e6b674SGordon Ross srvsvc_info[] = {
76*85e6b674SGordon Ross 	0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
77*85e6b674SGordon Ross #define	INFO_RPCLEN_OFF	8
78*85e6b674SGordon Ross 	/* V - RPC frag length */
79*85e6b674SGordon Ross 	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80*85e6b674SGordon Ross 	/* ... and the operation number is: VVVV */
81*85e6b674SGordon Ross 	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x15, 0x00,
82*85e6b674SGordon Ross #define	INFO_SLEN1_OFF	28
83*85e6b674SGordon Ross #define	INFO_SLEN2_OFF	36
84*85e6b674SGordon Ross 	/* server name, length 14 vv ... */
85*85e6b674SGordon Ross 	0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
86*85e6b674SGordon Ross 	0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00 };
87*85e6b674SGordon Ross 	/* UNC server here, i.e.: "\\192.168.1.6" */
88*85e6b674SGordon Ross 
89*85e6b674SGordon Ross static uchar_t sendbuf[1024];
90*85e6b674SGordon Ross static uchar_t recvbuf[1024];
91*85e6b674SGordon Ross static char *server;
92*85e6b674SGordon Ross 
93*85e6b674SGordon Ross static int pipetest(struct smb_ctx *);
94*85e6b674SGordon Ross 
95*85e6b674SGordon Ross static void
srvinfo_usage(void)96*85e6b674SGordon Ross srvinfo_usage(void)
97*85e6b674SGordon Ross {
98*85e6b674SGordon Ross 	printf("usage: srvinfo [-d domain][-u user][-p passwd] server\n");
99*85e6b674SGordon Ross 	exit(1);
100*85e6b674SGordon Ross }
101*85e6b674SGordon Ross 
102*85e6b674SGordon Ross int
main(int argc,char * argv[])103*85e6b674SGordon Ross main(int argc, char *argv[])
104*85e6b674SGordon Ross {
105*85e6b674SGordon Ross 	int c, error;
106*85e6b674SGordon Ross 	struct smb_ctx *ctx = NULL;
107*85e6b674SGordon Ross 	char *dom = NULL;
108*85e6b674SGordon Ross 	char *usr = NULL;
109*85e6b674SGordon Ross 	char *pw = NULL;
110*85e6b674SGordon Ross 
111*85e6b674SGordon Ross 	while ((c = getopt(argc, argv, "vd:u:p:")) != -1) {
112*85e6b674SGordon Ross 		switch (c) {
113*85e6b674SGordon Ross 		case 'v':
114*85e6b674SGordon Ross 			smb_verbose = 1;
115*85e6b674SGordon Ross 			break;
116*85e6b674SGordon Ross 
117*85e6b674SGordon Ross 		case 'd':
118*85e6b674SGordon Ross 			dom = optarg;
119*85e6b674SGordon Ross 			break;
120*85e6b674SGordon Ross 		case 'u':
121*85e6b674SGordon Ross 			usr = optarg;
122*85e6b674SGordon Ross 			break;
123*85e6b674SGordon Ross 		case 'p':
124*85e6b674SGordon Ross 			pw = optarg;
125*85e6b674SGordon Ross 			break;
126*85e6b674SGordon Ross 		case '?':
127*85e6b674SGordon Ross 			srvinfo_usage();
128*85e6b674SGordon Ross 			break;
129*85e6b674SGordon Ross 		}
130*85e6b674SGordon Ross 	}
131*85e6b674SGordon Ross 	if (optind >= argc)
132*85e6b674SGordon Ross 		srvinfo_usage();
133*85e6b674SGordon Ross 	server = argv[optind];
134*85e6b674SGordon Ross 
135*85e6b674SGordon Ross 	if (pw != NULL && (dom == NULL || usr == NULL)) {
136*85e6b674SGordon Ross 		fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
137*85e6b674SGordon Ross 		    argv[0]);
138*85e6b674SGordon Ross 		srvinfo_usage();
139*85e6b674SGordon Ross 	}
140*85e6b674SGordon Ross 
141*85e6b674SGordon Ross 	/*
142*85e6b674SGordon Ross 	 * This section is intended to demonstrate how an
143*85e6b674SGordon Ross 	 * RPC client library might use this interface.
144*85e6b674SGordon Ross 	 */
145*85e6b674SGordon Ross 	error = smb_ctx_alloc(&ctx);
146*85e6b674SGordon Ross 	if (error) {
147*85e6b674SGordon Ross 		fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
148*85e6b674SGordon Ross 		goto out;
149*85e6b674SGordon Ross 	}
150*85e6b674SGordon Ross 
151*85e6b674SGordon Ross 	/*
152*85e6b674SGordon Ross 	 * Set server, share, domain, user
153*85e6b674SGordon Ross 	 * (in the ctx handle).
154*85e6b674SGordon Ross 	 */
155*85e6b674SGordon Ross 	smb_ctx_setfullserver(ctx, server);
156*85e6b674SGordon Ross 	smb_ctx_setshare(ctx, "IPC$", USE_IPC);
157*85e6b674SGordon Ross 	if (dom)
158*85e6b674SGordon Ross 		smb_ctx_setdomain(ctx, dom, B_TRUE);
159*85e6b674SGordon Ross 	if (usr)
160*85e6b674SGordon Ross 		smb_ctx_setuser(ctx, usr, B_TRUE);
161*85e6b674SGordon Ross 	if (pw)
162*85e6b674SGordon Ross 		smb_ctx_setpassword(ctx, pw, NULL);
163*85e6b674SGordon Ross 
164*85e6b674SGordon Ross 
165*85e6b674SGordon Ross 	/*
166*85e6b674SGordon Ross 	 * If this code were in smbutil or mount_smbfs, it would
167*85e6b674SGordon Ross 	 * get system and $HOME/.nsmbrc settings here, like this:
168*85e6b674SGordon Ross 	 */
169*85e6b674SGordon Ross #if 0
170*85e6b674SGordon Ross 	error = smb_ctx_readrc(ctx);
171*85e6b674SGordon Ross 	if (error) {
172*85e6b674SGordon Ross 		fprintf(stderr, "%s: smb_ctx_readrc failed\n", argv[0]);
173*85e6b674SGordon Ross 		goto out;
174*85e6b674SGordon Ross 	}
175*85e6b674SGordon Ross #endif
176*85e6b674SGordon Ross 
177*85e6b674SGordon Ross 	/*
178*85e6b674SGordon Ross 	 * Resolve the server address,
179*85e6b674SGordon Ross 	 * setup derived defaults.
180*85e6b674SGordon Ross 	 */
181*85e6b674SGordon Ross 	error = smb_ctx_resolve(ctx);
182*85e6b674SGordon Ross 	if (error) {
183*85e6b674SGordon Ross 		fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
184*85e6b674SGordon Ross 		goto out;
185*85e6b674SGordon Ross 	}
186*85e6b674SGordon Ross 
187*85e6b674SGordon Ross 	/*
188*85e6b674SGordon Ross 	 * Get the session and tree.
189*85e6b674SGordon Ross 	 */
190*85e6b674SGordon Ross 	error = smb_ctx_get_ssn(ctx);
191*85e6b674SGordon Ross 	if (error) {
192*85e6b674SGordon Ross 		fprintf(stderr, "//%s: login failed, error %d\n",
193*85e6b674SGordon Ross 		    server, error);
194*85e6b674SGordon Ross 		goto out;
195*85e6b674SGordon Ross 	}
196*85e6b674SGordon Ross 	error = smb_ctx_get_tree(ctx);
197*85e6b674SGordon Ross 	if (error) {
198*85e6b674SGordon Ross 		fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
199*85e6b674SGordon Ross 		    server, "IPC$", error);
200*85e6b674SGordon Ross 		goto out;
201*85e6b674SGordon Ross 	}
202*85e6b674SGordon Ross 
203*85e6b674SGordon Ross 	/*
204*85e6b674SGordon Ross 	 * Do some named pipe I/O.
205*85e6b674SGordon Ross 	 */
206*85e6b674SGordon Ross 	error = pipetest(ctx);
207*85e6b674SGordon Ross 	if (error) {
208*85e6b674SGordon Ross 		fprintf(stderr, "pipetest, %d\n", error);
209*85e6b674SGordon Ross 		goto out;
210*85e6b674SGordon Ross 	}
211*85e6b674SGordon Ross 
212*85e6b674SGordon Ross out:
213*85e6b674SGordon Ross 	smb_ctx_free(ctx);
214*85e6b674SGordon Ross 
215*85e6b674SGordon Ross 	return ((error) ? 1 : 0);
216*85e6b674SGordon Ross }
217*85e6b674SGordon Ross 
218*85e6b674SGordon Ross static void
hexdump(const uchar_t * buf,int len)219*85e6b674SGordon Ross hexdump(const uchar_t *buf, int len) {
220*85e6b674SGordon Ross 	int ofs = 0;
221*85e6b674SGordon Ross 
222*85e6b674SGordon Ross 	while (len--) {
223*85e6b674SGordon Ross 		if (ofs % 16 == 0)
224*85e6b674SGordon Ross 			printf("\n%02X: ", ofs);
225*85e6b674SGordon Ross 		printf("%02x ", *buf++);
226*85e6b674SGordon Ross 		ofs++;
227*85e6b674SGordon Ross 	}
228*85e6b674SGordon Ross 	printf("\n");
229*85e6b674SGordon Ross }
230*85e6b674SGordon Ross 
231*85e6b674SGordon Ross /*
232*85e6b674SGordon Ross  * Put a unicode UNC server name, including the null.
233*85e6b674SGordon Ross  * Quick-n-dirty, just for this test...
234*85e6b674SGordon Ross  */
235*85e6b674SGordon Ross static int
put_uncserver(const char * s,uchar_t * buf)236*85e6b674SGordon Ross put_uncserver(const char *s, uchar_t *buf)
237*85e6b674SGordon Ross {
238*85e6b674SGordon Ross 	uchar_t *p = buf;
239*85e6b674SGordon Ross 	char c;
240*85e6b674SGordon Ross 
241*85e6b674SGordon Ross 	*p++ = '\\'; *p++ = '\0';
242*85e6b674SGordon Ross 	*p++ = '\\'; *p++ = '\0';
243*85e6b674SGordon Ross 
244*85e6b674SGordon Ross 	do {
245*85e6b674SGordon Ross 		c = *s++;
246*85e6b674SGordon Ross 		if (c == '/')
247*85e6b674SGordon Ross 			c = '\\';
248*85e6b674SGordon Ross 		*p++ = c;
249*85e6b674SGordon Ross 		*p++ = '\0';
250*85e6b674SGordon Ross 
251*85e6b674SGordon Ross 	} while (c != 0);
252*85e6b674SGordon Ross 
253*85e6b674SGordon Ross 	return (p - buf);
254*85e6b674SGordon Ross }
255*85e6b674SGordon Ross 
256*85e6b674SGordon Ross /* Get a little-endian int.  Just for testing. */
257*85e6b674SGordon Ross static int
getint(const uchar_t * p)258*85e6b674SGordon Ross getint(const uchar_t *p)
259*85e6b674SGordon Ross {
260*85e6b674SGordon Ross 	return (p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24));
261*85e6b674SGordon Ross }
262*85e6b674SGordon Ross 
263*85e6b674SGordon Ross /*
264*85e6b674SGordon Ross  * Send the bind and read the ack.
265*85e6b674SGordon Ross  * This tests smb_fh_xactnp.
266*85e6b674SGordon Ross  */
267*85e6b674SGordon Ross static int
do_bind(int fid)268*85e6b674SGordon Ross do_bind(int fid)
269*85e6b674SGordon Ross {
270*85e6b674SGordon Ross 	int err, len, more;
271*85e6b674SGordon Ross 
272*85e6b674SGordon Ross 	more = 0;
273*85e6b674SGordon Ross 	len = sizeof (recvbuf);
274*85e6b674SGordon Ross 	err = smb_fh_xactnp(fid,
275*85e6b674SGordon Ross 	    sizeof (srvsvc_bind), (char *)srvsvc_bind,
276*85e6b674SGordon Ross 	    &len, (char *)recvbuf, &more);
277*85e6b674SGordon Ross 	if (err) {
278*85e6b674SGordon Ross 		printf("xact bind, err=%d\n", err);
279*85e6b674SGordon Ross 		return (err);
280*85e6b674SGordon Ross 	}
281*85e6b674SGordon Ross 	if (smb_verbose) {
282*85e6b674SGordon Ross 		printf("bind ack, len=%d\n", len);
283*85e6b674SGordon Ross 		hexdump(recvbuf, len);
284*85e6b674SGordon Ross 	}
285*85e6b674SGordon Ross 	if (more > 0) {
286*85e6b674SGordon Ross 		if (more > sizeof (recvbuf)) {
287*85e6b674SGordon Ross 			printf("bogus more=%d\n", more);
288*85e6b674SGordon Ross 			more = sizeof (recvbuf);
289*85e6b674SGordon Ross 		}
290*85e6b674SGordon Ross 		len = smb_fh_read(fid, 0,
291*85e6b674SGordon Ross 		    more, (char *)recvbuf);
292*85e6b674SGordon Ross 		if (len == -1) {
293*85e6b674SGordon Ross 			err = EIO;
294*85e6b674SGordon Ross 			printf("read info resp, err=%d\n", err);
295*85e6b674SGordon Ross 			return (err);
296*85e6b674SGordon Ross 		}
297*85e6b674SGordon Ross 		if (smb_verbose) {
298*85e6b674SGordon Ross 			printf("bind ack (more), len=%d\n", len);
299*85e6b674SGordon Ross 			hexdump(recvbuf, len);
300*85e6b674SGordon Ross 		}
301*85e6b674SGordon Ross 	}
302*85e6b674SGordon Ross 
303*85e6b674SGordon Ross 	return (0);
304*85e6b674SGordon Ross }
305*85e6b674SGordon Ross 
306*85e6b674SGordon Ross static int
do_info(int fid)307*85e6b674SGordon Ross do_info(int fid)
308*85e6b674SGordon Ross {
309*85e6b674SGordon Ross 	int err, len, rlen, wlen, x;
310*85e6b674SGordon Ross 	uchar_t *p;
311*85e6b674SGordon Ross 
312*85e6b674SGordon Ross 	/*
313*85e6b674SGordon Ross 	 * Build the info request - two parts.
314*85e6b674SGordon Ross 	 * See above: srvsvc_info
315*85e6b674SGordon Ross 	 *
316*85e6b674SGordon Ross 	 * First part: RPC header, etc.
317*85e6b674SGordon Ross 	 */
318*85e6b674SGordon Ross 	p = sendbuf;
319*85e6b674SGordon Ross 	len = sizeof (srvsvc_info); /* 40 */
320*85e6b674SGordon Ross 	memcpy(p, srvsvc_info, len);
321*85e6b674SGordon Ross 	p += len;
322*85e6b674SGordon Ross 
323*85e6b674SGordon Ross 	/* Second part: UNC server name */
324*85e6b674SGordon Ross 	len = put_uncserver(server, p);
325*85e6b674SGordon Ross 	p += len;
326*85e6b674SGordon Ross 	sendbuf[INFO_SLEN1_OFF] = len / 2;
327*85e6b674SGordon Ross 	sendbuf[INFO_SLEN2_OFF] = len / 2;
328*85e6b674SGordon Ross 
329*85e6b674SGordon Ross 	/* Third part: level, etc. (align4) */
330*85e6b674SGordon Ross 	for (len = (p - sendbuf) & 3; len; len--)
331*85e6b674SGordon Ross 		*p++ = '\0';
332*85e6b674SGordon Ross 	*p++ = 101;	/* the "level" */
333*85e6b674SGordon Ross 	*p++ = 0; *p++ = 0; *p++ = 0;
334*85e6b674SGordon Ross 
335*85e6b674SGordon Ross 	/*
336*85e6b674SGordon Ross 	 * Compute total length, and fixup RPC header.
337*85e6b674SGordon Ross 	 */
338*85e6b674SGordon Ross 	len = p - sendbuf;
339*85e6b674SGordon Ross 	sendbuf[INFO_RPCLEN_OFF] = len;
340*85e6b674SGordon Ross 
341*85e6b674SGordon Ross 	/*
342*85e6b674SGordon Ross 	 * Send the info request, read the response.
343*85e6b674SGordon Ross 	 * This tests smb_fh_write, smb_fh_read.
344*85e6b674SGordon Ross 	 */
345*85e6b674SGordon Ross 	wlen = smb_fh_write(fid, 0, len, (char *)sendbuf);
346*85e6b674SGordon Ross 	if (wlen == -1) {
347*85e6b674SGordon Ross 		err = errno;
348*85e6b674SGordon Ross 		printf("write info req, err=%d\n", err);
349*85e6b674SGordon Ross 		return (err);
350*85e6b674SGordon Ross 	}
351*85e6b674SGordon Ross 	if (wlen != len) {
352*85e6b674SGordon Ross 		printf("write info req, short write %d\n", wlen);
353*85e6b674SGordon Ross 		return (EIO);
354*85e6b674SGordon Ross 	}
355*85e6b674SGordon Ross 
356*85e6b674SGordon Ross 	rlen = smb_fh_read(fid, 0,
357*85e6b674SGordon Ross 	    sizeof (recvbuf), (char *)recvbuf);
358*85e6b674SGordon Ross 	if (rlen == -1) {
359*85e6b674SGordon Ross 		err = errno;
360*85e6b674SGordon Ross 		printf("read info resp, err=%d\n", err);
361*85e6b674SGordon Ross 		return (err);
362*85e6b674SGordon Ross 	}
363*85e6b674SGordon Ross 
364*85e6b674SGordon Ross 	if (smb_verbose) {
365*85e6b674SGordon Ross 		printf("info recv, len=%d\n", rlen);
366*85e6b674SGordon Ross 		hexdump(recvbuf, rlen);
367*85e6b674SGordon Ross 	}
368*85e6b674SGordon Ross 
369*85e6b674SGordon Ross 	x = getint(recvbuf + 4);
370*85e6b674SGordon Ross 	if (x != 0x10) {
371*85e6b674SGordon Ross 		printf("Data representation 0x%x not supported\n", x);
372*85e6b674SGordon Ross 		return (ENOTSUP);
373*85e6b674SGordon Ross 	}
374*85e6b674SGordon Ross 	printf("Platform Id: %d\n", getint(recvbuf + 0x20));
375*85e6b674SGordon Ross 	printf("Version Major: %d\n", getint(recvbuf + 0x28));
376*85e6b674SGordon Ross 	printf("Version Minor: %d\n", getint(recvbuf + 0x2c));
377*85e6b674SGordon Ross 	printf("Srv type flags: 0x%x\n", getint(recvbuf + 0x30));
378*85e6b674SGordon Ross 
379*85e6b674SGordon Ross 	return (0);
380*85e6b674SGordon Ross }
381*85e6b674SGordon Ross 
382*85e6b674SGordon Ross static int
pipetest(struct smb_ctx * ctx)383*85e6b674SGordon Ross pipetest(struct smb_ctx *ctx)
384*85e6b674SGordon Ross {
385*85e6b674SGordon Ross 	static char path[] = "/srvsvc";
386*85e6b674SGordon Ross 	static uchar_t key[16];
387*85e6b674SGordon Ross 	int err, fd;
388*85e6b674SGordon Ross 
389*85e6b674SGordon Ross 	printf("open pipe: %s\n", path);
390*85e6b674SGordon Ross 	fd = smb_fh_open(ctx, path, O_RDWR);
391*85e6b674SGordon Ross 	if (fd < 0) {
392*85e6b674SGordon Ross 		perror(path);
393*85e6b674SGordon Ross 		return (errno);
394*85e6b674SGordon Ross 	}
395*85e6b674SGordon Ross 
396*85e6b674SGordon Ross 	/* Test this too. */
397*85e6b674SGordon Ross 	err = smb_fh_getssnkey(fd, key, sizeof (key));
398*85e6b674SGordon Ross 	if (err) {
399*85e6b674SGordon Ross 		printf("getssnkey: %d\n", err);
400*85e6b674SGordon Ross 		goto out;
401*85e6b674SGordon Ross 	}
402*85e6b674SGordon Ross 
403*85e6b674SGordon Ross 	err = do_bind(fd);
404*85e6b674SGordon Ross 	if (err) {
405*85e6b674SGordon Ross 		printf("do_bind: %d\n", err);
406*85e6b674SGordon Ross 		goto out;
407*85e6b674SGordon Ross 	}
408*85e6b674SGordon Ross 	err = do_info(fd);
409*85e6b674SGordon Ross 	if (err)
410*85e6b674SGordon Ross 		printf("do_info: %d\n", err);
411*85e6b674SGordon Ross 
412*85e6b674SGordon Ross out:
413*85e6b674SGordon Ross 	smb_fh_close(fd);
414*85e6b674SGordon Ross 	return (err);
415*85e6b674SGordon Ross }
416