@@ -278,6 +278,18 @@ print_port(uint16_t port, uint8_t protocol, int numeric)
}
static void
+print_port_xlate(struct xt_xlate *xl, uint16_t port, uint8_t protocol,
+ int numeric)
+{
+ const char *service;
+
+ if (numeric || (service = port_to_service(port, protocol)) == NULL)
+ xt_xlate_add(xl, "%u", port);
+ else
+ xt_xlate_add(xl, "%s", service);
+}
+
+static void
__multiport_print(const struct xt_entry_match *match, int numeric,
uint16_t proto)
{
@@ -318,6 +330,20 @@ static void multiport_print(const void *ip_void,
__multiport_print(match, numeric, ip->proto);
}
+static void multiport_print_xlate(const struct xt_entry_match *match,
+ struct xt_xlate *xl, uint16_t proto,
+ int numeric)
+{
+ const struct xt_multiport_v1 *multiinfo =
+ (const struct xt_multiport_v1 *)match->data;
+ unsigned int i;
+ for (i = 0; i < multiinfo->count; i++) {
+ xt_xlate_add(xl, "%s", i ? "," : "");
+ print_port_xlate(xl, multiinfo->ports[i],
+ proto, numeric);
+ }
+}
+
static void multiport_print6(const void *ip_void,
const struct xt_entry_match *match, int numeric)
{
@@ -372,6 +398,24 @@ static void multiport_print_v1(const void *ip_void,
__multiport_print_v1(match, numeric, ip->proto);
}
+static void multiport_print_v1_xlate(const struct xt_entry_match *match,
+ struct xt_xlate *xl, uint16_t proto,
+ int numeric)
+{
+ const struct xt_multiport_v1 *multiinfo =
+ (const struct xt_multiport_v1 *)match->data;
+ unsigned int i;
+ for (i = 0; i < multiinfo->count; i++) {
+ xt_xlate_add(xl, "%s", i ? "," : "");
+ print_port_xlate(xl, multiinfo->ports[i], proto, numeric);
+ if (multiinfo->pflags[i]) {
+ xt_xlate_add(xl, " - ");
+ print_port_xlate(xl, multiinfo->ports[++i],
+ proto, numeric);
+ }
+ }
+}
+
static void multiport_print6_v1(const void *ip_void,
const struct xt_entry_match *match, int numeric)
{
@@ -468,6 +512,157 @@ static void multiport_save6_v1(const void *ip_void,
__multiport_save_v1(match, ip->proto);
}
+static int __multiport_xlate(const struct xt_entry_match *match,
+ struct xt_xlate *xl, uint16_t protocol, int numeric)
+{
+ const struct xt_multiport_v1 *multiinfo =
+ (const struct xt_multiport_v1 *)match->data;
+ const char *proto_name;
+ bool have_multiple = false, have_invert = false ;
+
+ if((proto_name = proto_to_name(protocol)) != NULL){
+ if (multiinfo->count > 1) have_multiple = true;
+ if (multiinfo->invert) have_invert = true;
+ if (have_multiple && have_invert)
+ return 0;
+
+ switch (multiinfo->flags) {
+ case XT_MULTIPORT_SOURCE:
+ xt_xlate_add(xl, "%s sport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_xlate(match, xl, protocol,
+ numeric);
+ break;
+ case XT_MULTIPORT_DESTINATION:
+ xt_xlate_add(xl, "%s dport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_xlate(match, xl, protocol,
+ numeric);
+ break;
+ case XT_MULTIPORT_EITHER:
+ xt_xlate_add(xl, "%s dport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_xlate(match, xl, protocol,
+ numeric);
+ if (have_multiple)
+ xt_xlate_add(xl, " } ");
+ else
+ xt_xlate_add(xl, " ");
+
+ xt_xlate_add(xl, "%s sport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_xlate(match, xl, protocol,
+ numeric);
+ break;
+ default:
+ return 0;
+ }
+ if (have_multiple)
+ xt_xlate_add(xl, " } ");
+ else
+ xt_xlate_add(xl, " ");
+ }
+
+ return 1;
+}
+
+static int __multiport_xlate_v1(const struct xt_entry_match *match,
+ struct xt_xlate *xl, uint16_t protocol, int numeric)
+{
+ const struct xt_multiport_v1 *multiinfo =
+ (const struct xt_multiport_v1 *)match->data;
+ const char *proto_name;
+ bool have_multiple = false, have_invert = false ;
+
+ if((proto_name = proto_to_name(protocol)) != NULL){
+ if (multiinfo->count > 1) have_multiple = true;
+ if (multiinfo->invert) have_invert = true;
+ if (have_multiple && have_invert)
+ return 0;
+
+ switch (multiinfo->flags) {
+ case XT_MULTIPORT_SOURCE:
+ xt_xlate_add(xl, "%s sport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_v1_xlate(match, xl, protocol,
+ numeric);
+ break;
+ case XT_MULTIPORT_DESTINATION:
+ xt_xlate_add(xl, "%s dport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_v1_xlate(match, xl, protocol,
+ numeric);
+ break;
+ case XT_MULTIPORT_EITHER:
+ xt_xlate_add(xl, "%s dport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_v1_xlate(match, xl, protocol,
+ numeric);
+ if (have_multiple)
+ xt_xlate_add(xl, " } ");
+ else
+ xt_xlate_add(xl, " ");
+
+ xt_xlate_add(xl, "%s sport %s%s", proto_name,
+ (have_invert == true) ? "!= " : "",
+ (have_multiple == true) ? "{ " : "");
+ multiport_print_v1_xlate(match, xl, protocol,
+ numeric);
+ break;
+ default:
+ return 0;
+ }
+ if (have_multiple)
+ xt_xlate_add(xl, " } ");
+ else
+ xt_xlate_add(xl, " ");
+ }
+
+ return 1;
+}
+
+static int multiport_xlate(const void *ip_void,
+ const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+ const struct ipt_ip *ip = ip_void;
+ return __multiport_xlate(match, xl, ip->proto, numeric);
+}
+
+static int multiport_xlate6(const void *ip_void,
+ const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+
+ const struct ip6t_ip6 *ip = ip_void;
+ return __multiport_xlate(match, xl, ip->proto, numeric);
+}
+
+static int multiport_xlate_v1(const void *ip_void,
+ const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+
+ const struct ipt_ip *ip = ip_void;
+ return __multiport_xlate_v1(match, xl, ip->proto, numeric);
+}
+
+static int multiport_xlate6_v1(const void *ip_void,
+ const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+
+ const struct ip6t_ip6 *ip = ip_void;
+ return __multiport_xlate_v1(match, xl, ip->proto, numeric);
+}
+
static struct xtables_match multiport_mt_reg[] = {
{
.family = NFPROTO_IPV4,
@@ -482,6 +677,7 @@ static struct xtables_match multiport_mt_reg[] = {
.print = multiport_print,
.save = multiport_save,
.x6_options = multiport_opts,
+ .xlate = multiport_xlate,
},
{
.family = NFPROTO_IPV6,
@@ -496,6 +692,7 @@ static struct xtables_match multiport_mt_reg[] = {
.print = multiport_print6,
.save = multiport_save6,
.x6_options = multiport_opts,
+ .xlate = multiport_xlate6,
},
{
.family = NFPROTO_IPV4,
@@ -510,6 +707,7 @@ static struct xtables_match multiport_mt_reg[] = {
.print = multiport_print_v1,
.save = multiport_save_v1,
.x6_options = multiport_opts,
+ .xlate = multiport_xlate_v1,
},
{
.family = NFPROTO_IPV6,
@@ -524,6 +722,7 @@ static struct xtables_match multiport_mt_reg[] = {
.print = multiport_print6_v1,
.save = multiport_save6_v1,
.x6_options = multiport_opts,
+ .xlate = multiport_xlate6_v1,
},
};