2 * Copyright (c) 2000, Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: rap.c,v 1.8 2001/02/24 15:56:05 bp Exp $
35 * This is very simple implementation of RAP protocol.
37 #include <sys/param.h>
38 #include <sys/endian.h>
39 #include <sys/errno.h>
49 #include <netsmb/smb_lib.h>
50 #include <netsmb/smb_conn.h>
51 #include <netsmb/smb_rap.h>
53 /*#include <sys/ioctl.h>*/
56 smb_rap_parserqparam(const char *s, char **next, int *rlen)
84 len *= strtoul(s, &np, 10);
88 *(const char**)next = s;
93 smb_rap_parserpparam(const char *s, char **next, int *rlen)
114 len *= strtoul(s, &np, 10);
118 *(const char**)next = s;
123 smb_rap_parserpdata(const char *s, char **next, int *rlen)
145 len *= strtoul(s, &np, 10);
149 *(const char**)next = s;
154 smb_rap_rqparam_z(struct smb_rap *rap, const char *value)
156 int len = strlen(value) + 1;
158 bcopy(value, rap->r_npbuf, len);
165 smb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, long value)
167 char *p = rap->r_npbuf;
181 memset(p, value, plen);
192 smb_rap_create(int fn, const char *param, const char *data,
193 struct smb_rap **rapp)
199 rap = malloc(sizeof(*rap));
202 bzero(rap, sizeof(*rap));
203 p = rap->r_sparam = rap->r_nparam = strdup(param);
204 rap->r_sdata = rap->r_ndata = strdup(data);
206 * Calculate length of request parameter block
208 len = 2 + strlen(param) + 1 + strlen(data) + 1;
211 if (smb_rap_parserqparam(p, &p, &plen) != 0)
215 rap->r_pbuf = rap->r_npbuf = malloc(len);
216 smb_rap_rqparam(rap, 'W', 1, fn);
217 smb_rap_rqparam_z(rap, rap->r_sparam);
218 smb_rap_rqparam_z(rap, rap->r_sdata);
224 smb_rap_done(struct smb_rap *rap)
234 smb_rap_setNparam(struct smb_rap *rap, long value)
236 char *p = rap->r_nparam;
240 error = smb_rap_parserqparam(p, &p, &plen);
245 rap->r_rcvbuflen = value;
250 error = smb_rap_rqparam(rap, ptype, plen, value);
260 smb_rap_setPparam(struct smb_rap *rap, void *value)
262 char *p = rap->r_nparam;
266 error = smb_rap_parserqparam(p, &p, &plen);
271 rap->r_rcvbuf = value;
281 smb_rap_getNparam(struct smb_rap *rap, long *value)
283 char *p = rap->r_nparam;
287 error = smb_rap_parserpparam(p, &p, &plen);
292 *value = le16toh(*(u_int16_t*)rap->r_npbuf);
297 rap->r_npbuf += plen;
303 smb_rap_request(struct smb_rap *rap, struct smb_ctx *ctx)
307 char *dp, *p = rap->r_nparam;
309 int error, rdatacnt, rparamcnt, entries, done, dlen;
311 rdatacnt = rap->r_rcvbuflen;
312 rparamcnt = rap->r_plen;
313 error = smb_t2_request(ctx, 0, 0, "\\PIPE\\LANMAN",
314 rap->r_plen, rap->r_pbuf, /* int tparamcnt, void *tparam */
315 0, NULL, /* int tdatacnt, void *tdata */
316 &rparamcnt, rap->r_pbuf, /* rparamcnt, void *rparam */
317 &rdatacnt, rap->r_rcvbuf /* int *rdatacnt, void *rdata */
321 rp = (u_int16_t*)rap->r_pbuf;
322 rap->r_result = le16toh(*rp++);
323 conv = le16toh(*rp++);
324 rap->r_npbuf = (char*)rp;
325 rap->r_entries = entries = 0;
327 while (!done && *p) {
331 rap->r_entries = entries = le16toh(*(u_int16_t*)rap->r_npbuf);
338 /* error = smb_rap_parserpparam(p, &p, &plen);
340 smb_error("reply parameter mismath %s", 0, p);
346 * In general, unpacking entries we may need to relocate
347 * entries for proper alingning. For now use them as is.
354 error = smb_rap_parserpdata(p, &p, &dlen);
356 smb_error("reply data mismath %s", 0, p);
361 p32 = (u_int32_t*)dp;
362 *p32 = (*p32 & 0xffff) - conv;
372 smb_rap_error(struct smb_rap *rap, int error)
376 if (rap->r_result == 0)
378 return rap->r_result | SMB_RAP_ERROR;
382 smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
383 int cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
389 error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
392 smb_rap_setNparam(rap, sLevel); /* W - sLevel */
393 smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
394 smb_rap_setNparam(rap, cbBuffer); /* L - cbBuffer */
395 error = smb_rap_request(rap, ctx);
397 *pcEntriesRead = rap->r_entries;
398 error = smb_rap_getNparam(rap, &lval);
399 *pcTotalAvail = lval;
401 error = smb_rap_error(rap, error);