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