vtw.c revision 1.11 1 1.11 simonb /* $NetBSD: vtw.c,v 1.11 2021/03/02 01:02:12 simonb Exp $ */
2 1.1 dyoung
3 1.1 dyoung /*
4 1.1 dyoung * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 1.1 dyoung * All rights reserved.
6 1.1 dyoung *
7 1.1 dyoung * This code is derived from software contributed to The NetBSD Foundation
8 1.1 dyoung * by Coyote Point Systems, Inc.
9 1.1 dyoung *
10 1.1 dyoung * Redistribution and use in source and binary forms, with or without
11 1.1 dyoung * modification, are permitted provided that the following conditions
12 1.1 dyoung * are met:
13 1.1 dyoung * 1. Redistributions of source code must retain the above copyright
14 1.1 dyoung * notice, this list of conditions and the following disclaimer.
15 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 dyoung * notice, this list of conditions and the following disclaimer in the
17 1.1 dyoung * documentation and/or other materials provided with the distribution.
18 1.1 dyoung *
19 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 dyoung * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 dyoung * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 dyoung * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 dyoung * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 dyoung * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 dyoung * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 dyoung * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 dyoung * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 dyoung * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 dyoung * POSSIBILITY OF SUCH DAMAGE.
30 1.1 dyoung */
31 1.1 dyoung /*
32 1.1 dyoung * Copyright (c) 1983, 1988, 1993
33 1.1 dyoung * The Regents of the University of California. All rights reserved.
34 1.1 dyoung *
35 1.1 dyoung * Redistribution and use in source and binary forms, with or without
36 1.1 dyoung * modification, are permitted provided that the following conditions
37 1.1 dyoung * are met:
38 1.1 dyoung * 1. Redistributions of source code must retain the above copyright
39 1.1 dyoung * notice, this list of conditions and the following disclaimer.
40 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright
41 1.1 dyoung * notice, this list of conditions and the following disclaimer in the
42 1.1 dyoung * documentation and/or other materials provided with the distribution.
43 1.1 dyoung * 3. Neither the name of the University nor the names of its contributors
44 1.1 dyoung * may be used to endorse or promote products derived from this software
45 1.1 dyoung * without specific prior written permission.
46 1.1 dyoung *
47 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 1.1 dyoung * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 1.1 dyoung * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 1.1 dyoung * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 1.1 dyoung * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 1.1 dyoung * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 1.1 dyoung * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 1.1 dyoung * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 1.1 dyoung * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 1.1 dyoung * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 1.1 dyoung * SUCH DAMAGE.
58 1.1 dyoung */
59 1.1 dyoung
60 1.1 dyoung #include <sys/cdefs.h>
61 1.1 dyoung #ifndef lint
62 1.1 dyoung #if 0
63 1.1 dyoung static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
64 1.1 dyoung #else
65 1.11 simonb __RCSID("$NetBSD: vtw.c,v 1.11 2021/03/02 01:02:12 simonb Exp $");
66 1.1 dyoung #endif
67 1.1 dyoung #endif /* not lint */
68 1.1 dyoung
69 1.1 dyoung #define _CALLOUT_PRIVATE /* for defs in sys/callout.h */
70 1.1 dyoung
71 1.1 dyoung #include <sys/param.h>
72 1.1 dyoung #include <sys/queue.h>
73 1.1 dyoung #include <sys/socket.h>
74 1.1 dyoung #include <sys/socketvar.h>
75 1.1 dyoung #include <sys/mbuf.h>
76 1.1 dyoung #include <sys/protosw.h>
77 1.1 dyoung #include <sys/sysctl.h>
78 1.1 dyoung
79 1.1 dyoung #include <net/if_arp.h>
80 1.1 dyoung #include <net/route.h>
81 1.1 dyoung #include <netinet/in.h>
82 1.1 dyoung #include <netinet/in_systm.h>
83 1.1 dyoung #include <netinet/ip.h>
84 1.1 dyoung #include <netinet/in_pcb.h>
85 1.1 dyoung #include <netinet/ip_icmp.h>
86 1.1 dyoung
87 1.1 dyoung #ifdef INET6
88 1.1 dyoung #include <netinet/ip6.h>
89 1.1 dyoung #endif
90 1.1 dyoung
91 1.1 dyoung #include <netinet/icmp_var.h>
92 1.1 dyoung #include <netinet/igmp_var.h>
93 1.1 dyoung #include <netinet/ip_var.h>
94 1.1 dyoung #include <netinet/pim_var.h>
95 1.1 dyoung #include <netinet/tcp.h>
96 1.1 dyoung #include <netinet/tcp_seq.h>
97 1.1 dyoung #include <netinet/tcp_fsm.h>
98 1.1 dyoung #include <netinet/tcp_timer.h>
99 1.1 dyoung #include <netinet/tcp_var.h>
100 1.1 dyoung #include <netinet/tcp_debug.h>
101 1.1 dyoung #include <netinet/udp.h>
102 1.1 dyoung #include <netinet/ip_carp.h>
103 1.1 dyoung #include <netinet/udp_var.h>
104 1.1 dyoung #include <netinet/tcp_vtw.h>
105 1.1 dyoung
106 1.1 dyoung #include <arpa/inet.h>
107 1.1 dyoung #include <kvm.h>
108 1.1 dyoung #include <netdb.h>
109 1.1 dyoung #include <stdio.h>
110 1.1 dyoung #include <string.h>
111 1.1 dyoung #include <unistd.h>
112 1.1 dyoung #include <stdlib.h>
113 1.1 dyoung #include <err.h>
114 1.1 dyoung #include "netstat.h"
115 1.1 dyoung #include "vtw.h"
116 1.1 dyoung #include "prog_ops.h"
117 1.1 dyoung
118 1.11 simonb static bool vtw_enabled(void);
119 1.1 dyoung static void snarf(const void *, void *, size_t);
120 1.1 dyoung static void *lookup(const char *);
121 1.1 dyoung static void process_vtw(const vtw_ctl_t *, void (*)(const vtw_t *));
122 1.1 dyoung
123 1.11 simonb static bool
124 1.11 simonb vtw_enabled(void)
125 1.11 simonb {
126 1.11 simonb
127 1.11 simonb if (use_sysctl) {
128 1.11 simonb int enabled;
129 1.11 simonb size_t size = sizeof(enabled);
130 1.11 simonb
131 1.11 simonb if (prog_sysctlbyname("net.inet.tcp.vtw.enable",
132 1.11 simonb &enabled, &size, NULL, 0) == -1)
133 1.11 simonb return true;
134 1.11 simonb return enabled ? true : false;
135 1.11 simonb } else {
136 1.11 simonb return true;
137 1.11 simonb }
138 1.11 simonb }
139 1.11 simonb
140 1.1 dyoung static void
141 1.1 dyoung snarf(const void *addr, void *buf, size_t len)
142 1.1 dyoung {
143 1.1 dyoung size_t cc;
144 1.1 dyoung
145 1.1 dyoung memset(buf, 0, len);
146 1.1 dyoung
147 1.1 dyoung cc = kvm_read(get_kvmd(), (unsigned long) addr, buf, len);
148 1.1 dyoung
149 1.1 dyoung if (cc != len) {
150 1.8 christos warnx("%s: short read at %p, len %zx cc %zx", __func__, addr,
151 1.1 dyoung len, cc);
152 1.1 dyoung }
153 1.1 dyoung }
154 1.1 dyoung
155 1.1 dyoung static void *
156 1.1 dyoung lookup(const char *name)
157 1.1 dyoung {
158 1.1 dyoung kvm_t *k;
159 1.1 dyoung struct nlist nl[2];
160 1.1 dyoung
161 1.1 dyoung nl[0].n_name = name;
162 1.1 dyoung nl[0].n_value = 0;
163 1.1 dyoung nl[1].n_name = NULL;
164 1.1 dyoung
165 1.1 dyoung if ((k = get_kvmd()) == NULL) {
166 1.1 dyoung if (Vflag)
167 1.1 dyoung errx(EXIT_FAILURE, "kvm not available");
168 1.1 dyoung return NULL;
169 1.1 dyoung }
170 1.1 dyoung switch (kvm_nlist(k, &nl[0])) {
171 1.1 dyoung case -1:
172 1.1 dyoung err(EXIT_FAILURE, "kvm_nlist");
173 1.1 dyoung break;
174 1.1 dyoung
175 1.1 dyoung case 0:
176 1.1 dyoung return (void *)nl[0].n_value;
177 1.1 dyoung
178 1.1 dyoung default:
179 1.1 dyoung if (Vflag)
180 1.1 dyoung errx(EXIT_FAILURE, "%s missing in symbol table", name);
181 1.1 dyoung break;
182 1.1 dyoung }
183 1.1 dyoung
184 1.1 dyoung return NULL;
185 1.1 dyoung }
186 1.1 dyoung
187 1.6 drochner void
188 1.6 drochner timebase(struct timeval *tv)
189 1.6 drochner {
190 1.6 drochner void *p;
191 1.6 drochner struct bintime timebasebin;
192 1.6 drochner
193 1.11 simonb if (!vtw_enabled()) {
194 1.11 simonb memset(tv, 0, sizeof(*tv));
195 1.11 simonb return;
196 1.11 simonb }
197 1.11 simonb
198 1.6 drochner p = lookup("timebasebin");
199 1.6 drochner if (!p)
200 1.6 drochner return;
201 1.6 drochner snarf(p, &timebasebin, sizeof(timebasebin));
202 1.6 drochner bintime2timeval(&timebasebin, tv);
203 1.6 drochner }
204 1.6 drochner
205 1.1 dyoung static void
206 1.1 dyoung process_vtw(const vtw_ctl_t * ctl, void (*print)(const vtw_t *))
207 1.1 dyoung {
208 1.1 dyoung vtw_t *vp;
209 1.1 dyoung
210 1.1 dyoung for (vp = ctl->base.v; vp && vp <= ctl->lim.v;) {
211 1.1 dyoung
212 1.1 dyoung (*print)(vp);
213 1.1 dyoung
214 1.1 dyoung if (ctl->is_v4) {
215 1.1 dyoung vtw_v4_t *v4 = (vtw_v4_t *)vp;
216 1.1 dyoung
217 1.1 dyoung vp = &(++v4)->common;
218 1.1 dyoung } else if (ctl->is_v6) {
219 1.1 dyoung vtw_v6_t *v6 = (vtw_v6_t *)vp;
220 1.1 dyoung
221 1.1 dyoung vp = &(++v6)->common;
222 1.1 dyoung }
223 1.1 dyoung }
224 1.1 dyoung }
225 1.1 dyoung
226 1.1 dyoung void
227 1.1 dyoung show_vtw_stats(void)
228 1.1 dyoung {
229 1.1 dyoung vtw_stats_t stats;
230 1.1 dyoung void *p;
231 1.1 dyoung
232 1.1 dyoung if (!Vflag)
233 1.1 dyoung return;
234 1.1 dyoung
235 1.11 simonb if (!vtw_enabled())
236 1.11 simonb return;
237 1.11 simonb
238 1.1 dyoung if ((p = lookup("vtw_stats")) == NULL)
239 1.1 dyoung return;
240 1.1 dyoung snarf(p, &stats, sizeof(stats));
241 1.1 dyoung
242 1.1 dyoung printf("\t\t%" PRIu64 " inserts\n", stats.ins);
243 1.1 dyoung printf("\t\t%" PRIu64 " deletes\n", stats.del);
244 1.1 dyoung printf("\t\t%" PRIu64 " assassinations\n", stats.kill);
245 1.1 dyoung printf("\tvestigial time-wait lookup_connect\n");
246 1.1 dyoung printf("\t\t%" PRIu64 " look\n", stats.look[0]);
247 1.1 dyoung printf("\t\t%" PRIu64 " hit\n", stats.hit[0]);
248 1.1 dyoung printf("\t\t%" PRIu64 " miss\n", stats.miss[0]);
249 1.1 dyoung printf("\t\t%" PRIu64 " probe\n", stats.probe[0]);
250 1.1 dyoung printf("\t\t%" PRIu64 " losing\n", stats.losing[0]);
251 1.1 dyoung printf("\t\t%" PRIu64 " max_chain\n", stats.max_chain[0]);
252 1.1 dyoung printf("\t\t%" PRIu64 " max_probe\n", stats.max_probe[0]);
253 1.1 dyoung printf("\t\t%" PRIu64 " max_loss\n", stats.max_loss[0]);
254 1.1 dyoung printf("\tvestigial time-wait lookup_port\n");
255 1.1 dyoung printf("\t\t%" PRIu64 " look\n", stats.look[1]);
256 1.1 dyoung printf("\t\t%" PRIu64 " hit\n", stats.hit[1]);
257 1.1 dyoung printf("\t\t%" PRIu64 " miss\n", stats.miss[1]);
258 1.1 dyoung printf("\t\t%" PRIu64 " probe\n", stats.probe[1]);
259 1.1 dyoung printf("\t\t%" PRIu64 " losing\n", stats.losing[1]);
260 1.1 dyoung printf("\t\t%" PRIu64 " max_chain\n", stats.max_chain[1]);
261 1.1 dyoung printf("\t\t%" PRIu64 " max_probe\n", stats.max_probe[1]);
262 1.1 dyoung printf("\t\t%" PRIu64 " max_loss\n", stats.max_loss[1]);
263 1.1 dyoung }
264 1.1 dyoung
265 1.1 dyoung void
266 1.1 dyoung show_vtw_v4(void (*print)(const vtw_t *))
267 1.1 dyoung {
268 1.1 dyoung fatp_t *base, *lim;
269 1.1 dyoung fatp_t **hash, **port;
270 1.1 dyoung size_t n;
271 1.1 dyoung fatp_ctl_t fat_tcpv4;
272 1.1 dyoung vtw_ctl_t vtw_tcpv4[VTW_NCLASS];
273 1.1 dyoung int i;
274 1.1 dyoung int mem = 0;
275 1.1 dyoung void *p;
276 1.1 dyoung
277 1.11 simonb if (!vtw_enabled())
278 1.11 simonb return;
279 1.11 simonb
280 1.1 dyoung if ((p = lookup("fat_tcpv4")) == NULL)
281 1.1 dyoung return;
282 1.1 dyoung snarf(p, &fat_tcpv4, sizeof(fat_tcpv4));
283 1.1 dyoung
284 1.1 dyoung if ((p = lookup("vtw_tcpv4")) == NULL)
285 1.1 dyoung return;
286 1.1 dyoung snarf(p, &vtw_tcpv4[0], sizeof(vtw_tcpv4));
287 1.1 dyoung
288 1.1 dyoung mem += sizeof(fat_tcpv4);
289 1.1 dyoung mem += sizeof(vtw_tcpv4);
290 1.1 dyoung
291 1.1 dyoung /* snarf/adjust vtw_ctl */
292 1.1 dyoung for (i = 0; i < VTW_NCLASS; ++i) {
293 1.1 dyoung vtw_v4_t *kbase, *klim;
294 1.7 christos vtw_v4_t *ubase;
295 1.5 enami ptrdiff_t delta;
296 1.1 dyoung
297 1.1 dyoung kbase = vtw_tcpv4[i].base.v4;
298 1.1 dyoung klim = vtw_tcpv4[i].lim.v4;
299 1.1 dyoung
300 1.9 christos if (!kbase || !klim)
301 1.1 dyoung continue;
302 1.1 dyoung
303 1.1 dyoung n = (klim - kbase + 1);
304 1.1 dyoung
305 1.1 dyoung if (!i) {
306 1.1 dyoung if ((ubase = malloc(n * sizeof(*kbase))) == NULL)
307 1.1 dyoung err(EXIT_FAILURE, NULL);
308 1.1 dyoung snarf(kbase, ubase, n * sizeof(*ubase));
309 1.1 dyoung
310 1.1 dyoung mem += n * sizeof(*ubase);
311 1.1 dyoung } else {
312 1.1 dyoung ubase = vtw_tcpv4[0].base.v4;
313 1.1 dyoung }
314 1.1 dyoung
315 1.1 dyoung delta = ubase - kbase;
316 1.1 dyoung
317 1.1 dyoung vtw_tcpv4[i].base.v4 += delta;
318 1.1 dyoung vtw_tcpv4[i].lim.v4 += delta;
319 1.1 dyoung vtw_tcpv4[i].alloc.v4 += delta;
320 1.1 dyoung vtw_tcpv4[i].fat = &fat_tcpv4;
321 1.1 dyoung
322 1.1 dyoung if (vtw_tcpv4[i].oldest.v4)
323 1.1 dyoung vtw_tcpv4[i].oldest.v4 += delta;
324 1.1 dyoung }
325 1.1 dyoung
326 1.1 dyoung /* snarf/adjust fat_ctl */
327 1.1 dyoung
328 1.1 dyoung base = fat_tcpv4.base;
329 1.1 dyoung lim = fat_tcpv4.lim;
330 1.1 dyoung
331 1.9 christos if (!base || !lim)
332 1.1 dyoung goto end;
333 1.1 dyoung
334 1.1 dyoung mem += (lim - base + 1) * sizeof(*base);
335 1.1 dyoung
336 1.1 dyoung fat_tcpv4.base = malloc((lim - base + 1) * sizeof(*base));
337 1.1 dyoung if (fat_tcpv4.base == NULL)
338 1.1 dyoung err(EXIT_FAILURE, NULL);
339 1.1 dyoung fat_tcpv4.lim = fat_tcpv4.base + (lim - base);
340 1.1 dyoung
341 1.1 dyoung snarf(base, fat_tcpv4.base, sizeof(*base) * (lim - base + 1));
342 1.1 dyoung
343 1.1 dyoung fat_tcpv4.vtw = &vtw_tcpv4[0];
344 1.1 dyoung fat_tcpv4.free = fat_tcpv4.base + (fat_tcpv4.free - base);
345 1.1 dyoung
346 1.1 dyoung n = fat_tcpv4.mask + 1;
347 1.1 dyoung hash = fat_tcpv4.hash;
348 1.1 dyoung port = fat_tcpv4.port;
349 1.1 dyoung
350 1.1 dyoung fat_tcpv4.hash = malloc(n * sizeof(*hash));
351 1.1 dyoung fat_tcpv4.port = malloc(n * sizeof(*port));
352 1.1 dyoung if (fat_tcpv4.hash == NULL || fat_tcpv4.port == NULL)
353 1.1 dyoung err(EXIT_FAILURE, NULL);
354 1.1 dyoung
355 1.1 dyoung snarf(hash, fat_tcpv4.hash, n * sizeof(*hash));
356 1.1 dyoung snarf(port, fat_tcpv4.port, n * sizeof(*port));
357 1.1 dyoung
358 1.1 dyoung end:
359 1.1 dyoung process_vtw(&vtw_tcpv4[0], print);
360 1.1 dyoung
361 1.1 dyoung #if 0
362 1.1 dyoung if (Vflag && vflag) {
363 1.1 dyoung printf("total memory for VTW in current config: %d bytes %f MB\n"
364 1.1 dyoung ,mem
365 1.1 dyoung ,mem / (1024.0 * 1024));
366 1.1 dyoung }
367 1.1 dyoung #endif
368 1.1 dyoung }
369 1.1 dyoung
370 1.1 dyoung void
371 1.1 dyoung show_vtw_v6(void (*print)(const vtw_t *))
372 1.1 dyoung {
373 1.1 dyoung fatp_t *base, *lim;
374 1.1 dyoung fatp_t **hash, **port;
375 1.1 dyoung size_t n;
376 1.1 dyoung fatp_ctl_t fat_tcpv6;
377 1.1 dyoung vtw_ctl_t vtw_tcpv6[VTW_NCLASS];
378 1.1 dyoung int i;
379 1.1 dyoung int mem = 0;
380 1.1 dyoung void *p;
381 1.1 dyoung
382 1.11 simonb if (!vtw_enabled())
383 1.11 simonb return;
384 1.11 simonb
385 1.1 dyoung if ((p = lookup("fat_tcpv6")) == NULL)
386 1.1 dyoung return;
387 1.1 dyoung snarf(p, &fat_tcpv6, sizeof(fat_tcpv6));
388 1.1 dyoung if ((p = lookup("vtw_tcpv6")) == NULL)
389 1.1 dyoung return;
390 1.1 dyoung snarf(p, &vtw_tcpv6[0], sizeof(vtw_tcpv6));
391 1.1 dyoung
392 1.1 dyoung mem += sizeof(fat_tcpv6);
393 1.1 dyoung mem += sizeof(vtw_tcpv6);
394 1.1 dyoung
395 1.1 dyoung for (i = 0; i < VTW_NCLASS; ++i) {
396 1.1 dyoung vtw_v6_t *kbase, *klim;
397 1.7 christos vtw_v6_t *ubase;
398 1.5 enami ptrdiff_t delta;
399 1.1 dyoung
400 1.1 dyoung kbase = vtw_tcpv6[i].base.v6;
401 1.1 dyoung klim = vtw_tcpv6[i].lim.v6;
402 1.1 dyoung
403 1.9 christos if (!kbase || !klim)
404 1.1 dyoung continue;
405 1.1 dyoung
406 1.1 dyoung n = (klim - kbase + 1);
407 1.1 dyoung
408 1.1 dyoung if (!i) {
409 1.1 dyoung if ((ubase = malloc(n * sizeof(*kbase))) == NULL)
410 1.1 dyoung err(EXIT_FAILURE, NULL);
411 1.1 dyoung
412 1.1 dyoung snarf(kbase, ubase, n * sizeof(*ubase));
413 1.1 dyoung
414 1.1 dyoung mem += n * sizeof(*ubase);
415 1.1 dyoung } else {
416 1.1 dyoung ubase = vtw_tcpv6[0].base.v6;
417 1.1 dyoung }
418 1.1 dyoung
419 1.1 dyoung delta = ubase - kbase;
420 1.1 dyoung
421 1.1 dyoung vtw_tcpv6[i].base.v6 += delta;
422 1.1 dyoung vtw_tcpv6[i].lim.v6 += delta;
423 1.1 dyoung vtw_tcpv6[i].alloc.v6 += delta;
424 1.1 dyoung vtw_tcpv6[i].fat = &fat_tcpv6;
425 1.1 dyoung
426 1.1 dyoung if (vtw_tcpv6[i].oldest.v6)
427 1.1 dyoung vtw_tcpv6[i].oldest.v6 += delta;
428 1.1 dyoung }
429 1.1 dyoung
430 1.1 dyoung base = fat_tcpv6.base;
431 1.1 dyoung lim = fat_tcpv6.lim;
432 1.1 dyoung
433 1.9 christos if (!base || !lim)
434 1.1 dyoung goto end;
435 1.1 dyoung
436 1.1 dyoung mem += (lim - base + 1) * sizeof(*base);
437 1.1 dyoung
438 1.1 dyoung fat_tcpv6.base = malloc((lim - base + 1) * sizeof(*base));
439 1.1 dyoung if (fat_tcpv6.base == NULL)
440 1.1 dyoung err(EXIT_FAILURE, NULL);
441 1.1 dyoung fat_tcpv6.lim = fat_tcpv6.base + (lim - base);
442 1.1 dyoung
443 1.1 dyoung snarf(base, fat_tcpv6.base, sizeof(*base) * (lim - base + 1));
444 1.1 dyoung
445 1.1 dyoung fat_tcpv6.vtw = &vtw_tcpv6[0];
446 1.1 dyoung fat_tcpv6.free = fat_tcpv6.base + (fat_tcpv6.free - base);
447 1.1 dyoung
448 1.1 dyoung n = fat_tcpv6.mask + 1;
449 1.1 dyoung hash = fat_tcpv6.hash;
450 1.1 dyoung port = fat_tcpv6.port;
451 1.1 dyoung
452 1.1 dyoung fat_tcpv6.hash = malloc(n * sizeof(*hash));
453 1.1 dyoung fat_tcpv6.port = malloc(n * sizeof(*port));
454 1.1 dyoung if (fat_tcpv6.hash == NULL || fat_tcpv6.port == NULL)
455 1.1 dyoung err(EXIT_FAILURE, NULL);
456 1.1 dyoung
457 1.1 dyoung snarf(hash, fat_tcpv6.hash, n * sizeof(*hash));
458 1.1 dyoung snarf(port, fat_tcpv6.port, n * sizeof(*port));
459 1.1 dyoung
460 1.1 dyoung end:
461 1.1 dyoung
462 1.1 dyoung process_vtw(&vtw_tcpv6[0], print);
463 1.1 dyoung #if 0
464 1.1 dyoung if (Vflag && vflag) {
465 1.1 dyoung printf("total memory for VTW in current config: %d bytes %f MB\n"
466 1.1 dyoung ,mem
467 1.1 dyoung ,mem / (1024.0 * 1024));
468 1.1 dyoung }
469 1.1 dyoung #endif
470 1.1 dyoung }
471