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

unix.superglobalmegacorp.com

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