The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netncp/ncp_rq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1999, 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  * Routines to prepare request and fetch reply
   33  *
   34  * $FreeBSD$
   35  */ 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/errno.h>
   39 #include <sys/mbuf.h>
   40 #include <sys/uio.h>
   41 
   42 #include <netncp/ncp.h>
   43 #include <netncp/ncp_conn.h>
   44 #include <netncp/ncp_rq.h>
   45 #include <netncp/ncp_subr.h>
   46 #include <netncp/ncp_ncp.h>
   47 #include <netncp/ncp_nls.h>
   48 
   49 int
   50 ncp_rq_head(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn,struct proc *p,
   51     struct ucred *cred)
   52 {
   53         struct mbuf *m;
   54         struct ncp_rqhdr *rq;
   55         struct ncp_bursthdr *brq;
   56         caddr_t pstart;
   57 
   58         bzero(rqp, sizeof(*rqp));
   59         rqp->p = p;
   60         rqp->cred = cred;
   61         m = m_gethdr(M_WAIT, MT_DATA);
   62         if (m == NULL) 
   63                 return ENOBUFS;         /* if M_WAIT ? */
   64         m->m_pkthdr.rcvif = NULL;
   65         rqp->rq = rqp->mrq = m;
   66         rqp->rp = NULL;
   67         switch(ptype) {
   68             case NCP_PACKET_BURST:
   69                 MH_ALIGN(m, sizeof(*brq) + 24);
   70                 m->m_len = sizeof(*brq);
   71                 brq = mtod(m, struct ncp_bursthdr *);
   72                 brq->bh_type = ptype;
   73                 brq->bh_streamtype = 0x2;
   74                 pstart = (caddr_t)brq;
   75                 break;
   76             default:
   77                 MH_ALIGN(m, sizeof(*rq) + 2);   /* possible len field in some functions */
   78                 m->m_len = sizeof(*rq);
   79                 rq = mtod(m, struct ncp_rqhdr *);
   80                 rq->type = ptype;
   81                 rq->seq = 0;    /* filled later */
   82                 rq->fn = fn;
   83                 pstart = (caddr_t)rq;
   84                 break;
   85         }
   86         rqp->bpos = pstart + m->m_len;
   87         return 0;
   88 }
   89 
   90 int
   91 ncp_rq_done(struct ncp_rq *rqp) {
   92         m_freem(rqp->rq);
   93         rqp->rq=NULL;
   94         if (rqp->rp) m_freem(rqp->rp);
   95         rqp->rp=NULL;
   96         return (0);
   97 }
   98 
   99 /*
  100  * Routines to fill the request
  101  */
  102 static caddr_t ncp_mchecksize(struct ncp_rq *rqp, int size);
  103 #define NCP_RQADD(t)    ((t*)(ncp_mchecksize(rqp,sizeof(t))))
  104 
  105 caddr_t
  106 ncp_mchecksize(struct ncp_rq *rqp, int size) {
  107         caddr_t bpos1;
  108 
  109         if (size>MLEN)
  110                 panic("ncp_mchecksize\n");
  111         if (M_TRAILINGSPACE(rqp->mrq)<(size)) {
  112                 struct mbuf *m;
  113                 m = m_get(M_WAIT, MT_DATA);
  114                 m->m_len = 0;
  115                 rqp->bpos = mtod(m, caddr_t);
  116                 rqp->mrq->m_next = m;
  117                 rqp->mrq = m;
  118         }
  119         rqp->mrq->m_len += size;
  120         bpos1 = rqp->bpos;
  121         rqp->bpos += size;
  122         return bpos1;
  123 }
  124 
  125 void
  126 ncp_rq_byte(struct ncp_rq *rqp,u_int8_t x) {
  127         *NCP_RQADD(u_int8_t)=x;
  128 }
  129 
  130 void
  131 ncp_rq_word_hl(struct ncp_rq *rqp, u_int16_t x) {
  132         setwbe(NCP_RQADD(u_int16_t), 0, x);
  133 }
  134 
  135 void
  136 ncp_rq_word_lh(struct ncp_rq *rqp, u_int16_t x) {
  137         setwle(NCP_RQADD(u_int16_t), 0, x);
  138 }
  139 
  140 void
  141 ncp_rq_dword_lh(struct ncp_rq *rqp, u_int32_t x) {
  142         setdle(NCP_RQADD(u_int32_t), 0, x);
  143 }
  144 
  145 void
  146 ncp_rq_pathstring(struct ncp_rq *rqp, int size, char *name, struct ncp_nlstables *nt) {
  147         struct mbuf *m;
  148         int cplen;
  149 
  150         ncp_rq_byte(rqp, size);
  151         m = rqp->mrq;
  152         cplen = min(size, M_TRAILINGSPACE(m));
  153         if (cplen) {
  154                 ncp_pathcopy(name, rqp->bpos, cplen, nt);
  155                 size -= cplen;
  156                 name += cplen;
  157                 m->m_len += cplen;
  158         }
  159         if (size) {
  160                 m = m_getm(m, size, MT_DATA, M_WAIT);
  161                 while (size > 0){
  162                         m = m->m_next;
  163                         cplen = min(size, M_TRAILINGSPACE(m));
  164                         ncp_pathcopy(name, mtod(m, caddr_t) + m->m_len, cplen, nt);
  165                         size -= cplen;
  166                         name += cplen;
  167                         m->m_len += cplen;
  168                 }
  169         }
  170         rqp->bpos = mtod(m,caddr_t) + m->m_len;
  171         rqp->mrq = m;
  172         return;
  173 }
  174 
  175 int
  176 ncp_rq_putanymem(struct ncp_rq *rqp, caddr_t source, int size, int type) {
  177         struct mbuf *m;
  178         int cplen, error;
  179 
  180         m = rqp->mrq;
  181         cplen = min(size, M_TRAILINGSPACE(m));
  182         if (cplen) {
  183                 if (type==1) {
  184                         error = copyin(source, rqp->bpos, cplen);
  185                         if (error) return error;
  186                 } else
  187                         bcopy(source, rqp->bpos, cplen);
  188                 size -= cplen;
  189                 source += cplen;
  190                 m->m_len += cplen;
  191         }
  192         if (size) {
  193                 m = m_getm(m, size, MT_DATA, M_WAIT);
  194                 while (size > 0){
  195                         m = m->m_next;
  196                         cplen = min(size, M_TRAILINGSPACE(m));
  197                         if (type==1) {
  198                                 error = copyin(source, mtod(m, caddr_t) + m->m_len, cplen);
  199                                 if (error) return error;
  200                         } else
  201                                 bcopy(source, mtod(m, caddr_t) + m->m_len, cplen);
  202                         size -= cplen;
  203                         source += cplen;
  204                         m->m_len += cplen;
  205                 }
  206         }
  207         rqp->bpos = mtod(m,caddr_t) + m->m_len;
  208         rqp->mrq = m;
  209         return 0;
  210 }
  211 
  212 int
  213 ncp_rq_mbuf(struct ncp_rq *rqp, struct mbuf *m, int size) {
  214 
  215         rqp->mrq->m_next = m;
  216         m->m_next = NULL;
  217         if (size != M_COPYALL) m->m_len = size;
  218         rqp->bpos = mtod(m,caddr_t) + m->m_len;
  219         rqp->mrq = m;
  220         return 0;
  221 }
  222 
  223 void 
  224 ncp_rq_pstring(struct ncp_rq *rqp, char *s) {
  225         int len = strlen(s);
  226         if (len > 255) {
  227                 nwfs_printf("string too long: %s\n", s);
  228                 len = 255;
  229         }
  230         ncp_rq_byte(rqp, len);
  231         ncp_rq_mem(rqp, s, len);
  232         return;
  233 }
  234 
  235 void 
  236 ncp_rq_dbase_path(struct ncp_rq *rqp, u_int8_t vol_num, u_int32_t dir_base,
  237                     int namelen, u_char *path, struct ncp_nlstables *nt)
  238 {
  239         int complen;
  240 
  241         ncp_rq_byte(rqp, vol_num);
  242         ncp_rq_dword(rqp, dir_base);
  243         ncp_rq_byte(rqp, 1);    /* with dirbase */
  244         if (path != NULL && path[0]) {
  245                 if (namelen < 0) {
  246                         namelen = *path++;
  247                         ncp_rq_byte(rqp, namelen);
  248                         for(; namelen; namelen--) {
  249                                 complen = *path++;
  250                                 ncp_rq_byte(rqp, complen);
  251                                 ncp_rq_mem(rqp, path, complen);
  252                                 path += complen;
  253                         }
  254                 } else {
  255                         ncp_rq_byte(rqp, 1);    /* 1 component */
  256                         ncp_rq_pathstring(rqp, namelen, path, nt);
  257                 }
  258         } else {
  259                 ncp_rq_byte(rqp, 0);
  260                 ncp_rq_byte(rqp, 0);
  261         }
  262 }
  263 /*
  264  * fetch reply routines
  265  */
  266 #define ncp_mspaceleft  (mtod(rqp->mrp,caddr_t)+rqp->mrp->m_len-rqp->bpos)
  267 
  268 u_int8_t
  269 ncp_rp_byte(struct ncp_rq *rqp) {
  270         if (rqp->mrp == NULL) return 0;
  271         if (ncp_mspaceleft < 1) {
  272                 rqp->mrp = rqp->mrp->m_next;
  273                 if (rqp->mrp == NULL) return 0;
  274                 rqp->bpos = mtod(rqp->mrp, caddr_t);
  275         }
  276         rqp->bpos += 1;
  277         return rqp->bpos[-1];
  278 }
  279 
  280 u_int16_t
  281 ncp_rp_word_lh(struct ncp_rq *rqp) {
  282         caddr_t prev = rqp->bpos;
  283         u_int16_t t;
  284 
  285         if (rqp->mrp == NULL) return 0;
  286         if (ncp_mspaceleft >= 2) {
  287                 rqp->bpos += 2;
  288                 return getwle(prev,0);
  289         }
  290         t = *((u_int8_t*)(rqp->bpos));
  291         rqp->mrp = rqp->mrp->m_next;
  292         if (rqp->mrp == NULL) return 0;
  293         ((u_int8_t *)&t)[1] = *((u_int8_t*)(rqp->bpos = mtod(rqp->mrp, caddr_t)));
  294         rqp->bpos += 2;
  295         return t;
  296 }
  297 
  298 u_int16_t
  299 ncp_rp_word_hl(struct ncp_rq *rqp) {
  300         return (ntohs(ncp_rp_word_lh(rqp)));
  301 }
  302 
  303 u_int32_t
  304 ncp_rp_dword_hl(struct ncp_rq *rqp) {
  305         int togo, rest;
  306         caddr_t prev = rqp->bpos;
  307         u_int32_t t;
  308 
  309         if (rqp->mrp == NULL) return 0;
  310         rest = ncp_mspaceleft;
  311         if (rest >= 4) {
  312                 rqp->bpos += 4;
  313                 return getdbe(prev,0);
  314         }
  315         togo = 0;
  316         while (rest--) {
  317                 ((u_int8_t *)&t)[togo++] = *((u_int8_t*)(prev++));
  318         }
  319         rqp->mrp = rqp->mrp->m_next;
  320         if (rqp->mrp == NULL) return 0;
  321         prev = mtod(rqp->mrp, caddr_t);
  322         rqp->bpos = prev + 4 - togo;    /* XXX possible low than togo bytes in next mbuf */
  323         while (togo < 4) {
  324                 ((u_int8_t *)&t)[togo++] = *((u_int8_t*)(prev++));
  325         }
  326         return getdbe(&t,0);
  327 }
  328 
  329 u_int32_t
  330 ncp_rp_dword_lh(struct ncp_rq *rqp) {
  331         int rest, togo;
  332         caddr_t prev = rqp->bpos;
  333         u_int32_t t;
  334 
  335         if (rqp->mrp == NULL) return 0;
  336         rest = ncp_mspaceleft;
  337         if (rest >= 4) {
  338                 rqp->bpos += 4;
  339                 return getdle(prev,0);
  340         }
  341         togo = 0;
  342         while (rest--) {
  343                 ((u_int8_t *)&t)[togo++] = *((u_int8_t*)(prev++));
  344         }
  345         rqp->mrp = rqp->mrp->m_next;
  346         if (rqp->mrp == NULL) return 0;
  347         prev = mtod(rqp->mrp, caddr_t);
  348         rqp->bpos = prev + 4 - togo;    /* XXX possible low than togo bytes in next mbuf */
  349         while (togo < 4) {
  350                 ((u_int8_t *)&t)[togo++] = *((u_int8_t*)(prev++));
  351         }
  352         return getdle(&t,0);
  353 }
  354 void
  355 ncp_rp_mem(struct ncp_rq *rqp,caddr_t target, int size) {
  356         register struct mbuf *m=rqp->mrp;
  357         register unsigned count;
  358         
  359         while (size > 0) {
  360                 if (m==0) {     /* should be panic */
  361                         printf("ncp_rp_mem: incomplete copy\n");
  362                         return;
  363                 }
  364                 count = mtod(m,caddr_t)+m->m_len-rqp->bpos;
  365                 if (count == 0) {
  366                         m=m->m_next;
  367                         rqp->bpos=mtod(m,caddr_t);
  368                         continue;
  369                 }
  370                 count = min(count,size);
  371                 bcopy(rqp->bpos, target, count);
  372                 size -= count;
  373                 target += count;
  374                 rqp->bpos += count;
  375         }
  376         rqp->mrp=m;
  377         return;
  378 }
  379 
  380 int
  381 ncp_rp_usermem(struct ncp_rq *rqp,caddr_t target, int size) {
  382         register struct mbuf *m=rqp->mrp;
  383         register unsigned count;
  384         int error;
  385         
  386         while (size>0) {
  387                 if (m==0) {     /* should be panic */
  388                         printf("ncp_rp_mem: incomplete copy\n");
  389                         return EFAULT;
  390                 }
  391                 count = mtod(m,caddr_t)+m->m_len-rqp->bpos;
  392                 if (count == 0) {
  393                         m=m->m_next;
  394                         rqp->bpos=mtod(m,caddr_t);
  395                         continue;
  396                 }
  397                 count = min(count,size);
  398                 error=copyout(rqp->bpos, target, count);
  399                 if (error) return error;
  400                 size -= count;
  401                 target += count;
  402                 rqp->bpos += count;
  403         }
  404         rqp->mrp=m;
  405         return 0;
  406 }
  407 
  408 struct mbuf*
  409 ncp_rp_mbuf(struct ncp_rq *rqp, int size) {
  410         register struct mbuf *m=rqp->mrp, *rm;
  411         register unsigned count;
  412         
  413         rm = m_copym(m, rqp->bpos - mtod(m,caddr_t), size, M_WAIT);
  414         while (size > 0) {
  415                 if (m == 0) {
  416                         printf("ncp_rp_mbuf: can't advance\n");
  417                         return rm;
  418                 }
  419                 count = mtod(m,caddr_t)+ m->m_len - rqp->bpos;
  420                 if (count == 0) {
  421                         m = m->m_next;
  422                         rqp->bpos = mtod(m, caddr_t);
  423                         continue;
  424                 }
  425                 count = min(count, size);
  426                 size -= count;
  427                 rqp->bpos += count;
  428         }
  429         rqp->mrp=m;
  430         return rm;
  431 }
  432 
  433 int
  434 nwfs_mbuftouio(mrep, uiop, siz, dpos)
  435         struct mbuf **mrep;
  436         register struct uio *uiop;
  437         int siz;
  438         caddr_t *dpos;
  439 {
  440         register char *mbufcp, *uiocp;
  441         register int xfer, left, len;
  442         register struct mbuf *mp;
  443         long uiosiz;
  444         int error = 0;
  445 
  446         mp = *mrep;
  447         if (!mp) return 0;
  448         mbufcp = *dpos;
  449         len = mtod(mp, caddr_t)+mp->m_len-mbufcp;
  450         while (siz > 0) {
  451                 if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
  452                         return (EFBIG);
  453                 left = uiop->uio_iov->iov_len;
  454                 uiocp = uiop->uio_iov->iov_base;
  455                 if (left > siz)
  456                         left = siz;
  457                 uiosiz = left;
  458                 while (left > 0) {
  459                         while (len == 0) {
  460                                 mp = mp->m_next;
  461                                 if (mp == NULL)
  462                                         return (EBADRPC);
  463                                 mbufcp = mtod(mp, caddr_t);
  464                                 len = mp->m_len;
  465                         }
  466                         xfer = (left > len) ? len : left;
  467 #ifdef notdef
  468                         /* Not Yet.. */
  469                         if (uiop->uio_iov->iov_op != NULL)
  470                                 (*(uiop->uio_iov->iov_op))
  471                                 (mbufcp, uiocp, xfer);
  472                         else
  473 #endif
  474                         if (uiop->uio_segflg == UIO_SYSSPACE)
  475                                 bcopy(mbufcp, uiocp, xfer);
  476                         else
  477                                 copyout(mbufcp, uiocp, xfer);
  478                         left -= xfer;
  479                         len -= xfer;
  480                         mbufcp += xfer;
  481                         uiocp += xfer;
  482                         uiop->uio_offset += xfer;
  483                         uiop->uio_resid -= xfer;
  484                 }
  485                 if (uiop->uio_iov->iov_len <= siz) {
  486                         uiop->uio_iovcnt--;
  487                         uiop->uio_iov++;
  488                 } else {
  489                         uiop->uio_iov->iov_base += uiosiz;
  490                         uiop->uio_iov->iov_len -= uiosiz;
  491                 }
  492                 siz -= uiosiz;
  493         }
  494         *dpos = mbufcp;
  495         *mrep = mp;
  496         return (error);
  497 }
  498 /*
  499  * copies a uio scatter/gather list to an mbuf chain.
  500  * NOTE: can ony handle iovcnt == 1
  501  */
  502 int
  503 nwfs_uiotombuf(uiop, mq, siz, bpos)
  504         register struct uio *uiop;
  505         struct mbuf **mq;
  506         int siz;
  507         caddr_t *bpos;
  508 {
  509         register char *uiocp;
  510         register struct mbuf *mp, *mp2;
  511         register int xfer, left, mlen;
  512         int uiosiz, clflg;
  513 
  514 #ifdef DIAGNOSTIC
  515         if (uiop->uio_iovcnt != 1)
  516                 panic("nfsm_uiotombuf: iovcnt != 1");
  517 #endif
  518 
  519         if (siz > MLEN)         /* or should it >= MCLBYTES ?? */
  520                 clflg = 1;
  521         else
  522                 clflg = 0;
  523         mp = mp2 = *mq;
  524         while (siz > 0) {
  525                 left = uiop->uio_iov->iov_len;
  526                 uiocp = uiop->uio_iov->iov_base;
  527                 if (left > siz)
  528                         left = siz;
  529                 uiosiz = left;
  530                 while (left > 0) {
  531                         mlen = M_TRAILINGSPACE(mp);
  532                         if (mlen == 0) {
  533                                 MGET(mp, M_WAIT, MT_DATA);
  534                                 if (clflg)
  535                                         MCLGET(mp, M_WAIT);
  536                                 mp->m_len = 0;
  537                                 mp2->m_next = mp;
  538                                 mp2 = mp;
  539                                 mlen = M_TRAILINGSPACE(mp);
  540                         }
  541                         xfer = (left > mlen) ? mlen : left;
  542 #ifdef notdef
  543                         /* Not Yet.. */
  544                         if (uiop->uio_iov->iov_op != NULL)
  545                                 (*(uiop->uio_iov->iov_op))
  546                                 (uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
  547                         else
  548 #endif
  549                         if (uiop->uio_segflg == UIO_SYSSPACE)
  550                                 bcopy(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
  551                         else
  552                                 copyin(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
  553                         mp->m_len += xfer;
  554                         left -= xfer;
  555                         uiocp += xfer;
  556                         uiop->uio_offset += xfer;
  557                         uiop->uio_resid -= xfer;
  558                 }
  559                 uiop->uio_iov->iov_base += uiosiz;
  560                 uiop->uio_iov->iov_len -= uiosiz;
  561                 siz -= uiosiz;
  562         }
  563         *bpos = mtod(mp, caddr_t)+mp->m_len;
  564         *mq = mp;
  565         return (0);
  566 }

Cache object: ddf25e825fb46f4bc86702ed83db1982


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.