From patchwork Thu Jun 27 15:54:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Oester X-Patchwork-Id: 255707 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 358882C0040 for ; Sat, 29 Jun 2013 13:36:10 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753440Ab3F2DgI (ORCPT ); Fri, 28 Jun 2013 23:36:08 -0400 Received: from mail-pa0-f46.google.com ([209.85.220.46]:53051 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753428Ab3F2DgH (ORCPT ); Fri, 28 Jun 2013 23:36:07 -0400 Received: by mail-pa0-f46.google.com with SMTP id fa11so3138999pad.33 for ; Fri, 28 Jun 2013 20:36:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:from:to:cc:subject:message-id:mime-version:content-type :content-disposition:user-agent:x-gm-message-state; bh=uXj/xGfXS5DcQMsR84I6nVZGO0cPmgXi91jlKDykLOs=; b=aVQXRh7OuVPIP3LCCOSby3VvQi3Y5j0sbYLif/+Y1dJ+uIaVHuM25c/9yyj8QFFGk1 GYcms5Yd1DIrHjHoxV8Ce9Jp4CeBkgZ/ta8U1H1NsFBgyX6vJlzTg1MH0mmp/pguZ2AC NTG2dGWIMDUoC9FjPD7yKZ28Jr0RtElG+wjATbM9uU6Zyemp/oPbYEFk+WTLUWGspUWI 9phYuFUUeZXrTdjQWhmh+n9pphkoEsUOrT7iCpXO4zVIjlKBHoM8JcTHQ9HBGrjqe9F6 nQFAk5nLpfaSpIyqVwZO7mx/kXv/OL4lEr/KfoO72mtuPsOW3OBsf2yo+Tv8JDQsjpfH UGdw== X-Received: by 10.68.34.165 with SMTP id a5mr14169300pbj.156.1372476966459; Fri, 28 Jun 2013 20:36:06 -0700 (PDT) Received: from gmail.com (pool-98-112-127-79.lsanca.fios.verizon.net. [98.112.127.79]) by mx.google.com with ESMTPSA id vu5sm11826734pab.10.2013.06.28.20.36.04 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 28 Jun 2013 20:36:05 -0700 (PDT) Date: Thu, 27 Jun 2013 11:54:09 -0400 From: Phil Oester To: netfilter-devel@vger.kernel.org Cc: pablo@netfilter.org Subject: [PATCH] iptables: allow service names in [DS]NAT targets Message-ID: <20130627155409.GA8638@gmail.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Gm-Message-State: ALoCoQlmL3Fhaz0eFMaEmw96KWouPeqJTZot85Jt1xTu2NPwzOFuNtfPi21SyvqUQPWjfXPOUc5P Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org As reported by Alexander Hoogerhuis, the [DS]NAT targets do not allow use of service names in the --to argument. The same problem was fixed in the REDIRECT target in commit 84d758b3 ("extensions: REDIRECT: fix --to-ports parser"). Use a similar fix here. This closes bugzilla #514. Phil Signed-off-by: Phil Oester diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c index ff18799..e452cfc 100644 --- a/extensions/libipt_DNAT.c +++ b/extensions/libipt_DNAT.c @@ -67,7 +67,7 @@ static struct xt_entry_target * parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) { struct nf_nat_ipv4_range range; - char *arg, *colon, *dash, *error; + char *arg, *colon, *dash; const struct in_addr *ip; arg = strdup(orig_arg); @@ -77,7 +77,8 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) colon = strchr(arg, ':'); if (colon) { - int port; + char *end = ""; + unsigned int port, maxport; if (!portok) xtables_error(PARAMETER_PROBLEM, @@ -85,34 +86,29 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - port = atoi(colon+1); - if (port <= 0 || port > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", colon+1); - - error = strchr(colon+1, ':'); - if (error) - xtables_error(PARAMETER_PROBLEM, - "Invalid port:port syntax - use dash\n"); + if (!xtables_strtoui(colon + 1, &end, &port, 0, UINT16_MAX) && + (port = xtables_service_to_port(colon + 1, NULL)) == (unsigned)-1) + xtables_param_act(XTF_BAD_VALUE, "DNAT", "--to", arg); - dash = strchr(colon, '-'); - if (!dash) { + switch (*end) { + case '\0': range.min.tcp.port = range.max.tcp.port = htons(port); - } else { - int maxport; + break; + case '-': + if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) && + (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1) + xtables_param_act(XTF_BAD_VALUE, "DNAT", "--to", arg); - maxport = atoi(dash + 1); - if (maxport <= 0 || maxport > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", dash+1); if (maxport < port) - /* People are stupid. */ - xtables_error(PARAMETER_PROBLEM, - "Port range `%s' funky\n", colon+1); + xtables_param_act(XTF_BAD_VALUE, "DNAT", "--to", arg); + range.min.tcp.port = htons(port); range.max.tcp.port = htons(maxport); + break; + default: + xtables_param_act(XTF_BAD_VALUE, "DNAT", "--to", arg); } /* Starts with a colon? No IP info...*/ if (colon == arg) { diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c index 1a24f3d..01be677 100644 --- a/extensions/libipt_SNAT.c +++ b/extensions/libipt_SNAT.c @@ -67,7 +67,7 @@ static struct xt_entry_target * parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) { struct nf_nat_ipv4_range range; - char *arg, *colon, *dash, *error; + char *arg, *colon, *dash; const struct in_addr *ip; arg = strdup(orig_arg); @@ -77,7 +77,8 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) colon = strchr(arg, ':'); if (colon) { - int port; + char *end = ""; + unsigned int port, maxport; if (!portok) xtables_error(PARAMETER_PROBLEM, @@ -85,34 +86,29 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info) range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - port = atoi(colon+1); - if (port <= 0 || port > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", colon+1); - - error = strchr(colon+1, ':'); - if (error) - xtables_error(PARAMETER_PROBLEM, - "Invalid port:port syntax - use dash\n"); + if (!xtables_strtoui(colon + 1, &end, &port, 0, UINT16_MAX) && + (port = xtables_service_to_port(colon + 1, NULL)) == (unsigned)-1) + xtables_param_act(XTF_BAD_VALUE, "SNAT", "--to", arg); - dash = strchr(colon, '-'); - if (!dash) { + switch (*end) { + case '\0': range.min.tcp.port = range.max.tcp.port = htons(port); - } else { - int maxport; + break; + case '-': + if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) && + (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1) + xtables_param_act(XTF_BAD_VALUE, "SNAT", "--to", arg); - maxport = atoi(dash + 1); - if (maxport <= 0 || maxport > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", dash+1); if (maxport < port) - /* People are stupid. */ - xtables_error(PARAMETER_PROBLEM, - "Port range `%s' funky\n", colon+1); + xtables_param_act(XTF_BAD_VALUE, "SNAT", "--to", arg); + range.min.tcp.port = htons(port); range.max.tcp.port = htons(maxport); + break; + default: + xtables_param_act(XTF_BAD_VALUE, "SNAT", "--to", arg); } /* Starts with a colon? No IP info...*/ if (colon == arg) {