]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/ip_proxy.c
8d645eb400a725c3d2f7e3847f230aa08c2221fb
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (C) 1997 by Darren Reed.
25 * Redistribution and use in source and binary forms are permitted
26 * provided that this notice is preserved and due credit is given
27 * to the original author and the contributors.
32 #if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
36 #if !defined(_KERNEL) && !defined(KERNEL)
41 #include <sys/errno.h>
42 #include <sys/types.h>
43 #include <sys/param.h>
46 #if !defined(__FreeBSD__)
47 # include <sys/ioctl.h>
49 #include <sys/fcntl.h>
52 # include <sys/protosw.h>
54 #include <sys/socket.h>
57 # include <sys/systm.h>
59 # include <linux/string.h>
62 #if !defined(__SVR4) && !defined(__svr4__)
64 # include <sys/mbuf.h>
67 # include <sys/byteorder.h>
68 # include <sys/dditypes.h>
69 # include <sys/stream.h>
70 # include <sys/kmem.h>
73 # include <sys/queue.h>
74 # include <sys/malloc.h>
80 #include <net/route.h>
81 #include <netinet/in.h>
82 #include <netinet/in_systm.h>
83 #include <netinet/ip.h>
85 # include <netinet/ip_var.h>
87 #include <netinet/tcp.h>
88 #include <netinet/udp.h>
89 #include <netinet/ip_icmp.h>
90 #include "netinet/ip_compat.h"
91 #include <netinet/tcpip.h>
92 #include "netinet/ip_fil.h"
93 #include "netinet/ip_proxy.h"
94 #include "netinet/ip_nat.h"
95 #include "netinet/ip_state.h"
98 #define MIN(a,b) (((a)<(b))?(a):(b))
101 static ap_session_t
*ap_find
__P((ip_t
*, tcphdr_t
*));
102 static ap_session_t
*ap_new_session
__P((aproxy_t
*, ip_t
*, tcphdr_t
*,
103 fr_info_t
*, nat_t
*));
105 static int ap_matchsrcdst
__P((ap_session_t
*aps
, struct in_addr src
,
106 struct in_addr dst
, void *tcp
, u_short sport
,
109 #define AP_SESS_SIZE 53
111 #if defined(_KERNEL) && !defined(linux)
112 #include "netinet/ip_ftp_pxy.c"
115 ap_session_t
*ap_sess_tab
[AP_SESS_SIZE
];
116 aproxy_t ap_proxies
[] = {
118 { "ftp", (char)IPPROTO_TCP
, 0, 0, ippr_ftp_init
, ippr_ftp_in
, ippr_ftp_out
},
120 { "", '\0', 0, 0, NULL
, NULL
}
124 int ap_ok(ip
, tcp
, nat
)
129 aproxy_t
*apr
= nat
->in_apr
;
130 u_short dport
= nat
->in_dport
;
132 if (!apr
|| (apr
&& (apr
->apr_flags
& APR_DELETE
)) ||
133 (ip
->ip_p
!= apr
->apr_p
))
135 if ((tcp
&& (tcp
->th_dport
!= dport
)) || (!tcp
&& dport
))
142 ap_matchsrcdst(aps
, src
, dst
, tcp
, sport
, dport
)
144 struct in_addr src
, dst
;
146 u_short sport
, dport
;
148 if (aps
->aps_dst
.s_addr
== dst
.s_addr
) {
149 if ((aps
->aps_src
.s_addr
== src
.s_addr
) &&
150 (!tcp
|| (sport
== aps
->aps_sport
) &&
151 (dport
== aps
->aps_dport
)))
153 } else if (aps
->aps_dst
.s_addr
== src
.s_addr
) {
154 if ((aps
->aps_src
.s_addr
== dst
.s_addr
) &&
155 (!tcp
|| (sport
== aps
->aps_dport
) &&
156 (dport
== aps
->aps_sport
)))
163 static ap_session_t
*ap_find(ip
, tcp
)
167 register u_char p
= ip
->ip_p
;
168 register ap_session_t
*aps
;
169 register u_short sp
, dp
;
171 struct in_addr src
, dst
;
173 src
= ip
->ip_src
, dst
= ip
->ip_dst
;
174 sp
= dp
= 0; /* XXX gcc -Wunitialized */
176 hv
= ip
->ip_src
.s_addr
^ ip
->ip_dst
.s_addr
;
186 for (aps
= ap_sess_tab
[hv
]; aps
; aps
= aps
->aps_next
)
187 if ((aps
->aps_p
== p
) &&
188 ap_matchsrcdst(aps
, src
, dst
, tcp
, sp
, dp
))
195 * Allocate a new application proxy structure and fill it in with the
196 * relevant details. call the init function once complete, prior to
199 static ap_session_t
*ap_new_session(apr
, ip
, tcp
, fin
, nat
)
206 register ap_session_t
*aps
;
210 if (!apr
|| (apr
&& (apr
->apr_flags
& APR_DELETE
)) ||
211 (ip
->ip_p
!= apr
->apr_p
))
213 dport
= nat
->nat_ptr
->in_dport
;
214 if ((tcp
&& (tcp
->th_dport
!= dport
)) || (!tcp
&& dport
))
217 hv
= ip
->ip_src
.s_addr
^ ip
->ip_dst
.s_addr
;
220 hv
^= (tcp
->th_sport
+ tcp
->th_dport
);
225 KMALLOC(aps
, ap_session_t
*, sizeof(*aps
));
228 bzero((char *)aps
, sizeof(*aps
));
230 aps
->aps_src
= ip
->ip_src
;
231 aps
->aps_dst
= ip
->ip_dst
;
232 aps
->aps_p
= ip
->ip_p
;
233 aps
->aps_tout
= 1200; /* XXX */
235 aps
->aps_sport
= tcp
->th_sport
;
236 aps
->aps_dport
= tcp
->th_dport
;
238 aps
->aps_data
= NULL
;
240 aps
->aps_next
= ap_sess_tab
[hv
];
241 ap_sess_tab
[hv
] = aps
;
242 (void) (*apr
->apr_init
)(fin
, ip
, tcp
, aps
, nat
);
248 * check to see if a packet should be passed through an active proxy routine
249 * if one has been setup for it.
251 int ap_check(ip
, tcp
, fin
, nat
)
261 if (!(fin
->fin_fi
.fi_fl
& FI_TCPUDP
))
264 if ((aps
= ap_find(ip
, tcp
)) ||
265 (aps
= ap_new_session(nat
->nat_ptr
->in_apr
, ip
, tcp
, fin
, nat
))) {
266 if (ip
->ip_p
== IPPROTO_TCP
) {
268 * verify that the checksum is correct. If not, then
269 * don't do anything with this packet.
271 if (tcp
->th_sum
!= fr_tcpsum(*(mb_t
**)fin
->fin_mp
,
272 ip
, tcp
, ip
->ip_len
)) {
273 frstats
[fin
->fin_out
].fr_tcpbad
++;
276 fr_tcp_age(&aps
->aps_tout
, aps
->aps_state
, ip
, fin
,
277 tcp
->th_sport
== aps
->aps_sport
);
284 err
= (*apr
->apr_outpkt
)(fin
, ip
, tcp
,
288 err
= (*apr
->apr_inpkt
)(fin
, ip
, tcp
,
292 tcp
->th_sum
= fr_tcpsum(*(mb_t
**)fin
->fin_mp
, ip
,
302 aproxy_t
*ap_match(pr
, name
)
308 for (ap
= ap_proxies
; ap
->apr_p
; ap
++)
309 if ((ap
->apr_p
== pr
) &&
310 !strncmp(name
, ap
->apr_label
, sizeof(ap
->apr_label
))) {
328 if (aps
->aps_data
&& aps
->aps_psiz
)
329 KFREES(aps
->aps_data
, aps
->aps_psiz
);
339 for (i
= 0; i
< AP_SESS_SIZE
; i
++)
340 while ((aps
= ap_sess_tab
[i
])) {
341 ap_sess_tab
[i
] = aps
->aps_next
;
349 ap_session_t
*aps
, **apsp
;
352 for (i
= 0; i
< AP_SESS_SIZE
; i
++)
353 for (apsp
= &ap_sess_tab
[i
]; (aps
= *apsp
); ) {
355 if (!aps
->aps_tout
) {
356 ap_sess_tab
[i
] = aps
->aps_next
;
358 *apsp
= aps
->aps_next
;
360 apsp
= &aps
->aps_next
;