After much procrastination, I present the update RFC 1948 sequence number
patch.  Modifications have been made so that it more closely complies with
RFC 1948, but still allows flexibility for sysadmins who want to reseed.
Thanks go to Barney and Julian for suggesting these changes.

I've done extensive testing with this patch, and all sysctls controlling
its operation appear to work properly.  However, testing would still be
very helpful.

I'll be on vacation from the 12th through the 19th; if no problems have
been found during that time I expected to commit and MFC it on the 21st.

I've included diffs relevant to an up to date -stable and -current.

Thanks,

Mike "Silby" Silbersack

diff -u -r netinet.old/tcp_input.c netinet/tcp_input.c
--- netinet.old/tcp_input.c     Tue Jul 31 21:43:21 2001
+++ netinet/tcp_input.c Thu Aug  9 00:45:01 2001
@@ -101,7 +101,6 @@
 MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
 
 static int     tcprexmtthresh = 3;
-tcp_seq        tcp_iss;
 tcp_cc tcp_ccgen;
 
 struct tcpstat tcpstat;
@@ -1135,7 +1134,7 @@
                if (iss)
                        tp->iss = iss;
                else {
-                       tp->iss = tcp_new_isn();
+                       tp->iss = tcp_new_isn(tp);
                }
                tp->irs = th->th_seq;
                tcp_sendseqinit(tp);
@@ -1667,7 +1666,7 @@
                        if (thflags & TH_SYN &&
                            tp->t_state == TCPS_TIME_WAIT &&
                            SEQ_GT(th->th_seq, tp->rcv_nxt)) {
-                               iss = tcp_new_isn();
+                               iss = tcp_new_isn(tp);
                                tp = tcp_close(tp);
                                goto findpcb;
                        }
diff -u -r netinet.old/tcp_seq.h netinet/tcp_seq.h
--- netinet.old/tcp_seq.h       Tue Jul 31 21:43:21 2001
+++ netinet/tcp_seq.h   Thu Aug  9 00:48:30 2001
@@ -80,26 +80,5 @@
 
 #ifdef _KERNEL
 extern tcp_cc  tcp_ccgen;              /* global connection count */
-
-/*
- * Increment for tcp_iss each second.
- * This is designed to increment at the standard 250 KB/s,
- * but with a random component averaging 128 KB.
- * We also increment tcp_iss by a quarter of this amount
- * each time we use the value for a new connection.
- * If defined, the tcp_random18() macro should produce a
- * number in the range [0-0x3ffff] that is hard to predict.
- * 
- * The variable tcp_iss and tcp_random18() are only used
- * by sequence number generation scheme 0.
- */
-#ifndef tcp_random18
-#define        tcp_random18()  (arc4random() & 0x3ffff)
-#endif
-#define        TCP_ISSINCR     (122*1024 + tcp_random18())
-
-extern tcp_seq tcp_iss;
-#else
-#define        TCP_ISSINCR     (250*1024)      /* increment for tcp_iss each second 
*/
 #endif /* _KERNEL */
 #endif /* _NETINET_TCP_SEQ_H_ */
diff -u -r netinet.old/tcp_subr.c netinet/tcp_subr.c
--- netinet.old/tcp_subr.c      Tue Jul 31 21:43:21 2001
+++ netinet/tcp_subr.c  Thu Aug  9 01:21:16 2001
@@ -98,6 +98,7 @@
 #endif /*IPSEC*/
 
 #include <machine/in_cksum.h>
+#include <sys/md5.h>
 
 int    tcp_mssdflt = TCP_MSS;
 SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW, 
@@ -139,9 +140,13 @@
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_RW, &icmp_may_rst, 0, 
     "Certain ICMP unreachable messages may abort connections in SYN_SENT");
 
-static int     tcp_seq_genscheme = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_seq_genscheme, CTLFLAG_RW,
-    &tcp_seq_genscheme, 0, "TCP ISN generation scheme");
+static int     tcp_strict_rfc1948 = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, strict_rfc1948, CTLFLAG_RW,
+    &tcp_strict_rfc1948, 0, "Determines if RFC1948 is followed exactly");
+
+static int     tcp_isn_reseed_interval = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_RW,
+    &tcp_isn_reseed_interval, 0, "Seconds between reseeding of ISN secret");
 
 static void    tcp_cleartaocache __P((void));
 static void    tcp_notify __P((struct inpcb *, int));
