1/* $NetBSD: ip_proxy.h,v 1.4 2012/09/15 16:56:45 plunky 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