Attached to this email is a patch that should allow
multiple PPTP/GRE streams through an ipfilter firewall.
Unfortunately, I don't use PPTP/GRE, so I can't test
this out. Is there someone out there that does and
can?

Thanks,
Darren

Index: fil.c
===================================================================
RCS file: /devel/CVS/IP-Filter/fil.c,v
retrieving revision 2.243.2.147
diff -c -r2.243.2.147 fil.c
*** fil.c       21 Jul 2009 22:25:28 -0000      2.243.2.147
--- fil.c       16 Aug 2009 14:11:43 -0000
***************
*** 882,897 ****
  static INLINE void frpr_gre6(fin)
  fr_info_t *fin;
  {
!       grehdr_t *gre;
  
!       frpr_short6(fin, sizeof(grehdr_t));
  
!       if (frpr_pullup(fin, sizeof(grehdr_t)) == -1)
                return;
  
!       gre = fin->fin_dp;
!       if (GRE_REV(gre->gr_flags) == 1)
!               fin->fin_data[0] = gre->gr_call;
  }
  #endif        /* USE_INET6 */
  
--- 882,922 ----
  static INLINE void frpr_gre6(fin)
  fr_info_t *fin;
  {
!       grehdr_t *gre, grhdr;
!       int keyoff = 1;
!       int len;
! 
!       frpr_short6(fin, sizeof(*gre));
  
!       if (fin->fin_off != 0)
!               return;
  
!       if (frpr_pullup(fin, sizeof(*gre)) == -1)
                return;
  
!       if (fin->fin_off == 0) {
!               gre = fin->fin_dp;
!               grhdr.gr_flags = ntohl(gre->gr_flags);
!               if (grhdr.gr_ver == 0) {
!                       len = sizeof(grhdr);
!                       if (grhdr.gr_C == 1) {
!                               len += 4;
!                               keyoff = 2;
!                       }
!                       if (grhdr.gr_K == 1)
!                               len += 4;
!                       if (grhdr.gr_S == 1)
!                               len += 4;
!                       if (len > sizeof(grhdr)) {
!                               frpr_short6(fin, len);
!                               if (frpr_pullup(fin, len) == -1)
!                                       return;
!                       }
!                       if (!(fin->fin_flx & FI_SHORT) && (grhdr.gr_K == 1)) {
!                               fin->fin_datum = ((u_32_t *)gre)[keyoff];
!                       }
!               }
!       }
  }
  #endif        /* USE_INET6 */
  
***************
*** 1370,1376 ****
  static INLINE void frpr_gre(fin)
  fr_info_t *fin;
  {
!       grehdr_t *gre;
  
        frpr_short(fin, sizeof(*gre));
  
--- 1395,1403 ----
  static INLINE void frpr_gre(fin)
  fr_info_t *fin;
  {
!       grehdr_t *gre, grhdr;
!       int keyoff = 1;
!       int len;
  
        frpr_short(fin, sizeof(*gre));
  
***************
*** 1382,1389 ****
  
        if (fin->fin_off == 0) {
                gre = fin->fin_dp;
!               if (GRE_REV(gre->gr_flags) == 1)
!                       fin->fin_data[0] = gre->gr_call;
        }
  }
  
--- 1409,1434 ----
  
        if (fin->fin_off == 0) {
                gre = fin->fin_dp;
!               grhdr.gr_flags = ntohl(gre->gr_flags);
!               if (grhdr.gr_ver == 0) {
!                       len = sizeof(grhdr);
!                       if (grhdr.gr_C == 1) {
!                               len += 4;
!                               keyoff = 2;
!                       }
!                       if (grhdr.gr_K == 1)
!                               len += 4;
!                       if (grhdr.gr_S == 1)
!                               len += 4;
!                       if (len > sizeof(grhdr)) {
!                               frpr_short(fin, len);
!                               if (frpr_pullup(fin, len) == -1)
!                                       return;
!                       }
!                       if (!(fin->fin_flx & FI_SHORT) && (grhdr.gr_K == 1)) {
!                               fin->fin_datum = ((u_32_t *)gre)[keyoff];
!                       }
!               }
        }
  }
  
Index: ip_fil.h
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_fil.h,v
retrieving revision 2.170.2.62
diff -c -r2.170.2.62 ip_fil.h
*** ip_fil.h    22 Jul 2009 01:46:42 -0000      2.170.2.62
--- ip_fil.h    16 Aug 2009 14:11:43 -0000
***************
*** 361,366 ****
--- 361,367 ----
  #define       fin_sport       fin_dat.fid_16[0]
  #define       fin_dport       fin_dat.fid_16[1]
  #define       fin_ports       fin_dat.fid_32
+ #define       fin_datum       fin_dat.fid_32
  
  #define       IPF_IN          0
  #define       IPF_OUT         1
***************
*** 983,992 ****
  typedef       struct  grehdr  {
        union   {
                struct  grebits gru_bits;
!               u_short gru_flags;
        } gr_un;
-       u_short gr_len;
-       u_short gr_call;
  } grehdr_t;
  
  #define       gr_flags        gr_un.gru_flags
