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