Annotation of cci/sys/netinet/udp_usrreq.c, revision 1.1.1.1

1.1       root        1: /*     udp_usrreq.c    6.1     83/07/29        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/dir.h"
                      5: #include "../h/user.h"
                      6: #include "../h/mbuf.h"
                      7: #include "../h/protosw.h"
                      8: #include "../h/socket.h"
                      9: #include "../h/socketvar.h"
                     10: #include "../h/errno.h"
                     11: 
                     12: #include "../net/if.h"
                     13: #include "../net/route.h"
                     14: 
                     15: #include "../netinet/in.h"
                     16: #include "../netinet/in_pcb.h"
                     17: #include "../netinet/in_systm.h"
                     18: #include "../netinet/ip.h"
                     19: #include "../netinet/ip_var.h"
                     20: #include "../netinet/ip_icmp.h"
                     21: #include "../netinet/udp.h"
                     22: #include "../netinet/udp_var.h"
                     23: 
                     24: #ifdef UDPPRINTFS
                     25: int    udpprintfs = 0;
                     26: #endif
                     27: 
                     28: /*
                     29:  * Changes in udp_usrreq()
                     30:  *
                     31:  *     PRU_OOB         mark mbuf not to be deallocated for PRU_OOB (soreceive()
                     32:  *                     will).
                     33:  *
                     34:  *     PRU_ABORT       disconnect the socket first before detaching its
                     35:  *                     pcb. also comment out socket deallocation as
                     36:  *                     in_pcbdetach() already did.
                     37:  *
                     38:  *     PRU_ATTACH      reverse the sequence: soreserve() before 
                     39:  *                     in_pcballoc(). Otherwise, if soreserve() fails,
                     40:  *                     allocated mbufs are not returned to free pool.
                     41:  *                     
                     42:  */
                     43: /*
                     44:  * UDP protocol implementation.
                     45:  * Per RFC 768, August, 1980.
                     46:  */
                     47: udp_init()
                     48: {
                     49: 
                     50:        udb.inp_next = udb.inp_prev = &udb;
                     51: }
                     52: 
                     53: int    udpcksum;
                     54: struct sockaddr_in udp_in = { AF_INET };
                     55: 
                     56: udp_input(m0)
                     57:        struct mbuf *m0;
                     58: {
                     59:        register struct udpiphdr *ui;
                     60:        register struct inpcb *inp;
                     61:        register struct mbuf *m;
                     62:        int len;
                     63: 
                     64:        /*
                     65:         * Get IP and UDP header together in first mbuf.
                     66:         */
                     67:        m = m0;
                     68:        if ((m->m_off > MMAXOFF || m->m_len < sizeof (struct udpiphdr)) &&
                     69:            (m = m_pullup(m, sizeof (struct udpiphdr))) == 0) {
                     70:                udpstat.udps_hdrops++;
                     71:                return;
                     72:        }
                     73:        ui = mtod(m, struct udpiphdr *);
                     74:        if (((struct ip *)ui)->ip_hl > (sizeof (struct ip) >> 2))
                     75:                ip_stripoptions((struct ip *)ui, (struct mbuf *)0);
                     76: 
                     77:        /*
                     78:         * Make mbuf data length reflect UDP length.
                     79:         * If not enough data to reflect UDP length, drop.
                     80:         */
                     81:        len = ntohs((u_short)ui->ui_ulen);
                     82:        if (((struct ip *)ui)->ip_len != len) {
                     83:                if (len > ((struct ip *)ui)->ip_len) {
                     84:                        udpstat.udps_badlen++;
                     85:                        goto bad;
                     86:                }
                     87:                m_adj(m, ((struct ip *)ui)->ip_len - len);
                     88:                /* (struct ip *)ui->ip_len = len; */
                     89:        }
                     90: 
                     91:        /*
                     92:         * Checksum extended UDP header and data.
                     93:         */
                     94:        if (udpcksum) {
                     95:                ui->ui_next = ui->ui_prev = 0;
                     96:                ui->ui_x1 = 0;
                     97:                ui->ui_len = htons((u_short)len);
                     98:                if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
                     99:                        udpstat.udps_badsum++;
                    100:                        m_freem(m);
                    101:                        return;
                    102:                }
                    103:        }
                    104: 
                    105:        /*
                    106:         * Locate pcb for datagram.
                    107:         */
                    108:        inp = in_pcblookup(&udb,
                    109:            ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport,
                    110:                INPLOOKUP_WILDCARD);
                    111:        if (inp == 0) {
                    112: #ifdef UDPPRINTFS
                    113:                if (udpprintfs)
                    114:                        printf("udp_input:udb %x, src %x, sport %d, dst %x, dport %d\n",
                    115:                                &udb, ui->ui_src, ui->ui_sport, 
                    116:                                ui->ui_dst, ui->ui_dport);
                    117: #endif
                    118:                /* don't send ICMP response for broadcast packet */
                    119:                if (in_lnaof(ui->ui_dst) == INADDR_ANY)
                    120:                        goto bad;
                    121:                icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT);
                    122:                return;
                    123:        }
                    124: 
                    125:        /*
                    126:         * Construct sockaddr format source address.
                    127:         * Stuff source address and datagram in user buffer.
                    128:         */
                    129:        udp_in.sin_port = ui->ui_sport;
                    130:        udp_in.sin_addr = ui->ui_src;
                    131:        m->m_len -= sizeof (struct udpiphdr);
                    132:        m->m_off += sizeof (struct udpiphdr);
                    133:        if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in,
                    134:            m, (struct mbuf *)0) == 0)
                    135:                goto bad;
                    136:        sorwakeup(inp->inp_socket);
                    137:        return;
                    138: bad:
                    139:        m_freem(m);
                    140: }
                    141: 
                    142: udp_abort(inp)
                    143:        struct inpcb *inp;
                    144: {
                    145:        struct socket *so = inp->inp_socket;
                    146: 
                    147:        in_pcbdisconnect(inp);
                    148:        soisdisconnected(so);
                    149: }
                    150: 
                    151: udp_ctlinput(cmd, arg)
                    152:        int cmd;
                    153:        caddr_t arg;
                    154: {
                    155:        struct in_addr *sin;
                    156:        extern u_char inetctlerrmap[];
                    157: 
                    158:        if (cmd < 0 || cmd > PRC_NCMDS)
                    159:                return;
                    160:        switch (cmd) {
                    161: 
                    162:        case PRC_ROUTEDEAD:
                    163:                break;
                    164: 
                    165:        case PRC_QUENCH:
                    166:                break;
                    167: 
                    168:        /* these are handled by ip */
                    169:        case PRC_IFDOWN:
                    170:        case PRC_HOSTDEAD:
                    171:        case PRC_HOSTUNREACH:
                    172:                break;
                    173: 
                    174:        default:
                    175:                sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
                    176:                in_pcbnotify(&udb, sin, (int)inetctlerrmap[cmd], udp_abort);
                    177:        }
                    178: }
                    179: 
                    180: udp_output(inp, m0)
                    181:        struct inpcb *inp;
                    182:        struct mbuf *m0;
                    183: {
                    184:        register struct mbuf *m;
                    185:        register struct udpiphdr *ui;
                    186:        register struct socket *so;
                    187:        register int len = 0;
                    188:        int flags;
                    189: 
                    190:        /*
                    191:         * Calculate data length and get a mbuf
                    192:         * for UDP and IP headers.
                    193:         */
                    194:        for (m = m0; m; m = m->m_next)
                    195:                len += m->m_len;
                    196:        m = m_get(M_DONTWAIT, MT_HEADER);
                    197:        MBUFNULL(17, m);                /* for debugging */
                    198:        if (m == 0) {
                    199:                m_freem(m0);
                    200:                return (ENOBUFS);
                    201:        }
                    202: 
                    203:        /*
                    204:         * Fill in mbuf with extended UDP header
                    205:         * and addresses and length put into network format.
                    206:         */
                    207:        m->m_off = MMAXOFF - sizeof (struct udpiphdr);
                    208:        m->m_len = sizeof (struct udpiphdr);
                    209:        m->m_next = m0;
                    210:        ui = mtod(m, struct udpiphdr *);
                    211:        ui->ui_next = ui->ui_prev = 0;
                    212:        ui->ui_x1 = 0;
                    213:        ui->ui_pr = IPPROTO_UDP;
                    214:        ui->ui_len = len + sizeof (struct udphdr);
                    215:        ui->ui_src = inp->inp_laddr;
                    216:        ui->ui_dst = inp->inp_faddr;
                    217:        ui->ui_sport = inp->inp_lport;
                    218:        ui->ui_dport = inp->inp_fport;
                    219:        ui->ui_ulen = htons((u_short)ui->ui_len);
                    220: 
                    221:        /*
                    222:         * Stuff checksum and output datagram.
                    223:         */
                    224:        ui->ui_sum = 0;
                    225:        ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len);
                    226:        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
                    227:        ((struct ip *)ui)->ip_ttl = MAXTTL;
                    228:        so = inp->inp_socket;
                    229:        flags = (so->so_options & SO_DONTROUTE) | (so->so_state & SS_PRIV);
                    230:        return (ip_output(m, (struct mbuf *)0, (struct route *)0, flags));
                    231: }
                    232: 
                    233: /*ARGSUSED*/
                    234: udp_usrreq(so, req, m, nam, rights)
                    235:        struct socket *so;
                    236:        int req;
                    237:        struct mbuf *m, *nam, *rights;
                    238: {
                    239:        struct inpcb *inp = sotoinpcb(so);
                    240:        int error = 0;
                    241: 
                    242:        if (rights && rights->m_len) {
                    243:                error = EINVAL;
                    244:                goto release;
                    245:        }
                    246:        if (inp == NULL && req != PRU_ATTACH) {
                    247:                error = EINVAL;
                    248:                goto release;
                    249:        }
                    250:        switch (req) {
                    251: 
                    252:        case PRU_ATTACH:
                    253:                if (inp != NULL) {
                    254:                        error = EINVAL;
                    255:                        break;
                    256:                }
                    257:                error = soreserve(so, 2048, 2048);
                    258:                if (error)
                    259:                        break;
                    260:                error = in_pcballoc(so, &udb);
                    261:                if (error)
                    262:                        break;
                    263:                break;
                    264: 
                    265:        case PRU_DETACH:
                    266:                if (inp == NULL) {
                    267:                        error = ENOTCONN;
                    268:                        break;
                    269:                }
                    270:                in_pcbdetach(inp);
                    271:                break;
                    272: 
                    273:        case PRU_BIND:
                    274:                error = in_pcbbind(inp, nam);
                    275:                break;
                    276: 
                    277:        case PRU_LISTEN:
                    278:                error = EOPNOTSUPP;
                    279:                break;
                    280: 
                    281:        case PRU_CONNECT:
                    282:                if (inp->inp_faddr.s_addr != INADDR_ANY) {
                    283:                        error = EISCONN;
                    284:                        break;
                    285:                }
                    286:                error = in_pcbconnect(inp, nam);
                    287:                if (error == 0)
                    288:                        soisconnected(so);
                    289:                break;
                    290: 
                    291:        case PRU_CONNECT2:
                    292:                error = EOPNOTSUPP;
                    293:                break;
                    294: 
                    295:        case PRU_ACCEPT:
                    296:                error = EOPNOTSUPP;
                    297:                break;
                    298: 
                    299:        case PRU_DISCONNECT:
                    300:                if (inp->inp_faddr.s_addr == INADDR_ANY) {
                    301:                        error = ENOTCONN;
                    302:                        break;
                    303:                }
                    304:                in_pcbdisconnect(inp);
                    305:                soisdisconnected(so);
                    306:                break;
                    307: 
                    308:        case PRU_SHUTDOWN:
                    309:                socantsendmore(so);
                    310:                break;
                    311: 
                    312:        case PRU_SEND: {
                    313:                struct in_addr laddr;
                    314: 
                    315:                if (nam) {
                    316:                        laddr = inp->inp_laddr;
                    317:                        if (inp->inp_faddr.s_addr != INADDR_ANY) {
                    318:                                error = EISCONN;
                    319:                                break;
                    320:                        }
                    321:                        error = in_pcbconnect(inp, nam);
                    322:                        if (error)
                    323:                                break;
                    324:                } else {
                    325:                        if (inp->inp_faddr.s_addr == INADDR_ANY) {
                    326:                                error = ENOTCONN;
                    327:                                break;
                    328:                        }
                    329:                }
                    330:                error = udp_output(inp, m);
                    331:                m = NULL;
                    332:                if (nam) {
                    333:                        in_pcbdisconnect(inp);
                    334:                        inp->inp_laddr = laddr;
                    335:                }
                    336:                }
                    337:                break;
                    338: 
                    339:        case PRU_ABORT:
                    340:                soisdisconnected(so);
                    341:                in_pcbdetach(inp);
                    342:                /* sofree(so); */
                    343:                break;
                    344: 
                    345:        case PRU_SOCKADDR:
                    346:                in_setsockaddr(inp, nam);
                    347:                break;
                    348: 
                    349:        case PRU_PEERADDR:
                    350:                in_setpeeraddr(inp, nam);
                    351:                break;
                    352: 
                    353:        case PRU_CONTROL:
                    354:                m = NULL;
                    355:                error = EOPNOTSUPP;
                    356:                break;
                    357: 
                    358:        case PRU_SENSE:
                    359:        case PRU_RCVOOB:
                    360:                m = NULL;
                    361:                /* fall thru... */
                    362: 
                    363:        case PRU_RCVD:
                    364:        case PRU_SENDOOB:
                    365:        case PRU_FASTTIMO:
                    366:        case PRU_SLOWTIMO:
                    367:        case PRU_PROTORCV:
                    368:        case PRU_PROTOSEND:
                    369:                error =  EOPNOTSUPP;
                    370:                break;
                    371: 
                    372:        default:
                    373:                panic("udp_usrreq");
                    374:        }
                    375: release:
                    376:        if (m != NULL)
                    377:                m_freem(m);
                    378:        return (error);
                    379: }

unix.superglobalmegacorp.com

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