2 * Copyright (c) 2000-2001 Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
32 * $Id: smb_trantcp.c,v 1.39 2005/03/02 01:27:44 lindak Exp $
35 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
36 * Use is subject to license terms.
37 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/autoconf.h>
43 #include <sys/sysmacros.h>
44 #include <sys/sunddi.h>
47 #include <sys/protosw.h>
48 #include <sys/socket.h>
50 #include <sys/stream.h>
51 #include <sys/strsubr.h>
52 #include <sys/strsun.h>
53 #include <sys/stropts.h>
54 #include <sys/cmn_err.h>
55 #include <sys/tihdr.h>
56 #include <sys/tiuser.h>
57 #include <sys/t_kuser.h>
61 #include <net/route.h>
63 #include <netinet/in.h>
64 #include <netinet/tcp.h>
66 #include <netsmb/smb_osdep.h>
67 #include <netsmb/mchain.h>
68 #include <netsmb/netbios.h>
70 #include <netsmb/smb.h>
71 #include <netsmb/smb_conn.h>
72 #include <netsmb/smb_subr.h>
73 #include <netsmb/smb_tran.h>
74 #include <netsmb/smb_trantcp.h>
77 * SMB messages are up to 64K.
78 * Let's leave room for two.
80 static int smb_tcpsndbuf
= 0x20000;
81 static int smb_tcprcvbuf
= 0x20000;
83 static int nb_disconnect(struct nbpcb
*nbp
);
87 * Get mblks into *mpp until the data length is at least mlen.
88 * Note that *mpp may already contain a fragment.
90 * If we ever have to wait more than 15 sec. to read a message,
91 * return ETIME. (Caller will declare the VD dead.)
94 nb_getmsg_mlen(struct nbpcb
*nbp
, mblk_t
**mpp
, size_t mlen
)
97 union T_primitives
*pptr
;
99 int events
, fmode
, timo
, waitflg
;
102 /* We should be the only reader. */
103 ASSERT(nbp
->nbp_flags
& NBF_RECVLOCK
);
104 /* nbp->nbp_tiptr checked by caller */
107 * Get the first message (fragment) if
108 * we don't already have a left-over.
110 dlen
= msgdsize(*mpp
); /* *mpp==null is OK */
111 while (dlen
< mlen
) {
114 * I think we still want this to return ETIME
115 * if nothing arrives for SMB_NBTIMO (15) sec.
116 * so we can report "server not responding".
117 * We _could_ just block here now that our
118 * IOD is just a reader.
121 /* Wait with timeout... */
124 timo
= SEC_TO_TICK(SMB_NBTIMO
);
125 error
= t_kspoll(nbp
->nbp_tiptr
, timo
, waitflg
, &events
);
126 if (!error
&& !events
)
130 /* file mode for recv is: */
131 fmode
= FNDELAY
; /* non-blocking */
133 fmode
= 0; /* normal (blocking) */
136 /* Get some more... */
138 error
= tli_recv(nbp
->nbp_tiptr
, &tm
, fmode
);
145 * Normally get M_DATA messages here,
146 * but have to check for other types.
148 switch (tm
->b_datap
->db_type
) {
154 pptr
= (union T_primitives
*)tm
->b_rptr
;
155 switch (pptr
->type
) {
157 /* remove 1st mblk, keep the rest. */
164 /* Peer disconnected. */
165 NBDEBUG("T_DISCON_IND: reason=%d",
166 pptr
->discon_ind
.DISCON_reason
);
169 /* Peer disconnecting. */
170 NBDEBUG("T_ORDREL_IND");
173 switch (pptr
->ok_ack
.CORRECT_prim
) {
175 NBDEBUG("T_OK_ACK/T_DISCON_REQ");
178 NBDEBUG("T_OK_ACK/prim=%d",
179 pptr
->ok_ack
.CORRECT_prim
);
183 NBDEBUG("M_PROTO/type=%d", pptr
->type
);
186 break; /* M_PROTO, M_PCPROTO */
189 NBDEBUG("unexpected msg type=%d",
190 tm
->b_datap
->db_type
);
194 * The connection is no longer usable.
195 * Drop this message and disconnect.
197 * Note: nb_disconnect only does t_snddis
198 * on the first call, but does important
199 * cleanup and state change on any call.
202 (void) nb_disconnect(nbp
);
207 * If we have a data message, append it to
208 * the previous chunk(s) and update dlen
216 for (im
= *mpp
; im
->b_cont
; im
= im
->b_cont
)
220 dlen
+= msgdsize(tm
);
227 * Send a T_DISCON_REQ (disconnect)
230 nb_snddis(struct nbpcb
*nbp
)
232 TIUSER
*tiptr
= nbp
->nbp_tiptr
;
233 cred_t
*cr
= nbp
->nbp_cred
;
235 struct T_discon_req
*dreq
;
238 ASSERT(MUTEX_HELD(&nbp
->nbp_lock
));
243 mlen
= sizeof (struct T_discon_req
);
244 if (!(mp
= allocb_cred_wait(mlen
, STR_NOSIG
, &error
, cr
, NOPID
)))
247 mp
->b_datap
->db_type
= M_PROTO
;
249 dreq
= (struct T_discon_req
*)mp
->b_wptr
;
250 dreq
->PRIM_type
= T_DISCON_REQ
;
251 dreq
->SEQ_number
= -1;
252 mp
->b_wptr
+= sizeof (struct T_discon_req
);
254 error
= tli_send(tiptr
, mp
, tiptr
->fp
->f_flag
);
256 * There is an OK/ACK response expected, which is
257 * either handled by our receiver thread, or just
258 * discarded if we're closing this endpoint.
265 * Stuff the NetBIOS header into space already prepended.
268 nb_sethdr(mblk_t
*m
, uint8_t type
, uint32_t len
)
276 p
= (uint32_t *)m
->b_rptr
;
281 * Wait for up to 15 sec. for the next packet.
282 * Often return ETIME and do nothing else.
283 * When a packet header is available, check
284 * the header and get the length, but don't
285 * consume it. No side effects here except
286 * for the pullupmsg call.
289 nbssn_peekhdr(struct nbpcb
*nbp
, size_t *lenp
, uint8_t *rpcodep
)
295 * Get the first message (fragment) if
296 * we don't already have a left-over.
298 error
= nb_getmsg_mlen(nbp
, &nbp
->nbp_frag
, sizeof (len
));
302 if (!pullupmsg(nbp
->nbp_frag
, sizeof (len
)))
306 * Check the NetBIOS header.
307 * (NOT consumed here)
310 hdr
= (uint32_t *)nbp
->nbp_frag
->b_rptr
;
313 if ((len
>> 16) & 0xFE) {
314 NBDEBUG("bad nb header received 0x%x (MBZ flag set)\n", len
);
317 *rpcodep
= (len
>> 24) & 0xFF;
324 case NB_SSN_KEEPALIVE
:
327 NBDEBUG("bad nb header received 0x%x (bogus type)\n", len
);
331 if (len
> NB_MAXPKTLEN
) {
332 NBDEBUG("packet too long (%d)\n", len
);
340 * Receive a NetBIOS message. This may block to wait for the entire
341 * message to arrive. The caller knows there is (or should be) a
342 * message to be read. When we receive and drop a keepalive or
343 * zero-length message, return EAGAIN so the caller knows that
344 * something was received. This avoids false triggering of the
345 * "server not responding" state machine.
347 * Calls to this are serialized at a higher level.
350 nbssn_recv(struct nbpcb
*nbp
, mblk_t
**mpp
, int *lenp
,
358 /* We should be the only reader. */
359 ASSERT(nbp
->nbp_flags
& NBF_RECVLOCK
);
361 if (nbp
->nbp_tiptr
== NULL
)
365 NBDEBUG("*mpp not 0 - leak?");
372 * Get the NetBIOS header (not consumed yet)
374 error
= nbssn_peekhdr(nbp
, &len
, &rpcode
);
377 NBDEBUG("peekhdr, error=%d\n", error
);
380 NBDEBUG("Have pkt, type=0x%x len=0x%x\n",
381 (int)rpcode
, (int)len
);
384 * Block here waiting for the whole packet to arrive.
385 * If we get a timeout, return without side effects.
386 * The data length we wait for here includes both the
387 * NetBIOS header and the payload.
389 error
= nb_getmsg_mlen(nbp
, &nbp
->nbp_frag
, len
+ 4);
391 NBDEBUG("getmsg(body), error=%d\n", error
);
396 * We now have an entire NetBIOS message.
397 * Trim off the NetBIOS header and consume it.
398 * Note: _peekhdr has done pullupmsg for us,
399 * so we know it's safe to advance b_rptr.
405 * There may be more data after the message
406 * we're about to return, in which case we
407 * split it and leave the remainder.
411 nbp
->nbp_frag
= NULL
;
413 nbp
->nbp_frag
= m_split(m0
, len
, 1);
415 if (nbp
->nbp_state
!= NBST_SESSION
) {
417 * No session is established.
418 * Return whatever packet we got.
424 * A session is established; the only packets
425 * we should see are session message and
426 * keep-alive packets. Drop anything else.
430 case NB_SSN_KEEPALIVE
:
432 * It's a keepalive. Discard any data in it
433 * (there's not supposed to be any, but that
434 * doesn't mean some server won't send some)
437 NBDEBUG("Keepalive with data %d\n", (int)len
);
443 * Session message. Does it have any data?
447 * No data - treat as keepalive (drop).
453 * Yes, has data. Return it.
460 * Drop anything else.
462 NBDEBUG("non-session packet %x\n", rpcode
);
483 * SMB transport interface
485 * This is called only by the thread creating this endpoint,
486 * so we're single-threaded here.
490 smb_nbst_create(struct smb_vc
*vcp
, cred_t
*cr
)
494 nbp
= kmem_zalloc(sizeof (struct nbpcb
), KM_SLEEP
);
496 nbp
->nbp_timo
.tv_sec
= SMB_NBTIMO
;
497 nbp
->nbp_state
= NBST_CLOSED
; /* really IDLE */
499 nbp
->nbp_sndbuf
= smb_tcpsndbuf
;
500 nbp
->nbp_rcvbuf
= smb_tcprcvbuf
;
503 mutex_init(&nbp
->nbp_lock
, NULL
, MUTEX_DRIVER
, NULL
);
510 * destroy a transport endpoint
512 * This is called only by the thread with the last reference
513 * to this endpoint, so we're single-threaded here.
516 smb_nbst_done(struct smb_vc
*vcp
)
518 struct nbpcb
*nbp
= vcp
->vc_tdata
;
522 vcp
->vc_tdata
= NULL
;
525 * Don't really need to disconnect here,
526 * because the close following will do it.
529 if (nbp
->nbp_flags
& NBF_CONNECTED
)
530 (void) nb_disconnect(nbp
);
532 (void) t_kclose(nbp
->nbp_tiptr
, 0);
534 smb_free_sockaddr((struct sockaddr
*)nbp
->nbp_laddr
);
536 smb_free_sockaddr((struct sockaddr
*)nbp
->nbp_paddr
);
538 crfree(nbp
->nbp_cred
);
539 mutex_destroy(&nbp
->nbp_lock
);
540 kmem_free(nbp
, sizeof (*nbp
));
545 * Loan a transport file pointer (from user space) to this
546 * IOD endpoint. There should be no other thread using this
547 * endpoint when we do this, but lock for consistency.
550 nb_loan_fp(struct nbpcb
*nbp
, struct file
*fp
, cred_t
*cr
)
555 err
= t_kopen(fp
, 0, 0, &tiptr
, cr
);
559 mutex_enter(&nbp
->nbp_lock
);
561 nbp
->nbp_tiptr
= tiptr
;
562 nbp
->nbp_fmode
= tiptr
->fp
->f_flag
;
563 nbp
->nbp_flags
|= NBF_CONNECTED
;
564 nbp
->nbp_state
= NBST_SESSION
;
566 mutex_exit(&nbp
->nbp_lock
);
572 * Take back the transport file pointer we previously loaned.
573 * It's possible there may be another thread in here, so let
574 * others get out of the way before we pull the rug out.
576 * Some notes about the locking here: The higher-level IOD code
577 * serializes activity such that at most one reader and writer
578 * thread can be active in this code (and possibly both).
579 * Keeping nbp_lock held during the activities of these two
580 * threads would lead to the possibility of nbp_lock being
581 * held by a blocked thread, so this instead sets one of the
582 * flags (NBF_SENDLOCK | NBF_RECVLOCK) when a sender or a
583 * receiver is active (respectively). Lastly, tear-down is
584 * the only tricky bit (here) where we must wait for any of
585 * these activities to get out of current calls so they will
586 * notice that we've turned off the NBF_CONNECTED flag.
589 nb_unloan_fp(struct nbpcb
*nbp
)
592 mutex_enter(&nbp
->nbp_lock
);
594 nbp
->nbp_flags
&= ~NBF_CONNECTED
;
595 while (nbp
->nbp_flags
& (NBF_SENDLOCK
| NBF_RECVLOCK
)) {
596 nbp
->nbp_flags
|= NBF_LOCKWAIT
;
597 cv_wait(&nbp
->nbp_cv
, &nbp
->nbp_lock
);
599 if (nbp
->nbp_frag
!= NULL
) {
600 freemsg(nbp
->nbp_frag
);
601 nbp
->nbp_frag
= NULL
;
603 if (nbp
->nbp_tiptr
!= NULL
) {
604 (void) t_kclose(nbp
->nbp_tiptr
, 0);
605 nbp
->nbp_tiptr
= NULL
;
607 nbp
->nbp_state
= NBST_CLOSED
;
609 mutex_exit(&nbp
->nbp_lock
);
613 smb_nbst_loan_fp(struct smb_vc
*vcp
, struct file
*fp
, cred_t
*cr
)
615 struct nbpcb
*nbp
= vcp
->vc_tdata
;
619 * Un-loan the existing one, if any.
621 (void) nb_disconnect(nbp
);
625 * Loan the new one passed in.
628 error
= nb_loan_fp(nbp
, fp
, cr
);
636 smb_nbst_bind(struct smb_vc
*vcp
, struct sockaddr
*sap
)
643 smb_nbst_connect(struct smb_vc
*vcp
, struct sockaddr
*sap
)
650 smb_nbst_disconnect(struct smb_vc
*vcp
)
652 struct nbpcb
*nbp
= vcp
->vc_tdata
;
657 return (nb_disconnect(nbp
));
661 nb_disconnect(struct nbpcb
*nbp
)
665 mutex_enter(&nbp
->nbp_lock
);
667 if ((nbp
->nbp_flags
& NBF_CONNECTED
) != 0) {
668 nbp
->nbp_flags
&= ~NBF_CONNECTED
;
669 err
= nb_snddis(nbp
);
672 mutex_exit(&nbp
->nbp_lock
);
677 * Add the NetBIOS session header and send.
679 * Calls to this are serialized at a higher level.
682 nbssn_send(struct nbpcb
*nbp
, mblk_t
*m
)
688 /* We should be the only sender. */
689 ASSERT(nbp
->nbp_flags
& NBF_SENDLOCK
);
691 if (nbp
->nbp_tiptr
== NULL
) {
697 * Get the message length, which
698 * does NOT include the NetBIOS header
703 * Normally, mb_init() will have left space
704 * for us to prepend the NetBIOS header in
705 * the data block of the first mblk.
706 * However, we have to check in case other
707 * code did not leave this space, or if the
708 * message is from dupmsg (db_ref > 1)
710 * If don't find room in the first data block,
711 * we have to allocb a new message and link it
712 * on the front of the chain. We try not to
713 * do this becuase it's less efficient. Also,
714 * some network drivers will apparently send
715 * each mblk in the chain as separate frames.
716 * (That's arguably a driver bug.)
718 * Not bothering with allocb_cred_wait below
719 * because the message we're prepending to
720 * should already have a db_credp.
724 if (diff
== 4 && DB_REF(m
) == 1) {
725 /* We can use the first dblk. */
728 /* Link a new mblk on the head. */
732 m0
= allocb_wait(4, BPRI_LO
, STR_NOSIG
, &error
);
741 nb_sethdr(m
, NB_SSN_MESSAGE
, mlen
);
742 error
= tli_send(nbp
->nbp_tiptr
, m
, 0);
752 * Always consume the message.
756 smb_nbst_send(struct smb_vc
*vcp
, mblk_t
*m
)
758 struct nbpcb
*nbp
= vcp
->vc_tdata
;
761 mutex_enter(&nbp
->nbp_lock
);
762 if ((nbp
->nbp_flags
& NBF_CONNECTED
) == 0) {
766 if (nbp
->nbp_flags
& NBF_SENDLOCK
) {
767 NBDEBUG("multiple smb_nbst_send!\n");
771 nbp
->nbp_flags
|= NBF_SENDLOCK
;
772 mutex_exit(&nbp
->nbp_lock
);
774 err
= nbssn_send(nbp
, m
);
775 m
= NULL
; /* nbssn_send always consumes this */
777 mutex_enter(&nbp
->nbp_lock
);
778 nbp
->nbp_flags
&= ~NBF_SENDLOCK
;
779 if (nbp
->nbp_flags
& NBF_LOCKWAIT
) {
780 nbp
->nbp_flags
&= ~NBF_LOCKWAIT
;
781 cv_broadcast(&nbp
->nbp_cv
);
784 mutex_exit(&nbp
->nbp_lock
);
791 smb_nbst_recv(struct smb_vc
*vcp
, mblk_t
**mpp
)
793 struct nbpcb
*nbp
= vcp
->vc_tdata
;
797 mutex_enter(&nbp
->nbp_lock
);
798 if ((nbp
->nbp_flags
& NBF_CONNECTED
) == 0) {
802 if (nbp
->nbp_flags
& NBF_RECVLOCK
) {
803 NBDEBUG("multiple smb_nbst_recv!\n");
807 nbp
->nbp_flags
|= NBF_RECVLOCK
;
808 mutex_exit(&nbp
->nbp_lock
);
810 err
= nbssn_recv(nbp
, mpp
, &rplen
, &rpcode
);
812 mutex_enter(&nbp
->nbp_lock
);
813 nbp
->nbp_flags
&= ~NBF_RECVLOCK
;
814 if (nbp
->nbp_flags
& NBF_LOCKWAIT
) {
815 nbp
->nbp_flags
&= ~NBF_LOCKWAIT
;
816 cv_broadcast(&nbp
->nbp_cv
);
819 mutex_exit(&nbp
->nbp_lock
);
824 * Wait for up to "ticks" clock ticks for input on vcp.
825 * Returns zero if input is available, otherwise ETIME
826 * indicating time expired, or other error codes.
830 smb_nbst_poll(struct smb_vc
*vcp
, int ticks
)
836 smb_nbst_getparam(struct smb_vc
*vcp
, int param
, void *data
)
838 struct nbpcb
*nbp
= vcp
->vc_tdata
;
842 *(int *)data
= nbp
->nbp_sndbuf
;
845 *(int *)data
= nbp
->nbp_rcvbuf
;
848 *(struct timespec
*)data
= nbp
->nbp_timo
;
850 #ifdef SMBTP_SELECTID
852 *(void **)data
= nbp
->nbp_selectid
;
857 *(void **)data
= nbp
->nbp_upcall
;
868 smb_nbst_setparam(struct smb_vc
*vcp
, int param
, void *data
)
874 * Check for fatal errors
878 smb_nbst_fatal(struct smb_vc
*vcp
, int error
)
891 struct smb_tran_desc smb_tran_nbtcp_desc
= {