Annotation of 43BSDTahoe/sys/net/raw_usrreq.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980, 1986 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  *
                     17:  *     @(#)raw_usrreq.c        7.4 (Berkeley) 6/27/88
                     18:  */
                     19: 
                     20: #include "param.h"
                     21: #include "mbuf.h"
                     22: #include "domain.h"
                     23: #include "protosw.h"
                     24: #include "socket.h"
                     25: #include "socketvar.h"
                     26: #include "errno.h"
                     27: 
                     28: #include "if.h"
                     29: #include "route.h"
                     30: #include "netisr.h"
                     31: #include "raw_cb.h"
                     32: 
                     33: #include "../machine/mtpr.h"
                     34: 
                     35: /*
                     36:  * Initialize raw connection block q.
                     37:  */
                     38: raw_init()
                     39: {
                     40: 
                     41:        rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
                     42:        rawintrq.ifq_maxlen = IFQ_MAXLEN;
                     43: }
                     44: 
                     45: /*
                     46:  * Raw protocol interface.
                     47:  */
                     48: raw_input(m0, proto, src, dst)
                     49:        struct mbuf *m0;
                     50:        struct sockproto *proto;
                     51:        struct sockaddr *src, *dst;
                     52: {
                     53:        register struct mbuf *m;
                     54:        struct raw_header *rh;
                     55:        int s;
                     56: 
                     57:        /*
                     58:         * Rip off an mbuf for a generic header.
                     59:         */
                     60:        m = m_get(M_DONTWAIT, MT_HEADER);
                     61:        if (m == 0) {
                     62:                m_freem(m0);
                     63:                return;
                     64:        }
                     65:        m->m_next = m0;
                     66:        m->m_len = sizeof(struct raw_header);
                     67:        rh = mtod(m, struct raw_header *);
                     68:        rh->raw_dst = *dst;
                     69:        rh->raw_src = *src;
                     70:        rh->raw_proto = *proto;
                     71: 
                     72:        /*
                     73:         * Header now contains enough info to decide
                     74:         * which socket to place packet in (if any).
                     75:         * Queue it up for the raw protocol process
                     76:         * running at software interrupt level.
                     77:         */
                     78:        s = splimp();
                     79:        if (IF_QFULL(&rawintrq))
                     80:                m_freem(m);
                     81:        else
                     82:                IF_ENQUEUE(&rawintrq, m);
                     83:        splx(s);
                     84:        schednetisr(NETISR_RAW);
                     85: }
                     86: 
                     87: /*
                     88:  * Raw protocol input routine.  Process packets entered
                     89:  * into the queue at interrupt time.  Find the socket
                     90:  * associated with the packet(s) and move them over.  If
                     91:  * nothing exists for this packet, drop it.
                     92:  */
                     93: rawintr()
                     94: {
                     95:        int s;
                     96:        struct mbuf *m;
                     97:        register struct rawcb *rp;
                     98:        register struct raw_header *rh;
                     99:        struct socket *last;
                    100: 
                    101: next:
                    102:        s = splimp();
                    103:        IF_DEQUEUE(&rawintrq, m);
                    104:        splx(s);
                    105:        if (m == 0)
                    106:                return;
                    107:        rh = mtod(m, struct raw_header *);
                    108:        last = 0;
                    109:        for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
                    110:                if (rp->rcb_proto.sp_family != rh->raw_proto.sp_family)
                    111:                        continue;
                    112:                if (rp->rcb_proto.sp_protocol  &&
                    113:                    rp->rcb_proto.sp_protocol != rh->raw_proto.sp_protocol)
                    114:                        continue;
                    115:                /*
                    116:                 * We assume the lower level routines have
                    117:                 * placed the address in a canonical format
                    118:                 * suitable for a structure comparison.
                    119:                 */
                    120: #define equal(a1, a2) \
                    121:        (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
                    122:                if ((rp->rcb_flags & RAW_LADDR) &&
                    123:                    !equal(rp->rcb_laddr, rh->raw_dst))
                    124:                        continue;
                    125:                if ((rp->rcb_flags & RAW_FADDR) &&
                    126:                    !equal(rp->rcb_faddr, rh->raw_src))
                    127:                        continue;
                    128:                if (last) {
                    129:                        struct mbuf *n;
                    130:                        if (n = m_copy(m->m_next, 0, (int)M_COPYALL)) {
                    131:                                if (sbappendaddr(&last->so_rcv, &rh->raw_src,
                    132:                                    n, (struct mbuf *)0) == 0)
                    133:                                        /* should notify about lost packet */
                    134:                                        m_freem(n);
                    135:                                else
                    136:                                        sorwakeup(last);
                    137:                        }
                    138:                }
                    139:                last = rp->rcb_socket;
                    140:        }
                    141:        if (last) {
                    142:                if (sbappendaddr(&last->so_rcv, &rh->raw_src,
                    143:                    m->m_next, (struct mbuf *)0) == 0)
                    144:                        m_freem(m->m_next);
                    145:                else
                    146:                        sorwakeup(last);
                    147:                (void) m_free(m);               /* header */
                    148:        } else
                    149:                m_freem(m);
                    150:        goto next;
                    151: }
                    152: 
                    153: /*ARGSUSED*/
                    154: raw_ctlinput(cmd, arg)
                    155:        int cmd;
                    156:        struct sockaddr *arg;
                    157: {
                    158: 
                    159:        if (cmd < 0 || cmd > PRC_NCMDS)
                    160:                return;
                    161:        /* INCOMPLETE */
                    162: }
                    163: 
                    164: /*ARGSUSED*/
                    165: raw_usrreq(so, req, m, nam, rights)
                    166:        struct socket *so;
                    167:        int req;
                    168:        struct mbuf *m, *nam, *rights;
                    169: {
                    170:        register struct rawcb *rp = sotorawcb(so);
                    171:        register int error = 0;
                    172: 
                    173:        if (req == PRU_CONTROL)
                    174:                return (EOPNOTSUPP);
                    175:        if (rights && rights->m_len) {
                    176:                error = EOPNOTSUPP;
                    177:                goto release;
                    178:        }
                    179:        if (rp == 0 && req != PRU_ATTACH) {
                    180:                error = EINVAL;
                    181:                goto release;
                    182:        }
                    183:        switch (req) {
                    184: 
                    185:        /*
                    186:         * Allocate a raw control block and fill in the
                    187:         * necessary info to allow packets to be routed to
                    188:         * the appropriate raw interface routine.
                    189:         */
                    190:        case PRU_ATTACH:
                    191:                if ((so->so_state & SS_PRIV) == 0) {
                    192:                        error = EACCES;
                    193:                        break;
                    194:                }
                    195:                if (rp) {
                    196:                        error = EINVAL;
                    197:                        break;
                    198:                }
                    199:                error = raw_attach(so, (int)nam);
                    200:                break;
                    201: 
                    202:        /*
                    203:         * Destroy state just before socket deallocation.
                    204:         * Flush data or not depending on the options.
                    205:         */
                    206:        case PRU_DETACH:
                    207:                if (rp == 0) {
                    208:                        error = ENOTCONN;
                    209:                        break;
                    210:                }
                    211:                raw_detach(rp);
                    212:                break;
                    213: 
                    214:        /*
                    215:         * If a socket isn't bound to a single address,
                    216:         * the raw input routine will hand it anything
                    217:         * within that protocol family (assuming there's
                    218:         * nothing else around it should go to). 
                    219:         */
                    220:        case PRU_CONNECT:
                    221:                if (rp->rcb_flags & RAW_FADDR) {
                    222:                        error = EISCONN;
                    223:                        break;
                    224:                }
                    225:                raw_connaddr(rp, nam);
                    226:                soisconnected(so);
                    227:                break;
                    228: 
                    229:        case PRU_CONNECT2:
                    230:                error = EOPNOTSUPP;
                    231:                goto release;
                    232: 
                    233:        case PRU_BIND:
                    234:                if (rp->rcb_flags & RAW_LADDR) {
                    235:                        error = EINVAL;                 /* XXX */
                    236:                        break;
                    237:                }
                    238:                error = raw_bind(so, nam);
                    239:                break;
                    240: 
                    241:        case PRU_DISCONNECT:
                    242:                if ((rp->rcb_flags & RAW_FADDR) == 0) {
                    243:                        error = ENOTCONN;
                    244:                        break;
                    245:                }
                    246:                raw_disconnect(rp);
                    247:                soisdisconnected(so);
                    248:                break;
                    249: 
                    250:        /*
                    251:         * Mark the connection as being incapable of further input.
                    252:         */
                    253:        case PRU_SHUTDOWN:
                    254:                socantsendmore(so);
                    255:                break;
                    256: 
                    257:        /*
                    258:         * Ship a packet out.  The appropriate raw output
                    259:         * routine handles any massaging necessary.
                    260:         */
                    261:        case PRU_SEND:
                    262:                if (nam) {
                    263:                        if (rp->rcb_flags & RAW_FADDR) {
                    264:                                error = EISCONN;
                    265:                                break;
                    266:                        }
                    267:                        raw_connaddr(rp, nam);
                    268:                } else if ((rp->rcb_flags & RAW_FADDR) == 0) {
                    269:                        error = ENOTCONN;
                    270:                        break;
                    271:                }
                    272:                error = (*so->so_proto->pr_output)(m, so);
                    273:                m = NULL;
                    274:                if (nam)
                    275:                        rp->rcb_flags &= ~RAW_FADDR;
                    276:                break;
                    277: 
                    278:        case PRU_ABORT:
                    279:                raw_disconnect(rp);
                    280:                sofree(so);
                    281:                soisdisconnected(so);
                    282:                break;
                    283: 
                    284:        case PRU_SENSE:
                    285:                /*
                    286:                 * stat: don't bother with a blocksize.
                    287:                 */
                    288:                return (0);
                    289: 
                    290:        /*
                    291:         * Not supported.
                    292:         */
                    293:        case PRU_RCVOOB:
                    294:        case PRU_RCVD:
                    295:                return(EOPNOTSUPP);
                    296: 
                    297:        case PRU_LISTEN:
                    298:        case PRU_ACCEPT:
                    299:        case PRU_SENDOOB:
                    300:                error = EOPNOTSUPP;
                    301:                break;
                    302: 
                    303:        case PRU_SOCKADDR:
                    304:                bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
                    305:                    sizeof (struct sockaddr));
                    306:                nam->m_len = sizeof (struct sockaddr);
                    307:                break;
                    308: 
                    309:        case PRU_PEERADDR:
                    310:                bcopy((caddr_t)&rp->rcb_faddr, mtod(nam, caddr_t),
                    311:                    sizeof (struct sockaddr));
                    312:                nam->m_len = sizeof (struct sockaddr);
                    313:                break;
                    314: 
                    315:        default:
                    316:                panic("raw_usrreq");
                    317:        }
                    318: release:
                    319:        if (m != NULL)
                    320:                m_freem(m);
                    321:        return (error);
                    322: }

unix.superglobalmegacorp.com

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