Annotation of researchv8dc/sys/inet/udp_device.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * udp device driver.
                      3:  */
                      4: 
                      5: #include "udp.h"
                      6: #if NUDP
                      7: #include "../h/param.h"
                      8: #include "../h/systm.h"
                      9: #include "../h/stream.h"
                     10: #include "../h/ioctl.h"
                     11: #include "../h/ttyld.h"
                     12: #include "../h/buf.h"
                     13: #include "../h/conf.h"
                     14: #include "../h/inet/in.h"
                     15: #include "../h/inet/ip.h"
                     16: #include "../h/inet/ip_var.h"
                     17: #include "../h/inet/udp.h"
                     18: #include "../h/inet/udp_var.h"
                     19: #include "../h/inet/udp_user.h"
                     20: 
                     21: int    nodev(), udpdopen(), udpdclose(), udpdput();
                     22: int    udpdosrv();
                     23: static struct qinit udpdrinit = { nodev, NULL, udpdopen, udpdclose, 0, 0 };
                     24: static struct qinit udpdwinit = { udpdput, udpdosrv, udpdopen, udpdclose,
                     25:                                   UDP_BODY_LIMIT, 64 };
                     26: struct streamtab udpdinfo = { &udpdrinit, &udpdwinit };
                     27: 
                     28: int Nudp = NUDP;       /* for netstat */
                     29: struct udp udpconn[NUDP];
                     30: 
                     31: in_addr udpbaddst;
                     32: 
                     33: udpdopen(q, dev)
                     34: register struct queue *q;
                     35: dev_t dev;
                     36: {
                     37:        struct udp *udp;
                     38: 
                     39:        dev = minor(dev);
                     40:        if(dev >= NUDP)
                     41:                return(0);
                     42:        udp = &udpconn[dev];
                     43:        if(q->ptr)
                     44:                return(0);
                     45:        udp->rq = q;
                     46:        udp->flags = UDP_INIT;
                     47:        udp->head = udp->tail = 0;
                     48:        q->ptr = (caddr_t)udp;
                     49:        q->flag |= QDELIM;
                     50:        WR(q)->flag |= QBIGB;
                     51:        WR(q)->ptr = (caddr_t)udp;
                     52:        return(1);
                     53: }
                     54: 
                     55: udpdclose(q)
                     56: register struct queue *q;
                     57: {
                     58:        struct udp *udp;
                     59: 
                     60:        udp = (struct udp *)q->ptr;
                     61:        udp->rq = (struct queue *)0;
                     62:        q->ptr = (caddr_t)0;
                     63: }
                     64: 
                     65: udpdput(q, bp)
                     66: register struct queue *q;
                     67: register struct block *bp;
                     68: {
                     69:        struct udp *udp;
                     70:        int s, x;
                     71:        register union stmsg *sp;
                     72:        struct foo{
                     73:                u_long dst;
                     74:                u_long gate;
                     75:        } *foo;
                     76: 
                     77:        udp = (struct udp *)q->ptr;
                     78:        switch(bp->type){
                     79:        case M_IOCTL:
                     80:                bp->type = M_IOCNAK;
                     81:                bp->wptr = bp->rptr;
                     82:                qreply(q, bp);
                     83:                return;
                     84:        case M_DATA:
                     85:                putq(q, bp);
                     86:                break;
                     87:        case M_DELIM:
                     88:                putq(q, bp);
                     89:                qenable(q);
                     90:                break;
                     91:        default:
                     92:                freeb(bp);
                     93:                break;
                     94:        }
                     95: }
                     96: 
                     97: udpdosrv(q)
                     98: register struct queue *q;
                     99: {
                    100:        register struct block *bp;
                    101:        register struct udp *udp;
                    102: 
                    103:        udp = (struct udp *)q->ptr;
                    104:        while(bp = getq(q)){
                    105:                bp->next = 0;
                    106:                if(bp->type != M_DATA) {
                    107:                        freeb(bp);
                    108:                        if (udp->flags & UDP_INIT)
                    109:                                udpduser(udp->head, udp);
                    110:                        else {
                    111:                                if ((udp->flags & UDP_CONNECTED) == 0) {
                    112:                                        /* get user-supplied destination */
                    113:                                        if(udpdaddr(udp)) {
                    114:                                                bp_free(udp->head);
                    115:                                                udp->head = udp->tail = NULL;
                    116:                                                return;
                    117:                                        }
                    118:                                } else if (udp->head == NULL) {
                    119:                                        /* zero length message */
                    120:                                        udp->head = allocb(0);
                    121:                                }
                    122:                                udp_output(udp->head, udp);
                    123:                        }
                    124:                        udp->head = udp->tail = NULL;
                    125:                } else if(udp->head == 0){
                    126:                        udp->head = udp->tail = bp;
                    127:                } else {
                    128:                        udp->tail->next = bp;
                    129:                        udp->tail = bp;
                    130:                }
                    131:        }
                    132: }
                    133: 
                    134: /* extract address from a message */
                    135: udpdaddr(udp)
                    136: register struct udp *udp;
                    137: {
                    138:        struct udpaddr *uap;
                    139: 
                    140:        /* get destination */
                    141:        if((udp->head = bp_pullup(udp->head, sizeof(struct udpaddr))) == NULL)
                    142:                return(1);
                    143:        uap = (struct udpaddr *)udp->head->rptr;
                    144:        udp->dst = uap->host;
                    145:        udp->dport = uap->port;
                    146:        udp->head->rptr += sizeof(struct udpaddr);
                    147: 
                    148:        /* host address for datagrams depends on route */
                    149:        if ((udp->flags & UDP_CONNECTED) == 0) {
                    150:                udp->src = ip_hoston(udp->dst);
                    151:                if(udp->src == 0) {
                    152:                        udpbaddst = udp->dst;
                    153:                        return(1);
                    154:                }
                    155:        }
                    156:        return(0);
                    157: }
                    158: 
                    159: udpdrint(bp, ui)
                    160: register struct block *bp;
                    161: struct udpiphdr *ui;
                    162: {
                    163:        register struct block *bp1;
                    164:        register struct queue *q;
                    165:        register struct udp *udp;
                    166:        register struct udpaddr *uap;
                    167:        int     ps = spl6();
                    168: 
                    169:        /* find the udp port */
                    170:        for (udp = udpconn; udp < &udpconn[NUDP]; ++udp) {
                    171:                if (udp->rq == 0)
                    172:                        continue;
                    173:                if (udp->sport != ui->ui_dport)
                    174:                        continue;
                    175:                if (udp->flags & UDP_LISTEN)
                    176:                        break;
                    177:                if ((udp->flags & UDP_CONNECTED) == 0)
                    178:                        break;
                    179:                if (udp->dport == ui->ui_sport && udp->dst == ui->ui_src)
                    180:                        break;
                    181:        }
                    182: 
                    183:        if (udp == &udpconn[NUDP]) {
                    184:                bp_free(bp);
                    185:                splx(ps);
                    186:                return;
                    187:        }
                    188:        if (udp->flags & UDP_LISTEN) {
                    189:                udp->dport = ui->ui_sport;
                    190:                udp->dst = ui->ui_src;
                    191:                if (udp->src == 0) {
                    192:                        /* use host name connecting end called us */
                    193:                        udp->src = ui->ui_dst;
                    194:                }
                    195:                udp->flags |= UDP_CONNECTED;
                    196:                udp->flags &= ~UDP_LISTEN;
                    197:                udpreply(udp);
                    198:        }
                    199:        splx(ps);
                    200: 
                    201:        if((q = udp->rq) == NULL) {
                    202:                printf("udpdrint but no read queue\n");
                    203:                bp_free(bp);
                    204:                return;
                    205:        }
                    206:        if(q->next->flag & QFULL) {
                    207:                bp_free(bp);
                    208:                return;
                    209:        }
                    210:        if ((udp->flags & UDP_CONNECTED) == 0) {
                    211:                /* if not acting as a connected protocol, pass user source addr */
                    212:                bp1 = allocb(sizeof(struct udpaddr));
                    213:                if (bp1 == NULL) {
                    214:                        printf("udprint: out of blocks\n");
                    215:                        bp_free(bp);
                    216:                        return;
                    217:                }
                    218:                bp1->wptr += sizeof(struct udpaddr);
                    219:                uap = (struct udpaddr *)bp1->rptr;
                    220:                uap->host = ui->ui_src;
                    221:                uap->port = ui->ui_sport;
                    222:                putq(q->next, bp1);
                    223:        }
                    224:        while(bp){
                    225:                bp1 = bp->next;
                    226:                putq(q->next, bp);
                    227:                bp = bp1;
                    228:        }
                    229:        putctl(q->next, M_DELIM);
                    230: }
                    231: 
                    232: /*
                    233:  * imitation udp_usrreq
                    234:  */
                    235: udpduser(bp, udp)
                    236: register struct block *bp;
                    237: register struct udp *udp;
                    238: {
                    239:        struct udpuser *uu;
                    240: 
                    241:        if ((bp = bp_pullup(bp, sizeof(struct udpuser))) == 0) {
                    242:                printf("udpuser short\n");
                    243:                bp_free(bp);
                    244:                return;
                    245:        }
                    246:        uu = (struct udpuser *)bp->rptr;
                    247:        switch(uu->cmd){
                    248:        case UDPC_DATAGRAM:
                    249:                if (udpbind(udp, uu->sport))
                    250:                        goto bad;
                    251:                udp->flags &= ~UDP_INIT;
                    252:                udpreply(udp);
                    253:                break;
                    254:        case UDPC_CONNECT:
                    255:                if (udpbind(udp, uu->sport))
                    256:                        goto bad;
                    257:                udp->dport = uu->dport;
                    258:                udp->dst = uu->dst;
                    259:                udp->flags |= UDP_CONNECTED;
                    260:                udp->flags &= ~UDP_INIT;
                    261:                udpreply(udp);
                    262:                /* pick a local address related to the destination */
                    263:                udp->src = ip_hoston(udp->dst);
                    264:                if(udp->src == 0)
                    265:                        goto bad;
                    266:                break;
                    267:        case UDPC_LISTEN:
                    268:                if (udpbind(udp, uu->sport))
                    269:                        goto bad;
                    270:                udp->flags |= UDP_LISTEN;
                    271:                udp->flags &= ~UDP_INIT;
                    272:                break;
                    273:        default:
                    274: bad:           putctl(udp->rq->next, M_HANGUP);
                    275:                return;
                    276:        }
                    277:        bp_free(bp);
                    278: }
                    279: 
                    280: udpreply(udp)
                    281: register struct udp *udp;
                    282: {
                    283:        register struct queue *q;
                    284:        struct udpreply ur;
                    285: 
                    286:        ur.reply = UDPR_OK;
                    287:        ur.dport = udp->dport;
                    288:        ur.dst = udp->dst;
                    289:        ur.udpdev = udp - udpconn;
                    290: 
                    291:        q = udp->rq;
                    292:        putcpy(q->next, &ur, sizeof(ur));
                    293:        putctl(q->next, M_DELIM);
                    294: }
                    295: 
                    296: udpbind(udp, port)
                    297: register struct udp *udp;
                    298: register int port;
                    299: {
                    300:        register struct udp *udp2;
                    301:        static udp_port udpport = 600;
                    302: 
                    303:        udp->sport = 0;
                    304:        if(port){
                    305:                for(udp2 = &udpconn[0]; udp2 < &udpconn[NUDP]; udp2++){
                    306:                        if(udp2->rq == 0)
                    307:                                continue;
                    308:                        if(udp2->sport == port)
                    309:                                return(1);
                    310:                }
                    311:                udp->sport = port;
                    312:                return(0);
                    313:        }
                    314: 
                    315:        /* pick one for him */
                    316:        if(udpport >= 1024)
                    317:                udpport = 600;
                    318:        port = udpport;
                    319:        while(1){
                    320:                if(udpbind(udp, udpport) == 0){
                    321:                        udpport++;
                    322:                        return(0);
                    323:                }
                    324:                udpport++;
                    325:                if(udpport >= 1024)
                    326:                        udpport = 600;
                    327:                if(udpport == port)     /* tried them all */
                    328:                        break;
                    329:        }
                    330:        return(1);
                    331: }
                    332: 
                    333: #endif

unix.superglobalmegacorp.com

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