--- 984,991 ----
  typedef       struct  grehdr  {
        union   {
                struct  grebits gru_bits;
!               u_32_t  gru_flags;
        } gr_un;
  } grehdr_t;
  
  #define       gr_flags        gr_un.gru_flags
***************
*** 1005,1011 ****
   * GRE information tracked by "keep state"
   */
  typedef       struct  greinfo {
!       u_short gs_call[2];
        u_short gs_flags;
        u_short gs_ptype;
  } greinfo_t;
--- 1004,1010 ----
   * GRE information tracked by "keep state"
   */
  typedef       struct  greinfo {
!       u_32_t  gs_call;
        u_short gs_flags;
        u_short gs_ptype;
  } greinfo_t;
Index: ip_nat.c
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_nat.c,v
retrieving revision 2.195.2.127
diff -c -r2.195.2.127 ip_nat.c
*** ip_nat.c    21 Jul 2009 09:40:55 -0000      2.195.2.127
--- ip_nat.c    16 Aug 2009 14:11:43 -0000
***************
*** 2126,2142 ****
                ((icmphdr_t *)fin->fin_dp)->icmp_id = port;
                nat->nat_inport = port;
                nat->nat_outport = port;
- #if 0
        } else if (fin->fin_p == IPPROTO_GRE) {
                nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags;
                if (GRE_REV(nat->nat_gre.gs_flags) == 1) {
!                       nat->nat_oport = 0;/*fin->fin_data[1];*/
!                       nat->nat_inport = 0;/*fin->fin_data[0];*/
!                       nat->nat_outport = 0;/*fin->fin_data[0];*/
!                       nat->nat_call[0] = fin->fin_data[0];
!                       nat->nat_call[1] = fin->fin_data[0];
                }
- #endif
        }
        ni->nai_ip.s_addr = in.s_addr;
        ni->nai_port = port;
--- 2126,2139 ----
                ((icmphdr_t *)fin->fin_dp)->icmp_id = port;
                nat->nat_inport = port;
                nat->nat_outport = port;
        } else if (fin->fin_p == IPPROTO_GRE) {
                nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags;
                if (GRE_REV(nat->nat_gre.gs_flags) == 1) {
!                       nat->nat_oport = fin->fin_data[1];
!                       nat->nat_inport = fin->fin_data[0];
!                       nat->nat_outport = fin->fin_data[0];
!                       nat->nat_call = fin->fin_datum;
                }
        }
        ni->nai_ip.s_addr = in.s_addr;
        ni->nai_port = port;
***************
*** 2318,2334 ****
                ((icmphdr_t *)fin->fin_dp)->icmp_id = nport;
                nat->nat_inport = nport;
                nat->nat_outport = nport;
- #if 0
        } else if (fin->fin_p == IPPROTO_GRE) {
                nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags;
                if (GRE_REV(nat->nat_gre.gs_flags) == 1) {
!                       nat->nat_call[0] = fin->fin_data[0];
!                       nat->nat_call[1] = fin->fin_data[1];
!                       nat->nat_oport = 0; /*fin->fin_data[0];*/
!                       nat->nat_inport = 0; /*fin->fin_data[1];*/
!                       nat->nat_outport = 0; /*fin->fin_data[1];*/
                }
- #endif
        }
  
        return move;
--- 2315,2328 ----
                ((icmphdr_t *)fin->fin_dp)->icmp_id = nport;
                nat->nat_inport = nport;
                nat->nat_outport = nport;
        } else if (fin->fin_p == IPPROTO_GRE) {
                nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags;
                if (GRE_REV(nat->nat_gre.gs_flags) == 1) {
!                       nat->nat_oport = fin->fin_data[0];
!                       nat->nat_inport = fin->fin_data[1];
!                       nat->nat_outport = fin->fin_data[1];
!                       nat->nat_call = fin->fin_datum;
                }
        }
  
        return move;
