xref: /dragonfly/sys/netproto/smb/smb_trantcp.c (revision b272101acc636ac635f83d03265ef6a44a3ba51a)
1 /*
2  * Copyright (c) 2000-2001 Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
19  *
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
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/netsmb/smb_trantcp.c,v 1.3.2.1 2001/05/22 08:32:34 bp Exp $
33  */
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38 #include <sys/mbuf.h>
39 #include <sys/proc.h>
40 #include <sys/protosw.h>
41 #include <sys/resourcevar.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/socketvar2.h>
45 #include <sys/socketops.h>
46 #include <sys/poll.h>
47 #include <sys/uio.h>
48 #include <sys/fcntl.h>
49 #include <sys/sysctl.h>
50 #include <sys/thread2.h>
51 
52 #include <net/if.h>
53 #include <net/route.h>
54 
55 #include <netinet/in.h>
56 #include <netinet/tcp.h>
57 
58 #include <sys/mchain.h>
59 
60 #include "netbios.h"
61 
62 #include "smb.h"
63 #include "smb_conn.h"
64 #include "smb_tran.h"
65 #include "smb_trantcp.h"
66 #include "smb_subr.h"
67 
68 #define M_NBDATA    M_PCB
69 
70 static int smb_tcpsndbuf = 10 * 1024;
71 static int smb_tcprcvbuf = 10 * 1024;
72 
73 SYSCTL_DECL(_net_smb);
74 SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, "");
75 SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &smb_tcprcvbuf, 0, "");
76 
77 #define nb_sosend(so,m,flags,p)                                                 \
78     so_pru_sosend(so, NULL, NULL, m, NULL, flags, td)
79 
80 static int  nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
81           u_int8_t *rpcodep, struct thread *td);
82 static int  smb_nbst_disconnect(struct smb_vc *vcp, struct thread *td);
83 
84 static int
nb_setsockopt_int(struct socket * so,int level,int name,int val)85 nb_setsockopt_int(struct socket *so, int level, int name, int val)
86 {
87           struct sockopt sopt;
88 
89           bzero(&sopt, sizeof(sopt));
90           sopt.sopt_level = level;
91           sopt.sopt_name = name;
92           sopt.sopt_val = &val;
93           sopt.sopt_valsize = sizeof(val);
94           return sosetopt(so, &sopt);
95 }
96 
97 static int
nb_intr(struct nbpcb * nbp,struct thread * td)98 nb_intr(struct nbpcb *nbp, struct thread *td)
99 {
100           return 0;
101 }
102 
103 static void
nb_upcall(struct socket * so,void * arg,int waitflag)104 nb_upcall(struct socket *so, void *arg, int waitflag)
105 {
106           struct nbpcb *nbp = arg;
107 
108           if (arg == NULL || nbp->nbp_selectid == NULL)
109                     return;
110           wakeup(nbp->nbp_selectid);
111 }
112 
113 static int
nb_sethdr(struct mbuf * m,u_int8_t type,u_int32_t len)114 nb_sethdr(struct mbuf *m, u_int8_t type, u_int32_t len)
115 {
116           u_int32_t *p = mtod(m, u_int32_t *);
117 
118           *p = htonl((len & 0x1FFFF) | (type << 24));
119           return 0;
120 }
121 
122 static int
nb_put_name(struct mbchain * mbp,struct sockaddr_nb * snb)123 nb_put_name(struct mbchain *mbp, struct sockaddr_nb *snb)
124 {
125           int error;
126           u_char seglen, *cp;
127 
128           cp = snb->snb_name;
129           if (*cp == 0)
130                     return EINVAL;
131           NBDEBUG("[%s]\n", cp);
132           for (;;) {
133                     seglen = (*cp) + 1;
134                     error = mb_put_mem(mbp, cp, seglen, MB_MSYSTEM);
135                     if (error)
136                               return error;
137                     if (seglen == 1)
138                               break;
139                     cp += seglen;
140           }
141           return 0;
142 }
143 
144 static int
nb_connect_in(struct nbpcb * nbp,struct sockaddr_in * to,struct thread * td)145 nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct thread *td)
146 {
147           struct socket *so;
148           int error;
149 
150           error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, td);
151           if (error)
152                     return error;
153           nbp->nbp_tso = so;
154           so->so_upcallarg = (caddr_t)nbp;
155           so->so_upcall = nb_upcall;
156           atomic_set_int(&so->so_rcv.ssb_flags, SSB_UPCALL);
157           so->so_rcv.ssb_timeo = (5 * hz);
158           so->so_snd.ssb_timeo = (5 * hz);
159           error = soreserve(so, nbp->nbp_sndbuf, nbp->nbp_rcvbuf,
160                                 &td->td_proc->p_rlimit[RLIMIT_SBSIZE]);
161           if (error)
162                     goto bad;
163           nb_setsockopt_int(so, SOL_SOCKET, SO_KEEPALIVE, 1);
164           nb_setsockopt_int(so, IPPROTO_TCP, TCP_NODELAY, 1);
165           atomic_clear_int(&so->so_rcv.ssb_flags, SSB_NOINTR);
166           atomic_clear_int(&so->so_snd.ssb_flags, SSB_NOINTR);
167           error = soconnect(so, (struct sockaddr*)to, td, TRUE);
168 
169           /*
170            * If signals are allowed nbssn_recv() can wind up in a hard loop
171            * on EWOULDBLOCK.
172            */
173           atomic_set_int(&so->so_rcv.ssb_flags, SSB_NOINTR);
174           atomic_set_int(&so->so_snd.ssb_flags, SSB_NOINTR);
175           if (error)
176                     goto bad;
177           crit_enter();
178           while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
179                     tsleep(&so->so_timeo, 0, "nbcon", 2 * hz);
180                     if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 &&
181                               (error = nb_intr(nbp, td)) != 0) {
182                               soclrstate(so, SS_ISCONNECTING);
183                               crit_exit();
184                               goto bad;
185                     }
186           }
187           if (so->so_error) {
188                     error = so->so_error;
189                     so->so_error = 0;
190                     crit_exit();
191                     goto bad;
192           }
193           crit_exit();
194           return 0;
195 bad:
196           smb_nbst_disconnect(nbp->nbp_vc, td);
197           return error;
198 }
199 
200 static int
nbssn_rq_request(struct nbpcb * nbp,struct thread * td)201 nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
202 {
203           struct mbchain mb, *mbp = &mb;
204           struct mdchain md, *mdp = &md;
205           struct mbuf *m0;
206           struct sockaddr_in sin;
207           u_short port;
208           u_int8_t rpcode;
209           int error, rplen, res;
210 
211           error = mb_init(mbp);
212           if (error)
213                     return error;
214           mb_put_uint32le(mbp, 0);
215           nb_put_name(mbp, nbp->nbp_paddr);
216           nb_put_name(mbp, nbp->nbp_laddr);
217           nb_sethdr(mbp->mb_top, NB_SSN_REQUEST, mb_fixhdr(mbp) - 4);
218           error = nb_sosend(nbp->nbp_tso, mbp->mb_top, 0, td);
219           if (!error) {
220                     nbp->nbp_state = NBST_RQSENT;
221           }
222           mb_detach(mbp);
223           mb_done(mbp);
224           if (error)
225                     return error;
226           error = socket_wait(nbp->nbp_tso, &nbp->nbp_timo, &res);
227           if (error == EWOULDBLOCK) {   /* Timeout */
228                     NBDEBUG("initial request timeout\n");
229                     return ETIMEDOUT;
230           }
231           if (error)                              /* restart or interrupt */
232                     return error;
233           error = nbssn_recv(nbp, &m0, &rplen, &rpcode, td);
234           if (error) {
235                     NBDEBUG("recv() error %d\n", error);
236                     return error;
237           }
238           /*
239            * Process NETBIOS reply
240            */
241           if (m0)
242                     md_initm(mdp, m0);
243           error = 0;
244           do {
245                     if (rpcode == NB_SSN_POSRESP) {
246                               nbp->nbp_state = NBST_SESSION;
247                               nbp->nbp_flags |= NBF_CONNECTED;
248                               break;
249                     }
250                     if (rpcode != NB_SSN_RTGRESP) {
251                               error = ECONNABORTED;
252                               break;
253                     }
254                     if (rplen != 6) {
255                               error = ECONNABORTED;
256                               break;
257                     }
258                     md_get_mem(mdp, (caddr_t)&sin.sin_addr, 4, MB_MSYSTEM);
259                     md_get_uint16(mdp, &port);
260                     sin.sin_port = port;
261                     nbp->nbp_state = NBST_RETARGET;
262                     smb_nbst_disconnect(nbp->nbp_vc, td);
263                     error = nb_connect_in(nbp, &sin, td);
264                     if (!error)
265                               error = nbssn_rq_request(nbp, td);
266                     if (error) {
267                               smb_nbst_disconnect(nbp->nbp_vc, td);
268                               break;
269                     }
270           } while(0);
271           if (m0)
272                     md_done(mdp);
273           return error;
274 }
275 
276 static int
nbssn_recvhdr(struct nbpcb * nbp,int * lenp,u_int8_t * rpcodep,int flags,struct thread * td)277 nbssn_recvhdr(struct nbpcb *nbp, int *lenp,
278           u_int8_t *rpcodep, int flags, struct thread *td)
279 {
280           struct socket *so = nbp->nbp_tso;
281           struct uio auio;
282           struct iovec aio;
283           u_int32_t len;
284           int error;
285 
286           aio.iov_base = (caddr_t)&len;
287           aio.iov_len = sizeof(len);
288           auio.uio_iov = &aio;
289           auio.uio_iovcnt = 1;
290           auio.uio_segflg = UIO_SYSSPACE;
291           auio.uio_rw = UIO_READ;
292           auio.uio_offset = 0;
293           auio.uio_resid = sizeof(len);
294           auio.uio_td = td;
295           error = so_pru_soreceive(so, NULL, &auio, NULL, NULL, &flags);
296           if (error)
297                     return error;
298           if (auio.uio_resid > 0) {
299                     SMBSDEBUG("short reply\n");
300                     return EPIPE;
301           }
302           len = ntohl(len);
303           *rpcodep = (len >> 24) & 0xFF;
304           len &= 0x1ffff;
305           if (len > SMB_MAXPKTLEN) {
306                     SMBERROR("packet too long (%d)\n", len);
307                     return EFBIG;
308           }
309           *lenp = len;
310           return 0;
311 }
312 
313 static int
nbssn_recv(struct nbpcb * nbp,struct mbuf ** mpp,int * lenp,u_int8_t * rpcodep,struct thread * td)314 nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
315           u_int8_t *rpcodep, struct thread *td)
316 {
317           struct socket *so = nbp->nbp_tso;
318           struct sockbuf sio;
319           int error, rcvflg;
320           int savelen = 0;
321           u_int8_t rpcode = 0;
322 
323           if (so == NULL)
324                     return ENOTCONN;
325 
326           sbinit(&sio, 0);
327           if (mpp)
328                     *mpp = NULL;
329 
330           for(;;) {
331                     error = nbssn_recvhdr(nbp, &savelen, &rpcode, MSG_DONTWAIT, td);
332                     if (so->so_state &
333                         (SS_ISDISCONNECTING | SS_ISDISCONNECTED | SS_CANTRCVMORE)) {
334                               nbp->nbp_state = NBST_CLOSED;
335                               NBDEBUG("session closed by peer\n");
336                               error = ECONNRESET;
337                               break;
338                     }
339                     if (error)
340                               break;
341                     if (savelen == 0 && nbp->nbp_state != NBST_SESSION)
342                               break;
343                     if (rpcode == NB_SSN_KEEPALIVE)
344                               continue;
345                     do {
346                               sbinit(&sio, savelen);
347                               rcvflg = MSG_WAITALL;
348                               error = so_pru_soreceive(so, NULL, NULL, &sio,
349                                                              NULL, &rcvflg);
350                     } while (error == EWOULDBLOCK || error == EINTR ||
351                                          error == ERESTART);
352                     if (error)
353                               break;
354                     if (sio.sb_cc != savelen) {
355                               SMBERROR("packet is shorter than expected\n");
356                               error = EPIPE;
357                               m_freem(sio.sb_mb);
358                               break;
359                     }
360                     if (nbp->nbp_state == NBST_SESSION && rpcode == NB_SSN_MESSAGE)
361                               break;
362                     NBDEBUG("non-session packet %x\n", rpcode);
363                     m_freem(sio.sb_mb);
364                     sio.sb_mb = NULL;
365                     sio.sb_cc = 0;
366           }
367           if (error == 0) {
368                     if (mpp)
369                               *mpp = sio.sb_mb;
370                     else
371                               m_freem(sio.sb_mb);
372                     *lenp = sio.sb_cc;
373                     *rpcodep = rpcode;
374           }
375           return (error);
376 }
377 
378 /*
379  * SMB transport interface
380  */
381 static int
smb_nbst_create(struct smb_vc * vcp,struct thread * td)382 smb_nbst_create(struct smb_vc *vcp, struct thread *td)
383 {
384           struct nbpcb *nbp;
385 
386           nbp = kmalloc(sizeof *nbp, M_NBDATA, M_WAITOK | M_ZERO);
387           nbp->nbp_timo.tv_sec = 15;    /* XXX: sysctl ? */
388           nbp->nbp_state = NBST_CLOSED;
389           nbp->nbp_vc = vcp;
390           nbp->nbp_sndbuf = smb_tcpsndbuf;
391           nbp->nbp_rcvbuf = smb_tcprcvbuf;
392           vcp->vc_tdata = nbp;
393           return 0;
394 }
395 
396 static int
smb_nbst_done(struct smb_vc * vcp,struct thread * td)397 smb_nbst_done(struct smb_vc *vcp, struct thread *td)
398 {
399           struct nbpcb *nbp = vcp->vc_tdata;
400 
401           if (nbp == NULL)
402                     return ENOTCONN;
403           smb_nbst_disconnect(vcp, td);
404           if (nbp->nbp_laddr)
405                     kfree(nbp->nbp_laddr, M_SONAME);
406           if (nbp->nbp_paddr)
407                     kfree(nbp->nbp_paddr, M_SONAME);
408           kfree(nbp, M_NBDATA);
409           return 0;
410 }
411 
412 static int
smb_nbst_bind(struct smb_vc * vcp,struct sockaddr * sap,struct thread * td)413 smb_nbst_bind(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td)
414 {
415           struct nbpcb *nbp = vcp->vc_tdata;
416           struct sockaddr_nb *snb;
417           int error, slen;
418 
419           NBDEBUG("\n");
420           error = EINVAL;
421           do {
422                     if (nbp->nbp_flags & NBF_LOCADDR)
423                               break;
424                     /*
425                      * It is possible to create NETBIOS name in the kernel,
426                      * but nothing prevents us to do it in the user space.
427                      */
428                     if (sap == NULL)
429                               break;
430                     slen = sap->sa_len;
431                     if (slen < NB_MINSALEN)
432                               break;
433                     snb = (struct sockaddr_nb*)dup_sockaddr(sap);
434                     if (snb == NULL) {
435                               error = ENOMEM;
436                               break;
437                     }
438                     nbp->nbp_laddr = snb;
439                     nbp->nbp_flags |= NBF_LOCADDR;
440                     error = 0;
441           } while(0);
442           return error;
443 }
444 
445 static int
smb_nbst_connect(struct smb_vc * vcp,struct sockaddr * sap,struct thread * td)446 smb_nbst_connect(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td)
447 {
448           struct nbpcb *nbp = vcp->vc_tdata;
449           struct sockaddr_in sin;
450           struct sockaddr_nb *snb;
451           struct timespec ts1, ts2;
452           int error, slen;
453 
454           NBDEBUG("\n");
455           if (nbp->nbp_tso != NULL)
456                     return EISCONN;
457           if (nbp->nbp_laddr == NULL)
458                     return EINVAL;
459           slen = sap->sa_len;
460           if (slen < NB_MINSALEN)
461                     return EINVAL;
462           if (nbp->nbp_paddr) {
463                     kfree(nbp->nbp_paddr, M_SONAME);
464                     nbp->nbp_paddr = NULL;
465           }
466           snb = (struct sockaddr_nb*)dup_sockaddr(sap);
467           if (snb == NULL)
468                     return ENOMEM;
469           nbp->nbp_paddr = snb;
470           sin = snb->snb_addrin;
471           getnanotime(&ts1);
472           error = nb_connect_in(nbp, &sin, td);
473           if (error)
474                     return error;
475           getnanotime(&ts2);
476           timespecsub(&ts2, &ts1, &ts2);
477           if (ts2.tv_sec == 0) {
478                     ts2.tv_sec = 1;
479                     ts2.tv_nsec = 0;
480           }
481           timespecadd(&ts2, &ts2, &nbp->nbp_timo);
482           timespecadd(&nbp->nbp_timo, &ts2, &nbp->nbp_timo);
483           timespecadd(&nbp->nbp_timo, &ts2, &nbp->nbp_timo);          /*  * 4 */
484           error = nbssn_rq_request(nbp, td);
485           if (error)
486                     smb_nbst_disconnect(vcp, td);
487           return error;
488 }
489 
490 static int
smb_nbst_disconnect(struct smb_vc * vcp,struct thread * td)491 smb_nbst_disconnect(struct smb_vc *vcp, struct thread *td)
492 {
493           struct nbpcb *nbp = vcp->vc_tdata;
494           struct socket *so;
495 
496           if (nbp == NULL || nbp->nbp_tso == NULL)
497                     return ENOTCONN;
498           if ((so = nbp->nbp_tso) != NULL) {
499                     nbp->nbp_flags &= ~NBF_CONNECTED;
500                     nbp->nbp_tso = NULL;
501                     soshutdown(so, SHUT_RDWR);
502                     soclose(so, FNONBLOCK);
503           }
504           if (nbp->nbp_state != NBST_RETARGET) {
505                     nbp->nbp_state = NBST_CLOSED;
506           }
507           return 0;
508 }
509 
510 static int
smb_nbst_send(struct smb_vc * vcp,struct mbuf * m0,struct thread * td)511 smb_nbst_send(struct smb_vc *vcp, struct mbuf *m0, struct thread *td)
512 {
513           struct nbpcb *nbp = vcp->vc_tdata;
514           int error;
515 
516           if (nbp->nbp_state != NBST_SESSION) {
517                     error = ENOTCONN;
518                     goto abort;
519           }
520           M_PREPEND(m0, 4, M_WAITOK);
521           nb_sethdr(m0, NB_SSN_MESSAGE, m_fixhdr(m0) - 4);
522           error = nb_sosend(nbp->nbp_tso, m0, 0, td);
523           return error;
524 abort:
525           if (m0)
526                     m_freem(m0);
527           return error;
528 }
529 
530 
531 static int
smb_nbst_recv(struct smb_vc * vcp,struct mbuf ** mpp,struct thread * td)532 smb_nbst_recv(struct smb_vc *vcp, struct mbuf **mpp, struct thread *td)
533 {
534           struct nbpcb *nbp = vcp->vc_tdata;
535           u_int8_t rpcode;
536           int error, rplen;
537 
538           nbp->nbp_flags |= NBF_RECVLOCK;
539           error = nbssn_recv(nbp, mpp, &rplen, &rpcode, td);
540           nbp->nbp_flags &= ~NBF_RECVLOCK;
541           return error;
542 }
543 
544 static void
smb_nbst_timo(struct smb_vc * vcp)545 smb_nbst_timo(struct smb_vc *vcp)
546 {
547           return;
548 }
549 
550 static void
smb_nbst_intr(struct smb_vc * vcp)551 smb_nbst_intr(struct smb_vc *vcp)
552 {
553           struct nbpcb *nbp = vcp->vc_tdata;
554 
555           if (nbp == NULL || nbp->nbp_tso == NULL)
556                     return;
557           sorwakeup(nbp->nbp_tso);
558           sowwakeup(nbp->nbp_tso);
559 }
560 
561 static int
smb_nbst_getparam(struct smb_vc * vcp,int param,void * data)562 smb_nbst_getparam(struct smb_vc *vcp, int param, void *data)
563 {
564           struct nbpcb *nbp = vcp->vc_tdata;
565 
566           switch (param) {
567               case SMBTP_SNDSZ:
568                     *(int*)data = nbp->nbp_sndbuf;
569                     break;
570               case SMBTP_RCVSZ:
571                     *(int*)data = nbp->nbp_rcvbuf;
572                     break;
573               case SMBTP_TIMEOUT:
574                     *(struct timespec*)data = nbp->nbp_timo;
575                     break;
576               default:
577                     return EINVAL;
578           }
579           return 0;
580 }
581 
582 static int
smb_nbst_setparam(struct smb_vc * vcp,int param,void * data)583 smb_nbst_setparam(struct smb_vc *vcp, int param, void *data)
584 {
585           struct nbpcb *nbp = vcp->vc_tdata;
586 
587           switch (param) {
588               case SMBTP_SELECTID:
589                     nbp->nbp_selectid = data;
590                     break;
591               default:
592                     return EINVAL;
593           }
594           return 0;
595 }
596 
597 /*
598  * Check for fatal errors
599  */
600 static int
smb_nbst_fatal(struct smb_vc * vcp,int error)601 smb_nbst_fatal(struct smb_vc *vcp, int error)
602 {
603           switch (error) {
604               case ENOTCONN:
605               case ENETRESET:
606               case ECONNABORTED:
607                     return 1;
608           }
609           return 0;
610 }
611 
612 
613 struct smb_tran_desc smb_tran_nbtcp_desc = {
614           SMBT_NBTCP,
615           smb_nbst_create, smb_nbst_done,
616           smb_nbst_bind, smb_nbst_connect, smb_nbst_disconnect,
617           smb_nbst_send, smb_nbst_recv,
618           smb_nbst_timo, smb_nbst_intr,
619           smb_nbst_getparam, smb_nbst_setparam,
620           smb_nbst_fatal
621 };
622 
623