+ case TCPS_TIME_WAIT:
+ tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
+ break;
+ }
+ }
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0);
+
+ /*
+ * Return any desired output.
+ */
+ (void) tcp_output(tp);
+ return;
+
+dropafterack:
+ /*
+ * Generate an ACK dropping incoming segment if it occupies
+ * sequence space, where the ACK reflects our state.
+ */
+ if ((tiflags&TH_RST) ||
+ tlen == 0 && (tiflags&(TH_SYN|TH_FIN)) == 0)
+ goto drop;
+ if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)
+ tcp_trace(TA_RESPOND, ostate, tp, &tcp_saveti, 0);
+ tcp_respond(tp, ti, tp->rcv_nxt, tp->snd_nxt, TH_ACK);
+ return;
+
+dropwithreset:
+ if (om)
+ (void) m_free(om);
+ /*
+ * Generate a RST, dropping incoming segment.
+ * Make ACK acceptable to originator of segment.
+ */
+ if (tiflags & TH_RST)
+ goto drop;
+ if (tiflags & TH_ACK)
+ tcp_respond(tp, ti, (tcp_seq)0, ti->ti_ack, TH_RST);
+ else {
+ if (tiflags & TH_SYN)
+ ti->ti_len++;
+ tcp_respond(tp, ti, ti->ti_seq+ti->ti_len, (tcp_seq)0,
+ TH_RST|TH_ACK);
+ }
+ return;
+
+drop:
+ /*
+ * Drop space held by incoming segment and return.
+ */
+ if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
+ tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
+ m_freem(m);
+ return;
+}
+
+tcp_dooptions(tp, om)
+ struct tcpcb *tp;
+ struct mbuf *om;
+{
+ register u_char *cp;
+ int opt, optlen, cnt;
+
+ cp = mtod(om, u_char *);
+ cnt = om->m_len;
+ for (; cnt > 0; cnt -= optlen, cp += optlen) {
+ opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else
+ optlen = cp[1];
+ switch (opt) {
+
+ default:
+ break;
+
+ case TCPOPT_MAXSEG:
+ if (optlen != 4)
+ continue;
+ tp->t_maxseg = *(u_short *)(cp + 2);
+ tp->t_maxseg = ntohs((u_short)tp->t_maxseg);
+ break;