Annotation of kernel/bsd/netat/aurp_aurpd.c, revision 1.1.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) 1996 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:  *     File: aurpd.c
                     36:  */
                     37: 
                     38: /*
                     39:  * Kernel process to implement the AURP daemon:
                     40:  *  manage tunnels to remote AURP servers across IP networks
                     41:  */
                     42: #ifdef _AIX
                     43: #include <sys/sleep.h>
                     44: #endif
                     45: #include <sysglue.h>
                     46: #ifdef _AIX
                     47: #include <sys/atomic_op.h>
                     48: #endif
                     49: #include <sys/socket.h>
                     50: #include <sys/socketvar.h>
                     51: #include <sys/protosw.h>
                     52: #include <sys/errno.h>
                     53: #include <netinet/in.h>
                     54: #include <at/appletalk.h>
                     55: #include <lap.h>
                     56: #include <routing_tables.h>
                     57: #define _AURP
                     58: #define _KERNSYS
                     59: #include <at/aurp.h>
                     60: #include <at_aurp.h>
                     61: 
                     62: 
                     63: #undef  e_sleep_thread
                     64: #define M_RCVBUF (64 * 1024)
                     65: #define M_SNDBUF (64 * 1024)
                     66: struct aurp_global_t aurp_global;
                     67: /*
                     68:  * Initialize the aurp pipe -
                     69:  * -Create, initialize, and start the aurpd kernel process; we need
                     70:  *  a process to permit queueing between the socket and the stream,
                     71:  *  which is necessary for orderly access to the socket structure.
                     72:  * -The user process (aurpd) is there to 'build' the AURP
                     73:  *  stream, act as a 'logging agent' (:-}), and hold open the stream
                     74:  *  during its use.
                     75:  * -Data and AURP packets from the DDP stream will be fed into the
                     76:  *  UDP tunnel (AURPsend())
                     77:  * -Data and AURP packets from the UDP tunnel will be fed into the
                     78:  *  DDP stream (ip_to_atalk(), via the kernel process).
                     79:  */
                     80: aurpd_start()
                     81: {      register int error;
                     82:        register struct socket *so;
                     83:        int maxbuf;
                     84:        extern void aurp_wakeup(caddr_t, int);
                     85: /****### TEMPO HACK 9/26: we need more args than that for suser in bsd4.4 
                     86:        if (!suser())
                     87:                return(EPERM);
                     88: */
                     89: 
                     90:        /*
                     91:         * Set up state prior to starting kernel process so we can back out
                     92:         *  (error return) if something goes wrong.
                     93:         */
                     94:        bzero((char *)&aurp_global.tunnel, sizeof(aurp_global.tunnel));
                     95:        /*lock_alloc(&aurp_global.glock, LOCK_ALLOC_PIN, AURP_EVNT_LOCK, -1);*/
                     96:        ATLOCKINIT(aurp_global.glock);
                     97:        ATEVENTINIT(aurp_global.event_anchor);
                     98: 
                     99:        /* open udp socket */
                    100:        if (aurp_global.udp_port == 0)
                    101:                aurp_global.udp_port = AURP_SOCKNUM;
                    102:        error = socreate(AF_INET, &aurp_global.tunnel, SOCK_DGRAM,
                    103:                         IPPROTO_UDP);
                    104:        if (error)
                    105:        {       dPrintf(D_M_AURP, D_L_FATAL, ("AURP: Can't get socket (%d)\n",
                    106:                        error));
                    107:                return(error);
                    108:        }
                    109: 
                    110:        so = aurp_global.tunnel;
                    111: 
                    112:        if (error = aurp_bindrp(so))
                    113:        {       dPrintf(D_M_AURP, D_L_FATAL,
                    114:                        ("AURP: Can't bind to port %d (%d)\n",
                    115:                        &aurp_global.udp_port, error));
                    116:                soclose(so);
                    117:                return(error);
                    118:        }
                    119: 
                    120: #ifdef _AIX
                    121:        SOCKET_LOCK(so);
                    122: #else
                    123:        sblock(&so->so_rcv, M_WAIT);
                    124:        sblock(&so->so_snd, M_WAIT);
                    125: #endif
                    126:        maxbuf = M_RCVBUF;
                    127:        setsockopt(so,SOL_SOCKET,SO_RCVBUF,&maxbuf,sizeof(maxbuf));
                    128:        maxbuf = M_SNDBUF;
                    129:        setsockopt(so,SOL_SOCKET,SO_SNDBUF,&maxbuf,sizeof(maxbuf));
                    130: #ifdef _AIX
                    131:        so->so_snd.sb_wakeup  = 0;
                    132:        so->so_snd.sb_wakearg = 0;
                    133:        so->so_rcv.sb_wakeup  = aurp_wakeup;
                    134:        so->so_rcv.sb_wakearg = (caddr_t)AE_UDPIP; /* Yuck */
                    135:        so->so_rcv.sb_iodone  = 0;
                    136:        so->so_rcv.sb_ioarg = 0;
                    137: #else
                    138:        so->so_upcall = aurp_wakeup;
                    139:        so->so_upcallarg = (caddr_t)AE_UDPIP; /* Yuck */
                    140: #endif
                    141: 
                    142:        so->so_state |= SS_NBIO;
                    143: #ifdef _AIX
                    144:        so->so_special |=(SP_NOUAREA|SP_EXTPRIV);
                    145: #else
                    146:        kprintf("aurpd: warning what do we do with so_special?");
                    147: #endif
                    148:        so->so_rcv.sb_flags |=(SB_SEL|SB_NOINTR);
                    149:        so->so_snd.sb_flags |=(SB_SEL|SB_NOINTR);
                    150: #ifdef _AIX
                    151:        SOCKET_UNLOCK(so);
                    152: #else
                    153:        sbunlock(&so->so_snd);
                    154:        sbunlock(&so->so_rcv);
                    155: #endif
                    156: 
                    157:        return(0);
                    158: }
                    159: 
                    160: AURPgetmsg(err)
                    161:        int *err;
                    162: {      register struct socket *so;
                    163:        register int s, events;
                    164: 
                    165:        so = aurp_global.tunnel;
                    166: 
                    167:        for (;;)
                    168:        {       gbuf_t *from, *p_mbuf;
                    169: #ifdef _AIX
                    170:                int flags = MSG_NONBLOCK;
                    171: #else
                    172:                int flags = MSG_DONTWAIT;
                    173: #endif
                    174:                struct uio auio;
                    175: 
                    176:                /*
                    177:                 * Wait for a package to arrive.  This will be from the
                    178:                 * IP side - sowakeup() calls aurp_wakeup()
                    179:                 *           when a packet arrives
                    180:                 */
                    181: 
                    182:                ATDISABLE(s, aurp_global.glock);
                    183:                events = aurp_global.event;
                    184:                if (events == 0)
                    185:                  {
                    186: #ifdef _AIX
                    187:                    e_sleep_thread(&aurp_global.event_anchor,
                    188:                                        &aurp_global.glock, LOCK_HANDLER);
                    189: #else
                    190:                    (void) tsleep(&aurp_global.event_anchor, PSOCK, "AURPgetmsg", 0);
                    191: #endif
                    192:                    events = aurp_global.event;
                    193:                    aurp_global.event = 0;
                    194:                  }     
                    195:                ATENABLE(s, aurp_global.glock);  
                    196: 
                    197:                if (events & AE_SHUTDOWN)
                    198:                  {     
                    199:                    aurp_global.shutdown = 1;
                    200:                    while (aurp_global.running)
                    201:                        ;
                    202:                    /*lock_free(&aurp_global.glock);*/
                    203:                    aurp_global.tunnel = 0;
                    204:                    aurp_global.event = 0;
                    205:                    soclose(so);
                    206:                    *err = ESHUTDOWN;
                    207:                    return -1;
                    208:                  }
                    209: 
                    210: 
                    211: 
                    212:                /*
                    213:                 * Set up the nominal uio structure -
                    214:                 *  give it no iov's, point off to non-existant user space,
                    215:                 *  but make sure the 'resid' count means somehting.
                    216:                 */
                    217: 
                    218:                auio.uio_iov = NULL;
                    219:                auio.uio_iovcnt = 0;
                    220:                auio.uio_segflg = UIO_SYSSPACE;
                    221:                auio.uio_offset = 0;                    /* XXX */
                    222: 
                    223:                /* Keep up an even flow... */
                    224:                for (;;)
                    225:                {       register int empty = 0;
                    226: 
                    227: /*
                    228:  * This should be large enough to encompass a full DDP packet plus
                    229:  *  domain header.
                    230:  */
                    231: #define A_LARGE_SIZE 700
                    232: #ifdef _AIX
                    233:                        flags = MSG_NONBLOCK;
                    234: #else
                    235:                        flags = MSG_DONTWAIT;
                    236: #endif
                    237:                        auio.uio_resid = A_LARGE_SIZE;
                    238:                        *err = soreceive(so, &from, &auio, &p_mbuf, 0, &flags);
                    239:                        dPrintf(D_M_AURP, D_L_WARNING,
                    240:                                ("aurpd: soreceive returned %d\n", *err));
                    241:                        /* soreceive() sets *mp to zero! at start */
                    242:                        if (p_mbuf)
                    243:                                ip_to_atalk(from, p_mbuf);
                    244:                        else
                    245:                          break;
                    246:                }
                    247:        }
                    248: 
                    249:        return -1;
                    250: }
                    251: 
                    252: /*
                    253:  * Wakeup the sleeping giant - we've put a message on his queue(s).
                    254:  * The arg indicates what queue has been updated.
                    255:  */
                    256: void aurp_wakeup(register caddr_t p, int state)
                    257: {      register int s;
                    258:        register int bit;
                    259: 
                    260:        bit = (int) p;
                    261:        ATDISABLE(s, aurp_global.glock);
                    262:        aurp_global.event |= bit;
                    263:        ATENABLE(s, aurp_global.glock);
                    264: #ifdef _AIX
                    265:        e_wakeup(&aurp_global.event_anchor);
                    266: #else
                    267:        thread_wakeup(&aurp_global.event_anchor);
                    268: #endif
                    269: }
                    270: 
                    271: /*
                    272:  * Try to bind to the specified reserved port.
                    273:  * Sort of like sobind(), but no suser() check.
                    274:  */
                    275: aurp_bindrp(so)
                    276:        register struct socket *so;
                    277: {
                    278:        struct sockaddr_in *sin;
                    279:        gbuf_t *m;
                    280:        u_short i;
                    281:        int error;
                    282:        struct ucred *savecred;
                    283: 
                    284:        m = (gbuf_t *)gbuf_alloc(sizeof(struct sockaddr_in));
                    285:        if (m == NULL) {
                    286:                dPrintf(D_M_AURP, D_L_ERROR,
                    287:                        ("aurp_bindrp: couldn't alloc mbuf"));
                    288:                return (ENOBUFS);
                    289:        }
                    290: 
                    291:        sin = (struct sockaddr_in *)gbuf_rptr(m);
                    292:        sin->sin_family = AF_INET;
                    293:        sin->sin_addr.s_addr = htons(aurp_global.src_addr);
                    294:        sin->sin_port = htons(aurp_global.udp_port);
                    295:        gbuf_len(m) = sizeof(struct sockaddr_in);
                    296: 
                    297: #ifdef _AIX
                    298:        SOCKET_LOCK(so);
                    299: #else
                    300:        sblock(&so->so_rcv, M_WAIT);
                    301:        sblock(&so->so_snd, M_WAIT);
                    302: #endif
                    303:        so->so_state |= SS_PRIV;
                    304:        error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, 0, m, 0);
                    305: #ifdef _AIX
                    306:        SOCKET_UNLOCK(so);
                    307: #else
                    308:        sbunlock(&so->so_snd);
                    309:        sbunlock(&so->so_rcv);
                    310: #endif
                    311: 
                    312:        (void) gbuf_freeb(m);
                    313:        return (error);
                    314: }
                    315: 
                    316: /*
                    317:  * receive from UDP
                    318:  * fp is the 'source address' mbuf; p_mbuf is the data mbuf.
                    319:  * Use the source address to find the 'node number' (index of the address),
                    320:  *  and pass that to the next stage.
                    321:  */
                    322: int ip_to_atalk(register gbuf_t *fp, register gbuf_t *p_mbuf)
                    323: {      register aurp_hdr_t *hdr;
                    324:        register domain_t *domain;
                    325:        unsigned char node;
                    326:        register struct sockaddr_in *rem_addr;
                    327: 
                    328:        rem_addr = (struct sockaddr_in *)gbuf_rptr(fp);
                    329:        /* determine the node where the packet came from */
                    330:        for (node=1; node <= dst_addr_cnt; node++) {
                    331:                if (aurp_global.dst_addr[node] == *(long *)&rem_addr->sin_addr)
                    332:                        break;
                    333:        }
                    334:        if (node > dst_addr_cnt) {
                    335:                dPrintf(D_M_AURP, D_L_WARNING,
                    336:                        ("AURPrecv: invalid node, %d.%x\n",
                    337:                        rem_addr->sin_port,
                    338:                        *(long *)&rem_addr->sin_addr));
                    339:                gbuf_freem(fp);
                    340:                gbuf_freem(p_mbuf);
                    341:                return -1;
                    342:        }
                    343: 
                    344:        /* validate the domain */
                    345:        domain = (domain_t *)gbuf_rptr(p_mbuf);
                    346:        if ( (domain->dst_length != IP_LENGTH) ||
                    347:            (domain->dst_authority != IP_AUTHORITY) ||
                    348:            (domain->version != AUD_Version) ||
                    349:            ((domain->type != AUD_Atalk) && (domain->type != AUD_AURP)) ) {
                    350:                dPrintf(D_M_AURP, D_L_WARNING,
                    351:                        ("AURPrecv: invalid domain, %d.%x\n",
                    352:                        rem_addr->sin_port,
                    353:                        *(long *)&rem_addr->sin_addr));
                    354:                gbuf_freem(fp);
                    355:                gbuf_freem(p_mbuf);
                    356:                return -1;
                    357:        }
                    358: 
                    359:        /* Remove domain header */
                    360:      p_mbuf->m_pkthdr.len -= IP_DOMAINSIZE;
                    361:        gbuf_rinc(p_mbuf,IP_DOMAINSIZE);
                    362:        gbuf_set_type(p_mbuf, MSG_DATA);
                    363: 
                    364:        /* forward the packet to the local AppleTalk stack */
                    365:        gbuf_freem(fp);
                    366:        at_insert(p_mbuf, domain->type, node);
                    367:        return 0;
                    368: }
                    369: 
                    370: /*
                    371:  * send to UDP
                    372:  * The real work has been done already.         Here, we just cobble together
                    373:  *  a sockaddr for the destination and call sosend().
                    374:  */
                    375: void
                    376: atalk_to_ip(register gbuf_t *m)
                    377: {      register domain_t *domain;
                    378:        int error;
                    379: #ifdef _AIX
                    380:        int flags = MSG_NONBLOCK;
                    381: #else
                    382:        int flags = MSG_DONTWAIT;
                    383: #endif
                    384:        struct sockaddr_in *rem_addr;
                    385:        register gbuf_t *mbp;
                    386: 
                    387:        m->m_type = MT_HEADER;
                    388:        m->m_pkthdr.len = gbuf_msgsize(m);
                    389:        m->m_pkthdr.rcvif = 0;
                    390: 
                    391:        /* Cons up a destination sockaddr */
                    392:        if ((mbp = (gbuf_t *)gbuf_alloc(sizeof(struct sockaddr_in))) == NULL)
                    393:        {
                    394: #ifdef _AIX
                    395:                (void)fetch_and_add((atomic_p)&aurp_global.no_mbufs, 1);
                    396: #endif
                    397:                gbuf_freem(m);
                    398:                return;
                    399:        }
                    400: 
                    401:        rem_addr = (struct sockaddr_in *)gbuf_rptr(mbp);
                    402:        bzero((char *)rem_addr, sizeof(rem_addr));
                    403:        rem_addr->sin_family = PF_INET;
                    404:        rem_addr->sin_port = aurp_global.udp_port;
                    405:        gbuf_len(mbp) = sizeof (struct sockaddr_in);
                    406:        domain = (domain_t *)gbuf_rptr(m);
                    407:        *(long *)&rem_addr->sin_addr = domain->dst_address;
                    408: 
                    409: #ifdef _AIX
                    410:        (void)fetch_and_add((atomic_p)&aurp_global.running, 1);
                    411: #endif
                    412:        if (aurp_global.shutdown) {
                    413:                gbuf_freem(m);
                    414:                gbuf_freeb(mbp);
                    415: #ifdef _AIX
                    416:                (void)fetch_and_add((atomic_p)&aurp_global.running, -1);
                    417: #endif
                    418:                return;
                    419:        }
                    420:        error = sosend(aurp_global.tunnel, mbp, NULL, m, NULL, flags);
                    421:        if (error)
                    422:        {       /*log error*/
                    423:          dPrintf(D_M_AURP, D_L_ERROR, ("AURP: sosend error (%d)\n",
                    424:                  error));
                    425:        }
                    426: 
                    427:        gbuf_freeb(mbp);
                    428: #ifdef _AIX    
                    429:        (void)fetch_and_add((atomic_p)&aurp_global.running, -1);
                    430: #endif
                    431:        return;
                    432: }
                    433: 
                    434: 

unix.superglobalmegacorp.com

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