Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dist / ipf / netinet / ip_proxy.c
blob2ca5408671e12fa6e37309f2c177e1d03262321d
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 1997-2003 by Darren Reed.
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8 #if defined(KERNEL) || defined(_KERNEL)
9 # undef KERNEL
10 # undef _KERNEL
11 # define KERNEL 1
12 # define _KERNEL 1
13 #endif
14 #include <sys/errno.h>
15 #include <sys/types.h>
16 #include <sys/param.h>
17 #include <sys/time.h>
18 #include <sys/file.h>
19 #if !defined(AIX)
20 # include <sys/fcntl.h>
21 #endif
22 #if !defined(_KERNEL) && !defined(__KERNEL__)
23 # include <stdio.h>
24 # include <string.h>
25 # include <stdlib.h>
26 # include <ctype.h>
27 # define _KERNEL
28 # ifdef __OpenBSD__
29 struct file;
30 # endif
31 # include <sys/uio.h>
32 # undef _KERNEL
33 #endif
34 #if !defined(linux)
35 # include <sys/protosw.h>
36 #endif
37 #include <sys/socket.h>
38 #if defined(_KERNEL)
39 # if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \
40 !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) && \
41 !defined(AIX)
42 # include <sys/ctype.h>
43 # endif
44 # include <sys/systm.h>
45 # if !defined(__SVR4) && !defined(__svr4__)
46 # include <sys/mbuf.h>
47 # endif
48 #endif
49 #if defined(_KERNEL) && (__FreeBSD_version >= 220000)
50 # include <sys/filio.h>
51 # include <sys/fcntl.h>
52 # if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM)
53 # include "opt_ipfilter.h"
54 # endif
55 #else
56 # include <sys/ioctl.h>
57 #endif
58 #if defined(__SVR4) || defined(__svr4__)
59 # include <sys/byteorder.h>
60 # ifdef _KERNEL
61 # include <sys/dditypes.h>
62 # endif
63 # include <sys/stream.h>
64 # include <sys/kmem.h>
65 #endif
66 #if __FreeBSD__ > 2
67 # include <sys/queue.h>
68 #endif
69 #include <net/if.h>
70 #ifdef sun
71 # include <net/af.h>
72 #endif
73 #include <netinet/in.h>
74 #include <netinet/in_systm.h>
75 #include <netinet/ip.h>
76 #ifndef linux
77 # include <netinet/ip_var.h>
78 #endif
79 #include <netinet/tcp.h>
80 #include <netinet/udp.h>
81 #include <netinet/ip_icmp.h>
82 #include "netinet/ip_compat.h"
83 #include <netinet/tcpip.h>
84 #include "netinet/ip_fil.h"
85 #include "netinet/ip_nat.h"
86 #include "netinet/ip_state.h"
87 #include "netinet/ip_proxy.h"
88 #if (__FreeBSD_version >= 300000)
89 # include <sys/malloc.h>
90 #endif
92 /* END OF INCLUDES */
94 #include "netinet/ip_ftp_pxy.c"
95 #include "netinet/ip_rcmd_pxy.c"
96 # include "netinet/ip_pptp_pxy.c"
97 #if defined(_KERNEL)
98 # include "netinet/ip_irc_pxy.c"
99 # include "netinet/ip_raudio_pxy.c"
100 # include "netinet/ip_h323_pxy.c"
101 # include "netinet/ip_netbios_pxy.c"
102 #endif
103 #include "netinet/ip_ipsec_pxy.c"
104 #include "netinet/ip_rpcb_pxy.c"
106 #if !defined(lint)
107 #if defined(__NetBSD__)
108 #include <sys/cdefs.h>
109 __KERNEL_RCSID(0, "$NetBSD$");
110 #else
111 static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.62.2.23 2009/07/22 01:41:14 darrenr Exp";
112 #endif
113 #endif
115 #ifdef INET
116 static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int ));
117 #endif
119 #define AP_SESS_SIZE 53
121 #if defined(_KERNEL)
122 int ipf_proxy_debug = 0;
123 #else
124 int ipf_proxy_debug = 2;
125 #endif
126 ap_session_t *ap_sess_tab[AP_SESS_SIZE];
127 ap_session_t *ap_sess_list = NULL;
128 aproxy_t *ap_proxylist = NULL;
129 aproxy_t ap_proxies[] = {
130 #ifdef IPF_FTP_PROXY
131 { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_fini,
132 ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL, NULL },
133 #endif
134 #ifdef IPF_IRC_PROXY
135 { NULL, "irc", (char)IPPROTO_TCP, 0, 0, ippr_irc_init, ippr_irc_fini,
136 ippr_irc_new, NULL, NULL, ippr_irc_out, NULL, NULL },
137 #endif
138 #ifdef IPF_RCMD_PROXY
139 { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_fini,
140 ippr_rcmd_new, NULL, ippr_rcmd_in, ippr_rcmd_out, NULL, NULL },
141 #endif
142 #ifdef IPF_RAUDIO_PROXY
143 { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, ippr_raudio_fini,
144 ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL, NULL },
145 #endif
146 #ifdef IPF_MSNRPC_PROXY
147 { NULL, "msnrpc", (char)IPPROTO_TCP, 0, 0, ippr_msnrpc_init, ippr_msnrpc_fini,
148 ippr_msnrpc_new, NULL, ippr_msnrpc_in, ippr_msnrpc_out, NULL, NULL },
149 #endif
150 #ifdef IPF_NETBIOS_PROXY
151 { NULL, "netbios", (char)IPPROTO_UDP, 0, 0, ippr_netbios_init, ippr_netbios_fini,
152 NULL, NULL, NULL, ippr_netbios_out, NULL, NULL },
153 #endif
154 #ifdef IPF_IPSEC_PROXY
155 { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0,
156 ippr_ipsec_init, ippr_ipsec_fini, ippr_ipsec_new, ippr_ipsec_del,
157 ippr_ipsec_inout, ippr_ipsec_inout, ippr_ipsec_match, NULL },
158 #endif
159 #ifdef IPF_PPTP_PROXY
160 { NULL, "pptp", (char)IPPROTO_TCP, 0, 0,
161 ippr_pptp_init, ippr_pptp_fini, ippr_pptp_new, ippr_pptp_del,
162 ippr_pptp_inout, ippr_pptp_inout, NULL, NULL },
163 #endif
164 #ifdef IPF_H323_PROXY
165 { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, ippr_h323_fini,
166 ippr_h323_new, ippr_h323_del, ippr_h323_in, NULL, NULL, NULL },
167 { NULL, "h245", (char)IPPROTO_TCP, 0, 0, NULL, NULL,
168 ippr_h245_new, NULL, NULL, ippr_h245_out, NULL, NULL },
169 #endif
170 #ifdef IPF_RPCB_PROXY
171 # if 0
172 { NULL, "rpcbt", (char)IPPROTO_TCP, 0, 0,
173 ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del,
174 ippr_rpcb_in, ippr_rpcb_out, NULL, NULL },
175 # endif
176 { NULL, "rpcbu", (char)IPPROTO_UDP, 0, 0,
177 ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del,
178 ippr_rpcb_in, ippr_rpcb_out, NULL, NULL },
179 #endif
180 { NULL, "", '\0', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
184 * Dynamically add a new kernel proxy. Ensure that it is unique in the
185 * collection compiled in and dynamically added.
187 int appr_add(ap)
188 aproxy_t *ap;
190 aproxy_t *a;
192 for (a = ap_proxies; a->apr_p; a++)
193 if ((a->apr_p == ap->apr_p) &&
194 !strncmp(a->apr_label, ap->apr_label,
195 sizeof(ap->apr_label))) {
196 if (ipf_proxy_debug > 1)
197 printf("appr_add: %s/%d already present (B)\n",
198 a->apr_label, a->apr_p);
199 return -1;
202 for (a = ap_proxylist; (a != NULL); a = a->apr_next)
203 if ((a->apr_p == ap->apr_p) &&
204 !strncmp(a->apr_label, ap->apr_label,
205 sizeof(ap->apr_label))) {
206 if (ipf_proxy_debug > 1)
207 printf("appr_add: %s/%d already present (D)\n",
208 a->apr_label, a->apr_p);
209 return -1;
211 ap->apr_next = ap_proxylist;
212 ap_proxylist = ap;
213 if (ap->apr_init != NULL)
214 return (*ap->apr_init)();
215 return 0;
220 * Check to see if the proxy this control request has come through for
221 * exists, and if it does and it has a control function then invoke that
222 * control function.
224 int appr_ctl(ctl)
225 ap_ctl_t *ctl;
227 aproxy_t *a;
228 int error;
230 a = appr_lookup(ctl->apc_p, ctl->apc_label);
231 if (a == NULL) {
232 if (ipf_proxy_debug > 1)
233 printf("appr_ctl: can't find %s/%d\n",
234 ctl->apc_label, ctl->apc_p);
235 error = ESRCH;
236 } else if (a->apr_ctl == NULL) {
237 if (ipf_proxy_debug > 1)
238 printf("appr_ctl: no ctl function for %s/%d\n",
239 ctl->apc_label, ctl->apc_p);
240 error = ENXIO;
241 } else {
242 error = (*a->apr_ctl)(a, ctl);
243 if ((error != 0) && (ipf_proxy_debug > 1))
244 printf("appr_ctl: %s/%d ctl error %d\n",
245 a->apr_label, a->apr_p, error);
247 return error;
252 * Delete a proxy that has been added dynamically from those available.
253 * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1
254 * if it cannot be matched.
256 int appr_del(ap)
257 aproxy_t *ap;
259 aproxy_t *a, **app;
261 for (app = &ap_proxylist; ((a = *app) != NULL); app = &a->apr_next)
262 if (a == ap) {
263 a->apr_flags |= APR_DELETE;
264 *app = a->apr_next;
265 if (ap->apr_ref != 0) {
266 if (ipf_proxy_debug > 2)
267 printf("appr_del: orphaning %s/%d\n",
268 ap->apr_label, ap->apr_p);
269 return 1;
271 return 0;
273 if (ipf_proxy_debug > 1)
274 printf("appr_del: proxy %lx not found\n", (u_long)ap);
275 return -1;
280 * Return 1 if the packet is a good match against a proxy, else 0.
282 int appr_ok(fin, tcp, nat)
283 fr_info_t *fin;
284 tcphdr_t *tcp;
285 ipnat_t *nat;
287 aproxy_t *apr = nat->in_apr;
288 u_short dport = nat->in_dport;
290 if ((apr == NULL) || (apr->apr_flags & APR_DELETE) ||
291 (fin->fin_p != apr->apr_p))
292 return 0;
293 if ((tcp == NULL) && dport)
294 return 0;
295 return 1;
299 int appr_ioctl(data, cmd, mode, ctx)
300 void * data;
301 ioctlcmd_t cmd;
302 int mode;
303 void *ctx;
305 ap_ctl_t ctl;
306 void *ptr;
307 int error;
309 mode = mode; /* LINT */
311 switch (cmd)
313 case SIOCPROXY :
314 error = BCOPYIN(data, &ctl, sizeof(ctl));
315 if (error != 0)
316 return EFAULT;
317 ptr = NULL;
319 if (ctl.apc_dsize > 0) {
320 KMALLOCS(ptr, void *, ctl.apc_dsize);
321 if (ptr == NULL)
322 error = ENOMEM;
323 else {
324 error = copyinptr(ctl.apc_data, ptr,
325 ctl.apc_dsize);
326 if (error == 0)
327 ctl.apc_data = ptr;
329 } else {
330 ctl.apc_data = NULL;
331 error = 0;
334 if (error == 0)
335 error = appr_ctl(&ctl);
337 if (ptr != NULL) {
338 KFREES(ptr, ctl.apc_dsize);
340 break;
342 default :
343 error = EINVAL;
345 return error;
350 * If a proxy has a match function, call that to do extended packet
351 * matching.
353 int appr_match(fin, nat)
354 fr_info_t *fin;
355 nat_t *nat;
357 aproxy_t *apr;
358 ipnat_t *ipn;
359 int result;
361 ipn = nat->nat_ptr;
362 if (ipf_proxy_debug > 8)
363 printf("appr_match(%lx,%lx) aps %lx ptr %lx\n",
364 (u_long)fin, (u_long)nat, (u_long)nat->nat_aps,
365 (u_long)ipn);
367 if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) {
368 if (ipf_proxy_debug > 0)
369 printf("appr_match: flx 0x%x (BAD|SHORT)\n",
370 fin->fin_flx);
371 return -1;
374 apr = ipn->in_apr;
375 if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) {
376 if (ipf_proxy_debug > 0)
377 printf("appr_match:apr %lx apr_flags 0x%x\n",
378 (u_long)apr, apr ? apr->apr_flags : 0);
379 return -1;
382 if (apr->apr_match != NULL) {
383 result = (*apr->apr_match)(fin, nat->nat_aps, nat);
384 if (result != 0) {
385 if (ipf_proxy_debug > 4)
386 printf("appr_match: result %d\n", result);
387 return -1;
390 return 0;
395 * Allocate a new application proxy structure and fill it in with the
396 * relevant details. call the init function once complete, prior to
397 * returning.
399 int appr_new(fin, nat)
400 fr_info_t *fin;
401 nat_t *nat;
403 register ap_session_t *aps;
404 aproxy_t *apr;
406 if (ipf_proxy_debug > 8)
407 printf("appr_new(%lx,%lx) \n", (u_long)fin, (u_long)nat);
409 if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) {
410 if (ipf_proxy_debug > 0)
411 printf("appr_new: nat_ptr %lx nat_aps %lx\n",
412 (u_long)nat->nat_ptr, (u_long)nat->nat_aps);
413 return -1;
416 apr = nat->nat_ptr->in_apr;
418 if ((apr->apr_flags & APR_DELETE) ||
419 (fin->fin_p != apr->apr_p)) {
420 if (ipf_proxy_debug > 2)
421 printf("appr_new: apr_flags 0x%x p %d/%d\n",
422 apr->apr_flags, fin->fin_p, apr->apr_p);
423 return -1;
426 KMALLOC(aps, ap_session_t *);
427 if (!aps) {
428 if (ipf_proxy_debug > 0)
429 printf("appr_new: malloc failed (%lu)\n",
430 (u_long)sizeof(ap_session_t));
431 return -1;
434 bzero((char *)aps, sizeof(*aps));
435 aps->aps_p = fin->fin_p;
436 aps->aps_data = NULL;
437 aps->aps_apr = apr;
438 aps->aps_psiz = 0;
439 if (apr->apr_new != NULL)
440 if ((*apr->apr_new)(fin, aps, nat) == -1) {
441 if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) {
442 KFREES(aps->aps_data, aps->aps_psiz);
444 KFREE(aps);
445 if (ipf_proxy_debug > 2)
446 printf("appr_new: new(%lx) failed\n",
447 (u_long)apr->apr_new);
448 return -1;
450 aps->aps_nat = nat;
451 aps->aps_next = ap_sess_list;
452 ap_sess_list = aps;
453 nat->nat_aps = aps;
455 return 0;
460 * Check to see if a packet should be passed through an active proxy routine
461 * if one has been setup for it. We don't need to check the checksum here if
462 * IPFILTER_CKSUM is defined because if it is, a failed check causes FI_BAD
463 * to be set.
465 int appr_check(fin, nat)
466 fr_info_t *fin;
467 nat_t *nat;
469 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
470 # if defined(ICK_VALID)
471 mb_t *m;
472 # endif
473 int dosum = 1;
474 #endif
475 tcphdr_t *tcp = NULL;
476 udphdr_t *udp = NULL;
477 ap_session_t *aps;
478 aproxy_t *apr;
479 ip_t *ip;
480 short rv;
481 int err;
482 #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi)
483 u_32_t s1, s2, sd;
484 #endif
486 if (fin->fin_flx & FI_BAD) {
487 if (ipf_proxy_debug > 0)
488 printf("appr_check: flx 0x%x (BAD)\n", fin->fin_flx);
489 return -1;
492 #ifndef IPFILTER_CKSUM
493 if ((fin->fin_out == 0) && (fr_checkl4sum(fin) == -1)) {
494 if (ipf_proxy_debug > 0)
495 printf("appr_check: l4 checksum failure %d\n",
496 fin->fin_p);
497 if (fin->fin_p == IPPROTO_TCP)
498 frstats[fin->fin_out].fr_tcpbad++;
499 return -1;
501 #endif
503 aps = nat->nat_aps;
504 if ((aps != NULL) && (aps->aps_p == fin->fin_p)) {
506 * If there is data in this packet to be proxied then try and
507 * get it all into the one buffer, else drop it.
509 #if defined(MENTAT) || defined(HAVE_M_PULLDOWN)
510 if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE))
511 if (fr_coalesce(fin) == -1) {
512 if (ipf_proxy_debug > 0)
513 printf("appr_check: fr_coalesce failed %x\n", fin->fin_flx);
514 return -1;
516 #endif
517 ip = fin->fin_ip;
519 switch (fin->fin_p)
521 case IPPROTO_TCP :
522 tcp = (tcphdr_t *)fin->fin_dp;
524 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID)
525 m = fin->fin_qfm;
526 if (dohwcksum && (m->b_ick_flag == ICK_VALID))
527 dosum = 0;
528 #endif
530 * Don't bother the proxy with these...or in fact,
531 * should we free up proxy stuff when seen?
533 if ((fin->fin_tcpf & TH_RST) != 0)
534 break;
535 /*FALLTHROUGH*/
536 case IPPROTO_UDP :
537 udp = (udphdr_t *)fin->fin_dp;
538 break;
539 default :
540 break;
543 apr = aps->aps_apr;
544 err = 0;
545 if (fin->fin_out != 0) {
546 if (apr->apr_outpkt != NULL)
547 err = (*apr->apr_outpkt)(fin, aps, nat);
548 } else {
549 if (apr->apr_inpkt != NULL)
550 err = (*apr->apr_inpkt)(fin, aps, nat);
553 rv = APR_EXIT(err);
554 if (((ipf_proxy_debug > 0) && (rv != 0)) ||
555 (ipf_proxy_debug > 8))
556 printf("appr_check: out %d err %x rv %d\n",
557 fin->fin_out, err, rv);
558 if (rv == 1)
559 return -1;
561 if (rv == 2) {
562 appr_free(apr);
563 nat->nat_aps = NULL;
564 return -1;
568 * If err != 0 then the data size of the packet has changed
569 * so we need to recalculate the header checksums for the
570 * packet.
572 #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi)
573 if (err != 0) {
574 short adjlen = err & 0xffff;
576 s1 = LONG_SUM(fin->fin_plen - adjlen);
577 s2 = LONG_SUM(fin->fin_plen);
578 CALC_SUMD(s1, s2, sd);
579 fix_outcksum(fin, &ip->ip_sum, sd);
581 #endif
583 #ifdef INET
585 * For TCP packets, we may need to adjust the sequence and
586 * acknowledgement numbers to reflect changes in size of the
587 * data stream.
589 * For both TCP and UDP, recalculate the layer 4 checksum,
590 * regardless, as we can't tell (here) if data has been
591 * changed or not.
593 if (tcp != NULL) {
594 err = appr_fixseqack(fin, ip, aps, APR_INC(err));
595 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
596 if (dosum)
597 tcp->th_sum = fr_cksum(fin->fin_qfm, ip,
598 IPPROTO_TCP, tcp,
599 fin->fin_plen);
600 #else
601 tcp->th_sum = fr_cksum(fin->fin_m, ip,
602 IPPROTO_TCP, tcp,
603 fin->fin_plen);
604 #endif
605 } else if ((udp != NULL) && (udp->uh_sum != 0)) {
606 #if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6)
607 if (dosum)
608 udp->uh_sum = fr_cksum(fin->fin_qfm, ip,
609 IPPROTO_UDP, udp,
610 fin->fin_plen);
611 #else
612 udp->uh_sum = fr_cksum(fin->fin_m, ip,
613 IPPROTO_UDP, udp,
614 fin->fin_plen);
615 #endif
617 #endif
618 aps->aps_bytes += fin->fin_plen;
619 aps->aps_pkts++;
620 return 1;
622 return 0;
627 * Search for an proxy by the protocol it is being used with and its name.
629 aproxy_t *appr_lookup(pr, name)
630 u_int pr;
631 char *name;
633 aproxy_t *ap;
635 if (ipf_proxy_debug > 8)
636 printf("appr_lookup(%d,%s)\n", pr, name);
638 for (ap = ap_proxies; ap->apr_p; ap++)
639 if ((ap->apr_p == pr) &&
640 !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
641 ap->apr_ref++;
642 return ap;
645 for (ap = ap_proxylist; ap; ap = ap->apr_next)
646 if ((ap->apr_p == pr) &&
647 !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
648 ap->apr_ref++;
649 return ap;
651 if (ipf_proxy_debug > 2)
652 printf("appr_lookup: failed for %d/%s\n", pr, name);
653 return NULL;
657 void appr_free(ap)
658 aproxy_t *ap;
660 ap->apr_ref--;
664 void aps_free(aps)
665 ap_session_t *aps;
667 ap_session_t *a, **ap;
668 aproxy_t *apr;
670 if (!aps)
671 return;
673 for (ap = &ap_sess_list; ((a = *ap) != NULL); ap = &a->aps_next)
674 if (a == aps) {
675 *ap = a->aps_next;
676 break;
679 apr = aps->aps_apr;
680 if ((apr != NULL) && (apr->apr_del != NULL))
681 (*apr->apr_del)(aps);
683 if ((aps->aps_data != NULL) && (aps->aps_psiz != 0))
684 KFREES(aps->aps_data, aps->aps_psiz);
685 KFREE(aps);
689 #ifdef INET
691 * returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise
693 static int appr_fixseqack(fin, ip, aps, inc)
694 fr_info_t *fin;
695 ip_t *ip;
696 ap_session_t *aps;
697 int inc;
699 int sel, ch = 0, out, nlen;
700 u_32_t seq1, seq2;
701 tcphdr_t *tcp;
702 short inc2;
704 tcp = (tcphdr_t *)fin->fin_dp;
705 out = fin->fin_out;
707 * fin->fin_plen has already been adjusted by 'inc'.
709 nlen = fin->fin_plen;
710 nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2);
712 inc2 = inc;
713 inc = (int)inc2;
715 if (out != 0) {
716 seq1 = (u_32_t)ntohl(tcp->th_seq);
717 sel = aps->aps_sel[out];
719 /* switch to other set ? */
720 if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
721 (seq1 > aps->aps_seqmin[!sel])) {
722 if (ipf_proxy_debug > 7)
723 printf("proxy out switch set seq %d -> %d %x > %x\n",
724 sel, !sel, seq1,
725 aps->aps_seqmin[!sel]);
726 sel = aps->aps_sel[out] = !sel;
729 if (aps->aps_seqoff[sel]) {
730 seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel];
731 if (seq1 > seq2) {
732 seq2 = aps->aps_seqoff[sel];
733 seq1 += seq2;
734 tcp->th_seq = htonl(seq1);
735 ch = 1;
739 if (inc && (seq1 > aps->aps_seqmin[!sel])) {
740 aps->aps_seqmin[sel] = seq1 + nlen - 1;
741 aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc;
742 if (ipf_proxy_debug > 7)
743 printf("proxy seq set %d at %x to %d + %d\n",
744 sel, aps->aps_seqmin[sel],
745 aps->aps_seqoff[sel], inc);
748 /***/
750 seq1 = ntohl(tcp->th_ack);
751 sel = aps->aps_sel[1 - out];
753 /* switch to other set ? */
754 if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
755 (seq1 > aps->aps_ackmin[!sel])) {
756 if (ipf_proxy_debug > 7)
757 printf("proxy out switch set ack %d -> %d %x > %x\n",
758 sel, !sel, seq1,
759 aps->aps_ackmin[!sel]);
760 sel = aps->aps_sel[1 - out] = !sel;
763 if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) {
764 seq2 = aps->aps_ackoff[sel];
765 tcp->th_ack = htonl(seq1 - seq2);
766 ch = 1;
768 } else {
769 seq1 = ntohl(tcp->th_seq);
770 sel = aps->aps_sel[out];
772 /* switch to other set ? */
773 if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) &&
774 (seq1 > aps->aps_ackmin[!sel])) {
775 if (ipf_proxy_debug > 7)
776 printf("proxy in switch set ack %d -> %d %x > %x\n",
777 sel, !sel, seq1, aps->aps_ackmin[!sel]);
778 sel = aps->aps_sel[out] = !sel;
781 if (aps->aps_ackoff[sel]) {
782 seq2 = aps->aps_ackmin[sel] - aps->aps_ackoff[sel];
783 if (seq1 > seq2) {
784 seq2 = aps->aps_ackoff[sel];
785 seq1 += seq2;
786 tcp->th_seq = htonl(seq1);
787 ch = 1;
791 if (inc && (seq1 > aps->aps_ackmin[!sel])) {
792 aps->aps_ackmin[!sel] = seq1 + nlen - 1;
793 aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc;
795 if (ipf_proxy_debug > 7)
796 printf("proxy ack set %d at %x to %d + %d\n",
797 !sel, aps->aps_seqmin[!sel],
798 aps->aps_seqoff[sel], inc);
801 /***/
803 seq1 = ntohl(tcp->th_ack);
804 sel = aps->aps_sel[1 - out];
806 /* switch to other set ? */
807 if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) &&
808 (seq1 > aps->aps_seqmin[!sel])) {
809 if (ipf_proxy_debug > 7)
810 printf("proxy in switch set seq %d -> %d %x > %x\n",
811 sel, !sel, seq1, aps->aps_seqmin[!sel]);
812 sel = aps->aps_sel[1 - out] = !sel;
815 if (aps->aps_seqoff[sel] != 0) {
816 if (ipf_proxy_debug > 7)
817 printf("sel %d seqoff %d seq1 %x seqmin %x\n",
818 sel, aps->aps_seqoff[sel], seq1,
819 aps->aps_seqmin[sel]);
820 if (seq1 > aps->aps_seqmin[sel]) {
821 seq2 = aps->aps_seqoff[sel];
822 tcp->th_ack = htonl(seq1 - seq2);
823 ch = 1;
828 if (ipf_proxy_debug > 8)
829 printf("appr_fixseqack: seq %x ack %x\n",
830 (u_32_t)ntohl(tcp->th_seq), (u_32_t)ntohl(tcp->th_ack));
831 return ch ? 2 : 0;
833 #endif
837 * Initialise hook for kernel application proxies.
838 * Call the initialise routine for all the compiled in kernel proxies.
840 int appr_init()
842 aproxy_t *ap;
843 int err = 0;
845 for (ap = ap_proxies; ap->apr_p; ap++) {
846 if (ap->apr_init != NULL) {
847 err = (*ap->apr_init)();
848 if (err != 0)
849 break;
852 return err;
857 * Unload hook for kernel application proxies.
858 * Call the finialise routine for all the compiled in kernel proxies.
860 void appr_unload()
862 aproxy_t *ap;
864 for (ap = ap_proxies; ap->apr_p; ap++)
865 if (ap->apr_fini != NULL)
866 (*ap->apr_fini)();
867 for (ap = ap_proxylist; ap; ap = ap->apr_next)
868 if (ap->apr_fini != NULL)
869 (*ap->apr_fini)();