1/* 2 * Copyright (c) 2000-2001, Boris Popov 3 * All rights reserved. 4 * 5 * Portions Copyright (C) 2001 - 2012 Apple Inc. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Boris Popov. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35#ifndef _NETSMB_SMB_RQ_H_ 36#define _NETSMB_SMB_RQ_H_ 37 38#include <sys/smb_byte_order.h> 39#include <sys/mchain.h> 40 41/* smb_rq sr_flags */ 42#define SMBR_ALLOCED 0x0001 /* structure was malloced */ 43#define SMBR_ASYNC 0x0002 /* This is async request, should never be set if SMBR_INTERNAL is set */ 44#define SMBR_REXMIT 0x0004 /* Request was retransmitted during a reconnect*/ 45#define SMBR_INTR 0x0008 /* request interrupted */ 46#define SMBR_RECONNECTED 0x0010 /* The message was handled during a reconnect */ 47#define SMBR_DEAD 0x0020 /* Network down nothing we can do with it. */ 48#define SMBR_MULTIPACKET 0x0040 /* multiple packets can be sent and received */ 49#define SMBR_INTERNAL 0x0080 /* request is internal to smbrqd runs off the main thread. */ 50#define SMBR_COMPOUND_RQ 0x0100 /* SMB 2/3 compound request */ 51#define SMBR_NO_TIMEOUT 0x0200 /* Do not timeout, long-running request (i.e. Mac-to-Mac COPYCHUNK IOCTL) */ 52 /* Note: we need to remove this in Sarah */ 53#define SMBR_SIGNED 0x0400 /* SMB 2/3 sign this packet */ 54#define SMBR_MOREDATA 0x8000 /* our buffer was too small */ 55 56/* smb_t2rq t2_flags and smb_ntrq nt_flags */ 57#define SMBT2_ALLSENT 0x0001 /* all data and params are sent */ 58#define SMBT2_ALLRECV 0x0002 /* all data and params are received */ 59#define SMBT2_ALLOCED 0x0004 60#define SMBT2_SECONDARY 0x0020 61#define SMBT2_MOREDATA 0x8000 /* our buffer was too small */ 62 63#define SMBRQ_SLOCK(rqp) lck_mtx_lock(&(rqp)->sr_slock) 64#define SMBRQ_SUNLOCK(rqp) lck_mtx_unlock(&(rqp)->sr_slock) 65#define SMBRQ_SLOCKPTR(rqp) (&(rqp)->sr_slock) 66 67/* Need to look at this and see why SMBRQ_NOTSENT must be zero? */ 68enum smbrq_state { 69 SMBRQ_NOTSENT = 0x00, /* rq have data to send */ 70 SMBRQ_SENT = 0x01, /* send procedure completed */ 71 SMBRQ_NOTIFIED = 0x04, /* owner notified about completion */ 72 SMBRQ_RECONNECT = 0x08 /* Reconnect hold till done */ 73}; 74 75struct smb_vc; 76 77#define MAX_SR_RECONNECT_CNT 5 78 79struct smb_rq { 80 struct smb_rq *sr_next_rqp; 81 enum smbrq_state sr_state; 82 struct smb_vc *sr_vc; 83 struct smb_share *sr_share; 84 uint32_t sr_reconnect_cnt; 85 86 /* SMB 2/3 fields */ 87 uint32_t sr_extflags; 88 uint16_t sr_command; 89 uint16_t sr_creditcharge; 90 uint16_t sr_creditsrequested; 91 uint32_t sr_rqflags; 92 uint32_t sr_nextcmd; 93 uint64_t sr_messageid; /* local copy of message id */ 94 uint64_t *sr_messageidp; /* filled in right before the send */ 95 uint32_t sr_rqtreeid; 96 uint64_t sr_rqsessionid; 97 uint16_t *sr_bcount; /* used every now and then for lengths */ 98 uint32_t *sr_lcount; /* used every now and then for lengths */ 99 uint16_t *sr_creditchargep; 100 uint16_t *sr_creditreqp; 101 uint32_t *sr_flagsp; 102 uint32_t *sr_nextcmdp; 103 104 /* response fields */ 105 uint16_t sr_rspcreditsgranted; 106 uint32_t sr_rspflags; 107 uint32_t sr_rspnextcmd; 108 uint32_t sr_rsppid; 109 uint32_t sr_rsptreeid; 110 uint64_t sr_rspasyncid; 111 uint64_t sr_rspsessionid; 112 113 /* SMB 1 fields */ 114 uint16_t sr_mid; 115 uint16_t sr_pidHigh; 116 uint16_t sr_pidLow; 117 uint8_t sr_cmd; 118 u_char *sr_wcount; 119 uint16_t *sr_rqtid; 120 uint16_t *sr_rquid; 121 122 /* response fields */ 123 uint8_t sr_rpflags; 124 uint16_t sr_rpflags2; 125 uint16_t sr_rptid; 126 uint16_t sr_rppidHigh; /* Currently never used, handle with macro */ 127 uint16_t sr_rppidLow; /* Currently never used, handle with macro */ 128 uint16_t sr_rpuid; 129 uint16_t sr_rpmid; /* Currently never used, handle with macro */ 130 131 /* Used by SMB 1 and SMB 2/3 */ 132 uint32_t sr_seqno; 133 uint32_t sr_rseqno; 134 struct mbchain sr_rq; 135 struct mdchain sr_rp; 136 uint8_t *sr_rqsig; 137 uint32_t sr_ntstatus; 138 139 /* %%% TO DO 140 * Finish sorting rest of these fields on whether they belong to SMB 1 or 141 * or SMB 2/3 or both. 142 */ 143 int sr_rpgen; 144 int sr_rplast; 145 uint32_t sr_flags; 146 int sr_rpsize; 147 vfs_context_t sr_context; 148 int sr_timo; 149 struct timespec sr_timesent; 150 thread_t sr_threadId; 151 int sr_lerror; 152 lck_mtx_t sr_slock; /* short term locks */ 153 struct smb_t2rq *sr_t2; 154 TAILQ_ENTRY(smb_rq) sr_link; 155 void *sr_callback_args; 156 void (*sr_callback)(void *); 157}; 158 159struct smb_t2rq { 160 uint16_t t2_setupcount; 161 uint16_t * t2_setupdata; 162 uint16_t t2_setup[SMB_MAXSETUPWORDS]; 163 uint8_t t2_maxscount; /* max setup words to return */ 164 uint16_t t2_maxpcount; /* max param bytes to return */ 165 uint16_t t2_maxdcount; /* max data bytes to return */ 166 uint16_t t2_fid; /* for T2 request */ 167 char * t_name; /* for T, should be zero for T2 */ 168 int t2_flags; /* SMBT2_ */ 169 struct mbchain t2_tparam; /* parameters to transmit */ 170 struct mbchain t2_tdata; /* data to transmit */ 171 struct mdchain t2_rparam; /* received paramters */ 172 struct mdchain t2_rdata; /* received data */ 173 vfs_context_t t2_context; 174 struct smb_connobj * t2_obj; 175 struct smb_rq * t2_rq; 176 struct smb_vc * t2_vc; 177 struct smb_share * t2_share; /* for smb up/down */ 178 /* unmapped windows error detail */ 179 uint32_t t2_ntstatus; 180 uint16_t t2_sr_rpflags2; 181}; 182 183struct smb_ntrq { 184 uint16_t nt_function; 185 uint8_t nt_maxscount; /* max setup words to return */ 186 uint32_t nt_maxpcount; /* max param bytes to return */ 187 uint32_t nt_maxdcount; /* max data bytes to return */ 188 int nt_flags; /* SMBT2_ */ 189 struct mbchain nt_tsetup; /* setup to transmit */ 190 struct mbchain nt_tparam; /* parameters to transmit */ 191 struct mbchain nt_tdata; /* data to transmit */ 192 struct mdchain nt_rparam; /* received paramters */ 193 struct mdchain nt_rdata; /* received data */ 194 vfs_context_t nt_context; 195 struct smb_connobj * nt_obj; 196 struct smb_rq * nt_rq; 197 struct smb_vc * nt_vc; 198 struct smb_share * nt_share; 199 /* unmapped windows error details */ 200 uint32_t nt_status; 201 uint16_t nt_sr_rpflags2; 202}; 203 204int smb_rq_alloc(struct smb_connobj *obj, u_char cmd, uint16_t flags2, 205 vfs_context_t context, struct smb_rq **rqpp); 206int smb_rq_init(struct smb_rq *rqp, struct smb_connobj *obj, u_char cmd, 207 uint16_t flags2, vfs_context_t context); 208void smb_rq_done(struct smb_rq *rqp); 209int smb_rq_getrequest(struct smb_rq *rqp, struct mbchain **mbpp); 210int smb_rq_getreply(struct smb_rq *rqp, struct mdchain **mbpp); 211void smb_rq_wstart(struct smb_rq *rqp); 212void smb_rq_wend(struct smb_rq *rqp); 213void smb_rq_bstart(struct smb_rq *rqp); 214void smb_rq_bend(struct smb_rq *rqp); 215int smb_rq_reply(struct smb_rq *rqp); 216int smb_rq_simple(struct smb_rq *rqp); 217int smb_rq_simple_timed(struct smb_rq *rqp, int timo); 218 219int smb_t2_init(struct smb_t2rq *t2p, struct smb_connobj *obj, u_short *setup, 220 int setupcnt, vfs_context_t context); 221int smb_t2_alloc(struct smb_connobj *obj, u_short setup, int setupcnt, 222 vfs_context_t context, struct smb_t2rq **t2pp); 223void smb_t2_done(struct smb_t2rq *t2p); 224int smb_t2_request(struct smb_t2rq *t2p); 225uint32_t smb_t2_err(struct smb_t2rq *t2p); 226 227int smb_nt_alloc(struct smb_connobj *obj, u_short fn, 228 vfs_context_t context, struct smb_ntrq **ntpp); 229void smb_nt_done(struct smb_ntrq *ntp); 230int smb_nt_request(struct smb_ntrq *ntp); 231int smb_nt_reply(struct smb_ntrq *ntp); 232int smb_nt_async_request(struct smb_ntrq *ntp, void *nt_callback, 233 void *nt_callback_args); 234 235#endif /* !_NETSMB_SMB_RQ_H_ */ 236