@@ -186,7 +191,6 @@
 {
        int hashsize = TCBHASHSIZE;
        
-       tcp_iss = arc4random(); /* wrong, but better than a constant */
        tcp_ccgen = 1;
        tcp_cleartaocache();
 
@@ -1112,80 +1116,101 @@
 }
 #endif /* INET6 */
 
-tcp_seq
-tcp_new_isn()
-{
-
-       if (tcp_seq_genscheme > 1 || tcp_seq_genscheme < 0)
-               tcp_seq_genscheme = 1;
-
-       switch (tcp_seq_genscheme) {
-       case 0:                 /* Random positive increments */
-               tcp_iss += TCP_ISSINCR/2;
-               return tcp_iss;
-       case 1:                 /* OpenBSD randomized scheme */
-               return tcp_rndiss_next();
-       default:
-               panic("cannot happen");
-       }
-}
-
-#define TCP_RNDISS_ROUNDS      16
-#define TCP_RNDISS_OUT 7200
-#define TCP_RNDISS_MAX 30000
-
-u_int8_t tcp_rndiss_sbox[128];
-u_int16_t tcp_rndiss_msb;
-u_int16_t tcp_rndiss_cnt;
-long tcp_rndiss_reseed;
-
-u_int16_t
-tcp_rndiss_encrypt(val)
-       u_int16_t val;
-{
-       u_int16_t sum = 0, i;
-  
-       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
-               sum += 0x79b9;
-               val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7;
-               val = ((val & 0xff) << 7) | (val >> 8);
-       }
 
-       return val;
-}
-
-void
-tcp_rndiss_init()
-{
-       struct timeval time;
+/*
+ * Following is where TCP initial sequence number generation occurs.
+ *
+ * There are two places where we must use initial sequence numbers:
+ * 1.  In SYN-ACK packets.
+ * 2.  In SYN packets.
+ *
+ * The ISNs in SYN-ACK packets have no monotonicity requirement, 
+ * and should be as unpredictable as possible to avoid the possibility
+ * of spoofing and/or connection hijacking.  To satisfy this
+ * requirement, SYN-ACK ISNs are generated via the arc4random()
+ * function.  If exact RFC 1948 compliance is requested via sysctl,
+ * these ISNs will be generated just like those in SYN packets.
+ *
+ * The ISNs in SYN packets must be monotonic; TIME_WAIT recycling
+ * depends on this property.  In addition, these ISNs should be
+ * unguessable so as to prevent connection hijacking.  To satisfy
+ * the requirements of this situation, the algorithm outlined in
+ * RFC 1948 is used to generate sequence numbers.
+ *
+ * For more information on the theory of operation, please see
+ * RFC 1948.
+ *
+ * Implementation details:
+ *
+ * Time is based off the system timer, and is corrected so that it
+ * increases by one megabyte per second.  This allows for proper
+ * recycling on high speed LANs while still leaving over an hour
+ * before rollover.
+ *
+ * Two sysctls control the generation of ISNs:
+ *
+ * net.inet.tcp.isn_reseed_interval controls the number of seconds
+ * between seeding of isn_secret.  This is normally set to zero,
+ * as reseeding should not be necessary.
+ *
+ * net.inet.tcp.strict_rfc1948 controls whether RFC 1948 is followed
+ * strictly.  When strict compliance is requested, reseeding is
+ * disabled and SYN-ACKs will be generated in the same manner as
+ * SYNs.  Strict mode is disabled by default.
+ *
+ */
 
-       getmicrotime(&time);
-       read_random(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox));
+#define ISN_BYTES_PER_SECOND 1048576
 
-       tcp_rndiss_reseed = time.tv_sec + TCP_RNDISS_OUT;
-       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; 
-       tcp_rndiss_cnt = 0;
-}
+u_char isn_secret[32];
+int isn_last_reseed;
+MD5_CTX isn_ctx;
 
 tcp_seq