***************
*** 3190,3201 ****
                     || (p == nat->nat_p))) {
                        switch (p)
                        {
- #if 0
                        case IPPROTO_GRE :
!                               if (nat->nat_call[1] != fin->fin_data[0])
                                        continue;
                                break;
- #endif
                        case IPPROTO_ICMP :
                                if ((flags & IPN_ICMPERR) != 0) {
                                        if (nat->nat_outport != sport)
--- 3184,3193 ----
                     || (p == nat->nat_p))) {
                        switch (p)
                        {
                        case IPPROTO_GRE :
!                               if (nat->nat_call != fin->fin_datum)
                                        continue;
                                break;
                        case IPPROTO_ICMP :
                                if ((flags & IPN_ICMPERR) != 0) {
                                        if (nat->nat_outport != sport)
***************
*** 3433,3444 ****
                     || (p == nat->nat_p))) {
                        switch (p)
                        {
- #if 0
                        case IPPROTO_GRE :
!                               if (nat->nat_call[1] != fin->fin_data[0])
                                        continue;
                                break;
- #endif
                        case IPPROTO_TCP :
                        case IPPROTO_UDP :
                                if (nat->nat_oport != dport)
--- 3425,3434 ----
                     || (p == nat->nat_p))) {
                        switch (p)
                        {
                        case IPPROTO_GRE :
!                               if (nat->nat_call != fin->fin_datum)
                                        continue;
                                break;
                        case IPPROTO_TCP :
                        case IPPROTO_UDP :
                                if (nat->nat_oport != dport)
Index: ip_nat.h
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_nat.h,v
retrieving revision 2.90.2.23
diff -c -r2.90.2.23 ip_nat.h
*** ip_nat.h    6 Nov 2008 21:18:36 -0000       2.90.2.23
--- ip_nat.h    16 Aug 2009 14:11:43 -0000
***************
*** 137,142 ****
--- 137,144 ----
  #define       nat_tcpstate    nat_tqe.tqe_state
  #define       nat_die         nat_tqe.tqe_die
  #define       nat_touched     nat_tqe.tqe_touched
+ #define       nat_gre         nat_un.nat_ugre
+ #define       nat_call        nat_un.nat_ugre.gs_call
  
  /*
   * Values for nat_dir
Index: ip_pptp_pxy.c
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_pptp_pxy.c,v
retrieving revision 2.10.2.18
diff -c -r2.10.2.18 ip_pptp_pxy.c
*** ip_pptp_pxy.c       6 Nov 2008 21:18:36 -0000       2.10.2.18
--- ip_pptp_pxy.c       16 Aug 2009 14:11:43 -0000
***************
*** 93,106 ****
  
        ip = fin->fin_ip;
  
-       if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip,
-                         ip->ip_dst) != NULL) {
-               if (ippr_pptp_debug > 0)
-                       printf("ippr_pptp_new: GRE session %s\n",
-                              "already exists");
-               return -1;
-       }
- 
        aps->aps_psiz = sizeof(*pptp);
        KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp));
        if (aps->aps_data == NULL) {
--- 93,98 ----
Index: ip_state.c
===================================================================
RCS file: /devel/CVS/IP-Filter/ip_state.c,v
retrieving revision 2.186.2.98
diff -c -r2.186.2.98 ip_state.c
*** ip_state.c  21 Jul 2009 09:40:56 -0000      2.186.2.98
--- ip_state.c  16 Aug 2009 14:11:43 -0000
***************
*** 1284,1293 ****
  
                is->is_gre.gs_flags = gre->gr_flags;
                is->is_gre.gs_ptype = gre->gr_ptype;
!               if (GRE_REV(is->is_gre.gs_flags) == 1) {
!                       is->is_call[0] = fin->fin_data[0];
!                       is->is_call[1] = fin->fin_data[1];
!               }
                break;
  
        case IPPROTO_TCP :
--- 1284,1290 ----
  
                is->is_gre.gs_flags = gre->gr_flags;
                is->is_gre.gs_ptype = gre->gr_ptype;
!               is->is_call = fin->fin_datum;
                break;
  
        case IPPROTO_TCP :
***************
*** 2812,2825 ****
                fin->fin_flx |= oow;
                break;
  
- #if 0
        case IPPROTO_GRE :
!               gre = fin->fin_dp;
!               if (GRE_REV(gre->gr_flags) == 1) {
!                       hv += gre->gr_call;
!               }
                /* FALLTHROUGH */
- #endif
        default :
                ifqp = NULL;
                hvm = DOUBLE_HASH(hv);
--- 2809,2817 ----
                fin->fin_flx |= oow;
                break;
  
        case IPPROTO_GRE :
!               hv += fin->fin_datum;
                /* FALLTHROUGH */
        default :
                ifqp = NULL;
                hvm = DOUBLE_HASH(hv);
Index: lib/printstate.c
===================================================================
RCS file: /devel/CVS/IP-Filter/lib/printstate.c,v
retrieving revision 1.11.2.13
diff -c -r1.11.2.13 printstate.c
*** lib/printstate.c    9 Sep 2007 11:32:13 -0000       1.11.2.13
--- lib/printstate.c    16 Aug 2009 14:11:45 -0000
***************
*** 51,58 ****
                PRINTF(" %hu -> %hu\n", ntohs(sp->is_sport),
                        ntohs(sp->is_dport));
        } else if (sp->is_p == IPPROTO_GRE) {
!               PRINTF(" call %hx/%hx\n", ntohs(sp->is_gre.gs_call[0]),
!                      ntohs(sp->is_gre.gs_call[1]));
        } else if (sp->is_p == IPPROTO_ICMP
  #ifdef        USE_INET6
                 || sp->is_p == IPPROTO_ICMPV6
--- 51,57 ----
                PRINTF(" %hu -> %hu\n", ntohs(sp->is_sport),
                        ntohs(sp->is_dport));
        } else if (sp->is_p == IPPROTO_GRE) {
!               PRINTF(" call %x\n", ntohl(sp->is_gre.gs_call));
        } else if (sp->is_p == IPPROTO_ICMP
  #ifdef        USE_INET6
                 || sp->is_p == IPPROTO_ICMPV6

Reply via email to