1 | #include <rtems/freebsd/machine/rtems-bsd-config.h> |
---|
2 | |
---|
3 | /*- |
---|
4 | * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 |
---|
5 | * The Regents of the University of California. All rights reserved. |
---|
6 | * |
---|
7 | * Redistribution and use in source and binary forms, with or without |
---|
8 | * modification, are permitted provided that the following conditions |
---|
9 | * are met: |
---|
10 | * 1. Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * 4. Neither the name of the University nor the names of its contributors |
---|
16 | * may be used to endorse or promote products derived from this software |
---|
17 | * without specific prior written permission. |
---|
18 | * |
---|
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
29 | * SUCH DAMAGE. |
---|
30 | * |
---|
31 | */ |
---|
32 | |
---|
33 | #include <rtems/freebsd/local/opt_inet.h> |
---|
34 | #include <rtems/freebsd/local/opt_inet6.h> |
---|
35 | |
---|
36 | #include <rtems/freebsd/sys/cdefs.h> |
---|
37 | __FBSDID("$FreeBSD$"); |
---|
38 | |
---|
39 | #include <rtems/freebsd/sys/param.h> |
---|
40 | #include <rtems/freebsd/sys/kernel.h> |
---|
41 | #include <rtems/freebsd/sys/libkern.h> |
---|
42 | #include <rtems/freebsd/sys/mbuf.h> |
---|
43 | #include <rtems/freebsd/sys/md5.h> |
---|
44 | #include <rtems/freebsd/sys/time.h> |
---|
45 | #include <rtems/freebsd/sys/random.h> |
---|
46 | #include <rtems/freebsd/sys/socket.h> |
---|
47 | #include <rtems/freebsd/sys/socketvar.h> |
---|
48 | #include <rtems/freebsd/sys/systm.h> |
---|
49 | #include <rtems/freebsd/sys/time.h> |
---|
50 | |
---|
51 | #include <rtems/freebsd/net/if.h> |
---|
52 | #include <rtems/freebsd/net/if_types.h> |
---|
53 | #include <rtems/freebsd/net/bpf.h> |
---|
54 | #include <rtems/freebsd/net/route.h> |
---|
55 | |
---|
56 | #include <rtems/freebsd/netinet/in.h> |
---|
57 | #include <rtems/freebsd/netinet/in_var.h> |
---|
58 | #include <rtems/freebsd/netinet/in_systm.h> |
---|
59 | #include <rtems/freebsd/netinet/ip.h> |
---|
60 | #include <rtems/freebsd/netinet/ip_var.h> |
---|
61 | #include <rtems/freebsd/netinet/tcp.h> |
---|
62 | #include <rtems/freebsd/netinet/tcp_seq.h> |
---|
63 | #include <rtems/freebsd/netinet/udp.h> |
---|
64 | #include <rtems/freebsd/netinet/ip_icmp.h> |
---|
65 | #include <rtems/freebsd/netinet/in_pcb.h> |
---|
66 | #include <rtems/freebsd/netinet/tcp_timer.h> |
---|
67 | #include <rtems/freebsd/netinet/tcp_var.h> |
---|
68 | #include <rtems/freebsd/netinet/if_ether.h> |
---|
69 | #include <rtems/freebsd/net/pfvar.h> |
---|
70 | |
---|
71 | /* |
---|
72 | * Following is where TCP initial sequence number generation occurs. |
---|
73 | * |
---|
74 | * There are two places where we must use initial sequence numbers: |
---|
75 | * 1. In SYN-ACK packets. |
---|
76 | * 2. In SYN packets. |
---|
77 | * |
---|
78 | * All ISNs for SYN-ACK packets are generated by the syncache. See |
---|
79 | * tcp_syncache.c for details. |
---|
80 | * |
---|
81 | * The ISNs in SYN packets must be monotonic; TIME_WAIT recycling |
---|
82 | * depends on this property. In addition, these ISNs should be |
---|
83 | * unguessable so as to prevent connection hijacking. To satisfy |
---|
84 | * the requirements of this situation, the algorithm outlined in |
---|
85 | * RFC 1948 is used, with only small modifications. |
---|
86 | * |
---|
87 | * Implementation details: |
---|
88 | * |
---|
89 | * Time is based off the system timer, and is corrected so that it |
---|
90 | * increases by one megabyte per second. This allows for proper |
---|
91 | * recycling on high speed LANs while still leaving over an hour |
---|
92 | * before rollover. |
---|
93 | * |
---|
94 | * As reading the *exact* system time is too expensive to be done |
---|
95 | * whenever setting up a TCP connection, we increment the time |
---|
96 | * offset in two ways. First, a small random positive increment |
---|
97 | * is added to isn_offset for each connection that is set up. |
---|
98 | * Second, the function tcp_isn_tick fires once per clock tick |
---|
99 | * and increments isn_offset as necessary so that sequence numbers |
---|
100 | * are incremented at approximately ISN_BYTES_PER_SECOND. The |
---|
101 | * random positive increments serve only to ensure that the same |
---|
102 | * exact sequence number is never sent out twice (as could otherwise |
---|
103 | * happen when a port is recycled in less than the system tick |
---|
104 | * interval.) |
---|
105 | * |
---|
106 | * net.inet.tcp.isn_reseed_interval controls the number of seconds |
---|
107 | * between seeding of isn_secret. This is normally set to zero, |
---|
108 | * as reseeding should not be necessary. |
---|
109 | * |
---|
110 | * Locking of the global variables isn_secret, isn_last_reseed, isn_offset, |
---|
111 | * isn_offset_old, and isn_ctx is performed using the TCP pcbinfo lock. In |
---|
112 | * general, this means holding an exclusive (write) lock. |
---|
113 | */ |
---|
114 | |
---|
115 | #define ISN_BYTES_PER_SECOND 1048576 |
---|
116 | #define ISN_STATIC_INCREMENT 4096 |
---|
117 | #define ISN_RANDOM_INCREMENT (4096 - 1) |
---|
118 | |
---|
119 | static u_char pf_isn_secret[32]; |
---|
120 | static int pf_isn_last_reseed; |
---|
121 | static u_int32_t pf_isn_offset; |
---|
122 | |
---|
123 | u_int32_t |
---|
124 | pf_new_isn(struct pf_state *s) |
---|
125 | { |
---|
126 | MD5_CTX isn_ctx; |
---|
127 | u_int32_t md5_buffer[4]; |
---|
128 | u_int32_t new_isn; |
---|
129 | struct pf_state_host *src, *dst; |
---|
130 | |
---|
131 | /* Seed if this is the first use, reseed if requested. */ |
---|
132 | if (pf_isn_last_reseed == 0) { |
---|
133 | read_random(&pf_isn_secret, sizeof(pf_isn_secret)); |
---|
134 | pf_isn_last_reseed = ticks; |
---|
135 | } |
---|
136 | |
---|
137 | if (s->direction == PF_IN) { |
---|
138 | src = &s->ext; |
---|
139 | dst = &s->gwy; |
---|
140 | } else { |
---|
141 | src = &s->lan; |
---|
142 | dst = &s->ext; |
---|
143 | } |
---|
144 | |
---|
145 | /* Compute the md5 hash and return the ISN. */ |
---|
146 | MD5Init(&isn_ctx); |
---|
147 | MD5Update(&isn_ctx, (u_char *) &dst->port, sizeof(u_short)); |
---|
148 | MD5Update(&isn_ctx, (u_char *) &src->port, sizeof(u_short)); |
---|
149 | #ifdef INET6 |
---|
150 | if (s->af == AF_INET6) { |
---|
151 | MD5Update(&isn_ctx, (u_char *) &dst->addr, |
---|
152 | sizeof(struct in6_addr)); |
---|
153 | MD5Update(&isn_ctx, (u_char *) &src->addr, |
---|
154 | sizeof(struct in6_addr)); |
---|
155 | } else |
---|
156 | #endif |
---|
157 | { |
---|
158 | MD5Update(&isn_ctx, (u_char *) &dst->addr, |
---|
159 | sizeof(struct in_addr)); |
---|
160 | MD5Update(&isn_ctx, (u_char *) &src->addr, |
---|
161 | sizeof(struct in_addr)); |
---|
162 | } |
---|
163 | MD5Update(&isn_ctx, (u_char *) &pf_isn_secret, sizeof(pf_isn_secret)); |
---|
164 | MD5Final((u_char *) &md5_buffer, &isn_ctx); |
---|
165 | new_isn = (tcp_seq) md5_buffer[0]; |
---|
166 | pf_isn_offset += ISN_STATIC_INCREMENT + |
---|
167 | (arc4random() & ISN_RANDOM_INCREMENT); |
---|
168 | new_isn += pf_isn_offset; |
---|
169 | return (new_isn); |
---|
170 | } |
---|