Annotation of 42BSD/sys/netinet/tcp_subr.c, revision 1.1

1.1     ! root        1: /*     tcp_subr.c      6.1     83/07/29        */
        !             2: 
        !             3: #include "../h/param.h"
        !             4: #include "../h/systm.h"
        !             5: #include "../h/mbuf.h"
        !             6: #include "../h/socket.h"
        !             7: #include "../h/socketvar.h"
        !             8: #include "../h/protosw.h"
        !             9: #include "../h/errno.h"
        !            10: 
        !            11: #include "../net/route.h"
        !            12: #include "../net/if.h"
        !            13: 
        !            14: #include "../netinet/in.h"
        !            15: #include "../netinet/in_pcb.h"
        !            16: #include "../netinet/in_systm.h"
        !            17: #include "../netinet/ip.h"
        !            18: #include "../netinet/ip_var.h"
        !            19: #include "../netinet/ip_icmp.h"
        !            20: #include "../netinet/tcp.h"
        !            21: #include "../netinet/tcp_fsm.h"
        !            22: #include "../netinet/tcp_seq.h"
        !            23: #include "../netinet/tcp_timer.h"
        !            24: #include "../netinet/tcp_var.h"
        !            25: #include "../netinet/tcpip.h"
        !            26: 
        !            27: /*
        !            28:  * Tcp initialization
        !            29:  */
        !            30: tcp_init()
        !            31: {
        !            32: 
        !            33:        tcp_iss = 1;            /* wrong */
        !            34:        tcb.inp_next = tcb.inp_prev = &tcb;
        !            35:        tcp_alpha = TCP_ALPHA;
        !            36:        tcp_beta = TCP_BETA;
        !            37: }
        !            38: 
        !            39: /*
        !            40:  * Create template to be used to send tcp packets on a connection.
        !            41:  * Call after host entry created, allocates an mbuf and fills
        !            42:  * in a skeletal tcp/ip header, minimizing the amount of work
        !            43:  * necessary when the connection is used.
        !            44:  */
        !            45: struct tcpiphdr *
        !            46: tcp_template(tp)
        !            47:        struct tcpcb *tp;
        !            48: {
        !            49:        register struct inpcb *inp = tp->t_inpcb;
        !            50:        register struct mbuf *m;
        !            51:        register struct tcpiphdr *n;
        !            52: 
        !            53:        m = m_get(M_WAIT, MT_HEADER);
        !            54:        if (m == NULL)
        !            55:                return (0);
        !            56:        m->m_off = MMAXOFF - sizeof (struct tcpiphdr);
        !            57:        m->m_len = sizeof (struct tcpiphdr);
        !            58:        n = mtod(m, struct tcpiphdr *);
        !            59:        n->ti_next = n->ti_prev = 0;
        !            60:        n->ti_x1 = 0;
        !            61:        n->ti_pr = IPPROTO_TCP;
        !            62:        n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
        !            63:        n->ti_src = inp->inp_laddr;
        !            64:        n->ti_dst = inp->inp_faddr;
        !            65:        n->ti_sport = inp->inp_lport;
        !            66:        n->ti_dport = inp->inp_fport;
        !            67:        n->ti_seq = 0;
        !            68:        n->ti_ack = 0;
        !            69:        n->ti_x2 = 0;
        !            70:        n->ti_off = 5;
        !            71:        n->ti_flags = 0;
        !            72:        n->ti_win = 0;
        !            73:        n->ti_sum = 0;
        !            74:        n->ti_urp = 0;
        !            75:        return (n);
        !            76: }
        !            77: 
        !            78: /*
        !            79:  * Send a single message to the TCP at address specified by
        !            80:  * the given TCP/IP header.  If flags==0, then we make a copy
        !            81:  * of the tcpiphdr at ti and send directly to the addressed host.
        !            82:  * This is used to force keep alive messages out using the TCP
        !            83:  * template for a connection tp->t_template.  If flags are given
        !            84:  * then we send a message back to the TCP which originated the
        !            85:  * segment ti, and discard the mbuf containing it and any other
        !            86:  * attached mbufs.
        !            87:  *
        !            88:  * In any case the ack and sequence number of the transmitted
        !            89:  * segment are as specified by the parameters.
        !            90:  */
        !            91: tcp_respond(tp, ti, ack, seq, flags)
        !            92:        struct tcpcb *tp;
        !            93:        register struct tcpiphdr *ti;
        !            94:        tcp_seq ack, seq;
        !            95:        int flags;
        !            96: {
        !            97:        struct mbuf *m;
        !            98:        int win = 0, tlen;
        !            99:        struct route *ro = 0;
        !           100: 
        !           101:        if (tp) {
        !           102:                win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
        !           103:                ro = &tp->t_inpcb->inp_route;
        !           104:        }
        !           105:        if (flags == 0) {
        !           106:                m = m_get(M_DONTWAIT, MT_HEADER);
        !           107:                if (m == NULL)
        !           108:                        return;
        !           109:                m->m_len = sizeof (struct tcpiphdr) + 1;
        !           110:                *mtod(m, struct tcpiphdr *) = *ti;
        !           111:                ti = mtod(m, struct tcpiphdr *);
        !           112:                flags = TH_ACK;
        !           113:                tlen = 1;
        !           114:        } else {
        !           115:                m = dtom(ti);
        !           116:                m_freem(m->m_next);
        !           117:                m->m_next = 0;
        !           118:                m->m_off = (int)ti - (int)m;
        !           119:                m->m_len = sizeof (struct tcpiphdr);
        !           120: #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
        !           121:                xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
        !           122:                xchg(ti->ti_dport, ti->ti_sport, u_short);
        !           123: #undef xchg
        !           124:                tlen = 0;
        !           125:        }
        !           126:        ti->ti_next = ti->ti_prev = 0;
        !           127:        ti->ti_x1 = 0;
        !           128:        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
        !           129:        ti->ti_seq = htonl(seq);
        !           130:        ti->ti_ack = htonl(ack);
        !           131:        ti->ti_x2 = 0;
        !           132:        ti->ti_off = sizeof (struct tcphdr) >> 2;
        !           133:        ti->ti_flags = flags;
        !           134:        ti->ti_win = htons((u_short)win);
        !           135:        ti->ti_urp = 0;
        !           136:        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
        !           137:        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
        !           138:        ((struct ip *)ti)->ip_ttl = TCP_TTL;
        !           139:        (void) ip_output(m, (struct mbuf *)0, ro, 0);
        !           140: }
        !           141: 
        !           142: /*
        !           143:  * Create a new TCP control block, making an
        !           144:  * empty reassembly queue and hooking it to the argument
        !           145:  * protocol control block.
        !           146:  */
        !           147: struct tcpcb *
        !           148: tcp_newtcpcb(inp)
        !           149:        struct inpcb *inp;
        !           150: {
        !           151:        struct mbuf *m = m_getclr(M_DONTWAIT, MT_PCB);
        !           152:        register struct tcpcb *tp;
        !           153: 
        !           154:        if (m == NULL)
        !           155:                return ((struct tcpcb *)0);
        !           156:        tp = mtod(m, struct tcpcb *);
        !           157:        tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
        !           158:        /*
        !           159:         * If the default maximum IP packet size is 576 bytes
        !           160:         * and a standard IP header is 20 bytes, with a TCP
        !           161:         * header of 20 bytes plus the options necessary to
        !           162:         * upgrade it to something higher, then initialize the
        !           163:         * maximum segment size to 576 - (20 + 20 + 8 + slop).
        !           164:         */
        !           165:        tp->t_maxseg = 512;             /* satisfy the rest of the world */
        !           166:        tp->t_flags = 0;                /* sends options! */
        !           167:        tp->t_inpcb = inp;
        !           168:        inp->inp_ppcb = (caddr_t)tp;
        !           169:        return (tp);
        !           170: }
        !           171: 
        !           172: /*
        !           173:  * Drop a TCP connection, reporting
        !           174:  * the specified error.  If connection is synchronized,
        !           175:  * then send a RST to peer.
        !           176:  */
        !           177: struct tcpcb *
        !           178: tcp_drop(tp, errno)
        !           179:        register struct tcpcb *tp;
        !           180:        int errno;
        !           181: {
        !           182:        struct socket *so = tp->t_inpcb->inp_socket;
        !           183: 
        !           184:        if (TCPS_HAVERCVDSYN(tp->t_state)) {
        !           185:                tp->t_state = TCPS_CLOSED;
        !           186:                (void) tcp_output(tp);
        !           187:        }
        !           188:        so->so_error = errno;
        !           189:        return (tcp_close(tp));
        !           190: }
        !           191: 
        !           192: tcp_abort(inp)
        !           193:        struct inpcb *inp;
        !           194: {
        !           195: 
        !           196:        (void) tcp_close((struct tcpcb *)inp->inp_ppcb);
        !           197: }
        !           198: 
        !           199: /*
        !           200:  * Close a TCP control block:
        !           201:  *     discard all space held by the tcp
        !           202:  *     discard internet protocol block
        !           203:  *     wake up any sleepers
        !           204:  */
        !           205: struct tcpcb *
        !           206: tcp_close(tp)
        !           207:        register struct tcpcb *tp;
        !           208: {
        !           209:        register struct tcpiphdr *t;
        !           210:        struct inpcb *inp = tp->t_inpcb;
        !           211:        struct socket *so = inp->inp_socket;
        !           212:        register struct mbuf *m;
        !           213: 
        !           214:        t = tp->seg_next;
        !           215:        while (t != (struct tcpiphdr *)tp) {
        !           216:                t = (struct tcpiphdr *)t->ti_next;
        !           217:                m = dtom(t->ti_prev);
        !           218:                remque(t->ti_prev);
        !           219:                m_freem(m);
        !           220:        }
        !           221:        if (tp->t_template)
        !           222:                (void) m_free(dtom(tp->t_template));
        !           223:        if (tp->t_tcpopt)
        !           224:                (void) m_free(dtom(tp->t_tcpopt));
        !           225:        if (tp->t_ipopt)
        !           226:                (void) m_free(dtom(tp->t_ipopt));
        !           227:        (void) m_free(dtom(tp));
        !           228:        inp->inp_ppcb = 0;
        !           229:        soisdisconnected(so);
        !           230:        in_pcbdetach(inp);
        !           231:        return ((struct tcpcb *)0);
        !           232: }
        !           233: 
        !           234: tcp_drain()
        !           235: {
        !           236: 
        !           237: }
        !           238: 
        !           239: tcp_ctlinput(cmd, arg)
        !           240:        int cmd;
        !           241:        caddr_t arg;
        !           242: {
        !           243:        struct in_addr *sin;
        !           244:        extern u_char inetctlerrmap[];
        !           245: 
        !           246:        if (cmd < 0 || cmd > PRC_NCMDS)
        !           247:                return;
        !           248:        switch (cmd) {
        !           249: 
        !           250:        case PRC_ROUTEDEAD:
        !           251:                break;
        !           252: 
        !           253:        case PRC_QUENCH:
        !           254:                break;
        !           255: 
        !           256:        /* these are handled by ip */
        !           257:        case PRC_IFDOWN:
        !           258:        case PRC_HOSTDEAD:
        !           259:        case PRC_HOSTUNREACH:
        !           260:                break;
        !           261: 
        !           262:        default:
        !           263:                sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
        !           264:                in_pcbnotify(&tcb, sin, (int)inetctlerrmap[cmd], tcp_abort);
        !           265:        }
        !           266: }

unix.superglobalmegacorp.com

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