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 54 int 55 smb_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 71 void 72 smb_rq_done(struct smb_rq *rqp) 73 { 74 mb_done(&rqp->rq_rp); 75 mb_done(&rqp->rq_rq); 76 free(rqp); 77 } 78 79 void 80 smb_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 88 int 89 smb_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 120 int 121 smb_rq_dstring(struct mbdata *mbp, char *s) 122 { 123 return smb_rq_dmem(mbp, s, strlen(s) + 1); 124 } 125 126 int 127 smb_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 153 int 154 smb_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