Annotation of cci/sys/netinet/in_pcb.c, revision 1.1

1.1     ! root        1: /*     in_pcb.c        6.1     83/07/29        */
        !             2: 
        !             3: #include "../h/param.h"
        !             4: #include "../h/systm.h"
        !             5: #include "../h/dir.h"
        !             6: #include "../h/user.h"
        !             7: #include "../h/mbuf.h"
        !             8: #include "../h/socket.h"
        !             9: #include "../h/socketvar.h"
        !            10: #include "../netinet/in.h"
        !            11: #include "../netinet/in_systm.h"
        !            12: #include "../net/if.h"
        !            13: #include "../net/route.h"
        !            14: #include "../netinet/in_pcb.h"
        !            15: #include "../h/protosw.h"
        !            16: 
        !            17: struct in_addr zeroin_addr;
        !            18: 
        !            19: in_pcballoc(so, head)
        !            20:        struct socket *so;
        !            21:        struct inpcb *head;
        !            22: {
        !            23:        struct mbuf *m;
        !            24:        register struct inpcb *inp;
        !            25: 
        !            26:        m = m_getclr(M_DONTWAIT, MT_PCB);
        !            27:        MBUFNULL(45, m);        /* for debugging */
        !            28:        if (m == NULL)
        !            29:                return (ENOBUFS);
        !            30:        inp = mtod(m, struct inpcb *);
        !            31:        inp->inp_head = head;
        !            32:        inp->inp_socket = so;
        !            33:        insque(inp, head);
        !            34:        so->so_pcb = (caddr_t)inp;
        !            35:        return (0);
        !            36: }
        !            37:        
        !            38: in_pcbbind(inp, nam)
        !            39:        register struct inpcb *inp;
        !            40:        struct mbuf *nam;
        !            41: {
        !            42:        register struct socket *so = inp->inp_socket;
        !            43:        register struct inpcb *head = inp->inp_head;
        !            44:        register struct sockaddr_in *sin;
        !            45:        u_short lport = 0;
        !            46: 
        !            47:        if (ifnet == 0)
        !            48:                return (EADDRNOTAVAIL);
        !            49:        if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY)
        !            50:                return (EINVAL);
        !            51:        if (nam == 0)
        !            52:                goto noname;
        !            53:        sin = mtod(nam, struct sockaddr_in *);
        !            54:        if (nam->m_len != sizeof (*sin))
        !            55:                return (EINVAL);
        !            56:        if (sin->sin_addr.s_addr != INADDR_ANY) {
        !            57:                int tport = sin->sin_port;
        !            58: 
        !            59:                sin->sin_port = 0;              /* yech... */
        !            60:                if (if_ifwithaddr((struct sockaddr *)sin) == 0)
        !            61:                        return (EADDRNOTAVAIL);
        !            62:                sin->sin_port = tport;
        !            63:        }
        !            64:        lport = sin->sin_port;
        !            65:        if (lport) {
        !            66:                u_short aport = ntohs(lport);
        !            67:                int wild = 0;
        !            68: 
        !            69:                /* GROSS */
        !            70:                if (aport < IPPORT_RESERVED && u.u_uid != 0)
        !            71:                        return (EACCES);
        !            72:                /* even GROSSER, but this is the Internet */
        !            73:                if ((so->so_options & SO_REUSEADDR) == 0 &&
        !            74:                    ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
        !            75:                     (so->so_options & SO_ACCEPTCONN) == 0))
        !            76:                        wild = INPLOOKUP_WILDCARD;
        !            77:                if (in_pcblookup(head,
        !            78:                    zeroin_addr, 0, sin->sin_addr, lport, wild))
        !            79:                        return (EADDRINUSE);
        !            80:        }
        !            81:        inp->inp_laddr = sin->sin_addr;
        !            82: noname:
        !            83:        if (lport == 0)
        !            84:                do {
        !            85:                        if (head->inp_lport++ < IPPORT_RESERVED)
        !            86:                                head->inp_lport = IPPORT_RESERVED;
        !            87:                        lport = htons(head->inp_lport);
        !            88:                } while (in_pcblookup(head,
        !            89:                            zeroin_addr, 0, inp->inp_laddr, lport, 0));
        !            90:        inp->inp_lport = lport;
        !            91:        return (0);
        !            92: }
        !            93: 
        !            94: /*
        !            95:  * Connect from a socket to a specified address.
        !            96:  * Both address and port must be specified in argument sin.
        !            97:  * If don't have a local address for this socket yet,
        !            98:  * then pick one.
        !            99:  */
        !           100: in_pcbconnect(inp, nam)
        !           101:        struct inpcb *inp;
        !           102:        struct mbuf *nam;
        !           103: {
        !           104:        struct ifnet *ifp;
        !           105:        struct sockaddr_in *ifaddr;
        !           106:        register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
        !           107: 
        !           108:        if (nam->m_len != sizeof (*sin))
        !           109:                return (EINVAL);
        !           110:        if (sin->sin_family != AF_INET)
        !           111:                return (EAFNOSUPPORT);
        !           112:        if (sin->sin_addr.s_addr == INADDR_ANY || sin->sin_port == 0)
        !           113:                return (EADDRNOTAVAIL);
        !           114:        if (inp->inp_laddr.s_addr == INADDR_ANY) {
        !           115:                ifp = if_ifonnetof(in_netof(sin->sin_addr));
        !           116:                if (ifp == 0) {
        !           117:                        /*
        !           118:                         * We should select the interface based on
        !           119:                         * the route to be used, but for udp this would
        !           120:                         * result in two calls to rtalloc for each packet
        !           121:                         * sent; hardly worthwhile...
        !           122:                         */
        !           123:                        ifp = if_ifwithaf(AF_INET);
        !           124:                        if (ifp == 0)
        !           125:                                return (EADDRNOTAVAIL);
        !           126:                }
        !           127:                ifaddr = (struct sockaddr_in *)&ifp->if_addr;
        !           128:        }
        !           129:        if (in_pcblookup(inp->inp_head,
        !           130:            sin->sin_addr,
        !           131:            sin->sin_port,
        !           132:            inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
        !           133:            inp->inp_lport,
        !           134:            0))
        !           135:                return (EADDRINUSE);
        !           136:        if (inp->inp_laddr.s_addr == INADDR_ANY) {
        !           137:                if (inp->inp_lport == 0)
        !           138:                        in_pcbbind(inp, (struct mbuf *)0);
        !           139:                inp->inp_laddr = ifaddr->sin_addr;
        !           140:        }
        !           141:        inp->inp_faddr = sin->sin_addr;
        !           142:        inp->inp_fport = sin->sin_port;
        !           143:        return (0);
        !           144: }
        !           145: 
        !           146: in_pcbdisconnect(inp)
        !           147:        struct inpcb *inp;
        !           148: {
        !           149: 
        !           150:        inp->inp_faddr.s_addr = INADDR_ANY;
        !           151:        inp->inp_fport = 0;
        !           152:        if (inp->inp_socket->so_state & SS_NOFDREF)
        !           153:                in_pcbdetach(inp);
        !           154: }
        !           155: 
        !           156: in_pcbdetach(inp)
        !           157:        struct inpcb *inp;
        !           158: {
        !           159:        struct socket *so = inp->inp_socket;
        !           160: 
        !           161:        so->so_pcb = 0;
        !           162:        sofree(so);
        !           163:        if (inp->inp_route.ro_rt)
        !           164:                rtfree(inp->inp_route.ro_rt);
        !           165:        remque(inp);
        !           166:        (void) m_free(dtom(inp));
        !           167: }
        !           168: 
        !           169: in_setsockaddr(inp, nam)
        !           170:        register struct inpcb *inp;
        !           171:        struct mbuf *nam;
        !           172: {
        !           173:        register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
        !           174:        
        !           175:        nam->m_len = sizeof (*sin);
        !           176:        sin = mtod(nam, struct sockaddr_in *);
        !           177:        bzero((caddr_t)sin, sizeof (*sin));
        !           178:        sin->sin_family = AF_INET;
        !           179:        sin->sin_port = inp->inp_lport;
        !           180:        sin->sin_addr = inp->inp_laddr;
        !           181: }
        !           182: 
        !           183: in_setpeeraddr(inp, nam)
        !           184:        register struct inpcb *inp;
        !           185:        struct mbuf *nam;
        !           186: {
        !           187:        register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
        !           188:        
        !           189:        nam->m_len = sizeof (*sin);
        !           190:        sin = mtod(nam, struct sockaddr_in *);
        !           191:        bzero((caddr_t)sin, sizeof (*sin));
        !           192:        sin->sin_family = AF_INET;
        !           193:        sin->sin_port = inp->inp_fport;
        !           194:        sin->sin_addr = inp->inp_faddr;
        !           195: }
        !           196: 
        !           197: /*
        !           198:  * Pass an error to all internet connections
        !           199:  * associated with address sin.  Call the
        !           200:  * protocol specific routine to clean up the
        !           201:  * mess afterwards.
        !           202:  */
        !           203: in_pcbnotify(head, dst, errno, abort)
        !           204:        struct inpcb *head;
        !           205:        register struct in_addr *dst;
        !           206:        int errno, (*abort)();
        !           207: {
        !           208:        register struct inpcb *inp, *oinp;
        !           209:        int s = splimp();
        !           210: 
        !           211:        for (inp = head->inp_next; inp != head;) {
        !           212:                if (inp->inp_faddr.s_addr != dst->s_addr) {
        !           213:        next:
        !           214:                        inp = inp->inp_next;
        !           215:                        continue;
        !           216:                }
        !           217:                if (inp->inp_socket == 0)
        !           218:                        goto next;
        !           219:                inp->inp_socket->so_error = errno;
        !           220:                oinp = inp;
        !           221:                inp = inp->inp_next;
        !           222:                (*abort)(oinp);
        !           223:        }
        !           224:        splx(s);
        !           225: }
        !           226: 
        !           227: struct inpcb *
        !           228: in_pcblookup(head, faddr, fport, laddr, lport, flags)
        !           229:        struct inpcb *head;
        !           230:        struct in_addr faddr, laddr;
        !           231:        u_short fport, lport;
        !           232:        int flags;
        !           233: {
        !           234:        register struct inpcb *inp, *match = 0;
        !           235:        int matchwild = 3, wildcard;
        !           236: 
        !           237:        for (inp = head->inp_next; inp != head; inp = inp->inp_next) {
        !           238:                if (inp->inp_lport != lport)
        !           239:                        continue;
        !           240:                wildcard = 0;
        !           241:                if (inp->inp_laddr.s_addr != INADDR_ANY) {
        !           242:                        if (laddr.s_addr == INADDR_ANY)
        !           243:                                wildcard++;
        !           244:                        else if (inp->inp_laddr.s_addr != laddr.s_addr)
        !           245:                                continue;
        !           246:                } else {
        !           247:                        if (laddr.s_addr != INADDR_ANY)
        !           248:                                wildcard++;
        !           249:                }
        !           250:                if (inp->inp_faddr.s_addr != INADDR_ANY) {
        !           251:                        if (faddr.s_addr == INADDR_ANY)
        !           252:                                wildcard++;
        !           253:                        else if (inp->inp_faddr.s_addr != faddr.s_addr ||
        !           254:                            inp->inp_fport != fport)
        !           255:                                continue;
        !           256:                } else {
        !           257:                        if (faddr.s_addr != INADDR_ANY)
        !           258:                                wildcard++;
        !           259:                }
        !           260:                if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0)
        !           261:                        continue;
        !           262:                if (wildcard < matchwild) {
        !           263:                        match = inp;
        !           264:                        matchwild = wildcard;
        !           265:                        if (matchwild == 0)
        !           266:                                break;
        !           267:                }
        !           268:        }
        !           269:        return (match);
        !           270: }

unix.superglobalmegacorp.com

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