-tcp_rndiss_next()
+tcp_new_isn(tp)
+       struct tcpcb *tp;
 {
-       u_int16_t tmp;
-       struct timeval time;
+       u_int32_t md5_buffer[4];
+       tcp_seq new_isn;
 
-       getmicrotime(&time);
-
-        if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
-           time.tv_sec > tcp_rndiss_reseed)
-                tcp_rndiss_init();
-       
-       read_random(&tmp, sizeof(tmp));
-
-       /* (tmp & 0x7fff) ensures a 32768 byte gap between ISS */
-       return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) |
-               (tmp & 0x7fff);
+       /* Use arc4random for SYN-ACKs when not in exact RFC1948 mode. */
+       if (((tp->t_state == TCPS_LISTEN) || (tp->t_state == TCPS_TIME_WAIT))
+          && tcp_strict_rfc1948 != 1)
+               return arc4random();
+
+       /* Seed if this is the first use, reseed if requested. */
+       if ((isn_last_reseed == 0) ||
+           ((tcp_strict_rfc1948 != 1) && (tcp_isn_reseed_interval > 0) &&
+            (((u_int)isn_last_reseed + (u_int)tcp_isn_reseed_interval*hz)
+               < (u_int)ticks))) {
+               read_random(&isn_secret, sizeof(isn_secret));
+               isn_last_reseed = ticks;
+       }
+               
+       /* Compute the md5 hash and return the ISN. */
+       MD5Init(&isn_ctx);
+       MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_fport, sizeof(u_short));
+       MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_lport, sizeof(u_short));
+#ifdef INET6
+       if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) {
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_faddr,
+                         sizeof(struct in6_addr));
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_laddr,
+                         sizeof(struct in6_addr));
+       } else
+#endif
+       {
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_faddr,
+                         sizeof(struct in_addr));
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_laddr,
+                         sizeof(struct in_addr));
+       }
+       MD5Update(&isn_ctx, (u_char *) &isn_secret, sizeof(isn_secret));
+       MD5Final((u_char *) &md5_buffer, &isn_ctx);
+       new_isn = (tcp_seq) md5_buffer[0];
+       new_isn += ticks * (ISN_BYTES_PER_SECOND / hz);
+       return new_isn;
 }
-
 
 /*
  * When a source quench is received, close congestion window
diff -u -r netinet.old/tcp_timer.c netinet/tcp_timer.c
--- netinet.old/tcp_timer.c     Tue Jul 31 21:43:21 2001
+++ netinet/tcp_timer.c Thu Aug  9 00:45:50 2001
@@ -133,8 +133,6 @@
 
        tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
 
-       tcp_iss += TCP_ISSINCR/PR_SLOWHZ;
-
        splx(s);
 }
 
diff -u -r netinet.old/tcp_usrreq.c netinet/tcp_usrreq.c
--- netinet.old/tcp_usrreq.c    Tue Jul 31 21:43:21 2001
+++ netinet/tcp_usrreq.c        Tue Jul 31 21:45:58 2001
@@ -758,7 +758,7 @@
        tcpstat.tcps_connattempt++;
        tp->t_state = TCPS_SYN_SENT;
        callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
-       tp->iss = tcp_new_isn();
+       tp->iss = tcp_new_isn(tp);
        tcp_sendseqinit(tp);
 
        /*
@@ -844,7 +844,7 @@
        tcpstat.tcps_connattempt++;
        tp->t_state = TCPS_SYN_SENT;
        callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
-       tp->iss = tcp_new_isn();
+       tp->iss = tcp_new_isn(tp);
        tcp_sendseqinit(tp);
 
        /*
diff -u -r netinet.old/tcp_var.h netinet/tcp_var.h
--- netinet.old/tcp_var.h       Tue Jul 31 21:43:21 2001
+++ netinet/tcp_var.h   Thu Aug  9 00:55:16 2001
@@ -410,11 +410,7 @@
 extern struct pr_usrreqs tcp_usrreqs;
 extern u_long tcp_sendspace;
 extern u_long tcp_recvspace;
-void   tcp_rndiss_init __P((void));
-tcp_seq        tcp_rndiss_next __P((void));
-u_int16_t
-       tcp_rndiss_encrypt __P((u_int16_t));
-tcp_seq tcp_new_isn __P((void));
+tcp_seq tcp_new_isn __P((struct tcpcb *));
 
 #endif /* _KERNEL */
