diff -u --new-file --recursive iptables-1.2.7-20020511/extensions/libipt_REJECT.c iptables-1.2.7-20020511_extensions/extensions/libipt_REJECT.c --- iptables-1.2.7-20020511/extensions/libipt_REJECT.c Thu Mar 14 13:35:58 2002 +++ iptables-1.2.7-20020511_extensions/extensions/libipt_REJECT.c Sun May 12 02:20:34 2002 @@ -6,10 +6,17 @@ #include #include #include +#include #include #include #include +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + struct reject_names { const char *name; const char *alias; @@ -52,7 +59,7 @@ printf("\n"); } -/* Saves the union ipt_targinfo in parsable form to stdout. */ +/* Saves the struct ipt_targinfo in parsable form to stdout. */ /* Function which prints out usage message. */ static void @@ -62,12 +69,15 @@ "REJECT options:\n" "--reject-with type drop input packet and send back\n" " a reply packet according to type:\n"); - print_reject_types(); + printf( +"--fake-source ip_address fake the source address of the packet to\n" +" be ip_address (do not use with tcp-reset!)\n"); } static struct option opts[] = { { "reject-with", 1, 0, '1' }, + { "fake-source", 1, 0, '2' }, { 0 } }; @@ -79,6 +89,7 @@ /* default */ reject->with = IPT_ICMP_PORT_UNREACHABLE; + reject->fake_source_address = 0; /* by default we don't fake */ /* Can't cache this */ *nfcache |= NFC_UNKNOWN; @@ -94,6 +105,7 @@ struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names); unsigned int i; + struct in_addr *ip; switch(c) { case '1': @@ -113,6 +125,24 @@ fprintf(stderr, "--reject-with echo-reply no longer" " supported\n"); exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg); + if ((reject->fake_source_address != 0) && (reject->with == IPT_TCP_RESET)) + exit_error(PARAMETER_PROBLEM, + "Cannot use fake source address with TCP_RESET for REJECT"); + + break; + case '2': + if (invert) + exit_error(PARAMETER_PROBLEM, + "unexpected '!' with --fake-source"); + if (reject->with == IPT_TCP_RESET) + exit_error(PARAMETER_PROBLEM, + "Cannot use fake source address with TCP_RESET for REJECT"); + ip = dotted_to_addr(optarg); + if (!ip) + exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n", optarg); + reject->fake_source_address = ip->s_addr; + return 1; + break; default: /* Fall through */ break; @@ -140,6 +170,8 @@ break; } printf("reject-with %s ", reject_table[i].name); + if (reject->fake_source_address != 0) + printf("faked from %u.%u.%u.%u ", NIPQUAD(reject->fake_source_address)); } /* Saves ipt_reject in parsable form to stdout. */ @@ -154,6 +186,8 @@ break; printf("--reject-with %s ", reject_table[i].name); + if (reject->fake_source_address != 0) + printf("--fake-source %u.%u.%u.%u ", NIPQUAD(reject->fake_source_address)); } static diff -u --new-file --recursive iptables-1.2.7-20020511/extensions/libipt_mark.c iptables-1.2.7-20020511_extensions/extensions/libipt_mark.c --- iptables-1.2.7-20020511/extensions/libipt_mark.c Thu Mar 14 13:35:58 2002 +++ iptables-1.2.7-20020511_extensions/extensions/libipt_mark.c Sun May 12 02:20:46 2002 @@ -14,13 +14,17 @@ { printf( "MARK match v%s options:\n" -"[!] --mark value[/mask] Match nfmark value with optional mask\n" +"[!] --mark value Match nfmark value\n" +"[!] --markor value/mask Match nfmark value, the packets nfmark is ORed with mask before matching.\n" +"[!] --markand value/mask Match nfmark value, the packets nfmark is ORed with mask before matching.\n" "\n", NETFILTER_VERSION); } static struct option opts[] = { { "mark", 1, 0, '1' }, + { "markor", 1, 0, '2' }, + { "markand", 1, 0, '3' }, {0} }; @@ -41,48 +45,60 @@ struct ipt_entry_match **match) { struct ipt_mark_info *markinfo = (struct ipt_mark_info *)(*match)->data; + char *end; - switch (c) { - char *end; - case '1': - check_inverse(optarg, &invert, &optind, 0); + if ((c=='1') || (c=='2') || (c=='3')) // we ate an option ? + { + if (*flags) + exit_error(PARAMETER_PROBLEM, "mark match: can specify only one action"); markinfo->mark = strtoul(optarg, &end, 0); - if (*end == '/') { - markinfo->mask = strtoul(end+1, &end, 0); - } else - markinfo->mask = 0xffffffff; - if (*end != '\0' || end == optarg) - exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); + if (((*end != '\0') && (*end != '/')) || (end == optarg)) + exit_error(PARAMETER_PROBLEM, "Bad mark value `%s'", optarg); if (invert) markinfo->invert = 1; - *flags = 1; + *flags = 1; + } + else + return 0; + + switch (c) { + + case '1': + markinfo->bit_op = IPT_MARK_BIT_OP_NONE; + markinfo->mask = 0; break; + case '2': + if (*end != '/') + exit_error(PARAMETER_PROBLEM, "mark match: you must specify a mask when using markor\n"); + markinfo->mask = strtoul(end+1, &end, 0); + if (*end != '\0' || end == optarg) + exit_error(PARAMETER_PROBLEM, "Bad mark OR value `%s'", optarg); + markinfo->bit_op = IPT_MARK_BIT_OP_OR; + break; + + case '3': + if (*end != '/') + exit_error(PARAMETER_PROBLEM, "mark match: you must specify a mask when using markand\n"); + markinfo->mask = strtoul(end+1, &end, 0); + if (*end != '\0' || end == optarg) + exit_error(PARAMETER_PROBLEM, "Bad mark AND value `%s'", optarg); + markinfo->bit_op = IPT_MARK_BIT_OP_AND; + break; + default: - return 0; + break; /* will never happen, but at least no warning */ } return 1; } -static void -print_mark(unsigned long mark, unsigned long mask, int invert, int numeric) -{ - if (invert) - fputc('!', stdout); - - if(mask != 0xffffffff) - printf("0x%lx/0x%lx ", mark, mask); - else - printf("0x%lx ", mark); -} - /* Final check; must have specified --mark. */ static void final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, - "MARK match: You must specify `--mark'"); + "MARK match: you must specify a mark to match"); } /* Prints out the matchinfo. */ @@ -91,20 +107,39 @@ const struct ipt_entry_match *match, int numeric) { - printf("MARK match "); - print_mark(((struct ipt_mark_info *)match->data)->mark, - ((struct ipt_mark_info *)match->data)->mask, - ((struct ipt_mark_info *)match->data)->invert, numeric); + struct ipt_mark_info *info = (struct ipt_mark_info *)match->data; + + printf("MARK "); + if (info->bit_op == IPT_MARK_BIT_OP_AND) + printf("& 0x%lx ", info->mask); + else + if (info->bit_op == IPT_MARK_BIT_OP_OR) + printf("| 0x%lx ", info->mask); + if (info->invert) + printf("! "); + printf("match 0x%lx ", info->mark); } /* Saves the union ipt_matchinfo in parsable form to stdout. */ static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) { - printf("--mark "); - print_mark(((struct ipt_mark_info *)match->data)->mark, - ((struct ipt_mark_info *)match->data)->mask, - ((struct ipt_mark_info *)match->data)->invert, 0); + struct ipt_mark_info *info = (struct ipt_mark_info *)match->data; + + if (info->invert) + printf("! "); + switch (info->bit_op) + { + case IPT_MARK_BIT_OP_AND : + printf("--markand 0x%lx/0x%lx ", info->mark, info->mask); + break; + case IPT_MARK_BIT_OP_OR : + printf("--markor 0x%lx/0x%lx ", info->mark, info->mask); + break; + case IPT_MARK_BIT_OP_NONE : + printf("--mark 0x%lx ", info->mark); + break; + } } static