]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
add DSCP match
authorHarald Welte <laforge@gnumonks.org>
Thu, 14 Mar 2002 12:22:06 +0000 (12:22 +0000)
committerHarald Welte <laforge@gnumonks.org>
Thu, 14 Mar 2002 12:22:06 +0000 (12:22 +0000)
extensions/Makefile
extensions/libipt_dscp.c [new file with mode: 0644]
include/linux/netfilter_ipv4/ipt_DSCP.h
include/linux/netfilter_ipv4/ipt_dscp.h [new file with mode: 0644]

index 6cee75595e4318e4c847e9d3e647c54df4411a01..4e2fa052a7df37a07ebb5ce7e01b5ad09c2105e8 100644 (file)
@@ -1,6 +1,6 @@
 #! /usr/bin/make
 
-PF_EXT_SLIB:=ah esp icmp length limit mac mark multiport owner standard state tcp tcpmss tos ttl udp unclean DNAT DSCP ECN LOG MARK MASQUERADE MIRROR REDIRECT REJECT SAME SNAT TCPMSS TOS ULOG
+PF_EXT_SLIB:=ah dscp esp icmp length limit mac mark multiport owner standard state tcp tcpmss tos ttl udp unclean DNAT DSCP ECN LOG MARK MASQUERADE MIRROR REDIRECT REJECT SAME SNAT TCPMSS TOS ULOG
 PF6_EXT_SLIB:=icmpv6 length limit mac mark multiport owner standard tcp udp LOG MARK
 
 # The following may not be present, but compile them anyway.
diff --git a/extensions/libipt_dscp.c b/extensions/libipt_dscp.c
new file mode 100644 (file)
index 0000000..db380ce
--- /dev/null
@@ -0,0 +1,146 @@
+/* Shared library add-on to iptables for DSCP
+ *
+ * (C) 2002 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is distributed under the terms of GNU GPL v2, 1991
+ *
+ * libipt_dscp.c borrowed heavily from libipt_tos.c
+ *
+ * For a list of DSCP codepoints see 
+ * http://www.iana.org/assignments/dscp-registry
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_dscp.h>
+
+static void init(struct ipt_entry_match *m, unsigned int *nfcache) 
+{
+       *nfcache |= NFC_IP_TOS;
+}
+
+static void help(void) 
+{
+       printf(
+"DSCP match v%s options\n"
+"[!] --dscp value              Match DSCP codepoint with numerical value\n"
+"                              This value can be in decimal (ex: 32)\n"
+"                              or in hex (ex: 0x20)\n", NETFILTER_VERSION
+);
+}
+
+static struct option opts[] = {
+       { "dscp", 1, 0, 'F' },
+       { 0 }
+};
+
+static void
+parse_dscp(const unsigned char *s, struct ipt_dscp_info *dinfo)
+{
+       unsigned int dscp;
+       
+       if (string_to_number(s, 0, 255, &dscp) == -1)
+               exit_error(PARAMETER_PROBLEM,
+                          "Invalid dscp `%s'\n", s);
+
+       if (dscp > IPT_DSCP_MAX)
+               exit_error(PARAMETER_PROBLEM,
+                          "DSCP `%d` out of range\n", dscp);
+
+       dinfo->dscp = (u_int8_t )dscp;
+       return;
+}
+
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+      const struct ipt_entry *entry,
+      unsigned int *nfcache,
+      struct ipt_entry_match **match)
+{
+       struct ipt_dscp_info *dinfo
+               = (struct ipt_dscp_info *)(*match)->data;
+
+       switch (c) {
+       case 'F':
+               if (*flags)
+                       exit_error(PARAMETER_PROBLEM,
+                                  "DSCP match: Only use --dscp ONCE!");
+               check_inverse(optarg, &invert, &optind, 0);
+               parse_dscp(argv[optind-1], dinfo);
+               if (invert)
+                       dinfo->invert = 1;
+               *flags = 1;
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+       if (!flags)
+               exit_error(PARAMETER_PROBLEM,
+                          "DSCP match: Parameter --dscp is required");
+}
+
+static void
+print_dscp(u_int8_t dscp, int invert, int numeric)
+{
+       if (invert)
+               fputc('!', stdout);
+
+       printf("0x%02x ", dscp);
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *match,
+      int numeric)
+{
+       const struct ipt_dscp_info *dinfo =
+               (const struct ipt_dscp_info *)match->data;
+       printf("DSCP match ");
+       print_dscp(dinfo->dscp, dinfo->invert, numeric);
+}
+
+/* Saves the union ipt_matchinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+       const struct ipt_dscp_info *dinfo =
+               (const struct ipt_dscp_info *)match->data;
+
+       printf("--dscp ");
+       print_dscp(dinfo->dscp, dinfo->invert, 1);
+}
+
+static
+struct iptables_match dscp
+= { NULL,
+    "dscp",
+    NETFILTER_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_dscp_info)),
+    IPT_ALIGN(sizeof(struct ipt_dscp_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+       register_match(&dscp);
+}
index 361eb2af422a9665cbb14dcc7f225be4cade5aae..499fca495cdec8020df2555011a98af548664da1 100644 (file)
@@ -1,23 +1,20 @@
-/* Set DSCP field
- *
- * (C) 2000-2002 by Matthew G. Marsh <mgm@paktronix.com>
- *                  Harald Welte <laforge@gnumonks.org>
+/* iptables module for setting the IPv4 DSCP field
  *
+ * (C) 2002 Harald Welte <laforge@gnumonks.org>
+ * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
  * This software is distributed under GNU GPL v2, 1991
  * 
- * ipt_DSCP.h borrowed heavily from ipt_TOS.h  11/09/2000
+ * See RFC2474 for a description of the DSCP field within the IP Header.
  *
- * $Id: ipt_DSCP.h,v 1.3 2002/02/17 19:56:28 laforge Exp $
+ * Id: ipt_DSCP.h,v 1.7 2002/03/14 12:03:13 laforge Exp 
 */
