| /* |
| * Copyright (C) 2011 by Darren Reed. |
| * |
| * See the IPFILTER.LICENCE file for details on licencing. |
| * |
| * $Id$ |
| */ |
| |
| #ifndef __IP_PROXY_H__ |
| #define __IP_PROXY_H__ |
| |
| #ifndef SOLARIS |
| #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) |
| #endif |
| |
| #if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) |
| #define SIOCPROXY _IOWR('r', 64, struct ap_control) |
| #else |
| #define SIOCPROXY _IOWR(r, 64, struct ap_control) |
| #endif |
| |
| #ifndef APR_LABELLEN |
| #define APR_LABELLEN 16 |
| #endif |
| #define AP_SESS_SIZE 53 |
| |
| struct nat; |
| struct ipnat; |
| struct ipstate; |
| |
| typedef struct ap_tcp { |
| u_short apt_sport; /* source port */ |
| u_short apt_dport; /* destination port */ |
| short apt_sel[2]; /* {seq,ack}{off,min} set selector */ |
| short apt_seqoff[2]; /* sequence # difference */ |
| u_32_t apt_seqmin[2]; /* don't change seq-off until after this */ |
| short apt_ackoff[2]; /* sequence # difference */ |
| u_32_t apt_ackmin[2]; /* don't change seq-off until after this */ |
| u_char apt_state[2]; /* connection state */ |
| } ap_tcp_t; |
| |
| typedef struct ap_udp { |
| u_short apu_sport; /* source port */ |
| u_short apu_dport; /* destination port */ |
| } ap_udp_t; |
| |
| typedef struct ap_session { |
| struct aproxy *aps_apr; |
| union { |
| struct ap_tcp apu_tcp; |
| struct ap_udp apu_udp; |
| } aps_un; |
| U_QUAD_T aps_bytes; /* bytes sent */ |
| U_QUAD_T aps_pkts; /* packets sent */ |
| void *aps_nat; /* pointer back to nat struct */ |
| void *aps_data; /* private data */ |
| int aps_psiz; /* size of private data */ |
| struct ap_session *aps_next; |
| } ap_session_t; |
| |
| #define aps_sport aps_un.apu_tcp.apt_sport |
| #define aps_dport aps_un.apu_tcp.apt_dport |
| #define aps_sel aps_un.apu_tcp.apt_sel |
| #define aps_seqoff aps_un.apu_tcp.apt_seqoff |
| #define aps_seqmin aps_un.apu_tcp.apt_seqmin |
| #define aps_state aps_un.apu_tcp.apt_state |
| #define aps_ackoff aps_un.apu_tcp.apt_ackoff |
| #define aps_ackmin aps_un.apu_tcp.apt_ackmin |
| |
| |
| typedef struct ap_control { |
| char apc_label[APR_LABELLEN]; |
| char apc_config[APR_LABELLEN]; |
| u_char apc_p; |
| /* |
| * The following fields are upto the proxy's apr_ctl routine to deal |
| * with. When the proxy gets this in kernel space, apc_data will |
| * point to a malloc'd region of memory of apc_dsize bytes. If the |
| * proxy wants to keep that memory, it must set apc_data to NULL |
| * before it returns. It is expected if this happens that it will |
| * take care to free it in apr_fini or otherwise as appropriate. |
| * apc_cmd is provided as a standard place to put simple commands, |
| * with apc_arg being available to put a simple arg. |
| */ |
| u_long apc_cmd; |
| u_long apc_arg; |
| void *apc_data; |
| size_t apc_dsize; |
| } ap_ctl_t; |
| |
| #define APC_CMD_ADD 0 |
| #define APC_CMD_DEL 1 |
| |
| |
| typedef struct aproxy { |
| struct aproxy *apr_next; |
| struct aproxy *apr_parent; |
| char apr_label[APR_LABELLEN]; /* Proxy label # */ |
| u_char apr_p; /* protocol */ |
| int apr_flags; |
| int apr_ref; |
| int apr_clones; |
| void (* apr_load) __P((void)); |
| void (* apr_unload) __P((void)); |
| void *(* apr_create) __P((ipf_main_softc_t *)); |
| void (* apr_destroy) __P((ipf_main_softc_t *, void *)); |
| int (* apr_init) __P((ipf_main_softc_t *, void *)); |
| void (* apr_fini) __P((ipf_main_softc_t *, void *)); |
| int (* apr_new) __P((void *, fr_info_t *, ap_session_t *, |
| struct nat *)); |
| void (* apr_del) __P((ipf_main_softc_t *, ap_session_t *)); |
| int (* apr_inpkt) __P((void *, fr_info_t *, ap_session_t *, |
| struct nat *)); |
| int (* apr_outpkt) __P((void *, fr_info_t *, ap_session_t *, |
| struct nat *)); |
| int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *)); |
| int (* apr_ctl) __P((ipf_main_softc_t *, void *, ap_ctl_t *)); |
| int (* apr_clear) __P((struct aproxy *)); |
| int (* apr_flush) __P((struct aproxy *, int)); |
| void *apr_soft; |
| } aproxy_t; |
| |
| #define APR_DELETE 1 |
| |
| #define APR_ERR(x) ((x) << 16) |
| #define APR_EXIT(x) (((x) >> 16) & 0xffff) |
| #define APR_INC(x) ((x) & 0xffff) |
| |
| |
| #ifdef _KERNEL |
| /* |
| * Generic #define's to cover missing things in the kernel |
| */ |
| # ifndef isdigit |
| # define isdigit(x) ((x) >= '0' && (x) <= '9') |
| # endif |
| # ifndef isupper |
| # define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) |
| # endif |
| # ifndef islower |
| # define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) |
| # endif |
| # ifndef isalpha |
| # define isalpha(x) (isupper(x) || islower(x)) |
| # endif |
| # ifndef toupper |
| # define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') |
| # endif |
| # ifndef isspace |
| # define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ |
| ((x) == '\t') || ((x) == '\b')) |
| # endif |
| #endif /* _KERNEL */ |
| |
| /* |
| * For the ftp proxy. |
| */ |
| #define FTP_BUFSZ 160 |
| #define IPF_FTPBUFSZ 160 |
| |
| typedef struct ftpside { |
| char *ftps_rptr; |
| char *ftps_wptr; |
| void *ftps_ifp; |
| u_32_t ftps_seq[2]; |
| u_32_t ftps_len; |
| int ftps_junk; |
| int ftps_cmds; |
| int ftps_cmd; |
| char ftps_buf[FTP_BUFSZ]; |
| } ftpside_t; |
| |
| typedef struct ftpinfo { |
| int ftp_passok; |
| int ftp_incok; |
| void *ftp_pendstate; |
| nat_t *ftp_pendnat; |
| ftpside_t ftp_side[2]; |
| } ftpinfo_t; |
| |
| |
| /* |
| * For the irc proxy. |
| */ |
| typedef struct ircinfo { |
| size_t irc_len; |
| char *irc_snick; |
| char *irc_dnick; |
| char *irc_type; |
| char *irc_arg; |
| char *irc_addr; |
| u_32_t irc_ipnum; |
| u_short irc_port; |
| } ircinfo_t; |
| |
| |
| /* |
| * For the rcmd proxy. rcmd_rule must be last for names in ipnat_t |
| */ |
| typedef struct rcmdinfo { |
| u_32_t rcmd_port; /* Port number seen */ |
| u_32_t rcmd_portseq; /* Sequence number where port is first seen */ |
| ipnat_t rcmd_rule; /* Template rule for back connection */ |
| } rcmdinfo_t; |
| |
| /* |
| * For the DNS "proxy" |
| */ |
| typedef struct dnsinfo { |
| ipfmutex_t dnsi_lock; |
| u_short dnsi_id; |
| char dnsi_buffer[512]; |
| } dnsinfo_t; |
| |
| |
| /* |
| * Real audio proxy structure and #defines |
| */ |
| typedef struct raudio_s { |
| int rap_seenpna; |
| int rap_seenver; |
| int rap_version; |
| int rap_eos; /* End Of Startup */ |
| int rap_gotid; |
| int rap_gotlen; |
| int rap_mode; |
| int rap_sdone; |
| u_short rap_plport; |
| u_short rap_prport; |
| u_short rap_srport; |
| char rap_svr[19]; |
| u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have |
| * been filled |
| */ |
| u_32_t rap_sseq; |
| } raudio_t; |
| |
| #define RA_ID_END 0 |
| #define RA_ID_UDP 1 |
| #define RA_ID_ROBUST 7 |
| |
| #define RAP_M_UDP 1 |
| #define RAP_M_ROBUST 2 |
| #define RAP_M_TCP 4 |
| #define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST) |
| |
| |
| /* |
| * MSN RPC proxy |
| */ |
| typedef struct msnrpcinfo { |
| u_int mri_flags; |
| int mri_cmd[2]; |
| u_int mri_valid; |
| struct in_addr mri_raddr; |
| u_short mri_rport; |
| } msnrpcinfo_t; |
| |
| |
| /* |
| * IPSec proxy. ipsc_rule must be last for names in ipnat_t |
| */ |
| typedef u_32_t ipsec_cookie_t[2]; |
| |
| typedef struct ipsec_pxy { |
| ipsec_cookie_t ipsc_icookie; |
| ipsec_cookie_t ipsc_rcookie; |
| int ipsc_rckset; |
| nat_t *ipsc_nat; |
| struct ipstate *ipsc_state; |
| ipnat_t ipsc_rule; |
| } ipsec_pxy_t; |
| |
| /* |
| * PPTP proxy. pptp_rule must be last for names in ipnat_t |
| */ |
| typedef struct pptp_side { |
| u_32_t pptps_nexthdr; |
| u_32_t pptps_next; |
| int pptps_state; |
| int pptps_gothdr; |
| int pptps_len; |
| int pptps_bytes; |
| char *pptps_wptr; |
| char pptps_buffer[512]; |
| } pptp_side_t; |
| |
| typedef struct pptp_pxy { |
| nat_t *pptp_nat; |
| struct ipstate *pptp_state; |
| u_short pptp_call[2]; |
| pptp_side_t pptp_side[2]; |
| ipnat_t pptp_rule; |
| } pptp_pxy_t; |
| |
| |
| /* |
| * Sun RPCBIND proxy |
| */ |
| #define RPCB_MAXMSG 888 |
| #define RPCB_RES_PMAP 0 /* Response contains a v2 port. */ |
| #define RPCB_RES_STRING 1 /* " " " v3 (GETADDR) string. */ |
| #define RPCB_RES_LIST 2 /* " " " v4 (GETADDRLIST) list. */ |
| #define RPCB_MAXREQS 32 /* Arbitrary limit on tracked transactions */ |
| |
| #define RPCB_REQMIN 40 |
| #define RPCB_REQMAX 888 |
| #define RPCB_REPMIN 20 |
| #define RPCB_REPMAX 604 /* XXX double check this! */ |
| |
| /* |
| * These macros determine the number of bytes between p and the end of |
| * r->rs_buf relative to l. |
| */ |
| #define RPCB_BUF_END(r) (char *)((r)->rm_msgbuf + (r)->rm_buflen) |
| #define RPCB_BUF_GEQ(r, p, l) \ |
| ((RPCB_BUF_END((r)) > (char *)(p)) && \ |
| ((RPCB_BUF_END((r)) - (char *)(p)) >= (l))) |
| #define RPCB_BUF_EQ(r, p, l) \ |
| (RPCB_BUF_END((r)) == ((char *)(p) + (l))) |
| |
| /* |
| * The following correspond to RPC(B) detailed in RFC183[13]. |
| */ |
| #define RPCB_CALL 0 |
| #define RPCB_REPLY 1 |
| #define RPCB_MSG_VERSION 2 |
| #define RPCB_PROG 100000 |
| #define RPCB_GETPORT 3 |
| #define RPCB_GETADDR 3 |
| #define RPCB_GETADDRLIST 11 |
| #define RPCB_MSG_ACCEPTED 0 |
| #define RPCB_MSG_DENIED 1 |
| |
| /* BEGIN (Generic XDR structures) */ |
| typedef struct xdr_string { |
| u_32_t *xs_len; |
| char *xs_str; |
| } xdr_string_t; |
| |
| typedef struct xdr_auth { |
| /* u_32_t xa_flavor; */ |
| xdr_string_t xa_string; |
| } xdr_auth_t; |
| |
| typedef struct xdr_uaddr { |
| u_32_t xu_ip; |
| u_short xu_port; |
| xdr_string_t xu_str; |
| } xdr_uaddr_t; |
| |
| typedef struct xdr_proto { |
| u_int xp_proto; |
| xdr_string_t xp_str; |
| } xdr_proto_t; |
| |
| #define xu_xslen xu_str.xs_len |
| #define xu_xsstr xu_str.xs_str |
| #define xp_xslen xp_str.xs_len |
| #define xp_xsstr xp_str.xs_str |
| /* END (Generic XDR structures) */ |
| |
| /* BEGIN (RPC call structures) */ |
| typedef struct pmap_args { |
| /* u_32_t pa_prog; */ |
| /* u_32_t pa_vers; */ |
| u_32_t *pa_prot; |
| /* u_32_t pa_port; */ |
| } pmap_args_t; |
| |
| typedef struct rpcb_args { |
| /* u_32_t *ra_prog; */ |
| /* u_32_t *ra_vers; */ |
| xdr_proto_t ra_netid; |
| xdr_uaddr_t ra_maddr; |
| /* xdr_string_t ra_owner; */ |
| } rpcb_args_t; |
| |
| typedef struct rpc_call { |
| /* u_32_t rc_rpcvers; */ |
| /* u_32_t rc_prog; */ |
| u_32_t *rc_vers; |
| u_32_t *rc_proc; |
| xdr_auth_t rc_authcred; |
| xdr_auth_t rc_authverf; |
| union { |
| pmap_args_t ra_pmapargs; |
| rpcb_args_t ra_rpcbargs; |
| } rpcb_args; |
| } rpc_call_t; |
| |
| #define rc_pmapargs rpcb_args.ra_pmapargs |
| #define rc_rpcbargs rpcb_args.ra_rpcbargs |
| /* END (RPC call structures) */ |
| |
| /* BEGIN (RPC reply structures) */ |
| typedef struct rpcb_entry { |
| xdr_uaddr_t re_maddr; |
| xdr_proto_t re_netid; |
| /* u_32_t re_semantics; */ |
| xdr_string_t re_family; |
| xdr_proto_t re_proto; |
| u_32_t *re_more; /* 1 == another entry follows */ |
| } rpcb_entry_t; |
| |
| typedef struct rpcb_listp { |
| u_32_t *rl_list; /* 1 == list follows */ |
| int rl_cnt; |
| rpcb_entry_t rl_entries[2]; /* TCP / UDP only */ |
| } rpcb_listp_t; |
| |
| typedef struct rpc_resp { |
| /* u_32_t rr_acceptdeny; */ |
| /* Omitted 'message denied' fork; we don't care about rejects. */ |
| xdr_auth_t rr_authverf; |
| /* u_32_t *rr_astat; */ |
| union { |
| u_32_t *resp_pmap; |
| xdr_uaddr_t resp_getaddr; |
| rpcb_listp_t resp_getaddrlist; |
| } rpcb_reply; |
| } rpc_resp_t; |
| |
| #define rr_v2 rpcb_reply.resp_pmap |
| #define rr_v3 rpcb_reply.resp_getaddr |
| #define rr_v4 rpcb_reply.resp_getaddrlist |
| /* END (RPC reply structures) */ |
| |
| /* BEGIN (RPC message structure & macros) */ |
| typedef struct rpc_msg { |
| char rm_msgbuf[RPCB_MAXMSG]; /* RPCB data buffer */ |
| u_int rm_buflen; |
| u_32_t *rm_xid; |
| /* u_32_t Call vs Reply */ |
| union { |
| rpc_call_t rb_call; |
| rpc_resp_t rb_resp; |
| } rm_body; |
| } rpc_msg_t; |
| |
| #define rm_call rm_body.rb_call |
| #define rm_resp rm_body.rb_resp |
| /* END (RPC message structure & macros) */ |
| |
| /* |
| * These code paths aren't hot enough to warrant per transaction |
| * mutexes. |
| */ |
| typedef struct rpcb_xact { |
| struct rpcb_xact *rx_next; |
| struct rpcb_xact **rx_pnext; |
| u_32_t rx_xid; /* RPC transmission ID */ |
| u_int rx_type; /* RPCB response type */ |
| u_int rx_ref; /* reference count */ |
| u_int rx_proto; /* transport protocol (v2 only) */ |
| } rpcb_xact_t; |
| |
| typedef struct rpcb_session { |
| ipfmutex_t rs_rxlock; |
| rpcb_xact_t *rs_rxlist; |
| } rpcb_session_t; |
| |
| /* |
| * For an explanation, please see the following: |
| * RFC1832 - Sections 3.11, 4.4, and 4.5. |
| */ |
| #define XDRALIGN(x) ((((x) % 4) != 0) ? ((((x) + 3) / 4) * 4) : (x)) |
| |
| extern int ipf_proxy_add __P((void *, aproxy_t *)); |
| extern int ipf_proxy_check __P((fr_info_t *, struct nat *)); |
| extern int ipf_proxy_ctl __P((ipf_main_softc_t *, void *, ap_ctl_t *)); |
| extern int ipf_proxy_del __P((aproxy_t *)); |
| extern void ipf_proxy_flush __P((void *, int)); |
| extern void ipf_proxy_free __P((aproxy_t *)); |
| extern int ipf_proxy_init __P((void)); |
| extern int ipf_proxy_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, void *)); |
| extern aproxy_t *ipf_proxy_lookup __P((void *, u_int, char *)); |
| extern int ipf_proxy_match __P((fr_info_t *, struct nat *)); |
| extern int ipf_proxy_new __P((fr_info_t *, struct nat *)); |
| extern int ipf_proxy_ok __P((fr_info_t *, tcphdr_t *, struct ipnat *)); |
| extern void aps_free __P((ipf_main_softc_t *, void *, ap_session_t *)); |
| extern int ipf_proxy_main_load __P((void)); |
| extern int ipf_proxy_main_unload __P((void)); |
| extern void *ipf_proxy_soft_create __P((ipf_main_softc_t *)); |
| extern void ipf_proxy_soft_destroy __P((ipf_main_softc_t *, void *)); |
| extern int ipf_proxy_soft_init __P((ipf_main_softc_t *, void *)); |
| extern int ipf_proxy_soft_fini __P((ipf_main_softc_t *, void *)); |
| |
| #endif /* __IP_PROXY_H__ */ |