/*
* Copyright (C) 1997-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#endif
#if !defined(AIX)
#endif
#if !defined(_KERNEL) && !defined(__KERNEL__)
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>
# define _KERNEL
# ifdef __OpenBSD__
struct file;
# endif
#endif
#if !defined(linux)
#endif
#if defined(_KERNEL)
!defined(AIX)
# endif
# endif
#endif
# include "opt_ipfilter.h"
# endif
#else
#endif
# include <sys/byteorder.h>
# ifdef _KERNEL
# include <sys/dditypes.h>
# endif
#endif
#if __FreeBSD__ > 2
#endif
#ifdef sun
#endif
#include <netinet/in_systm.h>
#ifndef linux
#endif
#include "netinet/ip_compat.h"
#include "netinet/ipf_stack.h"
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#if (__FreeBSD_version >= 300000)
#endif
#include "netinet/ip_ftp_pxy.c"
#include "netinet/ip_rcmd_pxy.c"
# include "netinet/ip_pptp_pxy.c"
#if defined(_KERNEL)
# include "netinet/ip_irc_pxy.c"
# include "netinet/ip_raudio_pxy.c"
# include "netinet/ip_h323_pxy.c"
# include "netinet/ip_netbios_pxy.c"
#endif
#include "netinet/ip_ipsec_pxy.c"
#include "netinet/ip_rpcb_pxy.c"
/* END OF INCLUDES */
#if !defined(lint)
#endif
#if defined(_KERNEL)
int ipf_proxy_debug = 0;
#else
#endif
#ifdef IPF_FTP_PROXY
#endif
#ifdef IPF_IRC_PROXY
#endif
#ifdef IPF_RCMD_PROXY
#endif
#ifdef IPF_RAUDIO_PROXY
#endif
#ifdef IPF_MSNRPC_PROXY
#endif
#ifdef IPF_NETBIOS_PROXY
#endif
#ifdef IPF_IPSEC_PROXY
#endif
#ifdef IPF_PPTP_PROXY
#endif
#ifdef IPF_H323_PROXY
#endif
#ifdef IPF_RPCB_PROXY
# if 0
# endif
#endif
};
/*
* Dynamically add a new kernel proxy. Ensure that it is unique in the
* collection compiled in and dynamically added.
*/
{
aproxy_t *a;
if (ipf_proxy_debug > 1)
printf("appr_add: %s/%d already present (B)\n",
return -1;
}
if (ipf_proxy_debug > 1)
printf("appr_add: %s/%d already present (D)\n",
return -1;
}
return 0;
}
/*
* Check to see if the proxy this control request has come through for
* exists, and if it does and it has a control function then invoke that
* control function.
*/
{
aproxy_t *a;
int error;
if (a == NULL) {
if (ipf_proxy_debug > 1)
printf("appr_ctl: can't find %s/%d\n",
if (ipf_proxy_debug > 1)
printf("appr_ctl: no ctl function for %s/%d\n",
} else {
printf("appr_ctl: %s/%d ctl error %d\n",
}
return error;
}
/*
* Delete a proxy that has been added dynamically from those available.
* If it is in use, return 1 (do not destroy NOW), not in use 0 or -1
* if it cannot be matched.
*/
{
if (a == ap) {
a->apr_flags |= APR_DELETE;
if (ipf_proxy_debug > 2)
printf("appr_del: orphaning %s/%d\n",
return 1;
}
return 0;
}
if (ipf_proxy_debug > 1)
return -1;
}
/*
* Return 1 if the packet is a good match against a proxy, else 0.
*/
{
return 0;
return 0;
return 1;
}
int mode;
{
int error;
switch (cmd)
{
case SIOCPROXY :
if (error != 0)
return EFAULT;
else {
if (error == 0)
}
} else {
error = 0;
}
if (error == 0)
}
break;
default :
}
return error;
}
/*
* If a proxy has a match function, call that to do extended packet
* matching.
*/
{
int result;
if (ipf_proxy_debug > 8)
printf("appr_match(%lx,%lx) aps %lx ptr %lx\n",
if (ipf_proxy_debug > 0)
printf("appr_match: flx 0x%x (BAD|SHORT)\n",
return -1;
}
if (ipf_proxy_debug > 0)
printf("appr_match:apr %lx apr_flags 0x%x\n",
return -1;
}
if (result != 0) {
if (ipf_proxy_debug > 4)
return -1;
}
}
return 0;
}
/*
* Allocate a new application proxy structure and fill it in with the
* relevant details. call the init function once complete, prior to
* returning.
*/
{
if (ipf_proxy_debug > 8)
if (ipf_proxy_debug > 0)
printf("appr_new: nat_ptr %lx nat_aps %lx\n",
return -1;
}
if (ipf_proxy_debug > 2)
printf("appr_new: apr_flags 0x%x p %d/%d\n",
return -1;
}
if (!aps) {
if (ipf_proxy_debug > 0)
printf("appr_new: malloc failed (%lu)\n",
(u_long)sizeof(ap_session_t));
return -1;
}
}
if (ipf_proxy_debug > 2)
printf("appr_new: new(%lx) failed\n",
return -1;
}
return 0;
}
/*
* Check to see if a packet should be passed through an active proxy routine
* if one has been setup for it. We don't need to check the checksum here if
* IPFILTER_CKSUM is defined because if it is, a failed check causes FI_BAD
* to be set.
*/
{
mb_t *m;
#endif
short rv;
int err;
#endif
else
#endif
if (ipf_proxy_debug > 0)
return -1;
}
#ifndef IPFILTER_CKSUM
if (ipf_proxy_debug > 0)
printf("appr_check: l4 checksum failure %d\n",
return -1;
}
#endif
/*
* If there is data in this packet to be proxied then try and
* get it all into the one buffer, else drop it.
*/
#if defined(MENTAT) || defined(HAVE_M_PULLDOWN)
if (ipf_proxy_debug > 0)
return -1;
}
#endif
{
case IPPROTO_TCP :
dosum = 0;
#endif
/*
* Don't bother the proxy with these...or in fact,
* should we free up proxy stuff when seen?
*/
break;
/*FALLTHROUGH*/
case IPPROTO_UDP :
break;
default :
break;
}
err = 0;
} else {
}
if (((ipf_proxy_debug > 0) && (rv != 0)) ||
(ipf_proxy_debug > 8))
printf("appr_check: out %d err %x rv %d\n",
if (rv == 1)
return -1;
if (rv == 2) {
return -1;
}
/*
* If err != 0 then the data size of the packet has changed
* so we need to recalculate the header checksums for the
* packet.
* inbound packets always need to be adjusted.
*/
if (err != 0) {
}
#endif
/*
* For TCP packets, we may need to adjust the sequence and
* acknowledgement numbers to reflect changes in size of the
* data stream.
*
* For both TCP and UDP, recalculate the layer 4 checksum in
* software checksum case, as we can't tell if data has been
* changed or not.
*/
}
if (tcpudp) {
/*
* We are incapable of adjusting partial hcksum
* result for inbound packets here, as the
* partial hcksum calculation range might not
* cover the whole payload, and the payload data
* might be changed by proxy.
*/
/* Inbound packets always need recalculation. */
if (err != 0) {
}
#else
#endif
}
return 1;
}
return 0;
}
/*
* Search for an proxy by the protocol it is being used with and its name.
*/
char *name;
{
if (ipf_proxy_debug > 8)
return ap;
}
return ap;
}
if (ipf_proxy_debug > 2)
return NULL;
}
{
}
{
if (!aps)
return;
if (a == aps) {
break;
}
}
/*
* returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise
*/
int inc;
{
short inc2;
/*
* ip_len has already been adjusted by 'inc'.
*/
if (out != 0) {
/* switch to other set ? */
if (ipf_proxy_debug > 7)
printf("proxy out switch set seq %d -> %d %x > %x\n",
}
ch = 1;
}
}
if (ipf_proxy_debug > 7)
printf("proxy seq set %d at %x to %d + %d\n",
}
/***/
/* switch to other set ? */
if (ipf_proxy_debug > 7)
printf("proxy out switch set ack %d -> %d %x > %x\n",
}
ch = 1;
}
} else {
/* switch to other set ? */
if (ipf_proxy_debug > 7)
printf("proxy in switch set ack %d -> %d %x > %x\n",
}
ch = 1;
}
}
if (ipf_proxy_debug > 7)
printf("proxy ack set %d at %x to %d + %d\n",
}
/***/
/* switch to other set ? */
if (ipf_proxy_debug > 7)
printf("proxy in switch set seq %d -> %d %x > %x\n",
}
if (ipf_proxy_debug > 7)
printf("sel %d seqoff %d seq1 %x seqmin %x\n",
ch = 1;
}
}
}
if (ipf_proxy_debug > 8)
printf("appr_fixseqack: seq %x ack %x\n",
return ch ? 2 : 0;
}
/*
* Initialise hook for kernel application proxies.
* Call the initialise routine for all the compiled in kernel proxies.
*/
{
int err = 0;
/* Since the refcnt is used we make a copy of lcl_ap_proxies */
if (err != 0)
break;
}
}
return 0;
}
/*
* Unload hook for kernel application proxies.
* Call the finialise routine for all the compiled in kernel proxies.
*/
{
return;
}