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

unix.superglobalmegacorp.com

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