-#ifndef _IPT_DSCP_H
-#define _IPT_DSCP_H
-
-#define IPT_DSCP_MASK  0xf4    /* 11111100 */
-#define IPT_DSCP_SHIFT 2       /* shift DSCP two bits for ECN */
-#define IPT_DSCP_MAX   0x3f    /* 00111111 */
+#ifndef _IPT_DSCP_TARGET_H
+#define _IPT_DSCP_TARGET_H
+#include <linux/netfilter_ipv4/ipt_dscp.h>
 
+/* target info */
 struct ipt_DSCP_info {
        u_int8_t dscp;
 };
 
-#endif /* _IPT_DSCP_H */
+#endif /* _IPT_DSCP_TARGET_H */
diff --git a/include/linux/netfilter_ipv4/ipt_dscp.h b/include/linux/netfilter_ipv4/ipt_dscp.h
new file mode 100644 (file)
index 0000000..1d72875
--- /dev/null
@@ -0,0 +1,23 @@
+/* iptables module for matching the IPv4 DSCP field
+ *
+ * (C) 2002 Harald Welte <laforge@gnumonks.org>
+ * This software is distributed under GNU GPL v2, 1991
+ * 
+ * See RFC2474 for a description of the DSCP field within the IP Header.
+ *
+ * Id: ipt_dscp.h,v 1.1 2002/03/14 12:03:13 laforge Exp 
+*/
+#ifndef _IPT_DSCP_H
+#define _IPT_DSCP_H
+
+#define IPT_DSCP_MASK  0xfc    /* 11111100 */
+#define IPT_DSCP_SHIFT 2       /* shift DSCP two bits for ECN */
+#define IPT_DSCP_MAX   0x3f    /* 00111111 */
+
+/* match info */
+struct ipt_dscp_info {
+       u_int8_t dscp;
+       u_int8_t invert;
+};
+
+#endif /* _IPT_DSCP_H */