ip_proxy.c revision 98004
153642Sguido/* 292685Sdarrenr * Copyright (C) 1997-2002 by Darren Reed. 353642Sguido * 480482Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 553642Sguido */ 653642Sguido 753642Sguido#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) 853642Sguido# define _KERNEL 953642Sguido#endif 1053642Sguido 1192685Sdarrenr#ifdef __sgi 1292685Sdarrenr# include <sys/ptimers.h> 1392685Sdarrenr#endif 1453642Sguido#include <sys/errno.h> 1553642Sguido#include <sys/types.h> 1653642Sguido#include <sys/param.h> 1753642Sguido#include <sys/time.h> 1853642Sguido#include <sys/file.h> 1953642Sguido#if !defined(__FreeBSD_version) 2053642Sguido# include <sys/ioctl.h> 2153642Sguido#endif 2253642Sguido#include <sys/fcntl.h> 2353642Sguido#if !defined(_KERNEL) && !defined(KERNEL) 2453642Sguido# include <stdio.h> 2553642Sguido# include <string.h> 2653642Sguido# include <stdlib.h> 2753642Sguido#endif 2853642Sguido#ifndef linux 2953642Sguido# include <sys/protosw.h> 3053642Sguido#endif 3153642Sguido#include <sys/socket.h> 3253642Sguido#if defined(_KERNEL) 3353642Sguido# if !defined(linux) 3453642Sguido# include <sys/systm.h> 3553642Sguido# else 3653642Sguido# include <linux/string.h> 3753642Sguido# endif 3853642Sguido#endif 3953642Sguido#if !defined(__SVR4) && !defined(__svr4__) 4053642Sguido# ifndef linux 4153642Sguido# include <sys/mbuf.h> 4253642Sguido# endif 4353642Sguido#else 4453642Sguido# include <sys/byteorder.h> 4553642Sguido# ifdef _KERNEL 4653642Sguido# include <sys/dditypes.h> 4753642Sguido# endif 4853642Sguido# include <sys/stream.h> 4953642Sguido# include <sys/kmem.h> 5053642Sguido#endif 5153642Sguido#if __FreeBSD__ > 2 5253642Sguido# include <sys/queue.h> 5353642Sguido#endif 5453642Sguido#include <net/if.h> 5553642Sguido#ifdef sun 5653642Sguido# include <net/af.h> 5753642Sguido#endif 5853642Sguido#include <net/route.h> 5953642Sguido#include <netinet/in.h> 6053642Sguido#include <netinet/in_systm.h> 6153642Sguido#include <netinet/ip.h> 6253642Sguido#ifndef linux 6353642Sguido# include <netinet/ip_var.h> 6453642Sguido#endif 6553642Sguido#include <netinet/tcp.h> 6653642Sguido#include <netinet/udp.h> 6753642Sguido#include <netinet/ip_icmp.h> 6853642Sguido#include "netinet/ip_compat.h" 6953642Sguido#include <netinet/tcpip.h> 7053642Sguido#include "netinet/ip_fil.h" 7153642Sguido#include "netinet/ip_nat.h" 7253642Sguido#include "netinet/ip_state.h" 7392685Sdarrenr#include "netinet/ip_proxy.h" 7453642Sguido#if (__FreeBSD_version >= 300000) 7553642Sguido# include <sys/malloc.h> 7653642Sguido#endif 7753642Sguido 7880482Sdarrenr#if !defined(lint) 7980482Sdarrenr/* static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.9.2.6 2001/07/15 22:06:15 darrenr Exp $"; */ 8080482Sdarrenrstatic const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_proxy.c 98004 2002-06-07 08:56:30Z darrenr $"; 8180482Sdarrenr#endif 8253642Sguido 8392685Sdarrenr#if defined(_KERNEL) && (SOLARIS || defined(__sgi)) 8492685Sdarrenrextern KRWLOCK_T ipf_nat, ipf_state; 8592685Sdarrenr#endif 8680482Sdarrenr 8753642Sguido#ifndef MIN 8853642Sguido#define MIN(a,b) (((a)<(b))?(a):(b)) 8953642Sguido#endif 9053642Sguido 9153642Sguidostatic int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); 9253642Sguido 9353642Sguido 9453642Sguido#define AP_SESS_SIZE 53 9553642Sguido 9695563Sdarrenr#include "netinet/ip_ftp_pxy.c" 9792685Sdarrenr#if defined(_KERNEL) 9853642Sguido#include "netinet/ip_rcmd_pxy.c" 9953642Sguido#include "netinet/ip_raudio_pxy.c" 10092685Sdarrenr#include "netinet/ip_netbios_pxy.c" 10193224Sru#include "netinet/ip_ipsec_pxy.c" 10253642Sguido#endif 10353642Sguido 10453642Sguidoap_session_t *ap_sess_tab[AP_SESS_SIZE]; 10553642Sguidoap_session_t *ap_sess_list = NULL; 10660855Sdarrenraproxy_t *ap_proxylist = NULL; 10753642Sguidoaproxy_t ap_proxies[] = { 10853642Sguido#ifdef IPF_FTP_PROXY 10960855Sdarrenr { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, NULL, 11092685Sdarrenr ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL }, 11153642Sguido#endif 11253642Sguido#ifdef IPF_RCMD_PROXY 11360855Sdarrenr { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, NULL, 11492685Sdarrenr ippr_rcmd_new, NULL, NULL, ippr_rcmd_out, NULL }, 11553642Sguido#endif 11653642Sguido#ifdef IPF_RAUDIO_PROXY 11760855Sdarrenr { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, NULL, 11892685Sdarrenr ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL }, 11953642Sguido#endif 12092685Sdarrenr#ifdef IPF_IPSEC_PROXY 12192685Sdarrenr { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, ippr_ipsec_init, NULL, 12292685Sdarrenr ippr_ipsec_new, ippr_ipsec_del, NULL, ippr_ipsec_out, 12392685Sdarrenr ippr_ipsec_match }, 12492685Sdarrenr#endif 12592685Sdarrenr#ifdef IPF_NETBIOS_PROXY 12698004Sdarrenr { NULL, "netbios", (char)IPPROTO_UDP, 0, 0, ippr_netbios_init, NULL, 12792685Sdarrenr NULL, NULL, NULL, ippr_netbios_out, NULL }, 12892685Sdarrenr#endif 12992685Sdarrenr#ifdef IPF_H323_PROXY 13092685Sdarrenr { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, NULL, 13192685Sdarrenr ippr_h323_new, ippr_h323_del, ippr_h323_in, ippr_h323_out, NULL }, 13292685Sdarrenr { NULL, "h245", (char)IPPROTO_TCP, 0, 0, ippr_h245_init, NULL, 13392685Sdarrenr ippr_h245_new, NULL, NULL, ippr_h245_out, NULL }, 13492685Sdarrenr#endif 13592685Sdarrenr { NULL, "", '\0', 0, 0, NULL, NULL, NULL } 13653642Sguido}; 13753642Sguido 13853642Sguido 13992685Sdarrenr/* 14092685Sdarrenr * Dynamically add a new kernel proxy. Ensure that it is unique in the 14192685Sdarrenr * collection compiled in and dynamically added. 14292685Sdarrenr */ 14360855Sdarrenrint appr_add(ap) 14460855Sdarrenraproxy_t *ap; 14560855Sdarrenr{ 14660855Sdarrenr aproxy_t *a; 14760855Sdarrenr 14860855Sdarrenr for (a = ap_proxies; a->apr_p; a++) 14960855Sdarrenr if ((a->apr_p == ap->apr_p) && 15060855Sdarrenr !strncmp(a->apr_label, ap->apr_label, 15160855Sdarrenr sizeof(ap->apr_label))) 15260855Sdarrenr return -1; 15360855Sdarrenr 15492685Sdarrenr for (a = ap_proxylist; a && a->apr_p; a = a->apr_next) 15560855Sdarrenr if ((a->apr_p == ap->apr_p) && 15660855Sdarrenr !strncmp(a->apr_label, ap->apr_label, 15760855Sdarrenr sizeof(ap->apr_label))) 15860855Sdarrenr return -1; 15960855Sdarrenr ap->apr_next = ap_proxylist; 16060855Sdarrenr ap_proxylist = ap; 16160855Sdarrenr return (*ap->apr_init)(); 16260855Sdarrenr} 16360855Sdarrenr 16460855Sdarrenr 16592685Sdarrenr/* 16692685Sdarrenr * Delete a proxy that has been added dynamically from those available. 16792685Sdarrenr * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1 16892685Sdarrenr * if it cannot be matched. 16992685Sdarrenr */ 17060855Sdarrenrint appr_del(ap) 17160855Sdarrenraproxy_t *ap; 17260855Sdarrenr{ 17360855Sdarrenr aproxy_t *a, **app; 17460855Sdarrenr 17560855Sdarrenr for (app = &ap_proxylist; (a = *app); app = &a->apr_next) 17660855Sdarrenr if (a == ap) { 17792685Sdarrenr a->apr_flags |= APR_DELETE; 17892685Sdarrenr *app = a->apr_next; 17960855Sdarrenr if (ap->apr_ref != 0) 18060855Sdarrenr return 1; 18160855Sdarrenr return 0; 18260855Sdarrenr } 18360855Sdarrenr return -1; 18460855Sdarrenr} 18560855Sdarrenr 18660855Sdarrenr 18792685Sdarrenr/* 18892685Sdarrenr * Return 1 if the packet is a good match against a proxy, else 0. 18992685Sdarrenr */ 19053642Sguidoint appr_ok(ip, tcp, nat) 19153642Sguidoip_t *ip; 19253642Sguidotcphdr_t *tcp; 19353642Sguidoipnat_t *nat; 19453642Sguido{ 19553642Sguido aproxy_t *apr = nat->in_apr; 19653642Sguido u_short dport = nat->in_dport; 19753642Sguido 19892685Sdarrenr if ((apr == NULL) || (apr->apr_flags & APR_DELETE) || 19953642Sguido (ip->ip_p != apr->apr_p)) 20053642Sguido return 0; 20192685Sdarrenr if (((tcp != NULL) && (tcp->th_dport != dport)) || (!tcp && dport)) 20253642Sguido return 0; 20353642Sguido return 1; 20453642Sguido} 20553642Sguido 20653642Sguido 20753642Sguido/* 20892685Sdarrenr * If a proxy has a match function, call that to do extended packet 20992685Sdarrenr * matching. 21092685Sdarrenr */ 21192685Sdarrenrint appr_match(fin, nat) 21292685Sdarrenrfr_info_t *fin; 21392685Sdarrenrnat_t *nat; 21492685Sdarrenr{ 21592685Sdarrenr aproxy_t *apr; 21692685Sdarrenr ipnat_t *ipn; 21792685Sdarrenr 21892685Sdarrenr ipn = nat->nat_ptr; 21992685Sdarrenr if (ipn == NULL) 22092685Sdarrenr return -1; 22192685Sdarrenr apr = ipn->in_apr; 22292685Sdarrenr if ((apr == NULL) || (apr->apr_flags & APR_DELETE) || 22392685Sdarrenr (nat->nat_aps == NULL)) 22492685Sdarrenr return -1; 22592685Sdarrenr if (apr->apr_match != NULL) 22692685Sdarrenr if ((*apr->apr_match)(fin, nat->nat_aps, nat) != 0) 22792685Sdarrenr return -1; 22892685Sdarrenr return 0; 22992685Sdarrenr} 23092685Sdarrenr 23192685Sdarrenr 23292685Sdarrenr/* 23353642Sguido * Allocate a new application proxy structure and fill it in with the 23453642Sguido * relevant details. call the init function once complete, prior to 23553642Sguido * returning. 23653642Sguido */ 23792685Sdarrenrint appr_new(fin, ip, nat) 23892685Sdarrenrfr_info_t *fin; 23953642Sguidoip_t *ip; 24053642Sguidonat_t *nat; 24153642Sguido{ 24253642Sguido register ap_session_t *aps; 24392685Sdarrenr aproxy_t *apr; 24453642Sguido 24592685Sdarrenr if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) 24692685Sdarrenr return -1; 24792685Sdarrenr 24892685Sdarrenr apr = nat->nat_ptr->in_apr; 24992685Sdarrenr 25053642Sguido if (!apr || (apr->apr_flags & APR_DELETE) || (ip->ip_p != apr->apr_p)) 25192685Sdarrenr return -1; 25253642Sguido 25353642Sguido KMALLOC(aps, ap_session_t *); 25453642Sguido if (!aps) 25592685Sdarrenr return -1; 25653642Sguido bzero((char *)aps, sizeof(*aps)); 25753642Sguido aps->aps_p = ip->ip_p; 25853642Sguido aps->aps_data = NULL; 25953642Sguido aps->aps_apr = apr; 26053642Sguido aps->aps_psiz = 0; 26160855Sdarrenr if (apr->apr_new != NULL) 26260855Sdarrenr if ((*apr->apr_new)(fin, ip, aps, nat) == -1) { 26392685Sdarrenr if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) { 26492685Sdarrenr KFREES(aps->aps_data, aps->aps_psiz); 26592685Sdarrenr } 26660855Sdarrenr KFREE(aps); 26792685Sdarrenr return -1; 26860855Sdarrenr } 26960855Sdarrenr aps->aps_nat = nat; 27060855Sdarrenr aps->aps_next = ap_sess_list; 27153642Sguido ap_sess_list = aps; 27292685Sdarrenr nat->nat_aps = aps; 27392685Sdarrenr 27492685Sdarrenr return 0; 27553642Sguido} 27653642Sguido 27753642Sguido 27853642Sguido/* 27953642Sguido * check to see if a packet should be passed through an active proxy routine 28053642Sguido * if one has been setup for it. 28153642Sguido */ 28253642Sguidoint appr_check(ip, fin, nat) 28353642Sguidoip_t *ip; 28453642Sguidofr_info_t *fin; 28553642Sguidonat_t *nat; 28653642Sguido{ 28780482Sdarrenr#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) 28880482Sdarrenr mb_t *m = fin->fin_qfm; 28980482Sdarrenr int dosum = 1; 29080482Sdarrenr#endif 29180482Sdarrenr tcphdr_t *tcp = NULL; 29253642Sguido ap_session_t *aps; 29353642Sguido aproxy_t *apr; 29453642Sguido u_32_t sum; 29560855Sdarrenr short rv; 29653642Sguido int err; 29753642Sguido 29853642Sguido aps = nat->nat_aps; 29953642Sguido if ((aps != NULL) && (aps->aps_p == ip->ip_p)) { 30053642Sguido if (ip->ip_p == IPPROTO_TCP) { 30153642Sguido tcp = (tcphdr_t *)fin->fin_dp; 30253642Sguido /* 30353642Sguido * verify that the checksum is correct. If not, then 30453642Sguido * don't do anything with this packet. 30553642Sguido */ 30680482Sdarrenr#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) 30780482Sdarrenr if (dohwcksum && (m->b_ick_flag == ICK_VALID)) { 30880482Sdarrenr sum = tcp->th_sum; 30980482Sdarrenr dosum = 0; 31080482Sdarrenr } 31180482Sdarrenr if (dosum) 31280482Sdarrenr sum = fr_tcpsum(fin->fin_qfm, ip, tcp); 31353642Sguido#else 31453642Sguido sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp); 31553642Sguido#endif 31653642Sguido if (sum != tcp->th_sum) { 31753642Sguido frstats[fin->fin_out].fr_tcpbad++; 31853642Sguido return -1; 31953642Sguido } 32053642Sguido } 32153642Sguido 32253642Sguido apr = aps->aps_apr; 32353642Sguido err = 0; 32453642Sguido if (fin->fin_out != 0) { 32553642Sguido if (apr->apr_outpkt != NULL) 32653642Sguido err = (*apr->apr_outpkt)(fin, ip, aps, nat); 32753642Sguido } else { 32853642Sguido if (apr->apr_inpkt != NULL) 32953642Sguido err = (*apr->apr_inpkt)(fin, ip, aps, nat); 33053642Sguido } 33153642Sguido 33260855Sdarrenr rv = APR_EXIT(err); 33392685Sdarrenr if (rv == 1) 33492685Sdarrenr return -1; 33592685Sdarrenr if (rv == 2) { 33692685Sdarrenr appr_free(apr); 33792685Sdarrenr nat->nat_aps = NULL; 33892685Sdarrenr return -1; 33992685Sdarrenr } 34060855Sdarrenr 34153642Sguido if (tcp != NULL) { 34260855Sdarrenr err = appr_fixseqack(fin, ip, aps, APR_INC(err)); 34380482Sdarrenr#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) 34480482Sdarrenr if (dosum) 34580482Sdarrenr tcp->th_sum = fr_tcpsum(fin->fin_qfm, ip, tcp); 34653642Sguido#else 34753642Sguido tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp); 34853642Sguido#endif 34953642Sguido } 35053642Sguido aps->aps_bytes += ip->ip_len; 35153642Sguido aps->aps_pkts++; 35260855Sdarrenr return 1; 35353642Sguido } 35460855Sdarrenr return 0; 35553642Sguido} 35653642Sguido 35753642Sguido 35892685Sdarrenr/* 35992685Sdarrenr * Search for an proxy by the protocol it is being used with and its name. 36092685Sdarrenr */ 36192685Sdarrenraproxy_t *appr_lookup(pr, name) 36253642Sguidou_int pr; 36353642Sguidochar *name; 36453642Sguido{ 36553642Sguido aproxy_t *ap; 36653642Sguido 36753642Sguido for (ap = ap_proxies; ap->apr_p; ap++) 36853642Sguido if ((ap->apr_p == pr) && 36953642Sguido !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { 37053642Sguido ap->apr_ref++; 37153642Sguido return ap; 37253642Sguido } 37360855Sdarrenr 37460855Sdarrenr for (ap = ap_proxylist; ap; ap = ap->apr_next) 37560855Sdarrenr if ((ap->apr_p == pr) && 37660855Sdarrenr !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { 37760855Sdarrenr ap->apr_ref++; 37860855Sdarrenr return ap; 37960855Sdarrenr } 38053642Sguido return NULL; 38153642Sguido} 38253642Sguido 38353642Sguido 38453642Sguidovoid appr_free(ap) 38553642Sguidoaproxy_t *ap; 38653642Sguido{ 38753642Sguido ap->apr_ref--; 38853642Sguido} 38953642Sguido 39053642Sguido 39153642Sguidovoid aps_free(aps) 39253642Sguidoap_session_t *aps; 39353642Sguido{ 39453642Sguido ap_session_t *a, **ap; 39592685Sdarrenr aproxy_t *apr; 39653642Sguido 39753642Sguido if (!aps) 39853642Sguido return; 39953642Sguido 40053642Sguido for (ap = &ap_sess_list; (a = *ap); ap = &a->aps_next) 40153642Sguido if (a == aps) { 40253642Sguido *ap = a->aps_next; 40353642Sguido break; 40453642Sguido } 40553642Sguido 40692685Sdarrenr apr = aps->aps_apr; 40792685Sdarrenr if ((apr != NULL) && (apr->apr_del != NULL)) 40892685Sdarrenr (*apr->apr_del)(aps); 40992685Sdarrenr 41060855Sdarrenr if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) 41160855Sdarrenr KFREES(aps->aps_data, aps->aps_psiz); 41260855Sdarrenr KFREE(aps); 41353642Sguido} 41453642Sguido 41553642Sguido 41653642Sguidostatic int appr_fixseqack(fin, ip, aps, inc) 41753642Sguidofr_info_t *fin; 41853642Sguidoip_t *ip; 41953642Sguidoap_session_t *aps; 42053642Sguidoint inc; 42153642Sguido{ 42253642Sguido int sel, ch = 0, out, nlen; 42353642Sguido u_32_t seq1, seq2; 42453642Sguido tcphdr_t *tcp; 42598004Sdarrenr short inc2; 42653642Sguido 42753642Sguido tcp = (tcphdr_t *)fin->fin_dp; 42853642Sguido out = fin->fin_out; 42953642Sguido nlen = ip->ip_len; 43053642Sguido nlen -= (ip->ip_hl << 2) + (tcp->th_off << 2); 43198004Sdarrenr inc2 = inc; 43298004Sdarrenr inc = (int)inc2; 43353642Sguido 43453642Sguido if (out != 0) { 43553642Sguido seq1 = (u_32_t)ntohl(tcp->th_seq); 43653642Sguido sel = aps->aps_sel[out]; 43753642Sguido 43853642Sguido /* switch to other set ? */ 43953642Sguido if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && 44053642Sguido (seq1 > aps->aps_seqmin[!sel])) 44153642Sguido sel = aps->aps_sel[out] = !sel; 44253642Sguido 44353642Sguido if (aps->aps_seqoff[sel]) { 44453642Sguido seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel]; 44553642Sguido if (seq1 > seq2) { 44653642Sguido seq2 = aps->aps_seqoff[sel]; 44753642Sguido seq1 += seq2; 44853642Sguido tcp->th_seq = htonl(seq1); 44953642Sguido ch = 1; 45053642Sguido } 45153642Sguido } 45253642Sguido 45353642Sguido if (inc && (seq1 > aps->aps_seqmin[!sel])) { 45453642Sguido aps->aps_seqmin[!sel] = seq1 + nlen - 1; 45553642Sguido aps->aps_seqoff[!sel] = aps->aps_seqoff[sel] + inc; 45653642Sguido } 45753642Sguido 45853642Sguido /***/ 45953642Sguido 46053642Sguido seq1 = ntohl(tcp->th_ack); 46153642Sguido sel = aps->aps_sel[1 - out]; 46253642Sguido 46353642Sguido /* switch to other set ? */ 46453642Sguido if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && 46553642Sguido (seq1 > aps->aps_ackmin[!sel])) 46653642Sguido sel = aps->aps_sel[1 - out] = !sel; 46753642Sguido 46853642Sguido if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) { 46953642Sguido seq2 = aps->aps_ackoff[sel]; 47053642Sguido tcp->th_ack = htonl(seq1 - seq2); 47153642Sguido ch = 1; 47253642Sguido } 47353642Sguido } else { 47453642Sguido seq1 = ntohl(tcp->th_seq); 47553642Sguido sel = aps->aps_sel[out]; 47653642Sguido 47753642Sguido /* switch to other set ? */ 47853642Sguido if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && 47953642Sguido (seq1 > aps->aps_ackmin[!sel])) 48053642Sguido sel = aps->aps_sel[out] = !sel; 48153642Sguido 48253642Sguido if (aps->aps_ackoff[sel]) { 48353642Sguido seq2 = aps->aps_ackmin[sel] - 48453642Sguido aps->aps_ackoff[sel]; 48553642Sguido if (seq1 > seq2) { 48653642Sguido seq2 = aps->aps_ackoff[sel]; 48753642Sguido seq1 += seq2; 48853642Sguido tcp->th_seq = htonl(seq1); 48953642Sguido ch = 1; 49053642Sguido } 49153642Sguido } 49253642Sguido 49353642Sguido if (inc && (seq1 > aps->aps_ackmin[!sel])) { 49453642Sguido aps->aps_ackmin[!sel] = seq1 + nlen - 1; 49553642Sguido aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; 49653642Sguido } 49753642Sguido 49853642Sguido /***/ 49953642Sguido 50053642Sguido seq1 = ntohl(tcp->th_ack); 50153642Sguido sel = aps->aps_sel[1 - out]; 50253642Sguido 50353642Sguido /* switch to other set ? */ 50453642Sguido if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && 50553642Sguido (seq1 > aps->aps_seqmin[!sel])) 50653642Sguido sel = aps->aps_sel[1 - out] = !sel; 50753642Sguido 50853642Sguido if (aps->aps_seqoff[sel] && (seq1 > aps->aps_seqmin[sel])) { 50953642Sguido seq2 = aps->aps_seqoff[sel]; 51053642Sguido tcp->th_ack = htonl(seq1 - seq2); 51153642Sguido ch = 1; 51253642Sguido } 51353642Sguido } 51453642Sguido return ch ? 2 : 0; 51553642Sguido} 51653642Sguido 51753642Sguido 51892685Sdarrenr/* 51992685Sdarrenr * Initialise hook for kernel application proxies. 52092685Sdarrenr * Call the initialise routine for all the compiled in kernel proxies. 52192685Sdarrenr */ 52253642Sguidoint appr_init() 52353642Sguido{ 52453642Sguido aproxy_t *ap; 52553642Sguido int err = 0; 52653642Sguido 52753642Sguido for (ap = ap_proxies; ap->apr_p; ap++) { 52853642Sguido err = (*ap->apr_init)(); 52953642Sguido if (err != 0) 53053642Sguido break; 53153642Sguido } 53253642Sguido return err; 53353642Sguido} 53460855Sdarrenr 53560855Sdarrenr 53692685Sdarrenr/* 53792685Sdarrenr * Unload hook for kernel application proxies. 53892685Sdarrenr * Call the finialise routine for all the compiled in kernel proxies. 53992685Sdarrenr */ 54060855Sdarrenrvoid appr_unload() 54160855Sdarrenr{ 54260855Sdarrenr aproxy_t *ap; 54360855Sdarrenr 54460855Sdarrenr for (ap = ap_proxies; ap->apr_p; ap++) 54560855Sdarrenr if (ap->apr_fini) 54660855Sdarrenr (*ap->apr_fini)(); 54760855Sdarrenr for (ap = ap_proxylist; ap; ap = ap->apr_next) 54860855Sdarrenr if (ap->apr_fini) 54960855Sdarrenr (*ap->apr_fini)(); 55060855Sdarrenr} 551