+ 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);
+#if vax
+ tp->t_maxseg = ntohs(tp->t_maxseg);
+#endif
+ break;
+
+#ifdef TCPTRUEOOB
+ case TCPOPT_WILLOOB:
+ tp->t_flags |= TF_DOOOB;
+printf("tp %x dooob\n", tp);
+ break;
+
+ case TCPOPT_OOBDATA: {
+ int seq;
+ register struct socket *so = tp->t_inpcb->inp_socket;
+ tcp_seq mark;
+
+ if (optlen != 8)
+ continue;
+ seq = cp[2];
+ if (seq < tp->t_iobseq)
+ seq += 256;
+printf("oobdata cp[2] %d iobseq %d seq %d\n", cp[2], tp->t_iobseq, seq);
+ if (seq - tp->t_iobseq > 128) {
+printf("bad seq\n");
+ tp->t_oobflags |= TCPOOB_OWEACK;
+ break;
+ }
+ tp->t_iobseq = cp[2];
+ tp->t_iobc = cp[3];
+ mark = *(tcp_seq *)(cp + 4);
+#if vax
+ mark = ntohl(mark);
+#endif
+ so->so_oobmark = so->so_rcv.sb_cc + (mark-tp->rcv_nxt);
+ if (so->so_oobmark == 0)
+ so->so_state |= SS_RCVATMARK;
+printf("take oob data %x input iobseq now %x\n", tp->t_iobc, tp->t_iobseq);
+ sohasoutofband(so);
+ break;
+ }
+
+ case TCPOPT_OOBACK: {
+ int seq;
+
+ if (optlen != 4)
+ continue;
+ if (tp->t_oobseq != cp[2]) {
+printf("wrong ack\n");
+ break;
+ }
+printf("take oob ack %x and cancel rexmt\n", cp[2]);
+ tp->t_oobflags &= ~TCPOOB_NEEDACK;
+ tp->t_timer[TCPT_OOBREXMT] = 0;
+ break;
+ }
+#endif TCPTRUEOOB
+ }
+ }
+ m_free(om);
+}
+
+/*
+ * Pull out of band byte out of a segment so
+ * it doesn't appear in the user's data queue.
+ * It is still reflected in the segment length for
+ * sequencing purposes.
+ */
+tcp_pulloutofband(so, ti)
+ struct socket *so;
+ struct tcpiphdr *ti;
+{
+ register struct mbuf *m;
+ int cnt = sizeof (struct tcpiphdr) + ti->ti_urp - 1;
+
+ m = dtom(ti);
+ while (cnt >= 0) {
+ if (m->m_len > cnt) {
+ char *cp = mtod(m, caddr_t) + cnt;
+ struct tcpcb *tp = sototcpcb(so);
+
+ tp->t_iobc = *cp;
+ tp->t_oobflags |= TCPOOB_HAVEDATA;
+ bcopy(cp+1, cp, m->m_len - cnt - 1);
+ m->m_len--;
+ return;
+ }
+ cnt -= m->m_len;
+ m = m->m_next;
+ if (m == 0)
+ break;
+ }
+ panic("tcp_pulloutofband");