Annotation of 42BSD/sys/net/raw_usrreq.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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