2 * Copyright (C) 1997-2003 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
6 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
7 * Use is subject to license terms.
10 #if defined(KERNEL) || defined(_KERNEL)
16 #include <sys/errno.h>
17 #include <sys/types.h>
18 #include <sys/param.h>
22 # include <sys/fcntl.h>
24 #if !defined(_KERNEL) && !defined(__KERNEL__)
37 # include <sys/protosw.h>
39 #include <sys/socket.h>
41 # if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \
42 !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) && \
44 # include <sys/ctype.h>
46 # include <sys/systm.h>
47 # if !defined(__SVR4) && !defined(__svr4__)
48 # include <sys/mbuf.h>
51 #if defined(_KERNEL) && (__FreeBSD_version >= 220000)
52 # include <sys/filio.h>
53 # include <sys/fcntl.h>
54 # if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM)
55 # include "opt_ipfilter.h"
58 # include <sys/ioctl.h>
60 #if defined(__SVR4) || defined(__svr4__)
61 # include <sys/byteorder.h>
63 # include <sys/dditypes.h>
64 # include <sys/strsubr.h>
66 # include <sys/stream.h>
67 # include <sys/kmem.h>
68 # include <sys/pattr.h>
71 # include <sys/queue.h>
77 #include <net/route.h>
78 #include <netinet/in.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/ip.h>
82 # include <netinet/ip_var.h>
84 #include <netinet/tcp.h>
85 #include <netinet/udp.h>
86 #include <netinet/ip_icmp.h>
87 #include "netinet/ip_compat.h"
88 #include <netinet/tcpip.h>
89 #include "netinet/ipf_stack.h"
90 #include "netinet/ip_fil.h"
91 #include "netinet/ip_nat.h"
92 #include "netinet/ip_state.h"
93 #include "netinet/ip_proxy.h"
94 #if (__FreeBSD_version >= 300000)
95 # include <sys/malloc.h>
98 #include "netinet/ip_ftp_pxy.c"
99 #include "netinet/ip_rcmd_pxy.c"
100 # include "netinet/ip_pptp_pxy.c"
102 # include "netinet/ip_irc_pxy.c"
103 # include "netinet/ip_raudio_pxy.c"
104 # include "netinet/ip_h323_pxy.c"
105 # include "netinet/ip_netbios_pxy.c"
107 #include "netinet/ip_ipsec_pxy.c"
108 #include "netinet/ip_rpcb_pxy.c"
110 /* END OF INCLUDES */
113 static const char rcsid
[] = "@(#)$Id: ip_proxy.c,v 2.62.2.14 2005/06/18 02:41:33 darrenr Exp $";
116 static int appr_fixseqack
__P((fr_info_t
*, ip_t
*, ap_session_t
*, int ));
118 #define AP_SESS_SIZE 53
121 int ipf_proxy_debug
= 0;
123 int ipf_proxy_debug
= 2;
126 static aproxy_t lcl_ap_proxies
[] = {
128 { NULL
, "ftp", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_ftp_init
, ippr_ftp_fini
,
129 ippr_ftp_new
, NULL
, ippr_ftp_in
, ippr_ftp_out
, NULL
},
132 { NULL
, "irc", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_irc_init
, ippr_irc_fini
,
133 ippr_irc_new
, NULL
, NULL
, ippr_irc_out
, NULL
, NULL
},
135 #ifdef IPF_RCMD_PROXY
136 { NULL
, "rcmd", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_rcmd_init
, ippr_rcmd_fini
,
137 ippr_rcmd_new
, NULL
, ippr_rcmd_in
, ippr_rcmd_out
, NULL
, NULL
},
139 #ifdef IPF_RAUDIO_PROXY
140 { NULL
, "raudio", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_raudio_init
, ippr_raudio_fini
,
141 ippr_raudio_new
, NULL
, ippr_raudio_in
, ippr_raudio_out
, NULL
, NULL
},
143 #ifdef IPF_MSNRPC_PROXY
144 { NULL
, "msnrpc", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_msnrpc_init
, ippr_msnrpc_fini
,
145 ippr_msnrpc_new
, NULL
, ippr_msnrpc_in
, ippr_msnrpc_out
, NULL
, NULL
},
147 #ifdef IPF_NETBIOS_PROXY
148 { NULL
, "netbios", (char)IPPROTO_UDP
, 0, 0, NULL
, ippr_netbios_init
, ippr_netbios_fini
,
149 NULL
, NULL
, NULL
, ippr_netbios_out
, NULL
, NULL
},
151 #ifdef IPF_IPSEC_PROXY
152 { NULL
, "ipsec", (char)IPPROTO_UDP
, 0, 0, NULL
,
153 ippr_ipsec_init
, ippr_ipsec_fini
, ippr_ipsec_new
, ippr_ipsec_del
,
154 ippr_ipsec_inout
, ippr_ipsec_inout
, ippr_ipsec_match
, NULL
},
156 #ifdef IPF_PPTP_PROXY
157 { NULL
, "pptp", (char)IPPROTO_TCP
, 0, 0, NULL
,
158 ippr_pptp_init
, ippr_pptp_fini
, ippr_pptp_new
, ippr_pptp_del
,
159 ippr_pptp_inout
, ippr_pptp_inout
, NULL
, NULL
},
161 #ifdef IPF_H323_PROXY
162 { NULL
, "h323", (char)IPPROTO_TCP
, 0, 0, NULL
, ippr_h323_init
, ippr_h323_fini
,
163 ippr_h323_new
, ippr_h323_del
, ippr_h323_in
, NULL
, NULL
},
164 { NULL
, "h245", (char)IPPROTO_TCP
, 0, 0, NULL
, NULL
, NULL
,
165 ippr_h245_new
, NULL
, NULL
, ippr_h245_out
, NULL
},
167 #ifdef IPF_RPCB_PROXY
169 { NULL
, "rpcbt", (char)IPPROTO_TCP
, 0, 0, NULL
,
170 ippr_rpcb_init
, ippr_rpcb_fini
, ippr_rpcb_new
, ippr_rpcb_del
,
171 ippr_rpcb_in
, ippr_rpcb_out
, NULL
, NULL
},
173 { NULL
, "rpcbu", (char)IPPROTO_UDP
, 0, 0, NULL
,
174 ippr_rpcb_init
, ippr_rpcb_fini
, ippr_rpcb_new
, ippr_rpcb_del
,
175 ippr_rpcb_in
, ippr_rpcb_out
, NULL
, NULL
},
177 { NULL
, "", '\0', 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
}
181 * Dynamically add a new kernel proxy. Ensure that it is unique in the
182 * collection compiled in and dynamically added.
184 int appr_add(ap
, ifs
)
190 for (a
= ifs
->ifs_ap_proxies
; a
->apr_p
; a
++)
191 if ((a
->apr_p
== ap
->apr_p
) &&
192 !strncmp(a
->apr_label
, ap
->apr_label
,
193 sizeof(ap
->apr_label
))) {
194 if (ipf_proxy_debug
> 1)
195 printf("appr_add: %s/%d already present (B)\n",
196 a
->apr_label
, a
->apr_p
);
200 for (a
= ifs
->ifs_ap_proxylist
; a
->apr_p
; a
= a
->apr_next
)
201 if ((a
->apr_p
== ap
->apr_p
) &&
202 !strncmp(a
->apr_label
, ap
->apr_label
,
203 sizeof(ap
->apr_label
))) {
204 if (ipf_proxy_debug
> 1)
205 printf("appr_add: %s/%d already present (D)\n",
206 a
->apr_label
, a
->apr_p
);
209 ap
->apr_next
= ifs
->ifs_ap_proxylist
;
210 ifs
->ifs_ap_proxylist
= ap
;
211 if (ap
->apr_init
!= NULL
)
212 return (*ap
->apr_init
)(&ap
->apr_private
, ifs
);
219 * Check to see if the proxy this control request has come through for
220 * exists, and if it does and it has a control function then invoke that
223 int appr_ctl(ctl
, ifs
)
230 a
= appr_lookup(ctl
->apc_p
, ctl
->apc_label
, ifs
);
232 if (ipf_proxy_debug
> 1)
233 printf("appr_ctl: can't find %s/%d\n",
234 ctl
->apc_label
, ctl
->apc_p
);
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
);
242 error
= (*a
->apr_ctl
)(a
, ctl
, a
->apr_private
);
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
);
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
, ifs
)
262 for (app
= &ifs
->ifs_ap_proxylist
; ((a
= *app
) != NULL
);
265 a
->apr_flags
|= APR_DELETE
;
267 if (ap
->apr_ref
!= 0) {
268 if (ipf_proxy_debug
> 2)
269 printf("appr_del: orphaning %s/%d\n",
270 ap
->apr_label
, ap
->apr_p
);
275 if (ipf_proxy_debug
> 1)
276 printf("appr_del: proxy %lx not found\n", (u_long
)ap
);
282 * Return 1 if the packet is a good match against a proxy, else 0.
284 int appr_ok(fin
, tcp
, nat
)
289 aproxy_t
*apr
= nat
->in_apr
;
290 u_short dport
= nat
->in_dport
;
292 if ((apr
== NULL
) || (apr
->apr_flags
& APR_DELETE
) ||
293 (fin
->fin_p
!= apr
->apr_p
))
295 if ((tcp
== NULL
) && dport
)
301 int appr_ioctl(data
, cmd
, mode
, ifs
)
311 mode
= mode
; /* LINT */
316 error
= BCOPYIN(data
, &ctl
, sizeof(ctl
));
322 if (ctl
.apc_dsize
> 0) {
323 KMALLOCS(ptr
, caddr_t
, ctl
.apc_dsize
);
327 error
= copyinptr(ctl
.apc_data
, ptr
,
338 error
= appr_ctl(&ctl
, ifs
);
340 if ((ctl
.apc_dsize
> 0) && (ptr
!= NULL
) &&
341 (ctl
.apc_data
== ptr
)) {
342 KFREES(ptr
, ctl
.apc_dsize
);
354 * If a proxy has a match function, call that to do extended packet
357 int appr_match(fin
, nat
)
366 if (ipf_proxy_debug
> 8)
367 printf("appr_match(%lx,%lx) aps %lx ptr %lx\n",
368 (u_long
)fin
, (u_long
)nat
, (u_long
)nat
->nat_aps
,
371 if ((fin
->fin_flx
& (FI_SHORT
|FI_BAD
)) != 0) {
372 if (ipf_proxy_debug
> 0)
373 printf("appr_match: flx 0x%x (BAD|SHORT)\n",
379 if ((apr
== NULL
) || (apr
->apr_flags
& APR_DELETE
)) {
380 if (ipf_proxy_debug
> 0)
381 printf("appr_match:apr %lx apr_flags 0x%x\n",
382 (u_long
)apr
, apr
? apr
->apr_flags
: 0);
386 if (apr
->apr_match
!= NULL
) {
387 result
= (*apr
->apr_match
)(fin
, nat
->nat_aps
, nat
, apr
->apr_private
);
389 if (ipf_proxy_debug
> 4)
390 printf("appr_match: result %d\n", result
);
399 * Allocate a new application proxy structure and fill it in with the
400 * relevant details. call the init function once complete, prior to
403 int appr_new(fin
, nat
)
407 register ap_session_t
*aps
;
409 ipf_stack_t
*ifs
= fin
->fin_ifs
;
411 if (ipf_proxy_debug
> 8)
412 printf("appr_new(%lx,%lx) \n", (u_long
)fin
, (u_long
)nat
);
414 if ((nat
->nat_ptr
== NULL
) || (nat
->nat_aps
!= NULL
)) {
415 if (ipf_proxy_debug
> 0)
416 printf("appr_new: nat_ptr %lx nat_aps %lx\n",
417 (u_long
)nat
->nat_ptr
, (u_long
)nat
->nat_aps
);
421 apr
= nat
->nat_ptr
->in_apr
;
423 if ((apr
->apr_flags
& APR_DELETE
) ||
424 (fin
->fin_p
!= apr
->apr_p
)) {
425 if (ipf_proxy_debug
> 2)
426 printf("appr_new: apr_flags 0x%x p %d/%d\n",
427 apr
->apr_flags
, fin
->fin_p
, apr
->apr_p
);
431 KMALLOC(aps
, ap_session_t
*);
433 if (ipf_proxy_debug
> 0)
434 printf("appr_new: malloc failed (%lu)\n",
435 (u_long
)sizeof(ap_session_t
));
439 bzero((char *)aps
, sizeof(*aps
));
440 aps
->aps_p
= fin
->fin_p
;
441 aps
->aps_data
= NULL
;
444 if (apr
->apr_new
!= NULL
)
445 if ((*apr
->apr_new
)(fin
, aps
, nat
, apr
->apr_private
) == -1) {
446 if ((aps
->aps_data
!= NULL
) && (aps
->aps_psiz
!= 0)) {
447 KFREES(aps
->aps_data
, aps
->aps_psiz
);
450 if (ipf_proxy_debug
> 2)
451 printf("appr_new: new(%lx) failed\n",
452 (u_long
)apr
->apr_new
);
456 aps
->aps_next
= ifs
->ifs_ap_sess_list
;
457 ifs
->ifs_ap_sess_list
= aps
;
465 * Check to see if a packet should be passed through an active proxy routine
466 * if one has been setup for it. We don't need to check the checksum here if
467 * IPFILTER_CKSUM is defined because if it is, a failed check causes FI_BAD
470 int appr_check(fin
, nat
)
474 #if defined(SOLARIS) && defined(_KERNEL) && (SOLARIS2 >= 6) && \
479 tcphdr_t
*tcp
= NULL
;
480 udphdr_t
*udp
= NULL
;
488 #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi)
491 ipf_stack_t
*ifs
= fin
->fin_ifs
;
493 #if defined(SOLARIS) && defined(_KERNEL) && (SOLARIS2 >= 6)
494 net_handle_t net_data_p
;
496 net_data_p
= ifs
->ifs_ipf_ipv4
;
498 net_data_p
= ifs
->ifs_ipf_ipv6
;
501 if (fin
->fin_flx
& FI_BAD
) {
502 if (ipf_proxy_debug
> 0)
503 printf("appr_check: flx 0x%x (BAD)\n", fin
->fin_flx
);
507 #ifndef IPFILTER_CKSUM
508 if ((fin
->fin_out
== 0) && (fr_checkl4sum(fin
) == -1)) {
509 if (ipf_proxy_debug
> 0)
510 printf("appr_check: l4 checksum failure %d\n",
512 if (fin
->fin_p
== IPPROTO_TCP
)
513 ifs
->ifs_frstats
[fin
->fin_out
].fr_tcpbad
++;
519 if ((aps
!= NULL
) && (aps
->aps_p
== fin
->fin_p
)) {
521 * If there is data in this packet to be proxied then try and
522 * get it all into the one buffer, else drop it.
524 #if defined(MENTAT) || defined(HAVE_M_PULLDOWN)
525 if ((fin
->fin_dlen
> 0) && !(fin
->fin_flx
& FI_COALESCE
))
526 if (fr_coalesce(fin
) == -1) {
527 if (ipf_proxy_debug
> 0)
528 printf("appr_check: fr_coalesce failed %x\n", fin
->fin_flx
);
537 tcp
= (tcphdr_t
*)fin
->fin_dp
;
539 #if defined(SOLARIS) && defined(_KERNEL) && (SOLARIS2 >= 6) && \
542 if (dohwcksum
&& (m
->b_ick_flag
== ICK_VALID
))
546 * Don't bother the proxy with these...or in fact,
547 * should we free up proxy stuff when seen?
549 if ((fin
->fin_tcpf
& TH_RST
) != 0)
553 udp
= (udphdr_t
*)fin
->fin_dp
;
561 if (fin
->fin_out
!= 0) {
562 if (apr
->apr_outpkt
!= NULL
)
563 err
= (*apr
->apr_outpkt
)(fin
, aps
, nat
, apr
->apr_private
);
565 if (apr
->apr_inpkt
!= NULL
)
566 err
= (*apr
->apr_inpkt
)(fin
, aps
, nat
, apr
->apr_private
);
570 if (((ipf_proxy_debug
> 0) && (rv
!= 0)) ||
571 (ipf_proxy_debug
> 8))
572 printf("appr_check: out %d err %x rv %d\n",
573 fin
->fin_out
, err
, rv
);
584 * If err != 0 then the data size of the packet has changed
585 * so we need to recalculate the header checksums for the
587 * inbound packets always need to be adjusted.
589 #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi)
591 short adjlen
= err
& 0xffff;
593 s1
= LONG_SUM(ip
->ip_len
- adjlen
);
594 s2
= LONG_SUM(ip
->ip_len
);
595 CALC_SUMD(s1
, s2
, sd
);
596 sd
= (sd
& 0xffff) + (sd
>> 16);
598 !NET_IS_HCK_L3_FULL(net_data_p
, fin
->fin_m
))
599 fix_outcksum(&ip
->ip_sum
, sd
);
604 * For TCP packets, we may need to adjust the sequence and
605 * acknowledgement numbers to reflect changes in size of the
608 * For both TCP and UDP, recalculate the layer 4 checksum in
609 * software checksum case, as we can't tell if data has been
614 csump
= &tcp
->th_sum
;
615 (void) appr_fixseqack(fin
, ip
, aps
, APR_INC(err
));
616 } else if (udp
!= NULL
) {
618 csump
= &udp
->uh_sum
;
622 #if defined(SOLARIS) && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(MENTAT)
625 * We are incapable of adjusting partial hcksum
626 * result for inbound packets here, as the
627 * partial hcksum calculation range might not
628 * cover the whole payload, and the payload data
629 * might be changed by proxy.
631 DB_CKSUMFLAGS(fin
->fin_m
) &= ~HCK_PARTIALCKSUM
;
633 /* Inbound packets always need recalculation. */
634 *csump
= fr_cksum(fin
->fin_qfm
, ip
,
636 } else if (NET_IS_HCK_L4_PART(net_data_p
, fin
->fin_m
)) {
638 DB_CKSUMEND(fin
->fin_m
) += (short)err
;
639 fix_incksum(csump
, sd
);
641 } else if (!NET_IS_HCK_L4_FULL(net_data_p
, fin
->fin_m
))
642 *csump
= fr_cksum(fin
->fin_qfm
, ip
,
645 *csump
= fr_cksum(fin
->fin_m
, ip
, fin
->fin_p
, tcpudp
);
648 aps
->aps_bytes
+= fin
->fin_plen
;
657 * Search for an proxy by the protocol it is being used with and its name.
659 aproxy_t
*appr_lookup(pr
, name
, ifs
)
666 if (ipf_proxy_debug
> 8)
667 printf("appr_lookup(%d,%s)\n", pr
, name
);
669 for (ap
= ifs
->ifs_ap_proxies
; ap
->apr_p
; ap
++)
670 if ((ap
->apr_p
== pr
) &&
671 !strncmp(name
, ap
->apr_label
, sizeof(ap
->apr_label
))) {
676 for (ap
= ifs
->ifs_ap_proxylist
; ap
; ap
= ap
->apr_next
)
677 if ((ap
->apr_p
== pr
) &&
678 !strncmp(name
, ap
->apr_label
, sizeof(ap
->apr_label
))) {
682 if (ipf_proxy_debug
> 2)
683 printf("appr_lookup: failed for %d/%s\n", pr
, name
);
695 void aps_free(aps
, ifs
)
699 ap_session_t
*a
, **ap
;
705 for (ap
= &ifs
->ifs_ap_sess_list
; ((a
= *ap
) != NULL
); ap
= &a
->aps_next
)
712 if ((apr
!= NULL
) && (apr
->apr_del
!= NULL
))
713 (*apr
->apr_del
)(aps
, apr
->apr_private
, ifs
);
715 if ((aps
->aps_data
!= NULL
) && (aps
->aps_psiz
!= 0))
716 KFREES(aps
->aps_data
, aps
->aps_psiz
);
722 * returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise
724 static int appr_fixseqack(fin
, ip
, aps
, inc
)
730 int sel
, ch
= 0, out
, nlen
;
735 tcp
= (tcphdr_t
*)fin
->fin_dp
;
738 * ip_len has already been adjusted by 'inc'.
741 nlen
-= (IP_HL(ip
) << 2) + (TCP_OFF(tcp
) << 2);
747 seq1
= (u_32_t
)ntohl(tcp
->th_seq
);
748 sel
= aps
->aps_sel
[out
];
750 /* switch to other set ? */
751 if ((aps
->aps_seqmin
[!sel
] > aps
->aps_seqmin
[sel
]) &&
752 (seq1
> aps
->aps_seqmin
[!sel
])) {
753 if (ipf_proxy_debug
> 7)
754 printf("proxy out switch set seq %d -> %d %x > %x\n",
756 aps
->aps_seqmin
[!sel
]);
757 sel
= aps
->aps_sel
[out
] = !sel
;
760 if (aps
->aps_seqoff
[sel
]) {
761 seq2
= aps
->aps_seqmin
[sel
] - aps
->aps_seqoff
[sel
];
763 seq2
= aps
->aps_seqoff
[sel
];
765 tcp
->th_seq
= htonl(seq1
);
770 if (inc
&& (seq1
> aps
->aps_seqmin
[!sel
])) {
771 aps
->aps_seqmin
[sel
] = seq1
+ nlen
- 1;
772 aps
->aps_seqoff
[sel
] = aps
->aps_seqoff
[sel
] + inc
;
773 if (ipf_proxy_debug
> 7)
774 printf("proxy seq set %d at %x to %d + %d\n",
775 sel
, aps
->aps_seqmin
[sel
],
776 aps
->aps_seqoff
[sel
], inc
);
781 seq1
= ntohl(tcp
->th_ack
);
782 sel
= aps
->aps_sel
[1 - out
];
784 /* switch to other set ? */
785 if ((aps
->aps_ackmin
[!sel
] > aps
->aps_ackmin
[sel
]) &&
786 (seq1
> aps
->aps_ackmin
[!sel
])) {
787 if (ipf_proxy_debug
> 7)
788 printf("proxy out switch set ack %d -> %d %x > %x\n",
790 aps
->aps_ackmin
[!sel
]);
791 sel
= aps
->aps_sel
[1 - out
] = !sel
;
794 if (aps
->aps_ackoff
[sel
] && (seq1
> aps
->aps_ackmin
[sel
])) {
795 seq2
= aps
->aps_ackoff
[sel
];
796 tcp
->th_ack
= htonl(seq1
- seq2
);
800 seq1
= ntohl(tcp
->th_seq
);
801 sel
= aps
->aps_sel
[out
];
803 /* switch to other set ? */
804 if ((aps
->aps_ackmin
[!sel
] > aps
->aps_ackmin
[sel
]) &&
805 (seq1
> aps
->aps_ackmin
[!sel
])) {
806 if (ipf_proxy_debug
> 7)
807 printf("proxy in switch set ack %d -> %d %x > %x\n",
808 sel
, !sel
, seq1
, aps
->aps_ackmin
[!sel
]);
809 sel
= aps
->aps_sel
[out
] = !sel
;
812 if (aps
->aps_ackoff
[sel
]) {
813 seq2
= aps
->aps_ackmin
[sel
] - aps
->aps_ackoff
[sel
];
815 seq2
= aps
->aps_ackoff
[sel
];
817 tcp
->th_seq
= htonl(seq1
);
822 if (inc
&& (seq1
> aps
->aps_ackmin
[!sel
])) {
823 aps
->aps_ackmin
[!sel
] = seq1
+ nlen
- 1;
824 aps
->aps_ackoff
[!sel
] = aps
->aps_ackoff
[sel
] + inc
;
826 if (ipf_proxy_debug
> 7)
827 printf("proxy ack set %d at %x to %d + %d\n",
828 !sel
, aps
->aps_seqmin
[!sel
],
829 aps
->aps_seqoff
[sel
], inc
);
834 seq1
= ntohl(tcp
->th_ack
);
835 sel
= aps
->aps_sel
[1 - out
];
837 /* switch to other set ? */
838 if ((aps
->aps_seqmin
[!sel
] > aps
->aps_seqmin
[sel
]) &&
839 (seq1
> aps
->aps_seqmin
[!sel
])) {
840 if (ipf_proxy_debug
> 7)
841 printf("proxy in switch set seq %d -> %d %x > %x\n",
842 sel
, !sel
, seq1
, aps
->aps_seqmin
[!sel
]);
843 sel
= aps
->aps_sel
[1 - out
] = !sel
;
846 if (aps
->aps_seqoff
[sel
] != 0) {
847 if (ipf_proxy_debug
> 7)
848 printf("sel %d seqoff %d seq1 %x seqmin %x\n",
849 sel
, aps
->aps_seqoff
[sel
], seq1
,
850 aps
->aps_seqmin
[sel
]);
851 if (seq1
> aps
->aps_seqmin
[sel
]) {
852 seq2
= aps
->aps_seqoff
[sel
];
853 tcp
->th_ack
= htonl(seq1
- seq2
);
859 if (ipf_proxy_debug
> 8)
860 printf("appr_fixseqack: seq %x ack %x\n",
861 ntohl(tcp
->th_seq
), ntohl(tcp
->th_ack
));
867 * Initialise hook for kernel application proxies.
868 * Call the initialise routine for all the compiled in kernel proxies.
876 /* Since the refcnt is used we make a copy of lcl_ap_proxies */
877 KMALLOCS(ifs
->ifs_ap_proxies
, aproxy_t
*, sizeof (lcl_ap_proxies
));
878 bcopy(lcl_ap_proxies
, ifs
->ifs_ap_proxies
, sizeof (lcl_ap_proxies
));
880 for (ap
= ifs
->ifs_ap_proxies
; ap
->apr_p
; ap
++) {
881 if (ap
->apr_init
!= NULL
) {
882 err
= (*ap
->apr_init
)(&ap
->apr_private
, ifs
);
892 * Unload hook for kernel application proxies.
893 * Call the finialise routine for all the compiled in kernel proxies.
895 void appr_unload(ifs
)
899 if(ifs
->ifs_ap_proxies
== NULL
)
902 for (ap
= ifs
->ifs_ap_proxies
; ap
->apr_p
; ap
++)
903 if (ap
->apr_fini
!= NULL
)
904 (*ap
->apr_fini
)(&ap
->apr_private
, ifs
);
905 for (ap
= ifs
->ifs_ap_proxylist
; ap
; ap
= ap
->apr_next
)
906 if (ap
->apr_fini
!= NULL
)
907 (*ap
->apr_fini
)(&ap
->apr_private
, ifs
);
909 KFREES(ifs
->ifs_ap_proxies
, sizeof (lcl_ap_proxies
));
910 ifs
->ifs_ap_proxies
= NULL
;