+ * If the RST bit is set examine the state:
+ * SYN_RECEIVED STATE:
+ * If passive open, return to LISTEN state.
+ * If active open, inform user that connection was refused.
+ * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
+ * Inform user that connection was reset, and close tcb.
+ * CLOSING, LAST_ACK, TIME_WAIT STATES
+ * Close the tcb.
+ */
+ if (tiflags&TH_RST) switch (tp->t_state) {
+
+ case TCPS_SYN_RECEIVED:
+ if (inp->inp_socket->so_options & SO_ACCEPTCONN) {
+ /* a miniature tcp_close, but invisible to user */
+ (void) m_free(dtom(tp->t_template));
+ (void) m_free(dtom(tp));
+ inp->inp_ppcb = 0;
+ tp = tcp_newtcpcb(inp);
+ tp->t_state = TCPS_LISTEN;
+ inp->inp_faddr.s_addr = 0;
+ inp->inp_fport = 0;
+ inp->inp_laddr.s_addr = 0; /* not quite right */
+ tp = 0;
+ goto drop;
+ }
+ tcp_drop(tp, ECONNREFUSED);
+ tp = 0;
+ goto drop;
+
+ case TCPS_ESTABLISHED:
+ case TCPS_FIN_WAIT_1:
+ case TCPS_FIN_WAIT_2:
+ case TCPS_CLOSE_WAIT:
+ tcp_drop(tp, ECONNRESET);
+ tp = 0;
+ goto drop;
+
+ case TCPS_CLOSING:
+ case TCPS_LAST_ACK:
+ case TCPS_TIME_WAIT:
+ tcp_close(tp);
+ tp = 0;
+ goto drop;
+ }
+
+ /*
+ * If a SYN is in the window, then this is an
+ * error and we send an RST and drop the connection.
+ */
+ if (tiflags & TH_SYN) {
+ tcp_drop(tp, ECONNRESET);
+ tp = 0;
+ goto dropwithreset;
+ }
+
+ /*
+ * If the ACK bit is off we drop the segment and return.
+ */
+ if ((tiflags & TH_ACK) == 0)
+ goto drop;
+
+ /*
+ * Ack processing.