1/* $NetBSD: ip_proxy.h,v 1.3 2012/07/22 14:27:51 darrenr Exp $ */ 2 3/* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 * 8 * Id: ip_proxy.h,v 1.1.1.2 2012/07/22 13:45:33 darrenr Exp 9 */ 10 11#ifndef _NETINET_IP_PROXY_H_ 12#define _NETINET_IP_PROXY_H_ 13 14#ifndef SOLARIS 15# if (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 16# define SOLARIS 1 17# else 18# define SOLARIS 0 19# endif 20#endif 21 22#if defined(__STDC__) || defined(__GNUC__) || defined(_AIX51) 23#define SIOCPROXY _IOWR('r', 64, struct ap_control) 24#else 25#define SIOCPROXY _IOWR(r, 64, struct ap_control) 26#endif 27 28#ifndef APR_LABELLEN 29#define APR_LABELLEN 16 30#endif 31#define AP_SESS_SIZE 53 32 33struct nat; 34struct ipnat; 35struct ipstate; 36 37typedef struct ap_tcp { 38 u_short apt_sport; /* source port */ 39 u_short apt_dport; /* destination port */ 40 short apt_sel[2]; /* {seq,ack}{off,min} set selector */ 41 short apt_seqoff[2]; /* sequence # difference */ 42 u_32_t apt_seqmin[2]; /* don't change seq-off until after this */ 43 short apt_ackoff[2]; /* sequence # difference */ 44 u_32_t apt_ackmin[2]; /* don't change seq-off until after this */ 45 u_char apt_state[2]; /* connection state */ 46} ap_tcp_t; 47 48typedef struct ap_udp { 49 u_short apu_sport; /* source port */ 50 u_short apu_dport; /* destination port */ 51} ap_udp_t; 52 53typedef struct ap_session { 54 struct aproxy *aps_apr; 55 union { 56 struct ap_tcp apu_tcp; 57 struct ap_udp apu_udp; 58 } aps_un; 59 U_QUAD_T aps_bytes; /* bytes sent */ 60 U_QUAD_T aps_pkts; /* packets sent */ 61 void *aps_nat; /* pointer back to nat struct */ 62 void *aps_data; /* private data */ 63 int aps_psiz; /* size of private data */ 64 struct ap_session *aps_next; 65} ap_session_t; 66 67#define aps_sport aps_un.apu_tcp.apt_sport 68#define aps_dport aps_un.apu_tcp.apt_dport 69#define aps_sel aps_un.apu_tcp.apt_sel 70#define aps_seqoff aps_un.apu_tcp.apt_seqoff 71#define aps_seqmin aps_un.apu_tcp.apt_seqmin 72#define aps_state aps_un.apu_tcp.apt_state 73#define aps_ackoff aps_un.apu_tcp.apt_ackoff 74#define aps_ackmin aps_un.apu_tcp.apt_ackmin 75 76 77typedef struct ap_control { 78 char apc_label[APR_LABELLEN]; 79 char apc_config[APR_LABELLEN]; 80 u_char apc_p; 81 /* 82 * The following fields are upto the proxy's apr_ctl routine to deal 83 * with. When the proxy gets this in kernel space, apc_data will 84 * point to a malloc'd region of memory of apc_dsize bytes. If the 85 * proxy wants to keep that memory, it must set apc_data to NULL 86 * before it returns. It is expected if this happens that it will 87 * take care to free it in apr_fini or otherwise as appropriate. 88 * apc_cmd is provided as a standard place to put simple commands, 89 * with apc_arg being available to put a simple arg. 90 */ 91 u_long apc_cmd; 92 u_long apc_arg; 93 void *apc_data; 94 size_t apc_dsize; 95} ap_ctl_t; 96 97#define APC_CMD_ADD 0 98#define APC_CMD_DEL 1 99 100 101typedef struct aproxy { 102 struct aproxy *apr_next; 103 struct aproxy *apr_parent; 104 char apr_label[APR_LABELLEN]; /* Proxy label # */ 105 u_char apr_p; /* protocol */ 106 int apr_flags; 107 int apr_ref; 108 int apr_clones; 109 void (* apr_load)(void); 110 void (* apr_unload)(void); 111 void *(* apr_create)(ipf_main_softc_t *); 112 void (* apr_destroy)(ipf_main_softc_t *, void *); 113 int (* apr_init)(ipf_main_softc_t *, void *); 114 void (* apr_fini)(ipf_main_softc_t *, void *); 115 int (* apr_new)(void *, fr_info_t *, ap_session_t *, 116 struct nat *); 117 void (* apr_del)(ipf_main_softc_t *, ap_session_t *); 118 int (* apr_inpkt)(void *, fr_info_t *, ap_session_t *, 119 struct nat *); 120 int (* apr_outpkt)(void *, fr_info_t *, ap_session_t *, 121 struct nat *); 122 int (* apr_match)(fr_info_t *, ap_session_t *, struct nat *); 123 int (* apr_ctl)(ipf_main_softc_t *, void *, ap_ctl_t *); 124 int (* apr_clear)(struct aproxy *); 125 int (* apr_flush)(struct aproxy *, int); 126 void *apr_soft; 127} aproxy_t; 128 129#define APR_DELETE 1 130 131#define APR_ERR(x) ((x) << 16) 132#define APR_EXIT(x) (((x) >> 16) & 0xffff) 133#define APR_INC(x) ((x) & 0xffff) 134 135 136#ifdef _KERNEL 137/* 138 * Generic #define's to cover missing things in the kernel 139 */ 140# ifndef isdigit 141# define isdigit(x) ((x) >= '0' && (x) <= '9') 142# endif 143# ifndef isupper 144# define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) 145# endif 146# ifndef islower 147# define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) 148# endif 149# ifndef isalpha 150# define isalpha(x) (isupper(x) || islower(x)) 151# endif 152# ifndef toupper 153# define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') 154# endif 155# ifndef isspace 156# define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ 157 ((x) == '\t') || ((x) == '\b')) 158# endif 159#endif /* _KERNEL */ 160 161/* 162 * For the ftp proxy. 163 */ 164#define FTP_BUFSZ 160 165#define IPF_FTPBUFSZ 160 166 167typedef struct ftpside { 168 char *ftps_rptr; 169 char *ftps_wptr; 170 void *ftps_ifp; 171 u_32_t ftps_seq[2]; 172 u_32_t ftps_len; 173 int ftps_junk; 174 int ftps_cmds; 175 int ftps_cmd; 176 char ftps_buf[FTP_BUFSZ]; 177} ftpside_t; 178 179typedef struct ftpinfo { 180 int ftp_passok; 181 int ftp_incok; 182 void *ftp_pendstate; 183 nat_t *ftp_pendnat; 184 ftpside_t ftp_side[2]; 185} ftpinfo_t; 186 187 188/* 189 * IPsec proxy 190 */ 191typedef u_32_t ipsec_cookie_t[2]; 192 193typedef struct ipsec_pxy { 194 ipsec_cookie_t ipsc_icookie; 195 ipsec_cookie_t ipsc_rcookie; 196 int ipsc_rckset; 197 nat_t *ipsc_nat; 198 struct ipstate *ipsc_state; 199 ipnat_t *ipsc_rule; 200} ipsec_pxy_t; 201 202 203/* 204 * For the irc proxy. 205 */ 206typedef struct ircinfo { 207 size_t irc_len; 208 char *irc_snick; 209 char *irc_dnick; 210 char *irc_type; 211 char *irc_arg; 212 char *irc_addr; 213 u_32_t irc_ipnum; 214 u_short irc_port; 215} ircinfo_t; 216 217 218/* 219 * For the DNS "proxy" 220 */ 221typedef struct dnsinfo { 222 ipfmutex_t dnsi_lock; 223 u_short dnsi_id; 224 char dnsi_buffer[512]; 225} dnsinfo_t; 226 227 228/* 229 * Real audio proxy structure and #defines 230 */ 231typedef struct raudio_s { 232 int rap_seenpna; 233 int rap_seenver; 234 int rap_version; 235 int rap_eos; /* End Of Startup */ 236 int rap_gotid; 237 int rap_gotlen; 238 int rap_mode; 239 int rap_sdone; 240 u_short rap_plport; 241 u_short rap_prport; 242 u_short rap_srport; 243 char rap_svr[19]; 244 u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have 245 * been filled 246 */ 247 u_32_t rap_sseq; 248} raudio_t; 249 250#define RA_ID_END 0 251#define RA_ID_UDP 1 252#define RA_ID_ROBUST 7 253 254#define RAP_M_UDP 1 255#define RAP_M_ROBUST 2 256#define RAP_M_TCP 4 257#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST) 258 259 260/* 261 * MSN RPC proxy 262 */ 263typedef struct msnrpcinfo { 264 u_int mri_flags; 265 int mri_cmd[2]; 266 u_int mri_valid; 267 struct in_addr mri_raddr; 268 u_short mri_rport; 269} msnrpcinfo_t; 270 271 272/* 273 * Sun RPCBIND proxy 274 */ 275#define RPCB_MAXMSG 888 276#define RPCB_RES_PMAP 0 /* Response contains a v2 port. */ 277#define RPCB_RES_STRING 1 /* " " " v3 (GETADDR) string. */ 278#define RPCB_RES_LIST 2 /* " " " v4 (GETADDRLIST) list. */ 279#define RPCB_MAXREQS 32 /* Arbitrary limit on tracked transactions */ 280 281#define RPCB_REQMIN 40 282#define RPCB_REQMAX 888 283#define RPCB_REPMIN 20 284#define RPCB_REPMAX 604 /* XXX double check this! */ 285 286/* 287 * These macros determine the number of bytes between p and the end of 288 * r->rs_buf relative to l. 289 */ 290#define RPCB_BUF_END(r) (char *)((r)->rm_msgbuf + (r)->rm_buflen) 291#define RPCB_BUF_GEQ(r, p, l) \ 292 ((RPCB_BUF_END((r)) > (char *)(p)) && \ 293 ((RPCB_BUF_END((r)) - (char *)(p)) >= (l))) 294#define RPCB_BUF_EQ(r, p, l) \ 295 (RPCB_BUF_END((r)) == ((char *)(p) + (l))) 296 297/* 298 * The following correspond to RPC(B) detailed in RFC183[13]. 299 */ 300#define RPCB_CALL 0 301#define RPCB_REPLY 1 302#define RPCB_MSG_VERSION 2 303#define RPCB_PROG 100000 304#define RPCB_GETPORT 3 305#define RPCB_GETADDR 3 306#define RPCB_GETADDRLIST 11 307#define RPCB_MSG_ACCEPTED 0 308#define RPCB_MSG_DENIED 1 309 310/* BEGIN (Generic XDR structures) */ 311typedef struct xdr_string { 312 u_32_t *xs_len; 313 char *xs_str; 314} xdr_string_t; 315 316typedef struct xdr_auth { 317 /* u_32_t xa_flavor; */ 318 xdr_string_t xa_string; 319} xdr_auth_t; 320 321typedef struct xdr_uaddr { 322 u_32_t xu_ip; 323 u_short xu_port; 324 xdr_string_t xu_str; 325} xdr_uaddr_t; 326 327typedef struct xdr_proto { 328 u_int xp_proto; 329 xdr_string_t xp_str; 330} xdr_proto_t; 331 332#define xu_xslen xu_str.xs_len 333#define xu_xsstr xu_str.xs_str 334#define xp_xslen xp_str.xs_len 335#define xp_xsstr xp_str.xs_str 336/* END (Generic XDR structures) */ 337 338/* BEGIN (RPC call structures) */ 339typedef struct pmap_args { 340 /* u_32_t pa_prog; */ 341 /* u_32_t pa_vers; */ 342 u_32_t *pa_prot; 343 /* u_32_t pa_port; */ 344} pmap_args_t; 345 346typedef struct rpcb_args { 347 /* u_32_t *ra_prog; */ 348 /* u_32_t *ra_vers; */ 349 xdr_proto_t ra_netid; 350 xdr_uaddr_t ra_maddr; 351 /* xdr_string_t ra_owner; */ 352} rpcb_args_t; 353 354typedef struct rpc_call { 355 /* u_32_t rc_rpcvers; */ 356 /* u_32_t rc_prog; */ 357 u_32_t *rc_vers; 358 u_32_t *rc_proc; 359 xdr_auth_t rc_authcred; 360 xdr_auth_t rc_authverf; 361 union { 362 pmap_args_t ra_pmapargs; 363 rpcb_args_t ra_rpcbargs; 364 } rpcb_args; 365} rpc_call_t; 366 367#define rc_pmapargs rpcb_args.ra_pmapargs 368#define rc_rpcbargs rpcb_args.ra_rpcbargs 369/* END (RPC call structures) */ 370 371/* BEGIN (RPC reply structures) */ 372typedef struct rpcb_entry { 373 xdr_uaddr_t re_maddr; 374 xdr_proto_t re_netid; 375 /* u_32_t re_semantics; */ 376 xdr_string_t re_family; 377 xdr_proto_t re_proto; 378 u_32_t *re_more; /* 1 == another entry follows */ 379} rpcb_entry_t; 380 381typedef struct rpcb_listp { 382 u_32_t *rl_list; /* 1 == list follows */ 383 int rl_cnt; 384 rpcb_entry_t rl_entries[2]; /* TCP / UDP only */ 385} rpcb_listp_t; 386 387typedef struct rpc_resp { 388 /* u_32_t rr_acceptdeny; */ 389 /* Omitted 'message denied' fork; we don't care about rejects. */ 390 xdr_auth_t rr_authverf; 391 /* u_32_t *rr_astat; */ 392 union { 393 u_32_t *resp_pmap; 394 xdr_uaddr_t resp_getaddr; 395 rpcb_listp_t resp_getaddrlist; 396 } rpcb_reply; 397} rpc_resp_t; 398 399#define rr_v2 rpcb_reply.resp_pmap 400#define rr_v3 rpcb_reply.resp_getaddr 401#define rr_v4 rpcb_reply.resp_getaddrlist 402/* END (RPC reply structures) */ 403 404/* BEGIN (RPC message structure & macros) */ 405typedef struct rpc_msg { 406 char rm_msgbuf[RPCB_MAXMSG]; /* RPCB data buffer */ 407 u_int rm_buflen; 408 u_32_t *rm_xid; 409 /* u_32_t Call vs Reply */ 410 union { 411 rpc_call_t rb_call; 412 rpc_resp_t rb_resp; 413 } rm_body; 414} rpc_msg_t; 415 416#define rm_call rm_body.rb_call 417#define rm_resp rm_body.rb_resp 418/* END (RPC message structure & macros) */ 419 420/* 421 * These code paths aren't hot enough to warrant per transaction 422 * mutexes. 423 */ 424typedef struct rpcb_xact { 425 struct rpcb_xact *rx_next; 426 struct rpcb_xact **rx_pnext; 427 u_32_t rx_xid; /* RPC transmission ID */ 428 u_int rx_type; /* RPCB response type */ 429 u_int rx_ref; /* reference count */ 430 u_int rx_proto; /* transport protocol (v2 only) */ 431} rpcb_xact_t; 432 433typedef struct rpcb_session { 434 ipfmutex_t rs_rxlock; 435 rpcb_xact_t *rs_rxlist; 436} rpcb_session_t; 437 438/* 439 * For an explanation, please see the following: 440 * RFC1832 - Sections 3.11, 4.4, and 4.5. 441 */ 442#define XDRALIGN(x) ((((x) % 4) != 0) ? ((((x) + 3) / 4) * 4) : (x)) 443 444extern int ipf_proxy_add(void *, aproxy_t *); 445extern int ipf_proxy_check(fr_info_t *, struct nat *); 446extern int ipf_proxy_ctl(ipf_main_softc_t *, void *, ap_ctl_t *); 447extern int ipf_proxy_del(aproxy_t *); 448extern void ipf_proxy_deref(aproxy_t *); 449extern void ipf_proxy_flush(void *, int); 450extern void ipf_proxy_free(ipf_main_softc_t *, ap_session_t *); 451extern int ipf_proxy_init(void); 452extern int ipf_proxy_ioctl(ipf_main_softc_t *, void *, ioctlcmd_t, int, void *); 453extern aproxy_t *ipf_proxy_lookup(void *, u_int, char *); 454extern int ipf_proxy_match(fr_info_t *, struct nat *); 455extern int ipf_proxy_new(fr_info_t *, struct nat *); 456extern int ipf_proxy_ok(fr_info_t *, tcphdr_t *, struct ipnat *); 457extern void aps_free(ipf_main_softc_t *, void *, ap_session_t *); 458extern int ipf_proxy_main_load(void); 459extern int ipf_proxy_main_unload(void); 460extern ipnat_t *ipf_proxy_rule_fwd(nat_t *); 461extern ipnat_t *ipf_proxy_rule_rev(nat_t *); 462extern void *ipf_proxy_soft_create(ipf_main_softc_t *); 463extern void ipf_proxy_soft_destroy(ipf_main_softc_t *, void *); 464extern int ipf_proxy_soft_fini(ipf_main_softc_t *, void *); 465extern int ipf_proxy_soft_init(ipf_main_softc_t *, void *); 466 467#endif /* _NETINET_IP_PROXY_H_ */ 468