Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-3]: src/dist/ipf Pull up revision 1.1.1.4 (requested by martti in...
details: https://anonhg.NetBSD.org/src/rev/f8e83051f128
branches: netbsd-3
changeset: 575116:f8e83051f128
user: tron <tron%NetBSD.org@localhost>
date: Mon Apr 04 19:34:15 2005 +0000
description:
Pull up revision 1.1.1.4 (requested by martti in ticket #106):
Upgraded IPFilter to 4.1.8
diffstat:
dist/ipf/ip_pptp_pxy.c | 512 ++++++++++++++++++++++++++++++++++-----------
dist/ipf/lib/printfr.c | 55 ++--
dist/ipf/lib/printstate.c | 5 +-
3 files changed, 418 insertions(+), 154 deletions(-)
diffs (truncated from 712 to 300 lines):
diff -r c920a2c32055 -r f8e83051f128 dist/ipf/ip_pptp_pxy.c
--- a/dist/ipf/ip_pptp_pxy.c Mon Apr 04 19:34:09 2005 +0000
+++ b/dist/ipf/ip_pptp_pxy.c Mon Apr 04 19:34:15 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_pptp_pxy.c,v 1.1.1.3 2005/02/08 06:53:01 martti Exp $ */
+/* $NetBSD: ip_pptp_pxy.c,v 1.1.1.3.2.1 2005/04/04 19:34:15 tron Exp $ */
/*
* Copyright (C) 2002-2003 by Darren Reed
@@ -6,18 +6,33 @@
* Simple PPTP transparent proxy for in-kernel use. For use with the NAT
* code.
*
- * Id: ip_pptp_pxy.c,v 2.10.2.6 2004/11/25 15:37:37 darrenr Exp
+ * Id: ip_pptp_pxy.c,v 2.10.2.9 2005/03/16 18:17:34 darrenr Exp
*
*/
#define IPF_PPTP_PROXY
-typedef struct pptp_pxy {
- ipnat_t pptp_rule;
- nat_t *pptp_nat;
- ipstate_t *pptp_state;
- int pptp_seencookie;
- u_32_t pptp_cookie;
-} pptp_pxy_t;
+typedef struct pptp_hdr {
+ u_short pptph_len;
+ u_short pptph_type;
+ u_32_t pptph_cookie;
+} pptp_hdr_t;
+
+#define PPTP_MSGTYPE_CTL 1
+#define PPTP_MTCTL_STARTREQ 1
+#define PPTP_MTCTL_STARTREP 2
+#define PPTP_MTCTL_STOPREQ 3
+#define PPTP_MTCTL_STOPREP 4
+#define PPTP_MTCTL_ECHOREQ 5
+#define PPTP_MTCTL_ECHOREP 6
+#define PPTP_MTCTL_OUTREQ 7
+#define PPTP_MTCTL_OUTREP 8
+#define PPTP_MTCTL_INREQ 9
+#define PPTP_MTCTL_INREP 10
+#define PPTP_MTCTL_INCONNECT 11
+#define PPTP_MTCTL_CLEAR 12
+#define PPTP_MTCTL_DISCONNECT 13
+#define PPTP_MTCTL_WANERROR 14
+#define PPTP_MTCTL_LINKINFO 15
int ippr_pptp_init __P((void));
@@ -25,11 +40,16 @@
int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *));
void ippr_pptp_del __P((ap_session_t *));
int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *));
-int ippr_pptp_match __P((fr_info_t *, ap_session_t *, nat_t *));
+void ippr_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *));
+int ippr_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *));
+int ippr_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int));
+int ippr_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *));
static frentry_t pptpfr;
int pptp_proxy_init = 0;
+int ippr_pptp_debug = 0;
+int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */
/*
@@ -39,6 +59,8 @@
{
bzero((char *)&pptpfr, sizeof(pptpfr));
pptpfr.fr_ref = 1;
+ pptpfr.fr_age[0] = ippr_pptp_gretimeout;
+ pptpfr.fr_age[1] = ippr_pptp_gretimeout;
pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock");
pptp_proxy_init = 1;
@@ -65,72 +87,379 @@
nat_t *nat;
{
pptp_pxy_t *pptp;
- fr_info_t fi;
ipnat_t *ipn;
- nat_t *nat2;
- int p, off;
ip_t *ip;
+ int off;
ip = fin->fin_ip;
off = fin->fin_hlen + sizeof(udphdr_t);
if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
- ip->ip_dst) != NULL)
+ ip->ip_dst) != NULL) {
+ if (ippr_pptp_debug > 0)
+ printf("ippr_pptp_new: GRE session already exists\n");
return -1;
+ }
aps->aps_psiz = sizeof(*pptp);
KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
- if (aps->aps_data == NULL)
+ if (aps->aps_data == NULL) {
+ if (ippr_pptp_debug > 0)
+ printf("ippr_pptp_new: malloc for aps_data failed\n");
return -1;
-
- ip = fin->fin_ip;
- pptp = aps->aps_data;
- bzero((char *)pptp, sizeof(*pptp));
+ }
/*
* Create NAT rule against which the tunnel/transport mapping is
* created. This is required because the current NAT rule does not
* describe GRE but TCP instead.
*/
+ pptp = aps->aps_data;
+ bzero((char *)pptp, sizeof(*pptp));
ipn = &pptp->pptp_rule;
ipn->in_ifps[0] = fin->fin_ifp;
ipn->in_apr = NULL;
ipn->in_use = 1;
ipn->in_hits = 1;
- ipn->in_nip = ntohl(nat->nat_outip.s_addr);
ipn->in_ippip = 1;
+ if (nat->nat_dir == NAT_OUTBOUND) {
+ ipn->in_nip = ntohl(nat->nat_outip.s_addr);
+ ipn->in_outip = fin->fin_saddr;
+ ipn->in_redir = NAT_MAP;
+ } else if (nat->nat_dir == NAT_INBOUND) {
+ ipn->in_nip = 0;
+ ipn->in_outip = nat->nat_outip.s_addr;
+ ipn->in_redir = NAT_REDIRECT;
+ }
ipn->in_inip = nat->nat_inip.s_addr;
ipn->in_inmsk = 0xffffffff;
- ipn->in_outip = fin->fin_saddr;
- ipn->in_outmsk = nat->nat_outip.s_addr;
+ ipn->in_outmsk = 0xffffffff;
ipn->in_srcip = fin->fin_saddr;
ipn->in_srcmsk = 0xffffffff;
- ipn->in_redir = NAT_MAP;
bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0],
sizeof(ipn->in_ifnames[0]));
ipn->in_p = IPPROTO_GRE;
- bcopy((char *)fin, (char *)&fi, sizeof(fi));
- fi.fin_fi.fi_p = IPPROTO_GRE;
- fi.fin_fr = &pptpfr;
- fi.fin_data[0] = 0;
- fi.fin_data[1] = 0;
+ pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer;
+ pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer;
+ return 0;
+}
+
+
+void ippr_pptp_donatstate(fin, nat, pptp)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+{
+ fr_info_t fi;
+ grehdr_t gre;
+ nat_t *nat2;
+ u_char p;
+ ip_t *ip;
+
+ ip = fin->fin_ip;
p = ip->ip_p;
- ip->ip_p = IPPROTO_GRE;
- fi.fin_flx &= ~FI_TCPUDP;
- fi.fin_flx |= FI_IGNORE;
- nat2 = nat_new(&fi, ipn, &pptp->pptp_nat, NAT_SLAVE, NAT_OUTBOUND);
- pptp->pptp_nat = nat2;
- if (nat2 != NULL) {
- (void) nat_proto(&fi, nat2, 0);
- nat_update(&fi, nat2, nat2->nat_ptr);
+ nat2 = pptp->pptp_nat;
+ if ((nat2 == NULL) || (pptp->pptp_state == NULL)) {
+ bcopy((char *)fin, (char *)&fi, sizeof(fi));
+ bzero((char *)&gre, sizeof(gre));
+ fi.fin_state = NULL;
+ fi.fin_nat = NULL;
+ fi.fin_fi.fi_p = IPPROTO_GRE;
+ fi.fin_fr = &pptpfr;
+ if ((nat->nat_dir == NAT_OUTBOUND && fin->fin_out) ||
+ (nat->nat_dir == NAT_INBOUND && !fin->fin_out)) {
+ fi.fin_data[0] = pptp->pptp_call[0];
+ fi.fin_data[1] = pptp->pptp_call[1];
+ } else {
+ fi.fin_data[0] = pptp->pptp_call[1];
+ fi.fin_data[1] = pptp->pptp_call[0];
+ }
+ ip = fin->fin_ip;
+ ip->ip_p = IPPROTO_GRE;
+ fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG);
+ fi.fin_flx |= FI_IGNORE;
+ fi.fin_dp = &gre;
+ gre.gr_flags = htons(1 << 13);
+ if (fin->fin_out && nat->nat_dir == NAT_INBOUND) {
+ fi.fin_fi.fi_saddr = fin->fin_fi.fi_daddr;
+ fi.fin_fi.fi_daddr = nat->nat_outip.s_addr;
+ } else if (!fin->fin_out && nat->nat_dir == NAT_OUTBOUND) {
+ fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
+ fi.fin_fi.fi_daddr = fin->fin_fi.fi_saddr;
+ }
+ }
- fi.fin_data[0] = 0;
- fi.fin_data[1] = 0;
- pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, 0);
+ /*
+ * Update NAT timeout/create NAT if missing.
+ */
+ if (nat2 != NULL)
+ fr_queueback(&nat2->nat_tqe);
+ else {
+ nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat,
+ NAT_SLAVE, nat->nat_dir);
+ pptp->pptp_nat = nat2;
+ if (nat2 != NULL) {
+ (void) nat_proto(&fi, nat2, 0);
+ nat_update(&fi, nat2, nat2->nat_ptr);
+ }
+ }
+
+ READ_ENTER(&ipf_state);
+ if (pptp->pptp_state != NULL) {
+ fr_queueback(&pptp->pptp_state->is_sti);
+ RWLOCK_EXIT(&ipf_state);
+ } else {
+ RWLOCK_EXIT(&ipf_state);
+ if (nat->nat_dir == NAT_INBOUND)
+ fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr;
+ else
+ fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr;
+ fi.fin_ifp = NULL;
+ pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state,
+ 0);
+ if (fi.fin_state != NULL)
+ fr_statederef(&fi, (ipstate_t **)&fi.fin_state);
}
ip->ip_p = p;
+ return;
+}
+
+
+/*
+ * Try and build up the next PPTP message in the TCP stream and if we can
+ * build it up completely (fits in our buffer) then pass it off to the message
+ * parsing function.
+ */
+int ippr_pptp_nextmessage(fin, nat, pptp, rev)
+fr_info_t *fin;
+nat_t *nat;
+pptp_pxy_t *pptp;
+int rev;
+{
+ static char *funcname = "ippr_pptp_nextmessage";
+ pptp_side_t *pptps;
+ u_32_t start, end;
+ pptp_hdr_t *hdr;
+ tcphdr_t *tcp;
+ int dlen, off;
+ u_short len;
+ char *msg;
+
+ tcp = fin->fin_dp;
+ dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2);
+ start = ntohl(tcp->th_seq);
+ pptps = &pptp->pptp_side[rev];
+ off = (char *)tcp - (char *)fin->fin_ip + (TCP_OFF(tcp) << 2) +
+ fin->fin_ipoff;
+
+ if (dlen <= 0)
+ return 0;
+ /*
+ * If the complete data packet is before what we expect to see
+ * "next", just ignore it as the chances are we've already seen it.
+ * The next if statement following this one really just causes packets
+ * ahead of what we've seen to be dropped, implying that something in
+ * the middle went missing and we want to see that first.
+ */
+ end = start + dlen;
+ if (pptps->pptps_next > end && pptps->pptps_next > start)
+ return 0;
+
+ if (pptps->pptps_next != start) {
+ if (ippr_pptp_debug > 5)
+ printf("%s: next (%x) != start (%x)\n", funcname,
+ pptps->pptps_next, start);
+ return -1;
+ }
+
+ msg = (char *)fin->fin_dp + (TCP_OFF(tcp) << 2);
+
Home |
Main Index |
Thread Index |
Old Index