1/* 2 * Copyright (c) 2000, Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 19 * 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 30 * SUCH DAMAGE. 31 * 32 * $Id: rq.c,v 1.7 2001/04/16 04:33:01 bp Exp $ 33 * $FreeBSD$ 34 */ 35#include <sys/param.h> 36#include <sys/ioctl.h> 37#include <sys/errno.h> 38#include <sys/stat.h> 39#include <ctype.h> 40#include <err.h> 41#include <stdio.h> 42#include <unistd.h> 43#include <string.h> 44#include <stdlib.h> 45#include <sysexits.h> 46 47#include <sys/mchain.h> 48 49#include <netsmb/smb_lib.h> 50#include <netsmb/smb_conn.h> 51#include <netsmb/smb_rap.h> 52 53 54int 55smb_rq_init(struct smb_ctx *ctx, u_char cmd, size_t rpbufsz, struct smb_rq **rqpp) 56{ 57 struct smb_rq *rqp; 58 59 rqp = malloc(sizeof(*rqp)); 60 if (rqp == NULL) 61 return ENOMEM; 62 bzero(rqp, sizeof(*rqp)); 63 rqp->rq_cmd = cmd; 64 rqp->rq_ctx = ctx; 65 mb_init(&rqp->rq_rq, M_MINSIZE); 66 mb_init(&rqp->rq_rp, rpbufsz); 67 *rqpp = rqp; 68 return 0; 69} 70 71void 72smb_rq_done(struct smb_rq *rqp) 73{ 74 mb_done(&rqp->rq_rp); 75 mb_done(&rqp->rq_rq); 76 free(rqp); 77} 78 79void 80smb_rq_wend(struct smb_rq *rqp) 81{ 82 if (rqp->rq_rq.mb_count & 1) 83 smb_error("smbrq_wend: odd word count\n", 0); 84 rqp->rq_wcount = rqp->rq_rq.mb_count / 2; 85 rqp->rq_rq.mb_count = 0; 86} 87 88int 89smb_rq_dmem(struct mbdata *mbp, char *src, size_t size) 90{ 91 struct mbuf *m; 92 char * dst; 93 int cplen, error; 94 95 if (size == 0) 96 return 0; 97 m = mbp->mb_cur; 98 if ((error = m_getm(m, size, &m)) != 0) 99 return error; 100 while (size > 0) { 101 cplen = M_TRAILINGSPACE(m); 102 if (cplen == 0) { 103 m = m->m_next; 104 continue; 105 } 106 if (cplen > (int)size) 107 cplen = size; 108 dst = mtod(m, char *) + m->m_len; 109 nls_mem_toext(dst, src, cplen); 110 size -= cplen; 111 src += cplen; 112 m->m_len += cplen; 113 mbp->mb_count += cplen; 114 } 115 mbp->mb_pos = mtod(m, char *) + m->m_len; 116 mbp->mb_cur = m; 117 return 0; 118} 119 120int 121smb_rq_dstring(struct mbdata *mbp, char *s) 122{ 123 return smb_rq_dmem(mbp, s, strlen(s) + 1); 124} 125 126int 127smb_rq_simple(struct smb_rq *rqp) 128{ 129 struct smbioc_rq krq; 130 struct mbdata *mbp; 131 char *data; 132 133 mbp = smb_rq_getrequest(rqp); 134 m_lineup(mbp->mb_top, &mbp->mb_top); 135 data = mtod(mbp->mb_top, char*); 136 bzero(&krq, sizeof(krq)); 137 krq.ioc_cmd = rqp->rq_cmd; 138 krq.ioc_twc = rqp->rq_wcount; 139 krq.ioc_twords = data; 140 krq.ioc_tbc = mbp->mb_count; 141 krq.ioc_tbytes = data + rqp->rq_wcount * 2; 142 mbp = smb_rq_getreply(rqp); 143 krq.ioc_rpbufsz = mbp->mb_top->m_maxlen; 144 krq.ioc_rpbuf = mtod(mbp->mb_top, char *); 145 if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) 146 return errno; 147 mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc; 148 rqp->rq_wcount = krq.ioc_rwc; 149 rqp->rq_bcount = krq.ioc_rbc; 150 return 0; 151} 152 153int 154smb_t2_request(struct smb_ctx *ctx, int setup, int setupcount, 155 const char *name, 156 int tparamcnt, void *tparam, 157 int tdatacnt, void *tdata, 158 int *rparamcnt, void *rparam, 159 int *rdatacnt, void *rdata) 160{ 161 struct smbioc_t2rq krq; 162 163 bzero(&krq, sizeof(krq)); 164 krq.ioc_setup[0] = setup; 165 krq.ioc_setupcnt = setupcount; 166 krq.ioc_name = (char *)name; 167 krq.ioc_tparamcnt = tparamcnt; 168 krq.ioc_tparam = tparam; 169 krq.ioc_tdatacnt = tdatacnt; 170 krq.ioc_tdata = tdata; 171 krq.ioc_rparamcnt = *rparamcnt; 172 krq.ioc_rparam = rparam; 173 krq.ioc_rdatacnt = *rdatacnt; 174 krq.ioc_rdata = rdata; 175 if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, &krq) == -1) 176 return errno; 177 *rparamcnt = krq.ioc_rparamcnt; 178 *rdatacnt = krq.ioc_rdatacnt; 179 return 0; 180} 181