diff -u -r netinet.old/tcp_input.c netinet/tcp_input.c
--- netinet.old/tcp_input.c     Tue Jul 31 21:43:21 2001
+++ netinet/tcp_input.c Thu Aug  9 00:45:01 2001
@@ -101,7 +101,6 @@
 MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
 
 static int     tcprexmtthresh = 3;
-tcp_seq        tcp_iss;
 tcp_cc tcp_ccgen;
 
 struct tcpstat tcpstat;
@@ -1135,7 +1134,7 @@
                if (iss)
                        tp->iss = iss;
                else {
-                       tp->iss = tcp_new_isn();
+                       tp->iss = tcp_new_isn(tp);
                }
                tp->irs = th->th_seq;
                tcp_sendseqinit(tp);
@@ -1667,7 +1666,7 @@
                        if (thflags & TH_SYN &&
                            tp->t_state == TCPS_TIME_WAIT &&
                            SEQ_GT(th->th_seq, tp->rcv_nxt)) {
-                               iss = tcp_new_isn();
+                               iss = tcp_new_isn(tp);
                                tp = tcp_close(tp);
                                goto findpcb;
                        }
diff -u -r netinet.old/tcp_seq.h netinet/tcp_seq.h
--- netinet.old/tcp_seq.h       Tue Jul 31 21:43:21 2001
+++ netinet/tcp_seq.h   Thu Aug  9 00:48:30 2001
@@ -80,26 +80,5 @@
 
 #ifdef _KERNEL
 extern tcp_cc  tcp_ccgen;              /* global connection count */
-
-/*
- * Increment for tcp_iss each second.
- * This is designed to increment at the standard 250 KB/s,
- * but with a random component averaging 128 KB.
- * We also increment tcp_iss by a quarter of this amount
- * each time we use the value for a new connection.
- * If defined, the tcp_random18() macro should produce a
- * number in the range [0-0x3ffff] that is hard to predict.
- * 
- * The variable tcp_iss and tcp_random18() are only used
- * by sequence number generation scheme 0.
- */
-#ifndef tcp_random18
-#define        tcp_random18()  (arc4random() & 0x3ffff)
-#endif
-#define        TCP_ISSINCR     (122*1024 + tcp_random18())
-
-extern tcp_seq tcp_iss;
-#else
-#define        TCP_ISSINCR     (250*1024)      /* increment for tcp_iss each second 
*/
 #endif /* _KERNEL */
 #endif /* _NETINET_TCP_SEQ_H_ */
diff -u -r netinet.old/tcp_subr.c netinet/tcp_subr.c
--- netinet.old/tcp_subr.c      Tue Jul 31 21:43:21 2001
+++ netinet/tcp_subr.c  Thu Aug  9 01:21:16 2001
@@ -98,6 +98,7 @@
 #endif /*IPSEC*/
 
 #include <machine/in_cksum.h>
+#include <sys/md5.h>
 
 int    tcp_mssdflt = TCP_MSS;
 SYSCTL_INT(_net_inet_tcp, TCPCTL_MSSDFLT, mssdflt, CTLFLAG_RW, 
@@ -139,9 +140,13 @@
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_may_rst, CTLFLAG_RW, &icmp_may_rst, 0, 
     "Certain ICMP unreachable messages may abort connections in SYN_SENT");
 
-static int     tcp_seq_genscheme = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcp_seq_genscheme, CTLFLAG_RW,
-    &tcp_seq_genscheme, 0, "TCP ISN generation scheme");
+static int     tcp_strict_rfc1948 = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, strict_rfc1948, CTLFLAG_RW,
+    &tcp_strict_rfc1948, 0, "Determines if RFC1948 is followed exactly");
+
+static int     tcp_isn_reseed_interval = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, isn_reseed_interval, CTLFLAG_RW,
+    &tcp_isn_reseed_interval, 0, "Seconds between reseeding of ISN secret");
 
 static void    tcp_cleartaocache __P((void));
 static void    tcp_notify __P((struct inpcb *, int));
