1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
/*
* Copyright (c) 2000-2001, Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: smb_rq.h,v 1.9 2005/01/22 22:20:58 lindak Exp $
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Portions Copyright (C) 2001 - 2012 Apple Inc. All rights reserved.
* Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NETSMB_SMB_RQ_H_
#define _NETSMB_SMB_RQ_H_
#include <netsmb/mchain.h>
#include <sys/queue.h>
#define SMBR_ALLOCED 0x0001 /* structure was malloced */
#define SMBR_SENT 0x0002 /* request successfully transmitted */
#define SMBR_REXMIT 0x0004 /* request should be retransmitted */
#define SMBR_INTR 0x0008 /* request interrupted */
#define SMBR_RESTART 0x0010 /* req should be repeated if possible */
#define SMBR_NORESTART 0x0020 /* request is not restartable */
#define SMBR_MULTIPACKET 0x0040 /* multiple pkts can be sent/received */
#define SMBR_INTERNAL 0x0080 /* request enqueued by the IOD! */
#define SMBR_NOINTR_SEND 0x0100 /* no interrupt in send wait */
#define SMBR_NOINTR_RECV 0x0200 /* no interrupt in recv wait */
#define SMBR_SENDWAIT 0x0400 /* waiting for send to complete */
#define SMBR_NORECONNECT 0x0800 /* do not reconnect for this */
/* SMBR_VCREF 0x4000 * took vc reference (obsolete) */
#define SMBR_MOREDATA 0x8000 /* our buffer was too small */
#define SMBR_COMPOUND_RQ 0x10000 /* SMB 2/3 compound request */
#define SMBR_ASYNC 0x20000 /* got async response */
#define SMBR_RECONNECTED 0x40000 /* reconnected during request */
#define SMBT2_ALLSENT 0x0001 /* all data and params are sent */
#define SMBT2_ALLRECV 0x0002 /* all data and params are received */
#define SMBT2_ALLOCED 0x0004
#define SMBT2_RESTART 0x0008
#define SMBT2_NORESTART 0x0010
#define SMBT2_MOREDATA 0x8000 /* our buffer was too small */
#define SMBRQ_LOCK(rqp) mutex_enter(&(rqp)->sr_lock)
#define SMBRQ_UNLOCK(rqp) mutex_exit(&(rqp)->sr_lock)
enum smbrq_state {
SMBRQ_NOTSENT, /* rq have data to send */
SMBRQ_SENT, /* send procedure completed */
SMBRQ_REPLYRECEIVED,
SMBRQ_NOTIFIED /* owner notified about completion */
};
struct smb_vc;
struct smb_rq {
TAILQ_ENTRY(smb_rq) sr_link;
kmutex_t sr_lock;
kcondvar_t sr_cond;
enum smbrq_state sr_state;
struct smb_vc *sr_vc;
struct smb_share *sr_share;
struct _kthread *sr_owner;
uint32_t sr_seqno; /* Seq. no. of request */
uint32_t sr_rseqno; /* Seq. no. of reply */
struct mbchain sr_rq;
uchar_t sr_cmd;
uint8_t sr_rqflags;
uint16_t sr_rqflags2;
uint16_t sr_rqtid;
uint32_t sr_pid;
uint16_t sr_rquid;
uint16_t sr_mid;
uchar_t *sr_wcount;
uchar_t *sr_bcount;
/* SMB 2/3 request fields */
struct smb_rq *sr2_compound_next;
uint16_t sr2_command;
uint16_t sr2_totalcreditcharge;
uint16_t sr2_creditcharge;
uint16_t sr2_creditsrequested;
uint32_t sr2_rqflags;
uint32_t sr2_nextcmd;
uint64_t sr2_messageid; /* local copy of message id */
uint64_t sr2_rqsessionid;
uint32_t sr2_rqtreeid;
struct mdchain sr_rp;
int sr_rpgen;
int sr_rplast;
int sr_flags; /* SMBR_* */
int sr_rpsize;
struct smb_cred *sr_cred;
int sr_timo;
int sr_rexmit; /* how many more retries. dflt 0 */
int sr_sendcnt;
struct timespec sr_timesent;
int sr_lerror;
uint8_t sr_errclass;
uint16_t sr_serror;
uint32_t sr_error;
uint8_t sr_rpflags;
uint16_t sr_rpflags2;
uint16_t sr_rptid;
uint16_t sr_rppid;
uint16_t sr_rpuid;
uint16_t sr_rpmid;
/* SMB2 response fields */
uint16_t sr2_rspcreditsgranted;
uint32_t sr2_rspflags;
uint32_t sr2_rspnextcmd;
uint32_t sr2_rsppid;
uint32_t sr2_rsptreeid;
uint64_t sr2_rspasyncid;
uint64_t sr2_rspsessionid;
};
typedef struct smb_rq smb_rq_t;
struct smb_t2rq {
kmutex_t t2_lock;
kcondvar_t t2_cond;
uint16_t t2_setupcount;
uint16_t *t2_setupdata;
uint16_t t2_setup[4];
uint8_t t2_maxscount; /* max setup words to return */
uint16_t t2_maxpcount; /* max param bytes to return */
uint16_t t2_maxdcount; /* max data bytes to return */
uint16_t t2_fid; /* for T2 request */
char *t_name; /* for T, must be NULL for T2 */
int t_name_len; /* t_name string length */
int t_name_maxlen; /* t_name allocated size */
int t2_flags; /* SMBT2_ */
struct mbchain t2_tparam; /* parameters to transmit */
struct mbchain t2_tdata; /* data to transmit */
struct mdchain t2_rparam; /* received paramters */
struct mdchain t2_rdata; /* received data */
struct smb_cred *t2_cred;
struct smb_connobj *t2_source;
struct smb_rq *t2_rq;
struct smb_vc *t2_vc;
struct smb_share *t2_share; /* for smb up/down */
/* unmapped windows error detail */
uint8_t t2_sr_errclass;
uint16_t t2_sr_serror;
uint32_t t2_sr_error;
uint16_t t2_sr_rpflags2;
};
typedef struct smb_t2rq smb_t2rq_t;
struct smb_ntrq {
kmutex_t nt_lock;
kcondvar_t nt_cond;
uint16_t nt_function;
uint8_t nt_maxscount; /* max setup words to return */
uint32_t nt_maxpcount; /* max param bytes to return */
uint32_t nt_maxdcount; /* max data bytes to return */
int nt_flags; /* SMBT2_ */
struct mbchain nt_tsetup; /* setup to transmit */
struct mbchain nt_tparam; /* parameters to transmit */
struct mbchain nt_tdata; /* data to transmit */
struct mdchain nt_rparam; /* received paramters */
struct mdchain nt_rdata; /* received data */
struct smb_cred *nt_cred;
struct smb_connobj *nt_source;
struct smb_rq *nt_rq;
struct smb_vc *nt_vc;
struct smb_share *nt_share; /* for smb up/down */
/* unmapped windows error details */
uint32_t nt_sr_error;
uint16_t nt_sr_rpflags2;
};
typedef struct smb_ntrq smb_ntrq_t;
#define smb_rq_getrequest(RQ, MBPP) \
*(MBPP) = &(RQ)->sr_rq
#define smb_rq_getreply(RQ, MDPP) \
*(MDPP) = &(RQ)->sr_rp
void smb_rq_done(struct smb_rq *rqp);
int smb_rq_alloc(struct smb_connobj *layer, uchar_t cmd,
struct smb_cred *scred, struct smb_rq **rqpp);
int smb_rq_init(struct smb_rq *rqp, struct smb_connobj *layer,
uchar_t cmd, struct smb_cred *scred);
int smb_rq_getenv(struct smb_connobj *layer,
struct smb_vc **vcpp, struct smb_share **sspp);
void smb_rq_fillhdr(struct smb_rq *rqp);
void smb_rq_wstart(struct smb_rq *rqp);
void smb_rq_wend(struct smb_rq *rqp);
void smb_rq_bstart(struct smb_rq *rqp);
void smb_rq_bend(struct smb_rq *rqp);
int smb_rq_simple(struct smb_rq *rqp);
int smb_rq_simple_timed(struct smb_rq *rqp, int timeout);
int smb_rq_internal(struct smb_rq *rqp, int timeout);
int smb2_parse_smb1nego_resp(struct smb_rq *rqp);
int smb_t2_alloc(struct smb_connobj *layer, ushort_t setup,
struct smb_cred *scred, struct smb_t2rq **rqpp);
int smb_t2_init(struct smb_t2rq *rqp, struct smb_connobj *layer,
ushort_t *setup, int setupcnt, struct smb_cred *scred);
void smb_t2_done(struct smb_t2rq *t2p);
int smb_t2_request(struct smb_t2rq *t2p);
int smb_t2_xnp(struct smb_share *ssp, uint16_t fid,
struct mbchain *send_mb, struct mdchain *recv_md,
uint32_t *data_out_sz, uint32_t *more, struct smb_cred *scrp);
int smb_nt_alloc(struct smb_connobj *layer, ushort_t fn,
struct smb_cred *scred, struct smb_ntrq **rqpp);
int smb_nt_init(struct smb_ntrq *rqp, struct smb_connobj *layer,
ushort_t fn, struct smb_cred *scred);
void smb_nt_done(struct smb_ntrq *ntp);
int smb_nt_request(struct smb_ntrq *ntp);
#endif /* _NETSMB_SMB_RQ_H_ */
|