1469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Shared library add-on to iptables to add connmark matching support. 2469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 3469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 4469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * by Henrik Nordstrom <hno@marasystems.com> 5469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 6469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * Version 1.1 7469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 8469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is free software; you can redistribute it and/or modify 9469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * it under the terms of the GNU General Public License as published by 10469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * the Free Software Foundation; either version 2 of the License, or 11469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (at your option) any later version. 12469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 13469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is distributed in the hope that it will be useful, 14469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * but WITHOUT ANY WARRANTY; without even the implied warranty of 15469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * GNU General Public License for more details. 17469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 18469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * You should have received a copy of the GNU General Public License 19469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * along with this program; if not, write to the Free Software 20d6217f93926b174bb2e894c8a8fc3d73b01942e9Jiri Popelka * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte */ 2232b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt#include <stdbool.h> 237299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#include <stdint.h> 24469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <stdio.h> 25c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <xtables.h> 26c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <linux/netfilter/xt_connmark.h> 27469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 28350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct xt_connmark_info { 29350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt unsigned long mark, mask; 307ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt uint8_t invert; 31350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt}; 32350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt 33a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtenum { 347299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt O_MARK = 0, 35a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt}; 36a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 37a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void connmark_mt_help(void) 38469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 39469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf( 40a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt"connmark match options:\n" 418b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"[!] --mark value[/mask] Match ctmark value with optional mask\n"); 42469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 43469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 447299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic const struct xt_option_entry connmark_mt_opts[] = { 457299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32, 467299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt .flags = XTOPT_MAND | XTOPT_INVERT}, 477299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt XTOPT_TABLEEND, 48469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}; 49469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 507299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_mt_parse(struct xt_option_call *cb) 51a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{ 527299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt struct xt_connmark_mtinfo1 *info = cb->data; 537299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt 547299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt xtables_option_parse(cb); 557299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt if (cb->invert) 567299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt info->invert = true; 577299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt info->mark = cb->val.mark; 587299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt info->mask = cb->val.mask; 59a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt} 60a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 617299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_parse(struct xt_option_call *cb) 62469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 637299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt struct xt_connmark_info *markinfo = cb->data; 647299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt 657299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt xtables_option_parse(cb); 667299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt markinfo->mark = cb->val.mark; 677299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt markinfo->mask = cb->val.mask; 687299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt if (cb->invert) 697299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt markinfo->invert = 1; 70469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 71469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 72a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void print_mark(unsigned int mark, unsigned int mask) 73469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 74a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt if (mask != 0xffffffffU) 7573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" 0x%x/0x%x", mark, mask); 76469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte else 7773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" 0x%x", mark); 78469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 79469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 80469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltestatic void 81181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtconnmark_print(const void *ip, const struct xt_entry_match *match, int numeric) 82469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 8369f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_connmark_info *info = (const void *)match->data; 84469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 8573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" CONNMARK match "); 86469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (info->invert) 87469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("!"); 88a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt print_mark(info->mark, info->mask); 89a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt} 90a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 91a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void 92bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwajconnmark_mt_print(const void *ip, const struct xt_entry_match *match, 93bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj int numeric) 94a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{ 95a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 96a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 9773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" connmark match "); 98a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt if (info->invert) 99a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt printf("!"); 100a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt print_mark(info->mark, info->mask); 101469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 102469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 103181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connmark_save(const void *ip, const struct xt_entry_match *match) 104469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 10569f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt const struct xt_connmark_info *info = (const void *)match->data; 106469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 107469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (info->invert) 10873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 109469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 11073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --mark"); 111a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt print_mark(info->mark, info->mask); 112a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt} 113a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 114a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void 115a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtconnmark_mt_save(const void *ip, const struct xt_entry_match *match) 116a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{ 117a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 118a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 119a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt if (info->invert) 12073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" !"); 121a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt 12273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --mark"); 123a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt print_mark(info->mark, info->mask); 124469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 125469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 126bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwajstatic void print_mark_xlate(unsigned int mark, unsigned int mask, 1276b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso struct xt_xlate *xl, uint32_t op) 128bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj{ 129bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj if (mask != 0xffffffffU) 130f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay xt_xlate_add(xl, " and 0x%x %s 0x%x", mask, 1312bd49c03c8601aff8f951a8153e95bfdeb7b84d8Shivani Bhardwaj op == XT_OP_EQ ? "==" : "!=", mark); 132bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj else 133f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay xt_xlate_add(xl, " %s0x%x", 134bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj op == XT_OP_EQ ? "" : "!= ", mark); 135bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj} 136bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 1377a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusostatic int connmark_xlate(struct xt_xlate *xl, 1387a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso const struct xt_xlate_mt_params *params) 139bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj{ 1407a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso const struct xt_connmark_info *info = (const void *)params->match->data; 141bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj enum xt_op op = XT_OP_EQ; 142bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 143bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj if (info->invert) 144bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj op = XT_OP_NEQ; 145bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 1466b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso xt_xlate_add(xl, "ct mark"); 1476b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso print_mark_xlate(info->mark, info->mask, xl, op); 148bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 149bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj return 1; 150bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj} 151bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 152bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwajstatic int 1537a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusoconnmark_mt_xlate(struct xt_xlate *xl, 1547a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso const struct xt_xlate_mt_params *params) 155bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj{ 1567a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso const struct xt_connmark_mtinfo1 *info = 1577a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso (const void *)params->match->data; 158bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj enum xt_op op = XT_OP_EQ; 159bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 160bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj if (info->invert) 161bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj op = XT_OP_NEQ; 162bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 1636b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso xt_xlate_add(xl, "ct mark"); 1646b60dc5be58a5781cacc4e6f238454d5e8421760Pablo Neira Ayuso print_mark_xlate(info->mark, info->mask, xl, op); 165bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 166bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj return 1; 167bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj} 168bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj 169f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardtstatic struct xtables_match connmark_mt_reg[] = { 170f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt { 171f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .family = NFPROTO_UNSPEC, 172f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .name = "connmark", 173f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .revision = 0, 174f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .version = XTABLES_VERSION, 175f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 176f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 177f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .help = connmark_mt_help, 178f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .print = connmark_print, 179f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .save = connmark_save, 1807299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt .x6_parse = connmark_parse, 1817299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt .x6_options = connmark_mt_opts, 182bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj .xlate = connmark_xlate, 183f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt }, 184f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt { 185f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .version = XTABLES_VERSION, 186f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .name = "connmark", 187f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .revision = 1, 188f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .family = NFPROTO_UNSPEC, 189f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 190f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 191f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .help = connmark_mt_help, 192f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .print = connmark_mt_print, 193f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt .save = connmark_mt_save, 1947299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt .x6_parse = connmark_mt_parse, 1957299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt .x6_options = connmark_mt_opts, 196bdbf63b95176e6d7e7f968c9cb25d58d84fc729eShivani Bhardwaj .xlate = connmark_mt_xlate, 197f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt }, 198469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}; 199469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 200469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltevoid _init(void) 201469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 202f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg)); 203469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 204