|
|
1.1 ! root 1: /* tcp_subr.c 6.1 83/07/29 */ ! 2: ! 3: #include "sys/param.h" ! 4: #include "sys/systm.h" ! 5: #include "sys/stream.h" ! 6: #include "sys/inet/in.h" ! 7: #include "sys/inet/ip.h" ! 8: #include "sys/inet/ip_var.h" ! 9: #include "sys/inet/tcp.h" ! 10: #include "sys/inet/tcp_fsm.h" ! 11: #include "sys/inet/tcp_seq.h" ! 12: #include "sys/inet/tcp_timer.h" ! 13: #include "sys/inet/tcp_var.h" ! 14: #include "sys/inet/tcpip.h" ! 15: #include "sys/inet/tcpdebug.h" ! 16: ! 17: extern int tcp_maxseg; ! 18: ! 19: /* ! 20: * Create template to be used to send tcp packets on a connection. ! 21: * Call after host entry created, allocates a block and fills ! 22: * in a skeletal tcp/ip header, minimizing the amount of work ! 23: * necessary when the connection is used. ! 24: */ ! 25: tcp_template(tp) ! 26: struct tcpcb *tp; ! 27: { ! 28: register struct block *bp; ! 29: register struct tcpiphdr *n; ! 30: ! 31: if ((bp=tp->t_template) == (struct block *)0) ! 32: bp = bp_get(); ! 33: if (bp == NULL) ! 34: return; ! 35: tp->t_template = bp; ! 36: bp->next = 0; ! 37: bp->wptr += sizeof (struct tcpiphdr); ! 38: n = (struct tcpiphdr *)bp->rptr; ! 39: n->ti_bp = 0; ! 40: n->ti_next = 0; ! 41: n->ti_x1 = 0; ! 42: n->ti_pr = 6; /* tcp protocol number */ ! 43: n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); ! 44: n->ti_src = tp->so_laddr; ! 45: n->ti_dst = tp->so_faddr; ! 46: n->ti_sport = tp->so_lport; ! 47: n->ti_dport = tp->so_fport; ! 48: n->ti_seq = 0; ! 49: n->ti_ack = 0; ! 50: n->ti_x2 = 0; ! 51: n->ti_off = 5; ! 52: n->ti_flags = 0; ! 53: n->ti_win = 0; ! 54: n->ti_sum = 0; ! 55: n->ti_urp = 0; ! 56: } ! 57: ! 58: /* ! 59: * Send a single message to the TCP at address specified by ! 60: * the given TCP/IP header. If flags==0, then we make a copy ! 61: * of the tcpiphdr at ti and send directly to the addressed host. ! 62: * This is used to force keep alive messages out using the TCP ! 63: * template for a connection tp->t_template. If flags are given ! 64: * then we send a message back to the TCP which originated the ! 65: * segment ti, and discard the block containing it and any other ! 66: * attached blocks. ! 67: * ! 68: * In any case the ack and sequence number of the transmitted ! 69: * segment are as specified by the parameters. ! 70: */ ! 71: tcp_respond(tp, ti, ack, seq, flags) ! 72: struct tcpcb *tp; ! 73: register struct tcpiphdr *ti; ! 74: tcp_seq ack, seq; ! 75: int flags; ! 76: { ! 77: struct block *tibp; ! 78: int win = 0, tlen; ! 79: ! 80: if (tp) { ! 81: win = sbrcvspace(tp); ! 82: } ! 83: if (flags == 0) { ! 84: tibp = bp_get(); ! 85: if (tibp == NULL) ! 86: return; ! 87: tibp->next = 0; ! 88: tibp->wptr += sizeof (struct tcpiphdr) + 1; ! 89: *(struct tcpiphdr *)(tibp->rptr) = *ti; ! 90: ti = (struct tcpiphdr *)(tibp->rptr); ! 91: ti->ti_bp = tibp; ! 92: flags = TH_ACK; ! 93: tlen = 1; ! 94: } else { ! 95: in_addr taddr; ! 96: tcp_port tport; ! 97: ! 98: tibp = ti->ti_bp; ! 99: bp_check(tibp); ! 100: bp_free(tibp->next); ! 101: tibp->next = 0; ! 102: tibp->rptr = (u_char *)ti; ! 103: tibp->wptr = tibp->rptr + sizeof (struct tcpiphdr); ! 104: taddr = ti->ti_src; ! 105: ti->ti_src = ti->ti_dst; ! 106: ti->ti_dst = taddr; ! 107: tport = ti->ti_sport; ! 108: ti->ti_sport = ti->ti_dport; ! 109: ti->ti_dport = tport; ! 110: tlen = 0; ! 111: } ! 112: ti->ti_next = 0; ! 113: ti->ti_bp = 0; ! 114: ti->ti_x1 = 0; ! 115: ti->ti_pr = 6; /* tcp protocol number */ ! 116: ti->ti_len = (u_short)(sizeof (struct tcphdr) + tlen); ! 117: ti->ti_len = htons(ti->ti_len); ! 118: ti->ti_seq = htonl(seq); ! 119: ti->ti_ack = htonl(ack); ! 120: ti->ti_x2 = 0; ! 121: ti->ti_off = sizeof (struct tcphdr) >> 2; ! 122: ti->ti_flags = flags; ! 123: ti->ti_win = htons((u_short)win); ! 124: ti->ti_urp = 0; ! 125: ti->ti_src = htonl(ti->ti_src); ! 126: ti->ti_dst = htonl(ti->ti_dst); ! 127: ti->ti_sport = htons(ti->ti_sport); ! 128: ti->ti_dport = htons(ti->ti_dport); ! 129: ti->ti_sum = 0; ! 130: ti->ti_sum = in_cksum(tibp, sizeof(struct tcpiphdr) + tlen); ! 131: tcp_debug(ti, 1); ! 132: ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + tlen; ! 133: ((struct ip *)ti)->ip_ttl = TCP_TTL; ! 134: ti->ti_dst = ntohl(ti->ti_dst); ! 135: ti->ti_src = ntohl(ti->ti_src); ! 136: tcp_ldout(tibp); ! 137: } ! 138: ! 139: /* ! 140: * Drop a TCP connection. ! 141: * If connection is synchronized, ! 142: * then send a RST to peer. ! 143: */ ! 144: struct tcpcb * ! 145: tcp_drop(tp) ! 146: register struct tcpcb *tp; ! 147: { ! 148: ! 149: if (TCPS_HAVERCVDSYN(tp->t_state)) { ! 150: tp->t_state = TCPS_CLOSED; ! 151: (void) tcp_output(tp); ! 152: } ! 153: return (tcp_close(tp)); ! 154: } ! 155: ! 156: /* ! 157: * Close a TCP control block: ! 158: * discard all space held by the tcp ! 159: * discard internet protocol block ! 160: * wake up any sleepers ! 161: */ ! 162: struct tcpcb * ! 163: tcp_close(tp) ! 164: register struct tcpcb *tp; ! 165: { ! 166: register struct tcpiphdr *ti, *nextti; ! 167: ! 168: if(!tp) ! 169: panic("tcp_close"); ! 170: tcp_canceltimers(tp); ! 171: ti = tp->seg_next; ! 172: while (ti != (struct tcpiphdr *)0) { ! 173: nextti = ti->ti_next; ! 174: bp_free(ti->ti_bp); ! 175: ti = nextti; ! 176: } ! 177: tp->seg_next = 0; ! 178: if (tp->t_template) ! 179: freeb(tp->t_template); ! 180: tp->t_template = 0; ! 181: if (tp->t_tcpopt) ! 182: freeb(tp->t_tcpopt); ! 183: tp->t_tcpopt = 0; ! 184: if (tp->t_ipopt) ! 185: freeb(tp->t_ipopt); ! 186: tp->t_ipopt = 0; ! 187: ! 188: /* soisdisconnected(tp); */ ! 189: tp->so_state &= ~(SS_PLEASEOPEN|SS_RCVATMARK); ! 190: if(tp->so_state&SS_OPEN && !(tp->so_state&SS_HUNGUP)) { ! 191: tp->so_state |= SS_HUNGUP; ! 192: tcp_hungup(tp); ! 193: } ! 194: tp->so_laddr = tp->so_faddr = 0; ! 195: tp->so_lport = tp->so_fport = 0; ! 196: tp->t_state = TCPS_CLOSED; ! 197: return ((struct tcpcb *)0); ! 198: } ! 199: ! 200: /* ! 201: * For debugging save time event occurred, the direction of the message, ! 202: * and the tcp header. Then increment the pointer to the tcp ! 203: * debug queue. ! 204: */ ! 205: int Nbugarr=SIZDEBUG; ! 206: struct tcpdebug bugarr[SIZDEBUG]; /* buffer to store the debug info in */ ! 207: int tcpdbg_ind=0; /* index into bugarr at last entry */ ! 208: unsigned long tcpdbg_seq = 0; /* sequence number */ ! 209: ! 210: tcp_debug(ti, code) ! 211: struct tcpiphdr *ti; ! 212: { ! 213: register int i; ! 214: i = tcpdbg_ind; ! 215: bugarr[i].seq = tcpdbg_seq++; ! 216: bugarr[i].stamp = time; ! 217: bugarr[i].inout = code; ! 218: bugarr[i].hdr = *ti; ! 219: tcpdbg_ind = (i + 1) % SIZDEBUG; ! 220: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.