@@ -186,7 +191,6 @@
 {
        int hashsize = TCBHASHSIZE;
        
-       tcp_iss = arc4random(); /* wrong, but better than a constant */
        tcp_ccgen = 1;
        tcp_cleartaocache();
 
@@ -1112,80 +1116,101 @@
 }
 #endif /* INET6 */
 
-tcp_seq
-tcp_new_isn()
-{
-
-       if (tcp_seq_genscheme > 1 || tcp_seq_genscheme < 0)
-               tcp_seq_genscheme = 1;
-
-       switch (tcp_seq_genscheme) {
-       case 0:                 /* Random positive increments */
-               tcp_iss += TCP_ISSINCR/2;
-               return tcp_iss;
-       case 1:                 /* OpenBSD randomized scheme */
-               return tcp_rndiss_next();
-       default:
-               panic("cannot happen");
-       }
-}
-
-#define TCP_RNDISS_ROUNDS      16
-#define TCP_RNDISS_OUT 7200
-#define TCP_RNDISS_MAX 30000
-
-u_int8_t tcp_rndiss_sbox[128];
-u_int16_t tcp_rndiss_msb;
-u_int16_t tcp_rndiss_cnt;
-long tcp_rndiss_reseed;
-
-u_int16_t
-tcp_rndiss_encrypt(val)
-       u_int16_t val;
-{
-       u_int16_t sum = 0, i;
-  
-       for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
-               sum += 0x79b9;
-               val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7;
-               val = ((val & 0xff) << 7) | (val >> 8);
-       }
 
-       return val;
-}
-
-void
-tcp_rndiss_init()
-{
-       struct timeval time;
+/*
+ * Following is where TCP initial sequence number generation occurs.
+ *
+ * There are two places where we must use initial sequence numbers:
+ * 1.  In SYN-ACK packets.
+ * 2.  In SYN packets.
+ *
+ * The ISNs in SYN-ACK packets have no monotonicity requirement, 
+ * and should be as unpredictable as possible to avoid the possibility
+ * of spoofing and/or connection hijacking.  To satisfy this
+ * requirement, SYN-ACK ISNs are generated via the arc4random()
+ * function.  If exact RFC 1948 compliance is requested via sysctl,
+ * these ISNs will be generated just like those in SYN packets.
+ *
+ * The ISNs in SYN packets must be monotonic; TIME_WAIT recycling
+ * depends on this property.  In addition, these ISNs should be
+ * unguessable so as to prevent connection hijacking.  To satisfy
+ * the requirements of this situation, the algorithm outlined in
+ * RFC 1948 is used to generate sequence numbers.
+ *
+ * For more information on the theory of operation, please see
+ * RFC 1948.
+ *
+ * Implementation details:
+ *
+ * Time is based off the system timer, and is corrected so that it
+ * increases by one megabyte per second.  This allows for proper
+ * recycling on high speed LANs while still leaving over an hour
+ * before rollover.
+ *
+ * Two sysctls control the generation of ISNs:
+ *
+ * net.inet.tcp.isn_reseed_interval controls the number of seconds
+ * between seeding of isn_secret.  This is normally set to zero,
+ * as reseeding should not be necessary.
+ *
+ * net.inet.tcp.strict_rfc1948 controls whether RFC 1948 is followed
+ * strictly.  When strict compliance is requested, reseeding is
+ * disabled and SYN-ACKs will be generated in the same manner as
+ * SYNs.  Strict mode is disabled by default.
+ *
+ */
 
-       getmicrotime(&time);
-       read_random_unlimited(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox));
+#define ISN_BYTES_PER_SECOND 1048576
 
-       tcp_rndiss_reseed = time.tv_sec + TCP_RNDISS_OUT;
-       tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; 
-       tcp_rndiss_cnt = 0;
-}
+u_char isn_secret[32];
+int isn_last_reseed;
+MD5_CTX isn_ctx;
 
 tcp_seq
