Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 1 | /* Shared library add-on to iptables for ECN matching |
| 2 | * |
| 3 | * (C) 2002 by Harald Welte <laforge@gnumonks.org> |
| 4 | * |
| 5 | * This program is distributed under the terms of GNU GPL v2, 1991 |
| 6 | * |
| 7 | * libipt_ecn.c borrowed heavily from libipt_dscp.c |
| 8 | * |
| 9 | */ |
| 10 | #include <stdio.h> |
Jan Engelhardt | 5d9678a | 2008-11-20 10:15:35 +0100 | [diff] [blame] | 11 | #include <xtables.h> |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 12 | #include <linux/netfilter_ipv4/ipt_ecn.h> |
| 13 | |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 14 | enum { |
| 15 | O_ECN_TCP_CWR = 0, |
| 16 | O_ECN_TCP_ECE, |
| 17 | O_ECN_IP_ECT, |
| 18 | }; |
| 19 | |
Jan Engelhardt | 59d1640 | 2007-10-04 16:28:39 +0000 | [diff] [blame] | 20 | static void ecn_help(void) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 21 | { |
| 22 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 23 | "ECN match options\n" |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 24 | "[!] --ecn-tcp-cwr Match CWR bit of TCP header\n" |
| 25 | "[!] --ecn-tcp-ece Match ECE bit of TCP header\n" |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 26 | "[!] --ecn-ip-ect [0..3] Match ECN codepoint in IPv4 header\n"); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 27 | } |
| 28 | |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 29 | static const struct xt_option_entry ecn_opts[] = { |
| 30 | {.name = "ecn-tcp-cwr", .id = O_ECN_TCP_CWR, .type = XTTYPE_NONE, |
| 31 | .flags = XTOPT_INVERT}, |
| 32 | {.name = "ecn-tcp-ece", .id = O_ECN_TCP_ECE, .type = XTTYPE_NONE, |
| 33 | .flags = XTOPT_INVERT}, |
| 34 | {.name = "ecn-ip-ect", .id = O_ECN_IP_ECT, .type = XTTYPE_UINT8, |
| 35 | .min = 0, .max = 3, .flags = XTOPT_INVERT}, |
| 36 | XTOPT_TABLEEND, |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 37 | }; |
| 38 | |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 39 | static void ecn_parse(struct xt_option_call *cb) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 40 | { |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 41 | struct ipt_ecn_info *einfo = cb->data; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 42 | |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 43 | xtables_option_parse(cb); |
| 44 | switch (cb->entry->id) { |
| 45 | case O_ECN_TCP_CWR: |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 46 | einfo->operation |= IPT_ECN_OP_MATCH_CWR; |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 47 | if (cb->invert) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 48 | einfo->invert |= IPT_ECN_OP_MATCH_CWR; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 49 | break; |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 50 | case O_ECN_TCP_ECE: |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 51 | einfo->operation |= IPT_ECN_OP_MATCH_ECE; |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 52 | if (cb->invert) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 53 | einfo->invert |= IPT_ECN_OP_MATCH_ECE; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 54 | break; |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 55 | case O_ECN_IP_ECT: |
| 56 | if (cb->invert) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 57 | einfo->invert |= IPT_ECN_OP_MATCH_IP; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 58 | einfo->operation |= IPT_ECN_OP_MATCH_IP; |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 59 | einfo->ip_ect = cb->val.u8; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 60 | break; |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 61 | } |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 62 | } |
| 63 | |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 64 | static void ecn_check(struct xt_fcheck_call *cb) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 65 | { |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 66 | if (cb->xflags == 0) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 67 | xtables_error(PARAMETER_PROBLEM, |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 68 | "ECN match: some option required"); |
| 69 | } |
| 70 | |
Jan Engelhardt | 59d1640 | 2007-10-04 16:28:39 +0000 | [diff] [blame] | 71 | static void ecn_print(const void *ip, const struct xt_entry_match *match, |
| 72 | int numeric) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 73 | { |
| 74 | const struct ipt_ecn_info *einfo = |
| 75 | (const struct ipt_ecn_info *)match->data; |
| 76 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 77 | printf(" ECN match"); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 78 | |
| 79 | if (einfo->operation & IPT_ECN_OP_MATCH_ECE) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 80 | printf(" %sECE", |
| 81 | (einfo->invert & IPT_ECN_OP_MATCH_ECE) ? "!" : ""); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | if (einfo->operation & IPT_ECN_OP_MATCH_CWR) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 85 | printf(" %sCWR", |
| 86 | (einfo->invert & IPT_ECN_OP_MATCH_CWR) ? "!" : ""); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 87 | } |
| 88 | |
| 89 | if (einfo->operation & IPT_ECN_OP_MATCH_IP) { |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 90 | printf(" %sECT=%d", |
| 91 | (einfo->invert & IPT_ECN_OP_MATCH_IP) ? "!" : "", |
| 92 | einfo->ip_ect); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 93 | } |
| 94 | } |
| 95 | |
Jan Engelhardt | 59d1640 | 2007-10-04 16:28:39 +0000 | [diff] [blame] | 96 | static void ecn_save(const void *ip, const struct xt_entry_match *match) |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 97 | { |
| 98 | const struct ipt_ecn_info *einfo = |
| 99 | (const struct ipt_ecn_info *)match->data; |
| 100 | |
| 101 | if (einfo->operation & IPT_ECN_OP_MATCH_ECE) { |
| 102 | if (einfo->invert & IPT_ECN_OP_MATCH_ECE) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 103 | printf(" !"); |
| 104 | printf(" --ecn-tcp-ece"); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | if (einfo->operation & IPT_ECN_OP_MATCH_CWR) { |
| 108 | if (einfo->invert & IPT_ECN_OP_MATCH_CWR) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 109 | printf(" !"); |
| 110 | printf(" --ecn-tcp-cwr"); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | if (einfo->operation & IPT_ECN_OP_MATCH_IP) { |
| 114 | if (einfo->invert & IPT_ECN_OP_MATCH_IP) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 115 | printf(" !"); |
| 116 | printf(" --ecn-ip-ect %d", einfo->ip_ect); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 117 | } |
| 118 | } |
| 119 | |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 120 | static struct xtables_match ecn_mt_reg = { |
Jan Engelhardt | e1df221 | 2011-02-15 12:02:51 +0100 | [diff] [blame] | 121 | .name = "ecn", |
| 122 | .version = XTABLES_VERSION, |
| 123 | .family = NFPROTO_IPV4, |
| 124 | .size = XT_ALIGN(sizeof(struct ipt_ecn_info)), |
| 125 | .userspacesize = XT_ALIGN(sizeof(struct ipt_ecn_info)), |
| 126 | .help = ecn_help, |
Jan Engelhardt | e1df221 | 2011-02-15 12:02:51 +0100 | [diff] [blame] | 127 | .print = ecn_print, |
| 128 | .save = ecn_save, |
Jan Engelhardt | e364632 | 2011-03-03 00:51:16 +0100 | [diff] [blame] | 129 | .x6_parse = ecn_parse, |
| 130 | .x6_fcheck = ecn_check, |
| 131 | .x6_options = ecn_opts, |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 132 | }; |
| 133 | |
| 134 | void _init(void) |
| 135 | { |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 136 | xtables_register_match(&ecn_mt_reg); |
Harald Welte | 7a44731 | 2002-05-29 15:11:49 +0000 | [diff] [blame] | 137 | } |