Annotation of cci/sys/netinet/tcp_subr.c, revision 1.1.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:  * Changes
                     29:  *     .       from Usenet: set default max seg to 536 bytes (as
                     30:  *             mentioned by POSTEL <INC-PROJECT, MAX-SEG-SIZ.NLS.14>
                     31:  *             & letter of 7 Nov 1983.
                     32:  */
                     33: /*
                     34:  * Tcp initialization
                     35:  */
                     36: tcp_init()
                     37: {
                     38: 
                     39:        tcp_iss = 1;            /* wrong */
                     40:        tcb.inp_next = tcb.inp_prev = &tcb;
                     41:        tcp_alpha = TCP_ALPHA;
                     42:        tcp_beta = TCP_BETA;
                     43: }
                     44: 
                     45: /*
                     46:  * Create template to be used to send tcp packets on a connection.
                     47:  * Call after host entry created, allocates an mbuf and fills
                     48:  * in a skeletal tcp/ip header, minimizing the amount of work
                     49:  * necessary when the connection is used.
                     50:  */
                     51: struct tcpiphdr *
                     52: tcp_template(tp)
                     53:        struct tcpcb *tp;
                     54: {
                     55:        register struct inpcb *inp = tp->t_inpcb;
                     56:        register struct mbuf *m;
                     57:        register struct tcpiphdr *n;
                     58: 
                     59:        m = m_get(M_WAIT, MT_HEADER);
                     60:        MBUFNULL(14, m);                /* for debugging */
                     61:        if (m == NULL)
                     62:                return (0);
                     63:        m->m_off = MMAXOFF - sizeof (struct tcpiphdr);
                     64:        m->m_len = sizeof (struct tcpiphdr);
                     65:        n = mtod(m, struct tcpiphdr *);
                     66:        n->ti_next = n->ti_prev = 0;
                     67:        n->ti_x1 = 0;
                     68:        n->ti_pr = IPPROTO_TCP;
                     69:        n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
                     70:        n->ti_src = inp->inp_laddr;
                     71:        n->ti_dst = inp->inp_faddr;
                     72:        n->ti_sport = inp->inp_lport;
                     73:        n->ti_dport = inp->inp_fport;
                     74:        n->ti_seq = 0;
                     75:        n->ti_ack = 0;
                     76:        n->ti_x2 = 0;
                     77:        n->ti_off = 5;
                     78:        n->ti_flags = 0;
                     79:        n->ti_win = 0;
                     80:        n->ti_sum = 0;
                     81:        n->ti_urp = 0;
                     82:        return (n);
                     83: }
                     84: 
                     85: /*
                     86:  * Send a single message to the TCP at address specified by
                     87:  * the given TCP/IP header.  If flags==0, then we make a copy
                     88:  * of the tcpiphdr at ti and send directly to the addressed host.
                     89:  * This is used to force keep alive messages out using the TCP
                     90:  * template for a connection tp->t_template.  If flags are given
                     91:  * then we send a message back to the TCP which originated the
                     92:  * segment ti, and discard the mbuf containing it and any other
                     93:  * attached mbufs.
                     94:  *
                     95:  * In any case the ack and sequence number of the transmitted
                     96:  * segment are as specified by the parameters.
                     97:  */
                     98: tcp_respond(tp, ti, ack, seq, flags)
                     99:        struct tcpcb *tp;
                    100:        register struct tcpiphdr *ti;
                    101:        tcp_seq ack, seq;
                    102:        int flags;
                    103: {
                    104:        struct mbuf *m;
                    105:        int win = 0, tlen;
                    106:        struct route *ro = 0;
                    107: 
                    108:        if (tp) {
                    109:                win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
                    110:                ro = &tp->t_inpcb->inp_route;
                    111:        }
                    112:        if (flags == 0) {
                    113:                m = m_get(M_DONTWAIT, MT_HEADER);
                    114:                MBUFNULL(15, m);                /* for debugging */
                    115:                if (m == NULL)
                    116:                        return;
                    117:                m->m_len = sizeof (struct tcpiphdr) + 1;
                    118:                *mtod(m, struct tcpiphdr *) = *ti;
                    119:                ti = mtod(m, struct tcpiphdr *);
                    120:                flags = TH_ACK;
                    121:                tlen = 1;
                    122:        } else {
                    123:                m = dtom(ti);
                    124:                m_freem(m->m_next);
                    125:                m->m_next = 0;
                    126:                m->m_off = (int)ti - (int)m;
                    127:                m->m_len = sizeof (struct tcpiphdr);
                    128: #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
                    129:                xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
                    130:                xchg(ti->ti_dport, ti->ti_sport, u_short);
                    131: #undef xchg
                    132:                tlen = 0;
                    133:        }
                    134:        ti->ti_next = ti->ti_prev = 0;
                    135:        ti->ti_x1 = 0;
                    136:        ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
                    137:        ti->ti_seq = htonl(seq);
                    138:        ti->ti_ack = htonl(ack);
                    139:        ti->ti_x2 = 0;
                    140:        ti->ti_off = sizeof (struct tcphdr) >> 2;
                    141:        ti->ti_flags = flags;
                    142:        ti->ti_win = htons((u_short)win);
                    143:        ti->ti_urp = 0;
                    144:        ti->ti_sum = in_cksum(m, sizeof (struct tcpiphdr) + tlen);
                    145:        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen;
                    146:        ((struct ip *)ti)->ip_ttl = TCP_TTL;
                    147:        (void) ip_output(m, (struct mbuf *)0, ro, 0);
                    148: }
                    149: 
                    150: /*
                    151:  * Create a new TCP control block, making an
                    152:  * empty reassembly queue and hooking it to the argument
                    153:  * protocol control block.
                    154:  */
                    155: struct tcpcb *
                    156: tcp_newtcpcb(inp)
                    157:        struct inpcb *inp;
                    158: {
                    159:        struct mbuf *m = m_getclr(M_DONTWAIT, MT_PCB);
                    160:        register struct tcpcb *tp;
                    161:        struct ifnet *ifp;
                    162:        struct ifnet *tcp_getif();
                    163:        u_short ifmss;
                    164: 
                    165:        MBUFNULL(16, m);                /* for debugging */
                    166:        if (m == NULL)
                    167:                return ((struct tcpcb *)0);
                    168:        tp = mtod(m, struct tcpcb *);
                    169:        tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
                    170:        /*
                    171:         * If the default maximum IP packet size is 576 bytes
                    172:         * and a standard IP header is 20 bytes, with a TCP
                    173:         * header of 20 bytes plus the options necessary to
                    174:         * upgrade it to something higher, then initialize the
                    175:         * maximum segment size to 576 - (20 + 20 + 8 + slop).
                    176:         */
                    177:        tp->t_maxseg = 512;             /* satisfy the rest of the world */
                    178:        tp->t_flags = 0;                /* sends options! */
                    179:        tp->t_inpcb = inp;
                    180:        inp->inp_ppcb = (caddr_t)tp;
                    181:        return (tp);
                    182: }
                    183: 
                    184: /*
                    185:  * Drop a TCP connection, reporting
                    186:  * the specified error.  If connection is synchronized,
                    187:  * then send a RST to peer.
                    188:  */
                    189: struct tcpcb *
                    190: tcp_drop(tp, errno)
                    191:        register struct tcpcb *tp;
                    192:        int errno;
                    193: {
                    194:        struct socket *so = tp->t_inpcb->inp_socket;
                    195: 
                    196:        if (TCPS_HAVERCVDSYN(tp->t_state)) {
                    197:                tp->t_state = TCPS_CLOSED;
                    198:                (void) tcp_output(tp);
                    199:        }
                    200:        so->so_error = errno;
                    201:        return (tcp_close(tp));
                    202: }
                    203: 
                    204: tcp_abort(inp)
                    205:        struct inpcb *inp;
                    206: {
                    207: #ifdef NET_PERF
                    208:        printf("tcp_abort(local addr:%lx,%x, remote addr:%lx,%x)\n",
                    209:                inp->inp_faddr.s_addr, inp->inp_fport,
                    210:                inp->inp_laddr.s_addr, inp->inp_lport);
                    211: #endif
                    212: 
                    213:        (void) tcp_close((struct tcpcb *)inp->inp_ppcb);
                    214: }
                    215: 
                    216: /*
                    217:  * Close a TCP control block:
                    218:  *     discard all space held by the tcp
                    219:  *     discard internet protocol block
                    220:  *     wake up any sleepers
                    221:  */
                    222: struct tcpcb *
                    223: tcp_close(tp)
                    224:        register struct tcpcb *tp;
                    225: {
                    226:        register struct tcpiphdr *t;
                    227:        struct inpcb *inp = tp->t_inpcb;
                    228:        struct socket *so = inp->inp_socket;
                    229:        register struct mbuf *m;
                    230: 
                    231:        t = tp->seg_next;
                    232:        while (t != (struct tcpiphdr *)tp) {
                    233:                t = (struct tcpiphdr *)t->ti_next;
                    234:                m = dtom(t->ti_prev);
                    235:                remque(t->ti_prev);
                    236:                m_freem(m);
                    237:        }
                    238:        if (tp->t_template)
                    239:                (void) m_free(dtom(tp->t_template));
                    240:        if (tp->t_tcpopt)
                    241:                (void) m_free(dtom(tp->t_tcpopt));
                    242:        if (tp->t_ipopt)
                    243:                (void) m_free(dtom(tp->t_ipopt));
                    244:        (void) m_free(dtom(tp));
                    245:        inp->inp_ppcb = 0;
                    246:        soisdisconnected(so);
                    247:        in_pcbdetach(inp);
                    248:        return ((struct tcpcb *)0);
                    249: }
                    250: 
                    251: tcp_drain()
                    252: {
                    253: 
                    254: }
                    255: 
                    256: tcp_ctlinput(cmd, arg)
                    257:        int cmd;
                    258:        caddr_t arg;
                    259: {
                    260:        struct in_addr *sin;
                    261:        extern u_char inetctlerrmap[];
                    262: 
                    263:        if (cmd < 0 || cmd > PRC_NCMDS)
                    264:                return;
                    265:        switch (cmd) {
                    266: 
                    267:        case PRC_ROUTEDEAD:
                    268:                break;
                    269: 
                    270:        case PRC_QUENCH:
                    271:                break;
                    272: 
                    273:        /* these are handled by ip */
                    274:        case PRC_IFDOWN:
                    275:        case PRC_HOSTDEAD:
                    276:        case PRC_HOSTUNREACH:
                    277:                break;
                    278: 
                    279:        default:
                    280:                sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
                    281:                in_pcbnotify(&tcb, sin, (int)inetctlerrmap[cmd], tcp_abort);
                    282:        }
                    283: }
                    284: /*
                    285:  * Given a tcpcb, find the route associated with tcpcb, then the
                    286:  * interface through which packets are sent.
                    287:  */
                    288: struct ifnet *
                    289: tcp_getif(tp)
                    290: struct tcpcb *tp;
                    291: {
                    292:        register struct route   *ro;
                    293:        register struct ifnet   *ifp;
                    294:        struct  route   iproute;
                    295:        struct  in_addr faddr;
                    296:        
                    297:        ro = &iproute;
                    298:        bzero((caddr_t)ro, sizeof(*ro));
                    299:        ro->ro_dst.sa_family = AF_INET;
                    300:        faddr = tp->t_inpcb->inp_faddr;
                    301:        if (faddr.s_addr == 0)
                    302:                return((struct ifnet *)0);
                    303: 
                    304:        ((struct sockaddr_in *) &iproute.ro_dst)->sin_addr = faddr;
                    305:        rtalloc(ro);
                    306:        if ((ro->ro_rt == 0) || (ifp = ro->ro_rt->rt_ifp) == 0)
                    307:                return((struct ifnet *)0);
                    308:        rtfree(ro->ro_rt);
                    309:        return (ifp);
                    310: }
                    311:        

unix.superglobalmegacorp.com

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