187866Ssheldonh/* 287866Ssheldonh * Copyright (c) 2000, Boris Popov 387866Ssheldonh * All rights reserved. 487866Ssheldonh * 587866Ssheldonh * Redistribution and use in source and binary forms, with or without 687866Ssheldonh * modification, are permitted provided that the following conditions 787866Ssheldonh * are met: 887866Ssheldonh * 1. Redistributions of source code must retain the above copyright 987866Ssheldonh * notice, this list of conditions and the following disclaimer. 1087866Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright 1187866Ssheldonh * notice, this list of conditions and the following disclaimer in the 1287866Ssheldonh * documentation and/or other materials provided with the distribution. 1387866Ssheldonh * 3. All advertising materials mentioning features or use of this software 1487866Ssheldonh * must display the following acknowledgement: 1587866Ssheldonh * This product includes software developed by Boris Popov. 1687866Ssheldonh * 4. Neither the name of the author nor the names of any co-contributors 1787866Ssheldonh * may be used to endorse or promote products derived from this software 1887866Ssheldonh * without specific prior written permission. 1987866Ssheldonh * 2087866Ssheldonh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2187866Ssheldonh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2287866Ssheldonh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2387866Ssheldonh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2487866Ssheldonh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2587866Ssheldonh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2687866Ssheldonh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2787866Ssheldonh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2887866Ssheldonh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2987866Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3087866Ssheldonh * SUCH DAMAGE. 3187866Ssheldonh * 3287866Ssheldonh * $Id: rq.c,v 1.7 2001/04/16 04:33:01 bp Exp $ 33132752Skan * $FreeBSD: releng/10.3/contrib/smbfs/lib/smb/rq.c 282275 2015-04-30 16:08:47Z tijl $ 3487866Ssheldonh */ 3587866Ssheldonh#include <sys/param.h> 3687866Ssheldonh#include <sys/ioctl.h> 3787866Ssheldonh#include <sys/errno.h> 3887866Ssheldonh#include <sys/stat.h> 3987866Ssheldonh#include <ctype.h> 4087866Ssheldonh#include <err.h> 4187866Ssheldonh#include <stdio.h> 4287866Ssheldonh#include <unistd.h> 43136700Sobrien#include <string.h> 4487866Ssheldonh#include <stdlib.h> 4587866Ssheldonh#include <sysexits.h> 4687866Ssheldonh 4787866Ssheldonh#include <sys/mchain.h> 4887866Ssheldonh 4987866Ssheldonh#include <netsmb/smb_lib.h> 5087866Ssheldonh#include <netsmb/smb_conn.h> 5187866Ssheldonh#include <netsmb/smb_rap.h> 5287866Ssheldonh 5387866Ssheldonh 5487866Ssheldonhint 5587866Ssheldonhsmb_rq_init(struct smb_ctx *ctx, u_char cmd, size_t rpbufsz, struct smb_rq **rqpp) 5687866Ssheldonh{ 5787866Ssheldonh struct smb_rq *rqp; 5887866Ssheldonh 5987866Ssheldonh rqp = malloc(sizeof(*rqp)); 6087866Ssheldonh if (rqp == NULL) 6187866Ssheldonh return ENOMEM; 6287866Ssheldonh bzero(rqp, sizeof(*rqp)); 6387866Ssheldonh rqp->rq_cmd = cmd; 6487866Ssheldonh rqp->rq_ctx = ctx; 6587866Ssheldonh mb_init(&rqp->rq_rq, M_MINSIZE); 6687866Ssheldonh mb_init(&rqp->rq_rp, rpbufsz); 6787866Ssheldonh *rqpp = rqp; 6887866Ssheldonh return 0; 6987866Ssheldonh} 7087866Ssheldonh 7187866Ssheldonhvoid 7287866Ssheldonhsmb_rq_done(struct smb_rq *rqp) 7387866Ssheldonh{ 7487866Ssheldonh mb_done(&rqp->rq_rp); 7587866Ssheldonh mb_done(&rqp->rq_rq); 7687866Ssheldonh free(rqp); 7787866Ssheldonh} 7887866Ssheldonh 7987866Ssheldonhvoid 8087866Ssheldonhsmb_rq_wend(struct smb_rq *rqp) 8187866Ssheldonh{ 8287866Ssheldonh if (rqp->rq_rq.mb_count & 1) 8387866Ssheldonh smb_error("smbrq_wend: odd word count\n", 0); 8487866Ssheldonh rqp->rq_wcount = rqp->rq_rq.mb_count / 2; 8587866Ssheldonh rqp->rq_rq.mb_count = 0; 8687866Ssheldonh} 8787866Ssheldonh 8887866Ssheldonhint 89282275Stijlsmb_rq_dmem(struct mbdata *mbp, char *src, size_t size) 9087866Ssheldonh{ 9187866Ssheldonh struct mbuf *m; 9287866Ssheldonh char * dst; 9387866Ssheldonh int cplen, error; 9487866Ssheldonh 9587866Ssheldonh if (size == 0) 9687866Ssheldonh return 0; 9787866Ssheldonh m = mbp->mb_cur; 9887866Ssheldonh if ((error = m_getm(m, size, &m)) != 0) 9987866Ssheldonh return error; 10087866Ssheldonh while (size > 0) { 10187866Ssheldonh cplen = M_TRAILINGSPACE(m); 10287866Ssheldonh if (cplen == 0) { 10387866Ssheldonh m = m->m_next; 10487866Ssheldonh continue; 10587866Ssheldonh } 10687866Ssheldonh if (cplen > (int)size) 10787866Ssheldonh cplen = size; 10887866Ssheldonh dst = mtod(m, char *) + m->m_len; 10987866Ssheldonh nls_mem_toext(dst, src, cplen); 11087866Ssheldonh size -= cplen; 11187866Ssheldonh src += cplen; 11287866Ssheldonh m->m_len += cplen; 11387866Ssheldonh mbp->mb_count += cplen; 11487866Ssheldonh } 11587866Ssheldonh mbp->mb_pos = mtod(m, char *) + m->m_len; 11687866Ssheldonh mbp->mb_cur = m; 11787866Ssheldonh return 0; 11887866Ssheldonh} 11987866Ssheldonh 12087866Ssheldonhint 121282275Stijlsmb_rq_dstring(struct mbdata *mbp, char *s) 12287866Ssheldonh{ 12387866Ssheldonh return smb_rq_dmem(mbp, s, strlen(s) + 1); 12487866Ssheldonh} 12587866Ssheldonh 12687866Ssheldonhint 12787866Ssheldonhsmb_rq_simple(struct smb_rq *rqp) 12887866Ssheldonh{ 12987866Ssheldonh struct smbioc_rq krq; 13087866Ssheldonh struct mbdata *mbp; 13187866Ssheldonh char *data; 13287866Ssheldonh 13387866Ssheldonh mbp = smb_rq_getrequest(rqp); 13487866Ssheldonh m_lineup(mbp->mb_top, &mbp->mb_top); 13587866Ssheldonh data = mtod(mbp->mb_top, char*); 13687866Ssheldonh bzero(&krq, sizeof(krq)); 13787866Ssheldonh krq.ioc_cmd = rqp->rq_cmd; 13887866Ssheldonh krq.ioc_twc = rqp->rq_wcount; 13987866Ssheldonh krq.ioc_twords = data; 14087866Ssheldonh krq.ioc_tbc = mbp->mb_count; 14187866Ssheldonh krq.ioc_tbytes = data + rqp->rq_wcount * 2; 14287866Ssheldonh mbp = smb_rq_getreply(rqp); 14387866Ssheldonh krq.ioc_rpbufsz = mbp->mb_top->m_maxlen; 14487866Ssheldonh krq.ioc_rpbuf = mtod(mbp->mb_top, char *); 14587866Ssheldonh if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) 14687866Ssheldonh return errno; 14787866Ssheldonh mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc; 14887866Ssheldonh rqp->rq_wcount = krq.ioc_rwc; 14987866Ssheldonh rqp->rq_bcount = krq.ioc_rbc; 15087866Ssheldonh return 0; 15187866Ssheldonh} 15287866Ssheldonh 15387866Ssheldonhint 15487866Ssheldonhsmb_t2_request(struct smb_ctx *ctx, int setup, int setupcount, 15587866Ssheldonh const char *name, 15687866Ssheldonh int tparamcnt, void *tparam, 15787866Ssheldonh int tdatacnt, void *tdata, 15887866Ssheldonh int *rparamcnt, void *rparam, 15987866Ssheldonh int *rdatacnt, void *rdata) 16087866Ssheldonh{ 16187866Ssheldonh struct smbioc_t2rq krq; 16287866Ssheldonh 16387866Ssheldonh bzero(&krq, sizeof(krq)); 16487866Ssheldonh krq.ioc_setup[0] = setup; 16587866Ssheldonh krq.ioc_setupcnt = setupcount; 166132752Skan krq.ioc_name = (char *)name; 16787866Ssheldonh krq.ioc_tparamcnt = tparamcnt; 16887866Ssheldonh krq.ioc_tparam = tparam; 16987866Ssheldonh krq.ioc_tdatacnt = tdatacnt; 17087866Ssheldonh krq.ioc_tdata = tdata; 17187866Ssheldonh krq.ioc_rparamcnt = *rparamcnt; 17287866Ssheldonh krq.ioc_rparam = rparam; 17387866Ssheldonh krq.ioc_rdatacnt = *rdatacnt; 17487866Ssheldonh krq.ioc_rdata = rdata; 17587866Ssheldonh if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, &krq) == -1) 17687866Ssheldonh return errno; 17787866Ssheldonh *rparamcnt = krq.ioc_rparamcnt; 17887866Ssheldonh *rdatacnt = krq.ioc_rdatacnt; 17987866Ssheldonh return 0; 18087866Ssheldonh} 181