Annotation of XNU/bsd/netccitt/pk_usrreq.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) University of British Columbia, 1984
                     24:  * Copyright (C) Computer Science Department IV, 
                     25:  *              University of Erlangen-Nuremberg, Germany, 1992
                     26:  * Copyright (c) 1991, 1992, 1993
                     27:  *     The Regents of the University of California.  All rights reserved.
                     28:  *
                     29:  * This code is derived from software contributed to Berkeley by the
                     30:  * Laboratory for Computation Vision and the Computer Science Department
                     31:  * of the the University of British Columbia and the Computer Science
                     32:  * Department (IV) of the University of Erlangen-Nuremberg, Germany.
                     33:  *
                     34:  * Redistribution and use in source and binary forms, with or without
                     35:  * modification, are permitted provided that the following conditions
                     36:  * are met:
                     37:  * 1. Redistributions of source code must retain the above copyright
                     38:  *    notice, this list of conditions and the following disclaimer.
                     39:  * 2. Redistributions in binary form must reproduce the above copyright
                     40:  *    notice, this list of conditions and the following disclaimer in the
                     41:  *    documentation and/or other materials provided with the distribution.
                     42:  * 3. All advertising materials mentioning features or use of this software
                     43:  *    must display the following acknowledgement:
                     44:  *     This product includes software developed by the University of
                     45:  *     California, Berkeley and its contributors.
                     46:  * 4. Neither the name of the University nor the names of its contributors
                     47:  *    may be used to endorse or promote products derived from this software
                     48:  *    without specific prior written permission.
                     49:  *
                     50:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     51:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     52:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     53:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     54:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     55:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     56:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     57:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     58:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     59:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     60:  * SUCH DAMAGE.
                     61:  *
                     62:  *     @(#)pk_usrreq.c 8.1 (Berkeley) 6/10/93
                     63:  */
                     64: 
                     65: #include <sys/param.h>
                     66: #include <sys/systm.h>
                     67: #include <sys/mbuf.h>
                     68: #include <sys/socket.h>
                     69: #include <sys/socketvar.h>
                     70: #include <sys/protosw.h>
                     71: #include <sys/errno.h>
                     72: #include <sys/ioctl.h>
                     73: #include <sys/stat.h>
                     74: #include <sys/malloc.h>
                     75: 
                     76: #include <net/if.h>
                     77: #include <net/if_types.h>
                     78: #include <net/route.h>
                     79: 
                     80: #include <netccitt/x25.h>
                     81: #include <netccitt/pk.h>
                     82: #include <netccitt/pk_var.h>
                     83: 
                     84: static old_to_new();
                     85: static new_to_old();
                     86: /*
                     87:  * 
                     88:  *  X.25 Packet level protocol interface to socket abstraction.
                     89:  *
                     90:  *  Process an X.25 user request on a logical channel.  If this is a send
                     91:  *  request then m is the mbuf chain of the send data. If this is a timer
                     92:  *  expiration (called from the software clock routine) them timertype is
                     93:  *  the particular timer.
                     94:  *
                     95:  */
                     96: 
                     97: pk_usrreq (so, req, m, nam, control)
                     98: struct socket *so;
                     99: int req;
                    100: register struct mbuf *m, *nam;
                    101: struct mbuf *control;
                    102: {
                    103:        register struct pklcd *lcp = (struct pklcd *) so -> so_pcb;
                    104:        register int error = 0;
                    105: 
                    106:        if (req == PRU_CONTROL)
                    107:                return (pk_control (so, (int)m, (caddr_t)nam,
                    108:                        (struct ifnet *)control));
                    109:        if (control && control -> m_len) {
                    110:                error = EINVAL;
                    111:                goto release;
                    112:        }
                    113:        if (lcp == NULL && req != PRU_ATTACH) {
                    114:                error = EINVAL;
                    115:                goto release;
                    116:        }
                    117: 
                    118: /*
                    119:        pk_trace (pkcbhead, TR_USER, (struct pklcd *)0,
                    120:                req, (struct x25_packet *)0);
                    121: */
                    122: 
                    123:        switch (req) {
                    124:        /* 
                    125:         *  X.25 attaches to socket via PRU_ATTACH and allocates a logical
                    126:         *  channel descriptor.  If the socket is to  receive connections,
                    127:         *  then the LISTEN state is entered.
                    128:         */
                    129:        case PRU_ATTACH: 
                    130:                if (lcp) {
                    131:                        error = EISCONN;
                    132:                        /* Socket already connected. */
                    133:                        break;
                    134:                }
                    135:                lcp = pk_attach (so);
                    136:                if (lcp == 0)
                    137:                        error = ENOBUFS;
                    138:                break;
                    139: 
                    140:        /* 
                    141:         *  Detach a logical channel from the socket. If the state of the
                    142:         *  channel is embryonic, simply discard it. Otherwise we have to 
                    143:         *  initiate a PRU_DISCONNECT which will finish later.
                    144:         */
                    145:        case PRU_DETACH: 
                    146:                pk_disconnect (lcp);
                    147:                break;
                    148: 
                    149:        /* 
                    150:         *  Give the socket an address.
                    151:         */
                    152:        case PRU_BIND: 
                    153:                if (nam -> m_len == sizeof (struct x25_sockaddr))
                    154:                        old_to_new (nam);
                    155:                error = pk_bind (lcp, nam);
                    156:                break;
                    157: 
                    158:        /* 
                    159:         *  Prepare to accept connections.
                    160:         */
                    161:        case PRU_LISTEN: 
                    162:                error = pk_listen (lcp);
                    163:                break;
                    164: 
                    165:        /* 
                    166:         *  Initiate a CALL REQUEST to peer entity. Enter state SENT_CALL
                    167:         *  and mark the socket as connecting. Set timer waiting for 
                    168:         *  CALL ACCEPT or CLEAR.
                    169:         */
                    170:        case PRU_CONNECT: 
                    171:                if (nam -> m_len == sizeof (struct x25_sockaddr))
                    172:                        old_to_new (nam);
                    173:                if (pk_checksockaddr (nam))
                    174:                        return (EINVAL);
                    175:                error = pk_connect (lcp, mtod (nam, struct sockaddr_x25 *));
                    176:                break;
                    177: 
                    178:        /* 
                    179:         *  Initiate a disconnect to peer entity via a CLEAR REQUEST packet.
                    180:         *  The socket will be disconnected when we receive a confirmation
                    181:         *  or a clear collision.
                    182:         */
                    183:        case PRU_DISCONNECT: 
                    184:                pk_disconnect (lcp);
                    185:                break;
                    186: 
                    187:        /* 
                    188:         *  Accept an INCOMING CALL. Most of the work has already been done
                    189:         *  by pk_input. Just return the callers address to the user.
                    190:         */
                    191:        case PRU_ACCEPT: 
                    192:                if (lcp -> lcd_craddr == NULL)
                    193:                        break;
                    194:                bcopy ((caddr_t)lcp -> lcd_craddr, mtod (nam, caddr_t),
                    195:                        sizeof (struct sockaddr_x25));
                    196:                nam -> m_len = sizeof (struct sockaddr_x25);
                    197:                if (lcp -> lcd_flags & X25_OLDSOCKADDR)
                    198:                        new_to_old (nam);
                    199:                break;
                    200: 
                    201:        /* 
                    202:         *  After a receive, we should send a RR.
                    203:         */
                    204:        case PRU_RCVD: 
                    205:                pk_flowcontrol (lcp, /*sbspace (&so -> so_rcv) <= */ 0, 1);
                    206:                break;
                    207: 
                    208:        /* 
                    209:         *  Send INTERRUPT packet.
                    210:         */
                    211:        case PRU_SENDOOB: 
                    212:                if (m == 0) {
                    213:                        MGETHDR(m, M_WAITOK, MT_OOBDATA);
                    214:                        m -> m_pkthdr.len = m -> m_len = 1;
                    215:                        *mtod (m, octet *) = 0;
                    216:                }
                    217:                if (m -> m_pkthdr.len > 32) {
                    218:                        m_freem (m);
                    219:                        error = EMSGSIZE;
                    220:                        break;
                    221:                }
                    222:                MCHTYPE(m, MT_OOBDATA);
                    223:                /* FALLTHROUGH */
                    224: 
                    225:        /* 
                    226:         *  Do send by placing data on the socket output queue.
                    227:         */
                    228:        case PRU_SEND: 
                    229:                if (control) {
                    230:                        register struct cmsghdr *ch = mtod (m, struct cmsghdr *);
                    231:                        control -> m_len -= sizeof (*ch);
                    232:                        control -> m_data += sizeof (*ch);
                    233:                        error = pk_ctloutput (PRCO_SETOPT, so, ch -> cmsg_level,
                    234:                                        ch -> cmsg_type, &control);
                    235:                }
                    236:                if (error == 0 && m)
                    237:                        error = pk_send (lcp, m);
                    238:                break;
                    239: 
                    240:        /* 
                    241:         *  Abort a virtual circuit. For example all completed calls
                    242:         *  waiting acceptance.
                    243:         */
                    244:        case PRU_ABORT: 
                    245:                pk_disconnect (lcp);
                    246:                break;
                    247: 
                    248:        /* Begin unimplemented hooks. */
                    249: 
                    250:        case PRU_SHUTDOWN: 
                    251:                error = EOPNOTSUPP;
                    252:                break;
                    253: 
                    254:        case PRU_CONTROL: 
                    255:                error = EOPNOTSUPP;
                    256:                break;
                    257: 
                    258:        case PRU_SENSE: 
                    259: #ifdef BSD4_3
                    260:                ((struct stat *)m) -> st_blksize = so -> so_snd.sb_hiwat;
                    261: #else
                    262:                error = EOPNOTSUPP;
                    263: #endif
                    264:                break;
                    265: 
                    266:        /* End unimplemented hooks. */
                    267: 
                    268:        case PRU_SOCKADDR: 
                    269:                if (lcp -> lcd_ceaddr == 0)
                    270:                        return (EADDRNOTAVAIL);
                    271:                nam -> m_len = sizeof (struct sockaddr_x25);
                    272:                bcopy ((caddr_t)lcp -> lcd_ceaddr, mtod (nam, caddr_t),
                    273:                        sizeof (struct sockaddr_x25));
                    274:                if (lcp -> lcd_flags & X25_OLDSOCKADDR)
                    275:                        new_to_old (nam);
                    276:                break;
                    277: 
                    278:        case PRU_PEERADDR:
                    279:                if (lcp -> lcd_state != DATA_TRANSFER)
                    280:                        return (ENOTCONN);
                    281:                nam -> m_len = sizeof (struct sockaddr_x25);
                    282:                bcopy (lcp -> lcd_craddr ? (caddr_t)lcp -> lcd_craddr :
                    283:                        (caddr_t)lcp -> lcd_ceaddr,
                    284:                        mtod (nam, caddr_t), sizeof (struct sockaddr_x25));
                    285:                if (lcp -> lcd_flags & X25_OLDSOCKADDR)
                    286:                        new_to_old (nam);
                    287:                break;
                    288: 
                    289:        /* 
                    290:         *  Receive INTERRUPT packet.
                    291:         */
                    292:        case PRU_RCVOOB: 
                    293:                if (so -> so_options & SO_OOBINLINE) {
                    294:                        register struct mbuf *n  = so -> so_rcv.sb_mb;
                    295:                        if (n && n -> m_type == MT_OOBDATA) {
                    296:                                unsigned len =  n -> m_pkthdr.len;
                    297:                                so -> so_rcv.sb_mb = n -> m_nextpkt;
                    298:                                if (len !=  n -> m_len &&
                    299:                                    (n = m_pullup (n, len)) == 0)
                    300:                                        break;
                    301:                                m -> m_len = len;
                    302:                                bcopy (mtod (m, caddr_t), mtod (n, caddr_t), len);
                    303:                                m_freem (n);
                    304:                        }
                    305:                        break;
                    306:                }
                    307:                m -> m_len = 1;
                    308:                *mtod (m, char *) = lcp -> lcd_intrdata;
                    309:                break;
                    310: 
                    311:        default: 
                    312:                panic ("pk_usrreq");
                    313:        }
                    314: release:
                    315:        if (control != NULL)
                    316:                m_freem (control);
                    317:        return (error);
                    318: }
                    319: 
                    320: /* 
                    321:  * If you want to use UBC X.25 level 3 in conjunction with some
                    322:  * other X.25 level 2 driver, have the ifp -> if_ioctl routine
                    323:  * assign pk_start to ia -> ia_start when called with SIOCSIFCONF_X25.
                    324:  */
                    325: /* ARGSUSED */
                    326: pk_start (lcp)
                    327: register struct pklcd *lcp;
                    328: {
                    329:        pk_output (lcp);
                    330:        return (0); /* XXX pk_output should return a value */
                    331: }
                    332: 
                    333: #ifndef _offsetof
                    334: #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
                    335: #endif
                    336: struct sockaddr_x25 pk_sockmask = {
                    337:        _offsetof(struct sockaddr_x25, x25_addr[0]),      /* x25_len */
                    338:        0,                                                /* x25_family */
                    339:        -1,                                               /* x25_net id */
                    340: };
                    341: 
                    342: /*ARGSUSED*/
                    343: pk_control (so, cmd, data, ifp)
                    344: struct socket *so;
                    345: int cmd;
                    346: caddr_t data;
                    347: register struct ifnet *ifp;
                    348: {
                    349:        register struct ifreq_x25 *ifr = (struct ifreq_x25 *)data;
                    350:        register struct ifaddr *ifa = 0;
                    351:        register struct x25_ifaddr *ia = 0;
                    352:        struct pklcd *dev_lcp = 0;
                    353:        int error, s, old_maxlcn;
                    354:        unsigned n;
                    355: 
                    356:        /*
                    357:         * Find address for this interface, if it exists.
                    358:         */
                    359:        if (ifp)
                    360:                for (ifa = ifp -> if_addrlist; ifa; ifa = ifa -> ifa_next)
                    361:                        if (ifa -> ifa_addr -> sa_family == AF_CCITT)
                    362:                                break;
                    363: 
                    364:        ia = (struct x25_ifaddr *)ifa;
                    365:        switch (cmd) {
                    366:        case SIOCGIFCONF_X25:
                    367:                if (ifa == 0)
                    368:                        return (EADDRNOTAVAIL);
                    369:                ifr -> ifr_xc = ia -> ia_xc;
                    370:                return (0);
                    371: 
                    372:        case SIOCSIFCONF_X25:
                    373:                if ((so->so_state & SS_PRIV) == 0)
                    374:                        return (EPERM);
                    375:                if (ifp == 0)
                    376:                        panic ("pk_control");
                    377:                if (ifa == (struct ifaddr *)0) {
                    378:                        register struct mbuf *m;
                    379: 
                    380:                        MALLOC(ia, struct x25_ifaddr *, sizeof (*ia),
                    381:                                M_IFADDR, M_WAITOK);
                    382:                        if (ia == 0)
                    383:                                return (ENOBUFS);
                    384:                        bzero ((caddr_t)ia, sizeof (*ia));
                    385:                        if (ifa = ifp -> if_addrlist) {
                    386:                                for ( ; ifa -> ifa_next; ifa = ifa -> ifa_next)
                    387:                                        ;
                    388:                                ifa -> ifa_next = &ia -> ia_ifa;
                    389:                        } else
                    390:                                ifp -> if_addrlist = &ia -> ia_ifa;
                    391:                        ifa = &ia -> ia_ifa;
                    392:                        ifa -> ifa_netmask = (struct sockaddr *)&pk_sockmask;
                    393:                        ifa -> ifa_addr = (struct sockaddr *)&ia -> ia_xc.xc_addr;
                    394:                        ifa -> ifa_dstaddr = (struct sockaddr *)&ia -> ia_dstaddr; /* XXX */
                    395:                        ia -> ia_ifp = ifp;
                    396:                        ia -> ia_dstaddr.x25_family = AF_CCITT;
                    397:                        ia -> ia_dstaddr.x25_len = pk_sockmask.x25_len;
                    398:                } else if (ISISO8802(ifp) == 0) {
                    399:                        rtinit (ifa, (int)RTM_DELETE, 0);
                    400:                }
                    401:                old_maxlcn = ia -> ia_maxlcn;
                    402:                ia -> ia_xc = ifr -> ifr_xc;
                    403:                ia -> ia_dstaddr.x25_net = ia -> ia_xc.xc_addr.x25_net;
                    404:                if (ia -> ia_maxlcn != old_maxlcn && old_maxlcn != 0) {
                    405:                        /* VERY messy XXX */
                    406:                        register struct pkcb *pkp;
                    407:                        FOR_ALL_PKCBS(pkp)
                    408:                                if (pkp -> pk_ia == ia)
                    409:                                        pk_resize (pkp);
                    410:                }
                    411:                /*
                    412:                 * Give the interface a chance to initialize if this
                    413: p               * is its first address, and to validate the address.
                    414:                 */
                    415:                ia -> ia_start = pk_start;
                    416:                s = splimp();
                    417:                if (ifp -> if_ioctl)
                    418:                        error = (*ifp -> if_ioctl)(ifp, SIOCSIFCONF_X25, 
                    419:                                                   (caddr_t) ifa);
                    420:                if (error)
                    421:                        ifp -> if_flags &= ~IFF_UP;
                    422:                else if (ISISO8802(ifp) == 0)
                    423:                        error = rtinit (ifa, (int)RTM_ADD, RTF_UP);
                    424:                splx (s);
                    425:                return (error);
                    426: 
                    427:        default:
                    428:                if (ifp == 0 || ifp -> if_ioctl == 0)
                    429:                        return (EOPNOTSUPP);
                    430:                return ((*ifp -> if_ioctl)(ifp, cmd, data));
                    431:        }
                    432: }
                    433: 
                    434: pk_ctloutput (cmd, so, level, optname, mp)
                    435: struct socket *so;
                    436: struct mbuf **mp;
                    437: int cmd, level, optname;
                    438: {
                    439:        register struct mbuf *m = *mp;
                    440:        register struct pklcd *lcp = (struct pklcd *) so -> so_pcb;
                    441:        int error = EOPNOTSUPP;
                    442: 
                    443:        if (m == 0)
                    444:                return (EINVAL);
                    445:        if (cmd == PRCO_SETOPT) switch (optname) {
                    446:        case PK_FACILITIES:
                    447:                if (m == 0)
                    448:                        return (EINVAL);
                    449:                lcp -> lcd_facilities = m;
                    450:                *mp = 0;
                    451:                return (0);
                    452: 
                    453:        case PK_ACCTFILE:
                    454:                if ((so->so_state & SS_PRIV) == 0)
                    455:                        error = EPERM;
                    456:                else if (m -> m_len)
                    457:                        error = pk_accton (mtod (m, char *));
                    458:                else
                    459:                        error = pk_accton ((char *)0);
                    460:                break;
                    461: 
                    462:        case PK_RTATTACH:
                    463:                error = pk_rtattach (so, m);
                    464:                break;
                    465:            
                    466:        case PK_PRLISTEN:
                    467:                error = pk_user_protolisten (mtod (m, u_char *));
                    468:        }
                    469:        if (*mp) {
                    470:                (void) m_freem (*mp);
                    471:                *mp = 0;
                    472:        }
                    473:        return (error);
                    474: 
                    475: }
                    476: 
                    477: 
                    478: /*
                    479:  * Do an in-place conversion of an "old style"
                    480:  * socket address to the new style
                    481:  */
                    482: 
                    483: static
                    484: old_to_new (m)
                    485: register struct mbuf *m;
                    486: {
                    487:        register struct x25_sockaddr *oldp;
                    488:        register struct sockaddr_x25 *newp;
                    489:        register char *ocp, *ncp;
                    490:        struct sockaddr_x25 new;
                    491: 
                    492:        oldp = mtod (m, struct x25_sockaddr *);
                    493:        newp = &new;
                    494:        bzero ((caddr_t)newp, sizeof (*newp));
                    495: 
                    496:        newp -> x25_family = AF_CCITT;
                    497:        newp -> x25_len = sizeof(*newp);
                    498:        newp -> x25_opts.op_flags = (oldp -> xaddr_facilities & X25_REVERSE_CHARGE)
                    499:                | X25_MQBIT | X25_OLDSOCKADDR;
                    500:        if (oldp -> xaddr_facilities & XS_HIPRIO)       /* Datapac specific */
                    501:                newp -> x25_opts.op_psize = X25_PS128;
                    502:        bcopy ((caddr_t)oldp -> xaddr_addr, newp -> x25_addr,
                    503:               (unsigned)min (oldp -> xaddr_len, sizeof (newp -> x25_addr) - 1));
                    504:        if (bcmp ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4) != 0) {
                    505:                bcopy ((caddr_t)oldp -> xaddr_proto, newp -> x25_udata, 4);
                    506:                newp -> x25_udlen = 4;
                    507:        }
                    508:        ocp = (caddr_t)oldp -> xaddr_userdata;
                    509:        ncp = newp -> x25_udata + 4;
                    510:        while (*ocp && ocp < (caddr_t)oldp -> xaddr_userdata + 12) {
                    511:                if (newp -> x25_udlen == 0)
                    512:                        newp -> x25_udlen = 4;
                    513:                *ncp++ = *ocp++;
                    514:                newp -> x25_udlen++;
                    515:        }
                    516:        bcopy ((caddr_t)newp, mtod (m, char *), sizeof (*newp));
                    517:        m -> m_len = sizeof (*newp);
                    518: }
                    519: 
                    520: /*
                    521:  * Do an in-place conversion of a new style
                    522:  * socket address to the old style
                    523:  */
                    524: 
                    525: static
                    526: new_to_old (m)
                    527: register struct mbuf *m;
                    528: {
                    529:        register struct x25_sockaddr *oldp;
                    530:        register struct sockaddr_x25 *newp;
                    531:        register char *ocp, *ncp;
                    532:        struct x25_sockaddr old;
                    533: 
                    534:        oldp = &old;
                    535:        newp = mtod (m, struct sockaddr_x25 *);
                    536:        bzero ((caddr_t)oldp, sizeof (*oldp));
                    537: 
                    538:        oldp -> xaddr_facilities = newp -> x25_opts.op_flags & X25_REVERSE_CHARGE;
                    539:        if (newp -> x25_opts.op_psize == X25_PS128)
                    540:                oldp -> xaddr_facilities |= XS_HIPRIO;  /* Datapac specific */
                    541:        ocp = (char *)oldp -> xaddr_addr;
                    542:        ncp = newp -> x25_addr;
                    543:        while (*ncp) {
                    544:                *ocp++ = *ncp++;
                    545:                oldp -> xaddr_len++;
                    546:        }
                    547: 
                    548:        bcopy (newp -> x25_udata, (caddr_t)oldp -> xaddr_proto, 4);
                    549:        if (newp -> x25_udlen > 4)
                    550:                bcopy (newp -> x25_udata + 4, (caddr_t)oldp -> xaddr_userdata,
                    551:                        (unsigned)(newp -> x25_udlen - 4));
                    552: 
                    553:        bcopy ((caddr_t)oldp, mtod (m, char *), sizeof (*oldp));
                    554:        m -> m_len = sizeof (*oldp);
                    555: }
                    556: 
                    557: 
                    558: pk_checksockaddr (m)
                    559: struct mbuf *m;
                    560: {
                    561:        register struct sockaddr_x25 *sa = mtod (m, struct sockaddr_x25 *);
                    562:        register char *cp;
                    563: 
                    564:        if (m -> m_len != sizeof (struct sockaddr_x25))
                    565:                return (1);
                    566:        if (sa -> x25_family != AF_CCITT ||
                    567:                sa -> x25_udlen > sizeof (sa -> x25_udata))
                    568:                return (1);
                    569:        for (cp = sa -> x25_addr; *cp; cp++) {
                    570:                if (*cp < '0' || *cp > '9' ||
                    571:                        cp >= &sa -> x25_addr[sizeof (sa -> x25_addr) - 1])
                    572:                        return (1);
                    573:        }
                    574:        return (0);
                    575: }
                    576: 
                    577: pk_send (lcp, m)
                    578: struct pklcd *lcp;
                    579: register struct mbuf *m;
                    580: {
                    581:        int mqbit = 0, error = 0;
                    582:        register struct x25_packet *xp;
                    583:        register struct socket *so;
                    584: 
                    585:        if (m -> m_type == MT_OOBDATA) {
                    586:                if (lcp -> lcd_intrconf_pending)
                    587:                        error = ETOOMANYREFS;
                    588:                if (m -> m_pkthdr.len > 32)
                    589:                        error = EMSGSIZE;
                    590:                M_PREPEND(m, PKHEADERLN, M_WAITOK);
                    591:                if (m == 0 || error)
                    592:                        goto bad;
                    593:                *(mtod (m, octet *)) = 0;
                    594:                xp = mtod (m, struct x25_packet *);
                    595:                X25SBITS(xp -> bits, fmt_identifier, 1);
                    596:                xp -> packet_type = X25_INTERRUPT;
                    597:                SET_LCN(xp, lcp -> lcd_lcn);
                    598:                sbinsertoob ( (so = lcp -> lcd_so) ?
                    599:                        &so -> so_snd : &lcp -> lcd_sb, m);
                    600:                goto send;
                    601:        }
                    602:        /*
                    603:         * Application has elected (at call setup time) to prepend
                    604:         * a control byte to each packet written indicating m-bit
                    605:         * and q-bit status.  Examine and then discard this byte.
                    606:         */
                    607:        if (lcp -> lcd_flags & X25_MQBIT) {
                    608:                if (m -> m_len < 1) {
                    609:                        m_freem (m);
                    610:                        return (EMSGSIZE);
                    611:                }
                    612:                mqbit = *(mtod (m, u_char *));
                    613:                m -> m_len--;
                    614:                m -> m_data++;
                    615:                m -> m_pkthdr.len--;
                    616:        }
                    617:        error = pk_fragment (lcp, m, mqbit & 0x80, mqbit & 0x40, 1);
                    618: send:
                    619:        if (error == 0 && lcp -> lcd_state == DATA_TRANSFER)
                    620:                lcp -> lcd_send (lcp); /* XXXXXXXXX fix pk_output!!! */
                    621:        return (error);
                    622: bad:
                    623:        if (m)
                    624:                m_freem (m);
                    625:        return (error);
                    626: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.