summaryrefslogtreecommitdiffstats
path: root/xtables.c
diff options
context:
space:
mode:
author/C=JP/ST=JP/CN=Yasuyuki Kozakai/emailAddress=yasuyuki@netfilter.org </C=JP/ST=JP/CN=Yasuyuki Kozakai/emailAddress=yasuyuki@netfilter.org>2007-07-24 05:53:48 +0000
committer/C=JP/ST=JP/CN=Yasuyuki Kozakai/emailAddress=yasuyuki@netfilter.org </C=JP/ST=JP/CN=Yasuyuki Kozakai/emailAddress=yasuyuki@netfilter.org>2007-07-24 05:53:48 +0000
commit3f7f9a483b6405d6a2debf16db27182443f483a0 (patch)
treedf628c95c8f2f5f25cf5f7bdebcca8f8ae8d4e93 /xtables.c
parent7c634a2c1c4b4a866faee328d206195e7857d194 (diff)
Moves some duplicated functions in ip[6]tables.c to xtables.c
string_to_number_ll, string_to_number_l, string_to_number, service_to_port, parse_port, parse_interface, are moved.
Diffstat (limited to 'xtables.c')
-rw-r--r--xtables.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/xtables.c b/xtables.c
index f00531c..ea5633e 100644
--- a/xtables.c
+++ b/xtables.c
@@ -19,6 +19,7 @@
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -153,6 +154,108 @@ int load_xtables_ko(const char *modprobe, int quiet)
return ret;
}
+int string_to_number_ll(const char *s, unsigned long long min,
+ unsigned long long max, unsigned long long *ret)
+{
+ unsigned long long number;
+ char *end;
+
+ /* Handle hex, octal, etc. */
+ errno = 0;
+ number = strtoull(s, &end, 0);
+ if (*end == '\0' && end != s) {
+ /* we parsed a number, let's see if we want this */
+ if (errno != ERANGE && min <= number && (!max || number <= max)) {
+ *ret = number;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int string_to_number_l(const char *s, unsigned long min, unsigned long max,
+ unsigned long *ret)
+{
+ int result;
+ unsigned long long number;
+
+ result = string_to_number_ll(s, min, max, &number);
+ *ret = (unsigned long)number;
+
+ return result;
+}
+
+int string_to_number(const char *s, unsigned int min, unsigned int max,
+ unsigned int *ret)
+{
+ int result;
+ unsigned long number;
+
+ result = string_to_number_l(s, min, max, &number);
+ *ret = (unsigned int)number;
+
+ return result;
+}
+
+int service_to_port(const char *name, const char *proto)
+{
+ struct servent *service;
+
+ if ((service = getservbyname(name, proto)) != NULL)
+ return ntohs((unsigned short) service->s_port);
+
+ return -1;
+}
+
+u_int16_t parse_port(const char *port, const char *proto)
+{
+ unsigned int portnum;
+
+ if ((string_to_number(port, 0, 65535, &portnum)) != -1 ||
+ (portnum = service_to_port(port, proto)) != -1)
+ return (u_int16_t)portnum;
+
+ exit_error(PARAMETER_PROBLEM,
+ "invalid port/service `%s' specified", port);
+}
+
+void parse_interface(const char *arg, char *vianame, unsigned char *mask)
+{
+ int vialen = strlen(arg);
+ unsigned int i;
+
+ memset(mask, 0, IFNAMSIZ);
+ memset(vianame, 0, IFNAMSIZ);
+
+ if (vialen + 1 > IFNAMSIZ)
+ exit_error(PARAMETER_PROBLEM,
+ "interface name `%s' must be shorter than IFNAMSIZ"
+ " (%i)", arg, IFNAMSIZ-1);
+
+ strcpy(vianame, arg);
+ if ((vialen == 0) || (vialen == 1 && vianame[0] == '+'))
+ memset(mask, 0, IFNAMSIZ);
+ else if (vianame[vialen - 1] == '+') {
+ memset(mask, 0xFF, vialen - 1);
+ memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1);
+ /* Don't remove `+' here! -HW */
+ } else {
+ /* Include nul-terminator in match */
+ memset(mask, 0xFF, vialen + 1);
+ memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1);
+ for (i = 0; vianame[i]; i++) {
+ if (vianame[i] == ':' ||
+ vianame[i] == '!' ||
+ vianame[i] == '*') {
+ printf("Warning: weird character in interface"
+ " `%s' (No aliases, :, ! or *).\n",
+ vianame);
+ break;
+ }
+ }
+ }
+}
+
struct xtables_match *find_match(const char *name, enum xt_tryload tryload,
struct xtables_rule_match **matches)
{