4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000-2001 Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1. Redistributions of source code must retain the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2. Redistributions in binary form must reproduce the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * documentation and/or other materials provided with the distribution.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3. All advertising materials mentioning features or use of this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * must display the following acknowledgement:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This product includes software developed by Boris Popov.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 4. Neither the name of the author nor the names of any co-contributors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * may be used to endorse or promote products derived from this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * without specific prior written permission.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SUCH DAMAGE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * $Id: smb_trantcp.c,v 1.39 2005/03/02 01:27:44 lindak Exp $
de8c4a14ec9a49bad5e62b2cfa6c1ba21de1c708Erik Nordmark * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
22eb7cb54d8a6bcf6fe2674cb4b1f0cf2d85cfb6gd * Use is subject to license terms.
3ce9ce383e93f64f4baed13c5a0a28d7a5f1b71eBayard Bell * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SMB messages are up to 64K.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Let's leave room for two.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Get mblks into *mpp until the data length is at least mlen.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note that *mpp may already contain a fragment.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If we ever have to wait more than 15 sec. to read a message,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * return ETIME. (Caller will declare the VD dead.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlownb_getmsg_mlen(struct nbpcb *nbp, mblk_t **mpp, size_t mlen)
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross /* We should be the only reader. */
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross /* nbp->nbp_tiptr checked by caller */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Get the first message (fragment) if
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we don't already have a left-over.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * I think we still want this to return ETIME
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * if nothing arrives for SMB_NBTIMO (15) sec.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * so we can report "server not responding".
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We _could_ just block here now that our
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IOD is just a reader.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Wait with timeout... */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = t_kspoll(nbp->nbp_tiptr, timo, waitflg, &events);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* file mode for recv is: */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Get some more... */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Normally get M_DATA messages here,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * but have to check for other types.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* remove 1st mblk, keep the rest. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Peer disconnected. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Peer disconnecting. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break; /* M_PROTO, M_PCPROTO */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*FALLTHROUGH*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The connection is no longer usable.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Drop this message and disconnect.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: nb_disconnect only does t_snddis
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * on the first call, but does important
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * cleanup and state change on any call.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If we have a data message, append it to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the previous chunk(s) and update dlen
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Append */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Send a T_DISCON_REQ (disconnect)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (!(mp = allocb_cred_wait(mlen, STR_NOSIG, &error, cr, NOPID)))
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * There is an OK/ACK response expected, which is
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * either handled by our receiver thread, or just
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * discarded if we're closing this endpoint.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Stuff the NetBIOS header into space already prepended.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Wait for up to 15 sec. for the next packet.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Often return ETIME and do nothing else.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * When a packet header is available, check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the header and get the length, but don't
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * consume it. No side effects here except
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * for the pullupmsg call.
4bff34e37def8a90f9194d81bc345c52ba20086athurlownbssn_peekhdr(struct nbpcb *nbp, size_t *lenp, uint8_t *rpcodep)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Get the first message (fragment) if
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we don't already have a left-over.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = nb_getmsg_mlen(nbp, &nbp->nbp_frag, sizeof (len));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Check the NetBIOS header.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (NOT consumed here)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NBDEBUG("bad nb header received 0x%x (MBZ flag set)\n", len);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NBDEBUG("bad nb header received 0x%x (bogus type)\n", len);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Receive a NetBIOS message. This may block to wait for the entire
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * message to arrive. The caller knows there is (or should be) a
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * message to be read. When we receive and drop a keepalive or
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * zero-length message, return EAGAIN so the caller knows that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * something was received. This avoids false triggering of the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * "server not responding" state machine.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Calls to this are serialized at a higher level.
4bff34e37def8a90f9194d81bc345c52ba20086athurlownbssn_recv(struct nbpcb *nbp, mblk_t **mpp, int *lenp,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* We should be the only reader. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Get the NetBIOS header (not consumed yet)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Block here waiting for the whole packet to arrive.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If we get a timeout, return without side effects.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The data length we wait for here includes both the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * NetBIOS header and the payload.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = nb_getmsg_mlen(nbp, &nbp->nbp_frag, len + 4);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We now have an entire NetBIOS message.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Trim off the NetBIOS header and consume it.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: _peekhdr has done pullupmsg for us,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * so we know it's safe to advance b_rptr.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * There may be more data after the message
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we're about to return, in which case we
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * split it and leave the remainder.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No session is established.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Return whatever packet we got.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * A session is established; the only packets
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we should see are session message and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * keep-alive packets. Drop anything else.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * It's a keepalive. Discard any data in it
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (there's not supposed to be any, but that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * doesn't mean some server won't send some)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Session message. Does it have any data?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (len == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No data - treat as keepalive (drop).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Yes, has data. Return it.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Drop anything else.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SMB transport interface
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * This is called only by the thread creating this endpoint,
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * so we're single-threaded here.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mutex_init(&nbp->nbp_lock, NULL, MUTEX_DRIVER, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * destroy a transport endpoint
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * This is called only by the thread with the last reference
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * to this endpoint, so we're single-threaded here.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Don't really need to disconnect here,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * because the close following will do it.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * But it's harmless.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_free_sockaddr((struct sockaddr *)nbp->nbp_laddr);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_free_sockaddr((struct sockaddr *)nbp->nbp_paddr);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Loan a transport file pointer (from user space) to this
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * IOD endpoint. There should be no other thread using this
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * endpoint when we do this, but lock for consistency.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Rossnb_loan_fp(struct nbpcb *nbp, struct file *fp, cred_t *cr)
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Take back the transport file pointer we previously loaned.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * It's possible there may be another thread in here, so let
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * others get out of the way before we pull the rug out.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Some notes about the locking here: The higher-level IOD code
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * serializes activity such that at most one reader and writer
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * thread can be active in this code (and possibly both).
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Keeping nbp_lock held during the activities of these two
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * threads would lead to the possibility of nbp_lock being
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * held by a blocked thread, so this instead sets one of the
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * flags (NBF_SENDLOCK | NBF_RECVLOCK) when a sender or a
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * receiver is active (respectively). Lastly, tear-down is
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * the only tricky bit (here) where we must wait for any of
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * these activities to get out of current calls so they will
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * notice that we've turned off the NBF_CONNECTED flag.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross while (nbp->nbp_flags & (NBF_SENDLOCK | NBF_RECVLOCK)) {
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Rosssmb_nbst_loan_fp(struct smb_vc *vcp, struct file *fp, cred_t *cr)
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Un-loan the existing one, if any.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Loan the new one passed in.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_nbst_bind(struct smb_vc *vcp, struct sockaddr *sap)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_nbst_connect(struct smb_vc *vcp, struct sockaddr *sap)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Add the NetBIOS session header and send.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Calls to this are serialized at a higher level.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross /* We should be the only sender. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Get the message length, which
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * does NOT include the NetBIOS header
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Normally, mb_init() will have left space
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * for us to prepend the NetBIOS header in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the data block of the first mblk.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * However, we have to check in case other
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * code did not leave this space, or if the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * message is from dupmsg (db_ref > 1)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If don't find room in the first data block,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * we have to allocb a new message and link it
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * on the front of the chain. We try not to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * do this becuase it's less efficient. Also,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * some network drivers will apparently send
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * each mblk in the chain as separate frames.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (That's arguably a driver bug.)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Not bothering with allocb_cred_wait below
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * because the message we're prepending to
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * should already have a db_credp.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* We can use the first dblk. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Link a new mblk on the head. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* M_PREPEND */
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * Always consume the message.
3d804dabd641ca3bac12a320ebf63c36c6f3eba0Gordon Ross * (On error too!)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Wait for up to "ticks" clock ticks for input on vcp.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Returns zero if input is available, otherwise ETIME
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * indicating time expired, or other error codes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_nbst_getparam(struct smb_vc *vcp, int param, void *data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_nbst_setparam(struct smb_vc *vcp, int param, void *data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Check for fatal errors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);