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 
33 struct    nat;
34 struct    ipnat;
35 struct    ipstate;
36 
37 typedef   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 
48 typedef   struct    ap_udp {
49           u_short   apu_sport;          /* source port */
50           u_short   apu_dport;          /* destination port */
51 } ap_udp_t;
52 
53 typedef   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 
77 typedef   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 
101 typedef   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 
167 typedef 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 
179 typedef 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  */
191 typedef u_32_t                ipsec_cookie_t[2];
192 
193 typedef 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  */
206 typedef   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  */
221 typedef 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  */
231 typedef   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  */
263 typedef   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) */
311 typedef struct xdr_string {
312           u_32_t    *xs_len;
313           char      *xs_str;
314 } xdr_string_t;
315 
316 typedef struct xdr_auth {
317           /* u_32_t xa_flavor; */
318           xdr_string_t        xa_string;
319 } xdr_auth_t;
320 
321 typedef 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 
327 typedef   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) */
339 typedef 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 
346 typedef 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 
354 typedef 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) */
372 typedef 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 
381 typedef 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 
387 typedef 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) */
405 typedef 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  */
424 typedef 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 
433 typedef 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 
444 extern    int       ipf_proxy_add(void *, aproxy_t *);
445 extern    int       ipf_proxy_check(fr_info_t *, struct nat *);
446 extern    int       ipf_proxy_ctl(ipf_main_softc_t *, void *, ap_ctl_t *);
447 extern    int       ipf_proxy_del(aproxy_t *);
448 extern    void      ipf_proxy_deref(aproxy_t *);
449 extern    void      ipf_proxy_flush(void *, int);
450 extern    void      ipf_proxy_free(ipf_main_softc_t *, ap_session_t *);
451 extern    int       ipf_proxy_init(void);
452 extern    int       ipf_proxy_ioctl(ipf_main_softc_t *, void *, ioctlcmd_t, int, void *);
453 extern    aproxy_t  *ipf_proxy_lookup(void *, u_int, char *);
454 extern    int       ipf_proxy_match(fr_info_t *, struct nat *);
455 extern    int       ipf_proxy_new(fr_info_t *, struct nat *);
456 extern    int       ipf_proxy_ok(fr_info_t *, tcphdr_t *, struct ipnat *);
457 extern    void      aps_free(ipf_main_softc_t *, void *, ap_session_t *);
458 extern    int       ipf_proxy_main_load(void);
459 extern    int       ipf_proxy_main_unload(void);
460 extern    ipnat_t   *ipf_proxy_rule_fwd(nat_t *);
461 extern    ipnat_t   *ipf_proxy_rule_rev(nat_t *);
462 extern    void      *ipf_proxy_soft_create(ipf_main_softc_t *);
463 extern    void      ipf_proxy_soft_destroy(ipf_main_softc_t *, void *);
464 extern    int       ipf_proxy_soft_fini(ipf_main_softc_t *, void *);
465 extern    int       ipf_proxy_soft_init(ipf_main_softc_t *, void *);
466 
467 #endif /* _NETINET_IP_PROXY_H_ */
468