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 * from: Id: rap.c,v 1.8 2001/02/24 15:56:05 bp Exp
34 * This is very simple implementation of RAP protocol.
37 #include <sys/cdefs.h>
38 __RCSID("$NetBSD: rap.c,v 1.5 2004/10/29 19:18:32 dsl Exp $");
40 #include <sys/param.h>
41 #include <sys/errno.h>
43 #include <sys/endian.h>
52 #include <netsmb/smb_lib.h>
53 #include <netsmb/smb_conn.h>
54 #include <netsmb/smb_rap.h>
57 smb_rap_parserqparam(const char *s
, char **next
, int *rlen
)
84 if (isdigit((unsigned char)*s
)) {
85 len
*= strtoul(s
, &np
, 10);
89 *(const char**)next
= s
;
94 smb_rap_parserpparam(const char *s
, char **next
, int *rlen
)
114 if (isdigit((unsigned char)*s
)) {
115 len
*= strtoul(s
, &np
, 10);
119 *(const char**)next
= s
;
124 smb_rap_parserpdata(const char *s
, char **next
, int *rlen
)
145 if (isdigit((unsigned char)*s
)) {
146 len
*= strtoul(s
, &np
, 10);
150 *(const char**)next
= s
;
155 smb_rap_rqparam_z(struct smb_rap
*rap
, const char *value
)
157 int len
= strlen(value
) + 1;
159 bcopy(value
, rap
->r_npbuf
, len
);
166 smb_rap_rqparam(struct smb_rap
*rap
, char ptype
, char plen
, long value
)
168 char *p
= rap
->r_npbuf
;
182 memset(p
, value
, plen
);
193 smb_rap_create(int fn
, const char *param
, const char *data
,
194 struct smb_rap
**rapp
)
200 rap
= malloc(sizeof(*rap
));
203 bzero(rap
, sizeof(*rap
));
204 p
= rap
->r_sparam
= rap
->r_nparam
= strdup(param
);
205 rap
->r_sdata
= rap
->r_ndata
= strdup(data
);
207 * Calculate length of request parameter block
209 len
= 2 + strlen(param
) + 1 + strlen(data
) + 1;
212 if (smb_rap_parserqparam(p
, &p
, &plen
) != 0)
216 rap
->r_pbuf
= rap
->r_npbuf
= malloc(len
);
217 smb_rap_rqparam(rap
, 'W', 1, fn
);
218 smb_rap_rqparam_z(rap
, rap
->r_sparam
);
219 smb_rap_rqparam_z(rap
, rap
->r_sdata
);
225 smb_rap_done(struct smb_rap
*rap
)
235 smb_rap_setNparam(struct smb_rap
*rap
, long value
)
237 char *p
= rap
->r_nparam
;
241 error
= smb_rap_parserqparam(p
, &p
, &plen
);
246 rap
->r_rcvbuflen
= value
;
251 error
= smb_rap_rqparam(rap
, ptype
, plen
, value
);
261 smb_rap_setPparam(struct smb_rap
*rap
, void *value
)
263 char *p
= rap
->r_nparam
;
267 error
= smb_rap_parserqparam(p
, &p
, &plen
);
272 rap
->r_rcvbuf
= value
;
282 smb_rap_getNparam(struct smb_rap
*rap
, long *value
)
284 char *p
= rap
->r_nparam
;
288 error
= smb_rap_parserpparam(p
, &p
, &plen
);
293 *value
= ntohs(*(u_int16_t
*)rap
->r_npbuf
);
298 rap
->r_npbuf
+= plen
;
304 smb_rap_request(struct smb_rap
*rap
, struct smb_ctx
*ctx
)
308 char *dp
, *p
= rap
->r_nparam
;
310 int error
, rdatacnt
, rparamcnt
, entries
, done
, dlen
;
312 rdatacnt
= rap
->r_rcvbuflen
;
313 rparamcnt
= rap
->r_plen
;
314 error
= smb_t2_request(ctx
, 0, 0, "\\PIPE\\LANMAN",
315 rap
->r_plen
, rap
->r_pbuf
, /* int tparamcnt, void *tparam */
316 0, NULL
, /* int tdatacnt, void *tdata */
317 &rparamcnt
, rap
->r_pbuf
, /* rparamcnt, void *rparam */
318 &rdatacnt
, rap
->r_rcvbuf
/* int *rdatacnt, void *rdata */
322 rp
= (u_int16_t
*)rap
->r_pbuf
;
323 rap
->r_result
= le16toh(*rp
++);
324 conv
= le16toh(*rp
++);
325 rap
->r_npbuf
= (char*)rp
;
326 rap
->r_entries
= entries
= 0;
328 while (!done
&& *p
) {
332 rap
->r_entries
= entries
= le16toh(*(u_int16_t
*)rap
->r_npbuf
);
339 /* error = smb_rap_parserpparam(p, &p, &plen);
341 smb_error("reply parameter mismath %s", 0, p);
347 * In general, unpacking entries we may need to relocate
348 * entries for proper alingning. For now use them as is.
355 error
= smb_rap_parserpdata(p
, &p
, &dlen
);
357 smb_error("reply data mismath %s", 0, p
);
362 p32
= (u_int32_t
*)dp
;
363 *p32
= (*p32
& 0xffff) - conv
;
373 smb_rap_error(struct smb_rap
*rap
, int error
)
377 if (rap
->r_result
== 0)
379 return rap
->r_result
| SMB_RAP_ERROR
;
383 smb_rap_NetShareEnum(struct smb_ctx
*ctx
, int sLevel
, void *pbBuffer
,
384 int cbBuffer
, int *pcEntriesRead
, int *pcTotalAvail
)
390 lval
= -1; /* XXX gcc */
391 error
= smb_rap_create(0, "WrLeh", "B13BWz", &rap
);
394 smb_rap_setNparam(rap
, sLevel
); /* W - sLevel */
395 smb_rap_setPparam(rap
, pbBuffer
); /* r - pbBuffer */
396 smb_rap_setNparam(rap
, cbBuffer
); /* L - cbBuffer */
397 error
= smb_rap_request(rap
, ctx
);
399 *pcEntriesRead
= rap
->r_entries
;
400 error
= smb_rap_getNparam(rap
, &lval
);
401 *pcTotalAvail
= lval
;
403 error
= smb_rap_error(rap
, error
);