-tcp_rndiss_next()
+tcp_new_isn(tp)
+       struct tcpcb *tp;
 {
-       u_int32_t tmp;
-       struct timeval time;
+       u_int32_t md5_buffer[4];
+       tcp_seq new_isn;
 
-       getmicrotime(&time);
-
-        if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
-           time.tv_sec > tcp_rndiss_reseed)
-                tcp_rndiss_init();
-       
-       tmp = arc4random();
-
-       /* (tmp & 0x7fff) ensures a 32768 byte gap between ISS */
-       return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) |
-               (tmp & 0x7fff);
+       /* Use arc4random for SYN-ACKs when not in exact RFC1948 mode. */
+       if (((tp->t_state == TCPS_LISTEN) || (tp->t_state == TCPS_TIME_WAIT))
+          && tcp_strict_rfc1948 != 1)
+               return arc4random();
+
+       /* Seed if this is the first use, reseed if requested. */
+       if ((isn_last_reseed == 0) ||
+           ((tcp_strict_rfc1948 != 1) && (tcp_isn_reseed_interval > 0) &&
+            (((u_int)isn_last_reseed + (u_int)tcp_isn_reseed_interval*hz)
+               < (u_int)ticks))) {
+               read_random_unlimited(&isn_secret, sizeof(isn_secret));
+               isn_last_reseed = ticks;
+       }
+               
+       /* Compute the md5 hash and return the ISN. */
+       MD5Init(&isn_ctx);
+       MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_fport, sizeof(u_short));
+       MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_lport, sizeof(u_short));
+#ifdef INET6
+       if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) {
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_faddr,
+                         sizeof(struct in6_addr));
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_laddr,
+                         sizeof(struct in6_addr));
+       } else
+#endif
+       {
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_faddr,
+                         sizeof(struct in_addr));
+               MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_laddr,
+                         sizeof(struct in_addr));
+       }
+       MD5Update(&isn_ctx, (u_char *) &isn_secret, sizeof(isn_secret));
+       MD5Final((u_char *) &md5_buffer, &isn_ctx);
+       new_isn = (tcp_seq) md5_buffer[0];
+       new_isn += ticks * (ISN_BYTES_PER_SECOND / hz);
+       return new_isn;
 }
-
 
 /*
  * When a source quench is received, close congestion window
diff -u -r netinet.old/tcp_timer.c netinet/tcp_timer.c
--- netinet.old/tcp_timer.c     Tue Jul 31 21:43:21 2001
+++ netinet/tcp_timer.c Thu Aug  9 00:45:50 2001
@@ -133,8 +133,6 @@
 
        tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
 
-       tcp_iss += TCP_ISSINCR/PR_SLOWHZ;
-
        splx(s);
 }
 
diff -u -r netinet.old/tcp_usrreq.c netinet/tcp_usrreq.c
--- netinet.old/tcp_usrreq.c    Tue Jul 31 21:43:21 2001
+++ netinet/tcp_usrreq.c        Tue Jul 31 21:45:58 2001
@@ -758,7 +758,7 @@
        tcpstat.tcps_connattempt++;
        tp->t_state = TCPS_SYN_SENT;
        callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
-       tp->iss = tcp_new_isn();
+       tp->iss = tcp_new_isn(tp);
        tcp_sendseqinit(tp);
 
        /*
@@ -844,7 +844,7 @@
        tcpstat.tcps_connattempt++;
        tp->t_state = TCPS_SYN_SENT;
        callout_reset(tp->tt_keep, tcp_keepinit, tcp_timer_keep, tp);
-       tp->iss = tcp_new_isn();
+       tp->iss = tcp_new_isn(tp);
        tcp_sendseqinit(tp);
 
        /*
diff -u -r netinet.old/tcp_var.h netinet/tcp_var.h
--- netinet.old/tcp_var.h       Tue Jul 31 21:43:21 2001
+++ netinet/tcp_var.h   Thu Aug  9 00:55:16 2001
@@ -410,11 +410,7 @@
 extern struct pr_usrreqs tcp_usrreqs;
 extern u_long tcp_sendspace;
 extern u_long tcp_recvspace;
-void   tcp_rndiss_init __P((void));
-tcp_seq        tcp_rndiss_next __P((void));
-u_int16_t
-       tcp_rndiss_encrypt __P((u_int16_t));
-tcp_seq tcp_new_isn __P((void));
+tcp_seq tcp_new_isn __P((struct tcpcb *));
 
 #endif /* _KERNEL */

Reply via email to