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