Annotation of kernel/bsd/netat/ddp_proto.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*
        !            26:  *     Copyright (c) 1988, 1989, 1997, 1998 Apple Computer, Inc. 
        !            27:  *
        !            28:  *     The information contained herein is subject to change without
        !            29:  *     notice and  should not be  construed as a commitment by Apple
        !            30:  *     Computer, Inc. Apple Computer, Inc. assumes no responsibility
        !            31:  *     for any errors that may appear.
        !            32:  *
        !            33:  *     Confidential and Proprietary to Apple Computer, Inc.
        !            34:  */
        !            35: 
        !            36: /* ddp_proto.c: 2.0, 1.23; 10/18/93; Apple Computer, Inc. */
        !            37: 
        !            38: #include <sysglue.h>
        !            39: #ifdef _AIX
        !            40: #include <sys/sysmacros.h>
        !            41: #endif
        !            42: #include <sys/buf.h>
        !            43: #include <at/appletalk.h>
        !            44: #include <atlog.h>
        !            45: #include <lap.h>
        !            46: #include <at/ddp.h>
        !            47: #include <at/zip.h>
        !            48: #include <at/at_lap.h>
        !            49: #include <at_ddp.h>
        !            50: #include <at/elap.h>
        !            51: #include <h/at_elap.h>
        !            52: 
        !            53: extern atlock_t ddpall_lock;
        !            54: extern atlock_t ddpinp_lock;
        !            55: extern int ot_protoCnt;
        !            56: 
        !            57: #define DDPCLONEMIN    1
        !            58:  
        !            59: /* Pointer to LAP interface which DDP addresses are tied to */
        !            60: extern at_if_t   *ifID_table[];
        !            61: 
        !            62: ddp_dev_t        ddp_devs[DDP_SOCKET_LAST+1];
        !            63: 
        !            64: static void ddp_stop_ack();
        !            65: char ddp_off_flag;
        !            66: static gbuf_t *ddp_ack_m;
        !            67: static gref_t *ddp_ack_gref;
        !            68: 
        !            69: int
        !            70: lap_open(gref)
        !            71:        gref_t *gref;
        !            72: {
        !            73:        int rc;
        !            74: 
        !            75:        if ((rc = ddp_open(gref)) == 0)
        !            76:                ((ddp_dev_t *)gref->info)->pid = 0; 
        !            77:        return rc;
        !            78: }
        !            79: 
        !            80: int
        !            81: ddp_open(gref)
        !            82:        gref_t *gref;
        !            83: {
        !            84:        int s;
        !            85:        int i;
        !            86: 
        !            87:        if ((ot_protoCnt >= 3) && !ifID_table[IFID_HOME]) {
        !            88:                return(ENETDOWN);
        !            89:        }
        !            90: 
        !            91:        /*
        !            92:         *      If not ready, return error
        !            93:         */
        !            94:        if (ddp_off_flag)
        !            95:                return ENOTREADY;
        !            96: 
        !            97:        /* Look for an unused minor number */
        !            98:        ATDISABLE(s, ddpall_lock);
        !            99:        for (i=DDPCLONEMIN; i <= DDP_SOCKET_LAST; i++) {
        !           100:                if (!ddp_devs[i].flags) {
        !           101:                        break;  /* Either ALLOCATED or SHUTDOWN */
        !           102:                }
        !           103:        }
        !           104: 
        !           105:        if (i > DDP_SOCKET_LAST) {
        !           106:                ATENABLE(s, ddpall_lock);
        !           107:                return(EADDRNOTAVAIL);
        !           108:        }
        !           109: 
        !           110:        /* If we arrive here, i is the minor number to be
        !           111:         * allocated for this stream.
        !           112:         */
        !           113:        ddp_devs[i].flags |= DDPF_ALLOCATED;
        !           114:        ddp_devs[i].proto = 0;
        !           115:        ddp_devs[i].sock_entry = NULL;
        !           116:        ddp_devs[i].pid = gref->pid;
        !           117:        gref->info = (void *)&ddp_devs[i];
        !           118:        ATENABLE(s, ddpall_lock);
        !           119: 
        !           120:        return(0);
        !           121: }
        !           122: 
        !           123: int
        !           124: ddp_close(gref)
        !           125:        gref_t *gref;
        !           126: {
        !           127:        int s;
        !           128:        int rc = 0;
        !           129:  
        !           130:        /*
        !           131:         * Free the entry for this queue in the ddp_devs table.
        !           132:         * Can clear both DDPF_ALLOCATED, DDPF_SHUTDOWN since this is the
        !           133:         *  "last close" for this device.
        !           134:         */
        !           135:        ATDISABLE(s, ddpall_lock);
        !           136:        ((ddp_dev_t *)gref->info)->flags = 0;
        !           137: 
        !           138:        /* protect against the case where close is done on socket that's
        !           139:         * not bound
        !           140:         */
        !           141:        if (DDP_SOCKENTRY(gref))
        !           142:                rc = ddp_close_socket(DDP_SOCKENTRY(gref));
        !           143:        ATENABLE(s, ddpall_lock);
        !           144:        return rc;
        !           145: }
        !           146: 
        !           147: int ddp_putmsg(gref, mp)
        !           148:        gref_t *gref;
        !           149:        gbuf_t *mp;
        !           150: {
        !           151:        extern char ot_protoT[];
        !           152:        ddp_socket_t    socket;
        !           153:        register ioc_t  *iocbp;
        !           154:        register int    error;
        !           155:        at_ddp_t *ddp;
        !           156:        at_inet_t *addr;
        !           157:        gbuf_t *ymp;
        !           158:        union at_ddpopt *ddpopt;
        !           159: 
        !           160:        switch(gbuf_type(mp)) {
        !           161:        case MSG_DATA :
        !           162:                /* If this message is going out on a socket that's not bound, 
        !           163:                 * nail it.
        !           164:                 */
        !           165:        ddp = (at_ddp_t *)gbuf_rptr(mp);
        !           166:        if (ot_protoT[ddp->type]) {
        !           167:                if ((gref == 0) || !DDP_SOCKENTRY(gref)) {
        !           168:                        int src_addr_included = ((ddp->type==3) && ddp->src_node)? 1 : 0;
        !           169:                        if (ddp_output(&mp, ddp->src_socket, src_addr_included) != 0) {
        !           170:                                do {
        !           171:                                        ymp = gbuf_next(mp);
        !           172:                                        gbuf_next(mp) = 0;
        !           173:                                        gbuf_freem(mp);
        !           174:                                        mp = ymp;
        !           175:                                } while (mp);
        !           176:                        }
        !           177:                        return;
        !           178:                }
        !           179:        }
        !           180:                if (gref && !DDP_SOCKENTRY(gref)) {
        !           181:                        data_error(ENOTCONN, mp, gref);
        !           182:                        return;
        !           183:                }
        !           184: 
        !           185:                if ((error = ddp_output(&mp, DDP_SOCKNUM(gref), 0)) != 0)
        !           186:                  if (gref)
        !           187:                        data_error(error, mp, gref);
        !           188:                  else
        !           189:                        gbuf_freem(mp);
        !           190:                return;
        !           191: 
        !           192:        case MSG_IOCTL :
        !           193:                iocbp = (ioc_t *)gbuf_rptr(mp);
        !           194:                if (DDP_IOC_MYIOCTL(iocbp->ioc_cmd)) {
        !           195:                        switch(iocbp->ioc_cmd) {
        !           196:                        case DDP_IOC_GET_CFG :
        !           197:                                if (gbuf_cont(mp))
        !           198:                                        gbuf_freem(gbuf_cont(mp));
        !           199:                                if ((gbuf_cont(mp) = gbuf_alloc(sizeof(at_ddp_cfg_t),
        !           200:                                        PRI_MED)) == NULL) {
        !           201:                                  if (gref == 0) {
        !           202:                                        iocbp->ioc_error = ENOBUFS;
        !           203:                                        gbuf_set_type(mp, MSG_IOCNAK);
        !           204:                                        if (iocbp->ioc_error == 3)
        !           205:                                                atp_input(mp);
        !           206:                                        else
        !           207:                                                adsp_input(mp);
        !           208:                                  } else
        !           209:                                        ioc_ack(ENOBUFS, mp, gref);
        !           210:                                        break;
        !           211:                                }
        !           212:                          if (gref == 0) {
        !           213:                                ddp_get_cfg((at_ddp_cfg_t *)gbuf_rptr(gbuf_cont(mp)),
        !           214:                                        iocbp->ioc_count);
        !           215:                          } else
        !           216:                                ddp_get_cfg((at_ddp_cfg_t *)gbuf_rptr(gbuf_cont(mp)),
        !           217:                                        DDP_SOCKNUM(gref));
        !           218:                                gbuf_wset(gbuf_cont(mp),sizeof(at_ddp_cfg_t));
        !           219:                                iocbp->ioc_count = sizeof(at_ddp_cfg_t);
        !           220:                          if (gref == 0) {
        !           221:                                gbuf_set_type(mp, MSG_IOCACK);
        !           222:                                error = iocbp->ioc_error;
        !           223:                                iocbp->ioc_error = 0;
        !           224:                                if (error == 3)
        !           225:                                        atp_input(mp);
        !           226:                                else
        !           227:                                        adsp_input(mp);
        !           228:                          } else
        !           229:                                ioc_ack(0, mp, gref);
        !           230:                                break;
        !           231:                        case DDP_IOC_GET_STATS :
        !           232:                                if (gbuf_cont(mp))
        !           233:                                        gbuf_freem(gbuf_cont(mp));
        !           234:                                if ((gbuf_cont(mp) = gbuf_alloc(sizeof(at_ddp_stats_t),
        !           235:                                        PRI_MED)) == NULL) {
        !           236:                                        ioc_ack(ENOBUFS, mp, gref);
        !           237:                                        break;
        !           238:                                }
        !           239:                                ddp_get_stats(
        !           240:                                        (at_ddp_stats_t *)gbuf_rptr(gbuf_cont(mp)));
        !           241:                                gbuf_wset(gbuf_cont(mp),sizeof(at_ddp_stats_t));
        !           242:                                iocbp->ioc_count = sizeof(at_ddp_stats_t);
        !           243:                                ioc_ack(0, mp, gref);
        !           244:                                break;
        !           245:                        case DDP_IOC_BIND_SOCK :
        !           246:                                if ((iocbp->ioc_count < sizeof(at_socket)) ||
        !           247:                                        (gbuf_cont(mp) == NULL) ||
        !           248:                                        (gbuf_len(gbuf_cont(mp)) < sizeof(at_socket))) {
        !           249:                                        ioc_ack(EMSGSIZE, mp, gref);
        !           250:                                        break;
        !           251:                                }
        !           252:                                socket.number= *(at_socket *)gbuf_rptr(gbuf_cont(mp));
        !           253:                                socket.flags = 0;
        !           254:                                socket.sock_u.gref = gref;
        !           255:                                socket.dev = (void *)gref->info;
        !           256:                                if ((error = ddp_bind_socket(&socket)) != 0) {
        !           257:                                        ioc_ack(error, mp, gref);
        !           258:                                        break;
        !           259:                                } else {
        !           260:                                        DDP_SOCKENTRY(gref) = &ddp_socket[socket.number];
        !           261:                                        DDP_SOCKENTRY(gref)->otChecksum = 0;
        !           262:                                        DDP_SOCKENTRY(gref)->otType = 0;
        !           263:                                        DDP_SOCKENTRY(gref)->otPeerAddr = 0;
        !           264:                                        ddp_socket[socket.number].dev = (void *)gref->info;
        !           265:                                        *(at_socket *)gbuf_rptr(gbuf_cont(mp)) = socket.number;
        !           266:                                        ioc_ack(0, mp, gref);
        !           267:                                }
        !           268:                                break;
        !           269:                        case DDP_IOC_SET_PROTO :
        !           270:                                ((ddp_dev_t *)gref->info)->proto = *(u_char *)gbuf_rptr(gbuf_cont(mp));
        !           271:                                ioc_ack(0, mp, gref);
        !           272:                                break;
        !           273:                        case DDP_IOC_SET_OPTS:
        !           274:                                if (DDP_SOCKENTRY(gref) == NULL) {
        !           275:                                        ioc_ack(ENOTREADY, mp, gref);
        !           276:                                        break;
        !           277:                                }
        !           278:                                if (gbuf_cont(mp) != NULL) {
        !           279:                                        ddpopt = (union at_ddpopt *)gbuf_rptr(gbuf_cont(mp));
        !           280:                                        DDP_SOCKENTRY(gref)->otChecksum = ddpopt->ct.checksum;
        !           281:                                        DDP_SOCKENTRY(gref)->otType = ddpopt->ct.type;
        !           282:                                }
        !           283:                                ioc_ack(0, mp, gref);
        !           284:                                break;
        !           285:                        case DDP_IOC_GET_OPTS:
        !           286:                                if (DDP_SOCKENTRY(gref) == NULL) {
        !           287:                                        ioc_ack(ENOTREADY, mp, gref);
        !           288:                                        break;
        !           289:                                }
        !           290:                                if ((gbuf_cont(mp) == NULL)
        !           291:                                                && (gbuf_cont(mp) = gbuf_alloc(sizeof(union at_ddpopt),
        !           292:                                        PRI_MED)) == NULL) {
        !           293:                                        ioc_ack(ENOBUFS, mp, gref);
        !           294:                                        break;
        !           295:                                }
        !           296:                                gbuf_wset(gbuf_cont(mp),sizeof(union at_ddpopt));
        !           297:                                ddpopt = (union at_ddpopt *)gbuf_rptr(gbuf_cont(mp));
        !           298:                                ddpopt->ct.checksum = DDP_SOCKENTRY(gref)->otChecksum;
        !           299:                                ddpopt->ct.type = DDP_SOCKENTRY(gref)->otType;
        !           300:                                ioc_ack(0, mp, gref);
        !           301:                                break;
        !           302:                        case DDP_IOC_GET_SOCK:
        !           303:                        case DDP_IOC_GET_PEER:
        !           304:                                if (DDP_SOCKENTRY(gref) == NULL) {
        !           305:                                        ioc_ack(ENOTREADY, mp, gref);
        !           306:                                        break;
        !           307:                                }
        !           308:                                if ((gbuf_cont(mp) == NULL)
        !           309:                                                && (gbuf_cont(mp) = gbuf_alloc(sizeof(at_inet_t),
        !           310:                                        PRI_MED)) == NULL) {
        !           311:                                        ioc_ack(ENOBUFS, mp, gref);
        !           312:                                        break;
        !           313:                                }
        !           314:                                gbuf_wset(gbuf_cont(mp),sizeof(at_inet_t));
        !           315:                                addr = (at_inet_t *)gbuf_rptr(gbuf_cont(mp));
        !           316:                                if (iocbp->ioc_cmd == DDP_IOC_GET_SOCK) {
        !           317:                                        bzero((char *)addr, sizeof(at_inet_t));
        !           318:                                        addr->socket = DDP_SOCKENTRY(gref)->number;
        !           319:                                        if (ifID_table[IFID_HOME]) {
        !           320:                                                addr->node =
        !           321:                                                        ifID_table[IFID_HOME]->ifThisNode.atalk_node;
        !           322:                                                *(unsigned short *)addr->net = *(unsigned short *)
        !           323:                                                        ifID_table[IFID_HOME]->ifThisNode.atalk_net;
        !           324:                                        }
        !           325:                                } else
        !           326:                                        *addr = *(at_inet_t *)&DDP_SOCKENTRY(gref)->otPeerAddr;
        !           327:                                ioc_ack(0, mp, gref);
        !           328:                                break;
        !           329:                        case DDP_IOC_SET_PEER:
        !           330:                                if (DDP_SOCKENTRY(gref) == NULL) {
        !           331:                                        ioc_ack(ENOTREADY, mp, gref);
        !           332:                                        break;
        !           333:                                }
        !           334:                                if (gbuf_cont(mp) == NULL) {
        !           335:                                        ioc_ack(EINVAL, mp, gref);
        !           336:                                        break;
        !           337:                                }
        !           338:                                *(at_inet_t *)&DDP_SOCKENTRY(gref)->otPeerAddr =
        !           339:                                        *(at_inet_t *)gbuf_rptr(gbuf_cont(mp));
        !           340:                                ioc_ack(0, mp, gref);
        !           341:                                break;
        !           342:                        }
        !           343:                } else if (ZIP_IOC_MYIOCTL(iocbp->ioc_cmd)) {
        !           344:                        zip_ioctl(gref, mp);
        !           345:                        break;
        !           346:                } else {
        !           347:                        /* Unknown ioctl */
        !           348:                        ioc_ack(EINVAL, mp, gref);
        !           349:                }
        !           350:                break;
        !           351:        case MSG_PROTO:
        !           352:                if (((ddp_dev_t *)gref->info)->flags & DDPF_SI)
        !           353:                        si_ddp_proto_req(gref, mp);
        !           354:                else
        !           355:                        gbuf_freem(mp);
        !           356:                break;
        !           357:        case MSG_CTL:
        !           358:                /* *** this should never happen *** */
        !           359:                kprintf("ddp_putmsg: MSG_CTL received/n");
        !           360:                gbuf_freem(mp);
        !           361:                break;
        !           362:        case MSG_IOCACK:
        !           363:                ddp_stop_ack(gref, mp);
        !           364:                break;
        !           365:        default :
        !           366:                gbuf_freem(mp);
        !           367:                break;
        !           368:        }
        !           369:        return;
        !           370: } /* ddp_putmsg */
        !           371: 
        !           372: char   *
        !           373: ddps_init()
        !           374: {      register int i;
        !           375:        register ddp_dev_t *d;
        !           376: 
        !           377:        for (i=0, d=ddp_devs; i < DDP_SOCKET_LAST;i++, d++)
        !           378:                d->sock_entry = NULL;
        !           379: 
        !           380:        /* A non-zero value to keep ddp_init happy */
        !           381:        return ((char *)1);
        !           382: }
        !           383: 
        !           384: 
        !           385: int ddps_shutdown(grefInput)
        !           386: gref_t *grefInput;
        !           387: {
        !           388:        /* Network is shutting down... send error messages up on each open
        !           389:         * socket
        !           390:         */
        !           391:        register gbuf_t         *mp, *mp2;
        !           392:        register gref_t *gref;
        !           393:        register at_socket      socket;
        !           394:        register ddp_socket_t   *socketp;
        !           395:        register int            do_timeout = 0;
        !           396: 
        !           397:        if ((mp = gbuf_alloc(1, PRI_HI)) == NULL) {
        !           398:                goto later;
        !           399:        }
        !           400: 
        !           401:        gbuf_wset(mp, 1);
        !           402:        gbuf_set_type(mp, MSG_ERROR);
        !           403:        *gbuf_rptr(mp) = ESHUTDOWN;
        !           404: 
        !           405:        for (socket = 1, socketp = &ddp_socket[1]; socket <= DDP_SOCKET_LAST;
        !           406:                socket++, socketp++) {
        !           407:                if (gref = socketp->sock_u.gref) {
        !           408:                        if (mp2 = (gbuf_t *)gbuf_copym(mp)) {
        !           409:                                if (socketp->flags & DDP_CALL_HANDLER)
        !           410:                                        (*socketp->sock_u.handler)(mp2, 0);
        !           411:                                else
        !           412:                                        atalk_putnext(gref, mp2);
        !           413:                        } else {
        !           414:                                /* Out of buffers, wait a while...
        !           415:                                 */
        !           416:                                do_timeout = 1;
        !           417:                                ddp_devs[socketp->number].flags
        !           418:                                        |= DDPF_SHUTDOWN;
        !           419:                                continue;
        !           420:                        }
        !           421:                }
        !           422:        }
        !           423: 
        !           424:        gbuf_freem(mp);
        !           425:        if (do_timeout)
        !           426:                goto later;
        !           427:        return;
        !           428: 
        !           429: later:
        !           430:        atalk_timeout(ddps_shutdown, grefInput, SYS_HZ/10);
        !           431:        return;
        !           432: }
        !           433: 
        !           434: gbuf_t  *ddp_compress_msg(mp)
        !           435: register gbuf_t        *mp;
        !           436: {
        !           437:         register gbuf_t   *tmp;
        !           438: 
        !           439:         while (gbuf_len(mp) == 0) {
        !           440:                 tmp = mp;
        !           441:                 mp = gbuf_cont(mp);
        !           442:                 gbuf_freeb(tmp);
        !           443: 
        !           444:                if (mp == NULL)
        !           445:                        break;
        !           446:        }
        !           447:        return (mp);
        !           448: }
        !           449: 
        !           450: int
        !           451: si_ddp_proto_req(gref, mp)
        !           452:     gref_t *gref;
        !           453:     gbuf_t *mp;
        !           454: {
        !           455:     at_ddp_t *ddp;
        !           456:     at_inet_t *remaddr;
        !           457:     gbuf_t *xmp = gbuf_cont(mp);
        !           458: 
        !           459:     if ((DDP_SOCKENTRY(gref) == NULL) || (xmp == NULL)) {
        !           460:         gbuf_freem(mp);
        !           461:         return(-1);
        !           462:     }
        !           463: 
        !           464:     if (gbuf_len(mp) == 1) {
        !           465:         remaddr = (at_inet_t *)&DDP_SOCKENTRY(gref)->otPeerAddr;
        !           466:         if (remaddr->socket == 0) {
        !           467:             gbuf_freem(mp);
        !           468:             return(-1);
        !           469:         }
        !           470:     } else
        !           471:         remaddr = (at_inet_t *)gbuf_rptr(mp);
        !           472: 
        !           473:     gbuf_rinc(xmp,DDP_X_HDR_SIZE);
        !           474:     ddp = (at_ddp_t *)gbuf_rptr(mp);
        !           475:     *(unsigned short *)&ddp->checksum = DDP_SOCKENTRY(gref)->otChecksum;
        !           476:     ddp->length = gbuf_len(xmp);
        !           477:     ddp->dst_socket = remaddr->socket;
        !           478:     ddp->dst_node = remaddr->node;
        !           479:     ddp->type = DDP_SOCKENTRY(gref)->otType;
        !           480:     *(unsigned short *)&ddp->dst_net = *(unsigned short *)&remaddr->net;
        !           481:     gbuf_freeb(mp);
        !           482:     if (ddp_output(&xmp, DDP_SOCKENTRY(gref)->number, 0) != 0) {
        !           483:         gbuf_freem(xmp);
        !           484:         return(-1);
        !           485:     }
        !           486: 
        !           487:     return( 0);
        !           488: }
        !           489: 
        !           490: int
        !           491: si_ddp_input(gref, mp)
        !           492:     gref_t *gref;
        !           493:     gbuf_t  *mp;
        !           494: {
        !           495:     gbuf_t *xmp;
        !           496:     at_ddp_t *ddp;
        !           497:     at_inet_t *remaddr;
        !           498: 
        !           499:     /*
        !           500:      * allocate a buffer for the M_PROTO
        !           501:      */
        !           502:     if ((xmp = gbuf_alloc(sizeof(at_inet_t), PRI_MED)) == NULL) {
        !           503:         gbuf_freem(mp);
        !           504:         return(ENOBUFS);
        !           505:     }
        !           506:     gbuf_cont(xmp) = mp;
        !           507: 
        !           508:     /*
        !           509:      * construct the M_PROTO
        !           510:      */
        !           511:     ddp = (at_ddp_t *)gbuf_rptr(mp);
        !           512:     gbuf_rinc(mp,DDP_X_HDR_SIZE);
        !           513:     gbuf_wset(xmp,sizeof(at_inet_t));
        !           514:     remaddr = (at_inet_t *)gbuf_rptr(xmp);
        !           515:     remaddr->socket = ddp->src_socket;
        !           516:     remaddr->node = ddp->src_node;
        !           517:     *(unsigned short *)&remaddr->net = *(unsigned short *)&ddp->src_net;
        !           518:     gbuf_set_type(xmp, MSG_PROTO);
        !           519: 
        !           520:     /*
        !           521:      * send the M_PROTO upstream
        !           522:      */
        !           523:     atalk_putnext(gref, xmp);
        !           524:     return(0);
        !           525: }
        !           526: 
        !           527: /*
        !           528:  * stop DDP now
        !           529:  */
        !           530: void
        !           531: ddp_stop(mioc, gref)
        !           532:        gbuf_t *mioc;
        !           533:        gref_t *gref;
        !           534: {
        !           535:        unsigned char flag;
        !           536:        int k, s, *x_wptr;
        !           537:        ddp_dev_t *dev;
        !           538:        gbuf_t *m = gbuf_cont(mioc);
        !           539: 
        !           540:        ATDISABLE(s, ddpinp_lock);
        !           541:        if ((flag = *gbuf_rptr(m)) != 0)
        !           542:                ddp_off_flag = 1;
        !           543: 
        !           544:        x_wptr = (int *)gbuf_wptr(m);
        !           545:        for (k=0; k < (DDP_SOCKET_LAST+1); k++) {
        !           546:                dev = &ddp_devs[k];
        !           547:                if ((dev->flags == 0) || (dev->pid == 0))
        !           548:                        continue;
        !           549:                *(int *)gbuf_wptr(m) = dev->pid;
        !           550:                gbuf_winc(m,sizeof(int));
        !           551:        }
        !           552:        ATENABLE(s, ddpinp_lock);
        !           553: 
        !           554:        while (x_wptr != (int *)gbuf_wptr(m)) {
        !           555:                dPrintf(D_M_DDP,D_L_TRACE, ("ddp_stop: pid=%d\n", *x_wptr));
        !           556:                x_wptr++;
        !           557:        }
        !           558: 
        !           559:        ddp_ack_m = mioc;
        !           560:        ddp_ack_gref = gref;
        !           561:        gbuf_rptr(m)[1] = 0;
        !           562:        gbuf_set_type(m, MSG_IOCTL);
        !           563:        atp_input(m);
        !           564: }
        !           565: 
        !           566: static void
        !           567: ddp_stop_ack(gref, m)
        !           568:        gref_t *gref;
        !           569:        gbuf_t *m;
        !           570: {
        !           571:        static int gotADSPinput = 0;
        !           572: 
        !           573:        if (!gotADSPinput) {
        !           574:                dPrintf(D_M_DDP,D_L_INFO,
        !           575:                        ("ddp_stop_ack: CHECK_STATE...1\n"));
        !           576:                gotADSPinput = 1;
        !           577:                gbuf_set_type(m, MSG_IOCTL);
        !           578:                adsp_input(m);
        !           579:        } else {
        !           580:                dPrintf(D_M_DDP,D_L_INFO,
        !           581:                        ("ddp_stop_ack: CHECK_STATE...2\n"));
        !           582:                gotADSPinput = 0;
        !           583:                gbuf_rinc(m,sizeof(int));
        !           584:                gbuf_set_type(m, MSG_DATA);
        !           585:                ((ioc_t *)gbuf_rptr(ddp_ack_m))->ioc_count = gbuf_msgsize(m);
        !           586:                ioc_ack(0, ddp_ack_m, ddp_ack_gref);
        !           587:        }
        !           588: }

unix.superglobalmegacorp.com

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