[ipfilter-cvs] ipfilter ip_fil.h, v5-1-RELEASE ip_ftp_pxy.c, v5-1-RELEASE ip_proxy.c, v5-1-RELEASE
Brought to you by:
darren_r
From: Darren <dar...@us...> - 2012-07-20 08:18:56
|
Update of /cvsroot/ipfilter/ipfilter In directory vz-cvs-4.sog:/tmp/cvs-serv30074 Modified Files: Tag: v5-1-RELEASE ip_fil.h ip_ftp_pxy.c ip_proxy.c ip_proxy.h ip_rcmd_pxy.c ip_tftp_pxy.c Log Message: 3545324 proxy checksum calculation is not hardware aware 3545321 FTP sequence number adjustment incorrectly applied 3545320 EPSV is not recognised 3545319 move nat rule creation to ip_proxy.c 3545317 better feedback of checksum requirements for proxies 3545314 ftp proxy levels do not make sense 3545312 EPRT is not supported by ftp proxy Index: ip_proxy.c =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_proxy.c,v retrieving revision 1.16.2.15 retrieving revision 1.16.2.16 diff -C2 -d -r1.16.2.15 -r1.16.2.16 *** ip_proxy.c 13 Jul 2012 06:39:03 -0000 1.16.2.15 --- ip_proxy.c 20 Jul 2012 08:18:53 -0000 1.16.2.16 *************** *** 120,124 **** static ipftuneable_t ipf_proxy_tuneables[] = { { { (void *)offsetof(ipf_proxy_softc_t, ips_proxy_debug) }, ! "ips_proxy_debug", 0, 10, stsizeof(ipf_proxy_softc_t, ips_proxy_debug), 0, NULL, NULL }, --- 120,124 ---- static ipftuneable_t ipf_proxy_tuneables[] = { { { (void *)offsetof(ipf_proxy_softc_t, ips_proxy_debug) }, ! "proxy_debug", 0, 0x1f, stsizeof(ipf_proxy_softc_t, ips_proxy_debug), 0, NULL, NULL }, *************** *** 565,569 **** !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { ! if (softp->ips_proxy_debug > 1) printf("ipf_proxy_add: %s/%d present (B)\n", a->apr_label, a->apr_p); --- 565,569 ---- !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { ! if (softp->ips_proxy_debug & 0x01) printf("ipf_proxy_add: %s/%d present (B)\n", a->apr_label, a->apr_p); *************** *** 575,579 **** !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { ! if (softp->ips_proxy_debug > 1) printf("ipf_proxy_add: %s/%d present (D)\n", a->apr_label, a->apr_p); --- 575,579 ---- !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { ! if (softp->ips_proxy_debug & 0x01) printf("ipf_proxy_add: %s/%d present (D)\n", a->apr_label, a->apr_p); *************** *** 611,615 **** a = ipf_proxy_lookup(arg, ctl->apc_p, ctl->apc_label); if (a == NULL) { ! if (softp->ips_proxy_debug > 1) printf("ipf_proxy_ctl: can't find %s/%d\n", ctl->apc_label, ctl->apc_p); --- 611,615 ---- a = ipf_proxy_lookup(arg, ctl->apc_p, ctl->apc_label); if (a == NULL) { ! if (softp->ips_proxy_debug & 0x01) printf("ipf_proxy_ctl: can't find %s/%d\n", ctl->apc_label, ctl->apc_p); *************** *** 617,621 **** error = ESRCH; } else if (a->apr_ctl == NULL) { ! if (softp->ips_proxy_debug > 1) printf("ipf_proxy_ctl: no ctl function for %s/%d\n", ctl->apc_label, ctl->apc_p); --- 617,621 ---- error = ESRCH; } else if (a->apr_ctl == NULL) { ! if (softp->ips_proxy_debug & 0x01) printf("ipf_proxy_ctl: no ctl function for %s/%d\n", ctl->apc_label, ctl->apc_p); *************** *** 624,628 **** } else { error = (*a->apr_ctl)(softc, a->apr_soft, ctl); ! if ((error != 0) && (softp->ips_proxy_debug > 1)) printf("ipf_proxy_ctl: %s/%d ctl error %d\n", a->apr_label, a->apr_p, error); --- 624,628 ---- } else { error = (*a->apr_ctl)(softc, a->apr_soft, ctl); ! if ((error != 0) && (softp->ips_proxy_debug & 0x02)) printf("ipf_proxy_ctl: %s/%d ctl error %d\n", a->apr_label, a->apr_p, error); *************** *** 781,785 **** ipn = nat->nat_ptr; ! if (softp->ips_proxy_debug > 8) printf("ipf_proxy_match(%lx,%lx) aps %lx ptr %lx\n", (u_long)fin, (u_long)nat, (u_long)nat->nat_aps, --- 781,785 ---- ipn = nat->nat_ptr; ! if (softp->ips_proxy_debug & 0x04) printf("ipf_proxy_match(%lx,%lx) aps %lx ptr %lx\n", (u_long)fin, (u_long)nat, (u_long)nat->nat_aps, *************** *** 787,791 **** if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) { ! if (softp->ips_proxy_debug > 0) printf("ipf_proxy_match: flx 0x%x (BAD|SHORT)\n", fin->fin_flx); --- 787,791 ---- if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_match: flx 0x%x (BAD|SHORT)\n", fin->fin_flx); *************** *** 795,799 **** apr = ipn->in_apr; if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) { ! if (softp->ips_proxy_debug > 0) printf("ipf_proxy_match:apr %lx apr_flags 0x%x\n", (u_long)apr, apr ? apr->apr_flags : 0); --- 795,799 ---- apr = ipn->in_apr; if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_match:apr %lx apr_flags 0x%x\n", (u_long)apr, apr ? apr->apr_flags : 0); *************** *** 804,808 **** result = (*apr->apr_match)(fin, nat->nat_aps, nat); if (result != 0) { ! if (softp->ips_proxy_debug > 4) printf("ipf_proxy_match: result %d\n", result); return -1; --- 804,808 ---- result = (*apr->apr_match)(fin, nat->nat_aps, nat); if (result != 0) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_match: result %d\n", result); return -1; *************** *** 833,841 **** aproxy_t *apr; ! if (softp->ips_proxy_debug > 8) printf("ipf_proxy_new(%lx,%lx) \n", (u_long)fin, (u_long)nat); if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) { ! if (softp->ips_proxy_debug > 0) printf("ipf_proxy_new: nat_ptr %lx nat_aps %lx\n", (u_long)nat->nat_ptr, (u_long)nat->nat_aps); --- 833,841 ---- aproxy_t *apr; ! if (softp->ips_proxy_debug & 0x04) printf("ipf_proxy_new(%lx,%lx) \n", (u_long)fin, (u_long)nat); if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_new: nat_ptr %lx nat_aps %lx\n", (u_long)nat->nat_ptr, (u_long)nat->nat_aps); *************** *** 847,851 **** if ((apr->apr_flags & APR_DELETE) || (fin->fin_p != apr->apr_p)) { ! if (softp->ips_proxy_debug > 2) printf("ipf_proxy_new: apr_flags 0x%x p %d/%d\n", apr->apr_flags, fin->fin_p, apr->apr_p); --- 847,851 ---- if ((apr->apr_flags & APR_DELETE) || (fin->fin_p != apr->apr_p)) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_new: apr_flags 0x%x p %d/%d\n", apr->apr_flags, fin->fin_p, apr->apr_p); *************** *** 855,859 **** KMALLOC(aps, ap_session_t *); if (!aps) { ! if (softp->ips_proxy_debug > 0) printf("ipf_proxy_new: malloc failed (%lu)\n", (u_long)sizeof(ap_session_t)); --- 855,859 ---- KMALLOC(aps, ap_session_t *); if (!aps) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_new: malloc failed (%lu)\n", (u_long)sizeof(ap_session_t)); *************** *** 871,875 **** } KFREE(aps); ! if (softp->ips_proxy_debug > 2) printf("ipf_proxy_new: new(%lx) failed\n", (u_long)apr->apr_new); --- 871,875 ---- } KFREE(aps); ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_new: new(%lx) failed\n", (u_long)apr->apr_new); *************** *** 920,925 **** if (fin->fin_flx & FI_BAD) { ! if (softp->ips_proxy_debug > 0) ! printf("ipf_proxy_check: flx 0x%x (BAD)\n", fin->fin_flx); return -1; } --- 920,926 ---- if (fin->fin_flx & FI_BAD) { ! if (softp->ips_proxy_debug & 0x08) ! printf("ipf_proxy_check: flx 0x%x (BAD)\n", ! fin->fin_flx); return -1; } *************** *** 927,931 **** #ifndef IPFILTER_CKSUM if ((fin->fin_out == 0) && (ipf_checkl4sum(fin) == -1)) { ! if (softp->ips_proxy_debug > 0) printf("ipf_proxy_check: l4 checksum failure %d\n", fin->fin_p); --- 928,932 ---- #ifndef IPFILTER_CKSUM if ((fin->fin_out == 0) && (ipf_checkl4sum(fin) == -1)) { ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_check: l4 checksum failure %d\n", fin->fin_p); *************** *** 945,950 **** if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE)) if (ipf_coalesce(fin) == -1) { ! if (softp->ips_proxy_debug > 0) ! printf("ipf_proxy_check: coalesce failed %x\n", fin->fin_flx); return -1; } --- 946,952 ---- if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE)) if (ipf_coalesce(fin) == -1) { ! if (softp->ips_proxy_debug & 0x08) ! printf("ipf_proxy_check: %s %x\n", ! "coalesce failed", fin->fin_flx); return -1; } *************** *** 986,991 **** rv = APR_EXIT(err); ! if (((softp->ips_proxy_debug > 0) && (rv != 0)) || ! (softp->ips_proxy_debug > 8)) printf("ipf_proxy_check: out %d err %x rv %d\n", fin->fin_out, err, rv); --- 988,993 ---- rv = APR_EXIT(err); ! if (((softp->ips_proxy_debug & 0x08) && (rv != 0)) || ! (softp->ips_proxy_debug & 0x04)) printf("ipf_proxy_check: out %d err %x rv %d\n", fin->fin_out, err, rv); *************** *** 1004,1015 **** * packet. */ ! adjlen = err & 0xffff; #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) s1 = LONG_SUM(fin->fin_plen - adjlen); s2 = LONG_SUM(fin->fin_plen); CALC_SUMD(s1, s2, sd); ! if ((err != 0) && (fin->fin_cksum < FI_CK_L4PART)) ipf_fix_outcksum(0, &ip->ip_sum, sd, 0); #endif /* --- 1006,1020 ---- * packet. */ ! adjlen = APR_INC(err); #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) s1 = LONG_SUM(fin->fin_plen - adjlen); s2 = LONG_SUM(fin->fin_plen); CALC_SUMD(s1, s2, sd); ! if ((err != 0) && (fin->fin_cksum < FI_CK_L4PART) && ! fin->fin_v == 4) ipf_fix_outcksum(0, &ip->ip_sum, sd, 0); #endif + if (fin->fin_flx & FI_DOCKSUM) + dosum = 1; /* *************** *** 1023,1043 **** */ if (tcp != NULL) { ! err = ipf_proxy_fixseqack(fin, ip, aps, APR_INC(err)); ! if (dosum) { ! tcp->th_sum = fr_cksum(fin, ip, ! IPPROTO_TCP, tcp); ! } else if (fin->fin_cksum == FI_CK_L4PART) { u_short sum = ntohs(tcp->th_sum); sum += adjlen; tcp->th_sum = htons(sum); } } else if ((udp != NULL) && (udp->uh_sum != 0)) { ! if (dosum) { ! udp->uh_sum = fr_cksum(fin, ip, ! IPPROTO_UDP, udp); ! } else if (fin->fin_cksum == FI_CK_L4PART) { u_short sum = ntohs(udp->uh_sum); sum += adjlen; udp->uh_sum = htons(sum); } } --- 1028,1048 ---- */ if (tcp != NULL) { ! err = ipf_proxy_fixseqack(fin, ip, aps, adjlen); ! if (fin->fin_cksum == FI_CK_L4PART) { u_short sum = ntohs(tcp->th_sum); sum += adjlen; tcp->th_sum = htons(sum); + } else if (fin->fin_cksum < FI_CK_L4PART) { + tcp->th_sum = fr_cksum(fin, ip, + IPPROTO_TCP, tcp); } } else if ((udp != NULL) && (udp->uh_sum != 0)) { ! if (fin->fin_cksum == FI_CK_L4PART) { u_short sum = ntohs(udp->uh_sum); sum += adjlen; udp->uh_sum = htons(sum); + } else if (dosum) { + udp->uh_sum = fr_cksum(fin, ip, + IPPROTO_UDP, udp); } } *************** *** 1068,1072 **** aproxy_t *ap; ! if (softp->ips_proxy_debug > 8) printf("ipf_proxy_lookup(%d,%s)\n", pr, name); --- 1073,1077 ---- aproxy_t *ap; ! if (softp->ips_proxy_debug & 0x04) printf("ipf_proxy_lookup(%d,%s)\n", pr, name); *************** *** 1078,1082 **** } ! if (softp->ips_proxy_debug > 2) printf("ipf_proxy_lookup: failed for %d/%s\n", pr, name); return NULL; --- 1083,1087 ---- } ! if (softp->ips_proxy_debug & 0x08) printf("ipf_proxy_lookup: failed for %d/%s\n", pr, name); return NULL; *************** *** 1169,1174 **** * ip_len has already been adjusted by 'inc'. */ ! nlen = fin->fin_plen; ! nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2); inc2 = inc; --- 1174,1179 ---- * ip_len has already been adjusted by 'inc'. */ ! nlen = fin->fin_dlen; ! nlen -= (TCP_OFF(tcp) << 2); inc2 = inc; *************** *** 1182,1186 **** if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { ! if (softp->ips_proxy_debug > 7) printf("proxy out switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, --- 1187,1191 ---- if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { ! if (softp->ips_proxy_debug & 0x10) printf("proxy out switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, *************** *** 1202,1206 **** aps->aps_seqmin[sel] = seq1 + nlen - 1; aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc; ! if (softp->ips_proxy_debug > 7) printf("proxy seq set %d at %x to %d + %d\n", sel, aps->aps_seqmin[sel], --- 1207,1211 ---- aps->aps_seqmin[sel] = seq1 + nlen - 1; aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc; ! if (softp->ips_proxy_debug & 0x10) printf("proxy seq set %d at %x to %d + %d\n", sel, aps->aps_seqmin[sel], *************** *** 1216,1220 **** if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { ! if (softp->ips_proxy_debug > 7) printf("proxy out switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, --- 1221,1225 ---- if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { ! if (softp->ips_proxy_debug & 0x10) printf("proxy out switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, *************** *** 1235,1239 **** if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { ! if (softp->ips_proxy_debug > 7) printf("proxy in switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_ackmin[!sel]); --- 1240,1244 ---- if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { ! if (softp->ips_proxy_debug & 0x10) printf("proxy in switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_ackmin[!sel]); *************** *** 1255,1259 **** aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; ! if (softp->ips_proxy_debug > 7) printf("proxy ack set %d at %x to %d + %d\n", !sel, aps->aps_seqmin[!sel], --- 1260,1264 ---- aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; ! if (softp->ips_proxy_debug & 0x10) printf("proxy ack set %d at %x to %d + %d\n", !sel, aps->aps_seqmin[!sel], *************** *** 1269,1273 **** if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { ! if (softp->ips_proxy_debug > 7) printf("proxy in switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_seqmin[!sel]); --- 1274,1278 ---- if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { ! if (softp->ips_proxy_debug & 0x10) printf("proxy in switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_seqmin[!sel]); *************** *** 1276,1280 **** if (aps->aps_seqoff[sel] != 0) { ! if (softp->ips_proxy_debug > 7) printf("sel %d seqoff %d seq1 %x seqmin %x\n", sel, aps->aps_seqoff[sel], seq1, --- 1281,1285 ---- if (aps->aps_seqoff[sel] != 0) { ! if (softp->ips_proxy_debug & 0x10) printf("sel %d seqoff %d seq1 %x seqmin %x\n", sel, aps->aps_seqoff[sel], seq1, *************** *** 1288,1294 **** } ! if (softp->ips_proxy_debug > 8) ! printf("ipf_proxy_fixseqack: seq %x ack %x\n", (u_32_t)ntohl(tcp->th_seq), (u_32_t)ntohl(tcp->th_ack)); return ch ? 2 : 0; } --- 1293,1466 ---- } ! if (softp->ips_proxy_debug & 0x10) ! printf("ipf_proxy_fixseqack: seq %u ack %u\n", (u_32_t)ntohl(tcp->th_seq), (u_32_t)ntohl(tcp->th_ack)); return ch ? 2 : 0; } + + + /* ------------------------------------------------------------------------ */ + /* Function: ipf_proxy_rule_rev */ + /* Returns: ipnat_t * - NULL = failure, else pointer to new rule */ + /* Parameters: nat(I) - pointer to NAT session to create rule from */ + /* */ + /* This function creates a NAT rule that is based upon the reverse packet */ + /* flow associated with this NAT session. Thus if this NAT session was */ + /* created with a map rule then this function will create a rdr rule. */ + /* Only address fields and network interfaces are assigned in this function */ + /* and the address fields are formed such that an exact is required. If the */ + /* original rule had a netmask, that is not replicated here not is it */ + /* desired. The ultimate goal here is to create a NAT rule to support a NAT */ + /* session being created that does not have a user configured rule. The */ + /* classic example is supporting the FTP proxy, where a data channel needs */ + /* to be setup, based on the addresses used for the control connection. In */ + /* that case, this function is used to handle creating NAT rules to support */ + /* data connections with the PORT and EPRT commands. */ + /* ------------------------------------------------------------------------ */ + ipnat_t * + ipf_proxy_rule_rev(nat) + nat_t *nat; + { + ipnat_t *old; + ipnat_t *ipn; + int size; + + old = nat->nat_ptr; + size = old->in_size; + + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) + return NULL; + + bzero((char *)ipn, size); + + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + ipn->in_apr = NULL; + ipn->in_size = size; + ipn->in_pr[0] = old->in_pr[1]; + ipn->in_pr[1] = old->in_pr[0]; + ipn->in_v[0] = old->in_v[1]; + ipn->in_v[1] = old->in_v[0]; + ipn->in_ifps[0] = old->in_ifps[1]; + ipn->in_ifps[1] = old->in_ifps[0]; + ipn->in_flags = (old->in_flags | IPN_PROXYRULE); + + ipn->in_nsrcip6 = nat->nat_odst6; + ipn->in_osrcip6 = nat->nat_ndst6; + + if ((old->in_redir & NAT_REDIRECT) != 0) { + ipn->in_redir = NAT_MAP; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_nsrcaddr); + } else { + #ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_nsrc6; + #endif + } + ipn->in_ndstip6 = nat->nat_nsrc6; + ipn->in_odstip6 = nat->nat_osrc6; + } else { + ipn->in_redir = NAT_REDIRECT; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_osrcaddr); + } else { + #ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_osrc6; + #endif + } + ipn->in_ndstip6 = nat->nat_osrc6; + ipn->in_odstip6 = nat->nat_nsrc6; + } + + IP6_SETONES(&ipn->in_osrcmsk6); + IP6_SETONES(&ipn->in_nsrcmsk6); + IP6_SETONES(&ipn->in_odstmsk6); + IP6_SETONES(&ipn->in_ndstmsk6); + + ipn->in_namelen = old->in_namelen; + ipn->in_ifnames[0] = old->in_ifnames[1]; + ipn->in_ifnames[1] = old->in_ifnames[0]; + bcopy(old->in_names, ipn->in_names, ipn->in_namelen); + MUTEX_INIT(&ipn->in_lock, "ipnat rev rule lock"); + + return ipn; + } + + + /* ------------------------------------------------------------------------ */ + /* Function: ipf_proxy_rule_fwd */ + /* Returns: ipnat_t * - NULL = failure, else pointer to new rule */ + /* Parameters: nat(I) - pointer to NAT session to create rule from */ + /* */ + /* The purpose and rationale of this function is much the same as the above */ + /* function, ipf_proxy_rule_rev, except that a rule is created that matches */ + /* the same direction as that of the existing NAT session. Thus if this NAT */ + /* session was created with a map rule then this function will also create */ + /* a data structure to represent a map rule. Whereas ipf_proxy_rule_rev is */ + /* used to support PORT/EPRT, this function supports PASV/EPSV. */ + /* ------------------------------------------------------------------------ */ + ipnat_t * + ipf_proxy_rule_fwd(nat) + nat_t *nat; + { + ipnat_t *old; + ipnat_t *ipn; + int size; + + old = nat->nat_ptr; + size = old->in_size; + + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) + return NULL; + + bzero((char *)ipn, size); + + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + ipn->in_apr = NULL; + ipn->in_size = size; + ipn->in_pr[0] = old->in_pr[0]; + ipn->in_pr[1] = old->in_pr[1]; + ipn->in_v[0] = old->in_v[0]; + ipn->in_v[1] = old->in_v[1]; + ipn->in_ifps[0] = nat->nat_ifps[0]; + ipn->in_ifps[1] = nat->nat_ifps[1]; + ipn->in_flags = (old->in_flags | IPN_PROXYRULE); + + ipn->in_nsrcip6 = nat->nat_nsrc6; + ipn->in_osrcip6 = nat->nat_osrc6; + ipn->in_ndstip6 = nat->nat_ndst6; + ipn->in_odstip6 = nat->nat_odst6; + ipn->in_redir = old->in_redir; + + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_nsrcaddr); + ipn->in_dnip = ntohl(nat->nat_ndstaddr); + } else { + #ifdef USE_INET6 + ipn->in_snip6 = nat->nat_nsrc6; + ipn->in_dnip6 = nat->nat_ndst6; + #endif + } + + IP6_SETONES(&ipn->in_osrcmsk6); + IP6_SETONES(&ipn->in_nsrcmsk6); + IP6_SETONES(&ipn->in_odstmsk6); + IP6_SETONES(&ipn->in_ndstmsk6); + + ipn->in_namelen = old->in_namelen; + ipn->in_ifnames[0] = old->in_ifnames[0]; + ipn->in_ifnames[1] = old->in_ifnames[1]; + bcopy(old->in_names, ipn->in_names, ipn->in_namelen); + MUTEX_INIT(&ipn->in_lock, "ipnat fwd rule lock"); + + return ipn; + } Index: ip_tftp_pxy.c =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_tftp_pxy.c,v retrieving revision 1.1.2.7 retrieving revision 1.1.2.8 diff -C2 -d -r1.1.2.7 -r1.1.2.8 *** ip_tftp_pxy.c 13 Jul 2012 12:25:35 -0000 1.1.2.7 --- ip_tftp_pxy.c 20 Jul 2012 08:18:53 -0000 1.1.2.8 *************** *** 200,237 **** ipn->in_size = size; - ipn->in_ifps[0] = nat->nat_ifps[0]; - ipn->in_ifps[1] = nat->nat_ifps[1]; ipn->in_apr = NULL; ipn->in_use = 1; ipn->in_hits = 1; ipn->in_ippip = 1; if ((np->in_redir & NAT_REDIRECT) != 0) { ipn->in_redir = NAT_MAP; ! ipn->in_snip = ntohl(nat->nat_odstaddr); ! ipn->in_nsrcaddr = nat->nat_odstaddr; ! ipn->in_dnip = ntohl(nat->nat_nsrcaddr); ! ipn->in_ndstaddr = nat->nat_nsrcaddr; ! ipn->in_osrcaddr = nat->nat_ndstaddr; ! ipn->in_odstaddr = nat->nat_osrcaddr; } else { ipn->in_redir = NAT_REDIRECT; ! ipn->in_snip = ntohl(nat->nat_odstaddr); ! ipn->in_nsrcaddr = nat->nat_odstaddr; ! ipn->in_dnip = ntohl(nat->nat_osrcaddr); ! ipn->in_ndstaddr = nat->nat_osrcaddr; ! ipn->in_osrcaddr = nat->nat_ndstaddr; ! ipn->in_odstaddr = nat->nat_nsrcaddr; } ipn->in_odport = htons(fin->fin_sport); ipn->in_ndport = htons(fin->fin_sport); ! ipn->in_osrcmsk = 0xffffffff; ! ipn->in_nsrcmsk = 0xffffffff; ! ipn->in_odstmsk = 0xffffffff; ! ipn->in_ndstmsk = 0xffffffff; ! ipn->in_pr[0] = IPPROTO_UDP; ! ipn->in_pr[1] = IPPROTO_UDP; ! ipn->in_flags = IPN_UDP|IPN_FIXEDDPORT|IPN_PROXYRULE; MUTEX_INIT(&ipn->in_lock, "tftp proxy NAT rule"); --- 200,252 ---- ipn->in_size = size; ipn->in_apr = NULL; ipn->in_use = 1; ipn->in_hits = 1; ipn->in_ippip = 1; + ipn->in_pr[0] = IPPROTO_UDP; + ipn->in_pr[1] = IPPROTO_UDP; + ipn->in_ifps[0] = nat->nat_ifps[0]; + ipn->in_ifps[1] = nat->nat_ifps[1]; + ipn->in_v[0] = nat->nat_ptr->in_v[1]; + ipn->in_v[1] = nat->nat_ptr->in_v[0]; + ipn->in_flags = IPN_UDP|IPN_FIXEDDPORT|IPN_PROXYRULE; + + ipn->in_nsrcip6 = nat->nat_odst6; + ipn->in_osrcip6 = nat->nat_ndst6; if ((np->in_redir & NAT_REDIRECT) != 0) { ipn->in_redir = NAT_MAP; ! if (ipn->in_v[0] == 4) { ! ipn->in_snip = ntohl(nat->nat_odstaddr); ! ipn->in_dnip = ntohl(nat->nat_nsrcaddr); ! } else { ! #ifdef USE_INET6 ! ipn->in_snip6 = nat->nat_odst6; ! ipn->in_dnip6 = nat->nat_nsrc6; ! #endif ! } ! ipn->in_ndstip6 = nat->nat_nsrc6; ! ipn->in_odstip6 = nat->nat_osrc6; } else { ipn->in_redir = NAT_REDIRECT; ! if (ipn->in_v[0] == 4) { ! ipn->in_snip = ntohl(nat->nat_odstaddr); ! ipn->in_dnip = ntohl(nat->nat_osrcaddr); ! } else { ! #ifdef USE_INET6 ! ipn->in_snip6 = nat->nat_odst6; ! ipn->in_dnip6 = nat->nat_osrc6; ! #endif ! } ! ipn->in_ndstip6 = nat->nat_osrc6; ! ipn->in_odstip6 = nat->nat_nsrc6; } ipn->in_odport = htons(fin->fin_sport); ipn->in_ndport = htons(fin->fin_sport); ! IP6_SETONES(&ipn->in_osrcmsk6); ! IP6_SETONES(&ipn->in_nsrcmsk6); ! IP6_SETONES(&ipn->in_odstmsk6); ! IP6_SETONES(&ipn->in_ndstmsk6); MUTEX_INIT(&ipn->in_lock, "tftp proxy NAT rule"); *************** *** 275,279 **** ipf_nat_softc_t *softn = softc->ipf_nat_soft; #endif ! struct in_addr swip,swip2; tftpinfo_t *ti; udphdr_t udp; --- 290,298 ---- ipf_nat_softc_t *softn = softc->ipf_nat_soft; #endif ! #ifdef USE_INET6 ! i6addr_t swip6, sw2ip6; ! ip6_t *ip6; ! #endif ! struct in_addr swip, sw2ip; tftpinfo_t *ti; udphdr_t udp; *************** *** 294,303 **** fi.fin_data[1] = 0; - ip = fin->fin_ip; - slen = ip->ip_len; - swip = ip->ip_src; - swip2 = ip->ip_dst; - - ip->ip_len = htons(fin->fin_hlen + sizeof(udp)); bzero((char *)&udp, sizeof(udp)); udp.uh_sport = 0; /* XXX - don't specify remote port */ --- 313,316 ---- *************** *** 305,321 **** udp.uh_ulen = htons(sizeof(udp)); udp.uh_sum = 0; ! fi.fin_dp = (char *)&udp; fi.fin_fr = &tftpfr; ! fi.fin_dport = ntohs(ti->ti_rule->in_ndport); fi.fin_sport = 0; fi.fin_dlen = sizeof(udp); fi.fin_plen = fi.fin_hlen + sizeof(udp); fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; nflags = NAT_SLAVE|IPN_UDP|SI_W_SPORT; ! fi.fin_fi.fi_saddr = nat->nat_ndstaddr; ! ip->ip_src = nat->nat_ndstip; ! fi.fin_fi.fi_daddr = nat->nat_nsrcaddr; ! ip->ip_dst = nat->nat_nsrcip; if (nat->nat_dir == NAT_INBOUND) { --- 318,356 ---- udp.uh_ulen = htons(sizeof(udp)); udp.uh_sum = 0; ! fi.fin_fr = &tftpfr; ! fi.fin_dp = (char *)&udp; fi.fin_sport = 0; + fi.fin_dport = ntohs(ti->ti_rule->in_ndport); fi.fin_dlen = sizeof(udp); fi.fin_plen = fi.fin_hlen + sizeof(udp); fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; nflags = NAT_SLAVE|IPN_UDP|SI_W_SPORT; + #ifdef USE_INET6 + ip6 = (ip6_t *)fin->fin_ip; + #endif + ip = fin->fin_ip; + sw2ip.s_addr = 0; + swip.s_addr = 0; ! fi.fin_src6 = nat->nat_ndst6; ! fi.fin_dst6 = nat->nat_nsrc6; ! if (nat->nat_v[0] == 4) { ! slen = ip->ip_len; ! ip->ip_len = htons(fin->fin_hlen + sizeof(udp)); ! swip = ip->ip_src; ! sw2ip = ip->ip_dst; ! ip->ip_src = nat->nat_ndstip; ! ip->ip_dst = nat->nat_nsrcip; ! } else { ! #ifdef USE_INET6 ! slen = ip6->ip6_plen; ! ip6->ip6_plen = htons(sizeof(udp)); ! swip6.in6 = ip6->ip6_src; ! sw2ip6.in6 = ip6->ip6_dst; ! ip6->ip6_src = nat->nat_ndst6.in6; ! ip6->ip6_dst = nat->nat_nsrc6.in6; ! #endif ! } if (nat->nat_dir == NAT_INBOUND) { *************** *** 329,333 **** MUTEX_ENTER(&softn->ipf_nat_new); ! nat2 = ipf_nat_add(&fi, ti->ti_rule, NULL, nflags, dir); MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { --- 364,371 ---- MUTEX_ENTER(&softn->ipf_nat_new); ! if (nat->nat_v[0] == 4) ! nat2 = ipf_nat_add(&fi, ti->ti_rule, NULL, nflags, dir); ! else ! nat2 = ipf_nat6_add(&fi, ti->ti_rule, NULL, nflags, dir); MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { *************** *** 336,348 **** fi.fin_ifp = NULL; if (ti->ti_rule->in_redir == NAT_MAP) { ! fi.fin_fi.fi_saddr = nat->nat_ndstaddr; ! ip->ip_src = nat->nat_ndstip; ! fi.fin_fi.fi_daddr = nat->nat_nsrcaddr; ! ip->ip_dst = nat->nat_nsrcip; } else { ! fi.fin_fi.fi_saddr = nat->nat_odstaddr; ! ip->ip_src = nat->nat_odstip; ! fi.fin_fi.fi_daddr = nat->nat_osrcaddr; ! ip->ip_dst = nat->nat_osrcip; } if (ipf_state_add(softc, &fi, NULL, SI_W_SPORT) != 0) { --- 374,400 ---- fi.fin_ifp = NULL; if (ti->ti_rule->in_redir == NAT_MAP) { ! fi.fin_src6 = nat->nat_ndst6; ! fi.fin_dst6 = nat->nat_nsrc6; ! if (nat->nat_v[0] == 4) { ! ip->ip_src = nat->nat_ndstip; ! ip->ip_dst = nat->nat_nsrcip; ! } else { ! #ifdef USE_INET6 ! ip6->ip6_src = nat->nat_ndst6.in6; ! ip6->ip6_dst = nat->nat_nsrc6.in6; ! #endif ! } } else { ! fi.fin_src6 = nat->nat_odst6; ! fi.fin_dst6 = nat->nat_osrc6; ! if (fin->fin_v == 4) { ! ip->ip_src = nat->nat_odstip; ! ip->ip_dst = nat->nat_osrcip; ! } else { ! #ifdef USE_INET6 ! ip6->ip6_src = nat->nat_odst6.in6; ! ip6->ip6_dst = nat->nat_osrc6.in6; ! #endif ! } } if (ipf_state_add(softc, &fi, NULL, SI_W_SPORT) != 0) { *************** *** 350,356 **** } } ! ip->ip_len = slen; ! ip->ip_src = swip; ! ip->ip_dst = swip2; return 0; } --- 402,416 ---- } } ! if (nat->nat_v[0] == 4) { ! ip->ip_len = slen; ! ip->ip_src = swip; ! ip->ip_dst = sw2ip; ! } else { ! #ifdef USE_INET6 ! ip6->ip6_plen = slen; ! ip6->ip6_src = swip6.in6; ! ip6->ip6_dst = sw2ip6.in6; ! #endif ! } return 0; } Index: ip_proxy.h =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_proxy.h,v retrieving revision 1.7.2.7 retrieving revision 1.7.2.8 diff -C2 -d -r1.7.2.7 -r1.7.2.8 *** ip_proxy.h 13 Jul 2012 06:39:03 -0000 1.7.2.7 --- ip_proxy.h 20 Jul 2012 08:18:53 -0000 1.7.2.8 *************** *** 451,454 **** --- 451,456 ---- extern int ipf_proxy_main_load __P((void)); extern int ipf_proxy_main_unload __P((void)); + extern ipnat_t *ipf_proxy_rule_fwd __P((nat_t *)); + extern ipnat_t *ipf_proxy_rule_rev __P((nat_t *)); extern void *ipf_proxy_soft_create __P((ipf_main_softc_t *)); extern void ipf_proxy_soft_destroy __P((ipf_main_softc_t *, void *)); Index: ip_rcmd_pxy.c =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_rcmd_pxy.c,v retrieving revision 1.17.2.6 retrieving revision 1.17.2.7 diff -C2 -d -r1.17.2.6 -r1.17.2.7 *** ip_rcmd_pxy.c 13 Jul 2012 12:25:35 -0000 1.17.2.6 --- ip_rcmd_pxy.c 20 Jul 2012 08:18:53 -0000 1.17.2.7 *************** *** 86,91 **** return -1; } ! KMALLOCS(ipn, ipnat_t *, size); if (ipn == NULL) { KFREE(rc); --- 86,93 ---- return -1; } + aps->aps_sport = tcp->th_sport; + aps->aps_dport = tcp->th_dport; ! ipn = ipf_proxy_rule_rev(nat); if (ipn == NULL) { KFREE(rc); *************** *** 96,144 **** aps->aps_psiz = sizeof(*rc); bzero((char *)rc, sizeof(*rc)); - bzero((char *)ipn, size); - rc->rcmd_rule = ipn; - - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - - ipn->in_size = size; - ipn->in_ifps[0] = nat->nat_ifps[0]; - ipn->in_ifps[1] = nat->nat_ifps[1]; - ipn->in_apr = NULL; - ipn->in_use = 1; - ipn->in_hits = 1; - ipn->in_ippip = 1; - - if ((np->in_redir & NAT_REDIRECT) != 0) { - ipn->in_redir = NAT_MAP; - ipn->in_snip = ntohl(nat->nat_odstaddr); - ipn->in_nsrcaddr = nat->nat_odstaddr; - ipn->in_dnip = ntohl(nat->nat_nsrcaddr); - ipn->in_ndstaddr = nat->nat_nsrcaddr; - ipn->in_osrcaddr = nat->nat_ndstaddr; - ipn->in_odstaddr = nat->nat_osrcaddr; - } else { - ipn->in_redir = NAT_REDIRECT; - ipn->in_snip = ntohl(nat->nat_odstaddr); - ipn->in_nsrcaddr = nat->nat_odstaddr; - ipn->in_dnip = ntohl(nat->nat_osrcaddr); - ipn->in_ndstaddr = nat->nat_osrcaddr; - ipn->in_osrcaddr = nat->nat_ndstaddr; - ipn->in_odstaddr = nat->nat_nsrcaddr; - } - - ipn->in_osrcmsk = 0xffffffff; - ipn->in_nsrcmsk = 0xffffffff; - ipn->in_odstmsk = 0xffffffff; - ipn->in_ndstmsk = 0xffffffff; - ipn->in_pr[0] = IPPROTO_TCP; - ipn->in_pr[1] = IPPROTO_TCP; - ipn->in_flags = (np->in_flags | IPN_PROXYRULE); - MUTEX_INIT(&ipn->in_lock, "rcmd proxy NAT rule"); ! ipn->in_namelen = np->in_namelen; ! bcopy(np->in_names, ipn->in_ifnames, ipn->in_namelen); ! ipn->in_ifnames[0] = nat->nat_ptr->in_ifnames[0]; ! ipn->in_ifnames[1] = nat->nat_ptr->in_ifnames[1]; return 0; --- 98,103 ---- aps->aps_psiz = sizeof(*rc); bzero((char *)rc, sizeof(*rc)); ! rc->rcmd_rule = ipn; return 0; *************** *** 188,191 **** --- 147,151 ---- int off, dlen, nflags, direction; ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; char portbuf[8], *s; rcmdinfo_t *rc; *************** *** 193,196 **** --- 153,159 ---- u_short sp; nat_t *nat2; + ip6_t *ip6; + int tcpsz; + int slen; ip_t *ip; mb_t *m; *************** *** 200,210 **** m = fin->fin_m; ip = fin->fin_ip; ! off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; ! #ifdef __sgi ! dlen = fin->fin_plen - off; ! #else ! dlen = MSGDSIZE(m) - off; ! #endif if (dlen <= 0) return 0; --- 163,173 ---- m = fin->fin_m; ip = fin->fin_ip; ! tcpsz = TCP_OFF(tcp) << 2; ! ip6 = (ip6_t *)fin->fin_ip; ! softc = fin->fin_main_soft; ! softn = softc->ipf_nat_soft; ! off = (char *)tcp - (char *)ip + tcpsz + fin->fin_ipoff; ! dlen = fin->fin_dlen - tcpsz; if (dlen <= 0) return 0; *************** *** 249,323 **** fi.fin_data[0] = 0; fi.fin_data[1] = sp; ! fi.fin_fi.fi_saddr = nat->nat_ndstaddr; ! fi.fin_fi.fi_daddr = nat->nat_nsrcaddr; ! if (nat->nat_dir == NAT_OUTBOUND) { ! nat2 = ipf_nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[1], ! nat->nat_osrcip, nat->nat_odstip); } else { ! nat2 = ipf_nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[0], ! nat->nat_osrcip, nat->nat_odstip); } ! softc = fin->fin_main_soft; ! if (nat2 == NULL) { ! #ifdef USE_MUTEXES ! ipf_nat_softc_t *softn = softc->ipf_nat_soft; ! #endif ! ! /* ! * Add skeleton NAT entry for connection which will come ! * back the other way. ! */ ! int slen; slen = ip->ip_len; ip->ip_len = htons(fin->fin_hlen + sizeof(*tcp)); ! /* ! * Fill out the fake TCP header with a few fields that ipfilter ! * considers to be important. ! */ ! bzero((char *)tcp2, sizeof(*tcp2)); ! tcp2->th_win = htons(8192); ! TCP_OFF_A(tcp2, 5); ! tcp2->th_flags = TH_SYN; ! ! fi.fin_dp = (char *)tcp2; ! fi.fin_fr = &rcmdfr; ! fi.fin_dlen = sizeof(*tcp2); ! fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); ! if (nat->nat_dir == NAT_OUTBOUND) { ! fi.fin_out = 0; ! direction = NAT_INBOUND; ! } else { ! fi.fin_out = 1; ! direction = NAT_OUTBOUND; ! } ! nflags = SI_W_SPORT; ! fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; ! nflags |= NAT_SLAVE|IPN_TCP; ! MUTEX_ENTER(&softn->ipf_nat_new); nat2 = ipf_nat_add(&fi, rc->rcmd_rule, NULL, nflags, direction); ! MUTEX_EXIT(&softn->ipf_nat_new); ! if (nat2 != NULL) { ! (void) ipf_nat_proto(&fi, nat2, IPN_TCP); ! MUTEX_ENTER(&nat2->nat_lock); ! ipf_nat_update(&fi, nat2); ! MUTEX_EXIT(&nat2->nat_lock); ! fi.fin_ifp = NULL; ! if (nat2->nat_dir == NAT_INBOUND) ! fi.fin_fi.fi_daddr = nat->nat_osrcaddr; ! (void) ipf_state_add(softc, &fi, NULL, SI_W_SPORT); ! } ip->ip_len = slen; } return 0; } --- 212,319 ---- fi.fin_data[0] = 0; fi.fin_data[1] = sp; ! fi.fin_src6 = nat->nat_ndst6; ! fi.fin_dst6 = nat->nat_nsrc6; ! if (nat->nat_v[0] == 6) { ! #ifdef USE_INET6 ! if (nat->nat_dir == NAT_OUTBOUND) { ! nat2 = ipf_nat6_outlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[1], ! &nat->nat_osrc6.in6, ! &nat->nat_odst6.in6); ! } else { ! nat2 = ipf_nat6_inlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[0], ! &nat->nat_osrc6.in6, ! &nat->nat_odst6.in6); ! } ! #else ! nat2 = (void *)-1; ! #endif } else { ! if (nat->nat_dir == NAT_OUTBOUND) { ! nat2 = ipf_nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[1], ! nat->nat_osrcip, ! nat->nat_odstip); ! } else { ! nat2 = ipf_nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, ! nat->nat_pr[0], ! nat->nat_osrcip, ! nat->nat_odstip); ! } } + if (nat2 != NULL) + return APR_ERR(1); ! /* ! * Add skeleton NAT entry for connection which will come ! * back the other way. ! */ + if (nat->nat_v[0] == 6) { + #ifdef USE_INET6 + slen = ip6->ip6_plen; + ip6->ip6_plen = htons(sizeof(*tcp)); + #endif + } else { slen = ip->ip_len; ip->ip_len = htons(fin->fin_hlen + sizeof(*tcp)); + } ! /* ! * Fill out the fake TCP header with a few fields that ipfilter ! * considers to be important. ! */ ! bzero((char *)tcp2, sizeof(*tcp2)); ! tcp2->th_win = htons(8192); ! TCP_OFF_A(tcp2, 5); ! tcp2->th_flags = TH_SYN; ! fi.fin_dp = (char *)tcp2; ! fi.fin_fr = &rcmdfr; ! fi.fin_dlen = sizeof(*tcp2); ! fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); ! fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; ! if (nat->nat_dir == NAT_OUTBOUND) { ! fi.fin_out = 0; ! direction = NAT_INBOUND; ! } else { ! fi.fin_out = 1; ! direction = NAT_OUTBOUND; ! } ! nflags = SI_W_SPORT|NAT_SLAVE|IPN_TCP; ! MUTEX_ENTER(&softn->ipf_nat_new); ! if (fin->fin_v == 4) nat2 = ipf_nat_add(&fi, rc->rcmd_rule, NULL, nflags, direction); ! #ifdef USE_INET6 ! else ! nat2 = ipf_nat6_add(&fi, rc->rcmd_rule, NULL, nflags, ! direction); ! #endif ! MUTEX_EXIT(&softn->ipf_nat_new); ! if (nat2 != NULL) { ! (void) ipf_nat_proto(&fi, nat2, IPN_TCP); ! MUTEX_ENTER(&nat2->nat_lock); ! ipf_nat_update(&fi, nat2); ! MUTEX_EXIT(&nat2->nat_lock); ! fi.fin_ifp = NULL; ! if (nat2->nat_dir == NAT_INBOUND) ! fi.fin_dst6 = nat->nat_osrc6; ! (void) ipf_state_add(softc, &fi, NULL, SI_W_SPORT); ! } ! if (nat->nat_v[0] == 6) { ! #ifdef USE_INET6 ! ip6->ip6_plen = slen; ! #endif ! } else { ip->ip_len = slen; } + if (nat2 == NULL) + return APR_ERR(1); return 0; } Index: ip_ftp_pxy.c =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_ftp_pxy.c,v retrieving revision 1.19.2.6 retrieving revision 1.19.2.7 diff -C2 -d -r1.19.2.6 -r1.19.2.7 *** ip_ftp_pxy.c 29 May 2012 12:22:38 -0000 1.19.2.6 --- ip_ftp_pxy.c 20 Jul 2012 08:18:53 -0000 1.19.2.7 *************** *** 98,101 **** --- 98,103 ---- int ipf_p_ftp_eprt4 __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); + int ipf_p_ftp_eprt6 __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); int ipf_p_ftp_addport __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int, int, int)); *************** *** 103,114 **** [...1621 lines suppressed...] + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; + #if !defined(_KERNEL) + M_ADJ(m, inc); + #else + if (inc < 0) + M_ADJ(m, inc); + #endif + /* the mbuf chain will be extended if necessary by m_copyback() */ + COPYBACK(m, off, nlen, newbuf); + fin->fin_flx |= FI_DOCKSUM; + + if (inc != 0) { + fin->fin_plen += inc; + ip6->ip6_plen = htons(fin->fin_plen - fin->fin_hlen); + fin->fin_dlen += inc; + } + + f->ftps_cmd = FTPXY_C_EPRT; + return ipf_p_ftp_addport(softf, fin, ip, nat, ftp, dlen, port, inc); + } Index: ip_fil.h =================================================================== RCS file: /cvsroot/ipfilter/ipfilter/ip_fil.h,v retrieving revision 1.42.2.31 retrieving revision 1.42.2.32 diff -C2 -d -r1.42.2.31 -r1.42.2.32 *** ip_fil.h 13 Jul 2012 06:15:08 -0000 1.42.2.31 --- ip_fil.h 20 Jul 2012 08:18:53 -0000 1.42.2.32 *************** *** 210,214 **** #define NLADD(n,x) htonl(ntohl(n) + (x)) #define IP6_INC(a) \ ! { u_32_t *_i6 = (u_32_t *)(a); \ _i6[3] = NLADD(_i6[3], 1); \ if (_i6[3] == 0) { \ --- 210,214 ---- #define NLADD(n,x) htonl(ntohl(n) + (x)) #define IP6_INC(a) \ ! do { u_32_t *_i6 = (u_32_t *)(a); \ _i6[3] = NLADD(_i6[3], 1); \ if (_i6[3] == 0) { \ *************** *** 221,227 **** } \ } \ ! } #define IP6_ADD(a,x,d) \ ! { i6addr_t *_s = (i6addr_t *)(a); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[0] = NLADD(_s->i6[0], x); \ --- 221,227 ---- } \ } \ ! } while (0) #define IP6_ADD(a,x,d) \ ! do { i6addr_t *_s = (i6addr_t *)(a); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[0] = NLADD(_s->i6[0], x); \ *************** *** 235,240 **** } \ } \ ! } ! #define IP6_AND(a,b,d) { i6addr_t *_s1 = (i6addr_t *)(a); \ i6addr_t *_s2 = (i6addr_t *)(b); \ i6addr_t *_d = (i6addr_t *)(d); \ --- 235,240 ---- } \ } \ ! } while (0) ! #define IP6_AND(a,b,d) do { i6addr_t *_s1 = (i6addr_t *)(a); \ i6addr_t *_s2 = (i6addr_t *)(b); \ i6addr_t *_d = (i6addr_t *)(d); \ *************** *** 243,249 **** _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \ ! } #define IP6_ANDASSIGN(a,m) \ ! { i6addr_t *_d = (i6addr_t *)(a); \ i6addr_t *_m = (i6addr_t *)(m); \ _d->i6[0] &= _m->i6[0]; \ --- 243,249 ---- _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \ ! } while (0) #define IP6_ANDASSIGN(a,m) \ ! do { i6addr_t *_d = (i6addr_t *)(a); \ i6addr_t *_m = (i6addr_t *)(m); \ _d->i6[0] &= _m->i6[0]; \ *************** *** 251,255 **** _d->i6[2] &= _m->i6[2]; \ _d->i6[3] &= _m->i6[3]; \ ! } #define IP6_MASKEQ(a,m,b) \ (((I60(a) & I60(m)) == I60(b)) && \ --- 251,255 ---- _d->i6[2] &= _m->i6[2]; \ _d->i6[3] &= _m->i6[3]; \ ! } while (0) #define IP6_MASKEQ(a,m,b) \ (((I60(a) & I60(m)) == I60(b)) && \ *************** *** 263,267 **** ((I63(a) & I63(m)) != I63(b))) #define IP6_MERGE(a,b,c) \ ! { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ --- 263,267 ---- ((I63(a) & I63(m)) != I63(b))) #define IP6_MERGE(a,b,c) \ ! do { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ *************** *** 271,277 **** _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \ _d->i6[3] |= _s1->i6[3] & ~_s2->i6[3]; \ ! } #define IP6_MASK(a,b,c) \ ! { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ --- 271,277 ---- _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \ _d->i6[3] |= _s1->i6[3] & ~_s2->i6[3]; \ ! } while (0) #define IP6_MASK(a,b,c) \ ! do { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ *************** *** 281,285 **** _d->i6[2] = _s1->i6[2] & ~_s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & ~_s2->i6[3]; \ ! } typedef union ipso_u { u_short ipso_ripso[2]; --- 281,293 ---- _d->i6[2] = _s1->i6[2] & ~_s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & ~_s2->i6[3]; \ ! } while (0) ! #define IP6_SETONES(a) \ ! do { i6addr_t *_d = (i6addr_t *)(a); \ ! _d->i6[0] = 0xffffffff; \ ! _d->i6[1] = 0xffffffff; \ ! _d->i6[2] = 0xffffffff; \ ! _d->i6[3] = 0xffffffff; \ ! } while (0) ! typedef union ipso_u { u_short ipso_ripso[2]; *************** *** 333,336 **** --- 341,345 ---- #define FI_ENCAP 0x100000 /* encap/decap with NAT */ #define FI_AH 0x200000 /* AH header present */ + #define FI_DOCKSUM 0x10000000 /* Proxy wants L4 recalculation */ #define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */ #define FI_NOWILD 0x40000000 /* Do not do wildcard searches */ |