Annotation of cci/sys/netinet/udp_usrreq.c, revision 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.