KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 1 | /* |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 2 | * shared library add-on to iptables to add TPROXY target support. |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 3 | * |
| 4 | * Copyright (C) 2002-2008 BalaBit IT Ltd. |
| 5 | */ |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 6 | #include <stdio.h> |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 7 | #include <limits.h> |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 8 | #include <xtables.h> |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 9 | #include <linux/netfilter/xt_TPROXY.h> |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 10 | #include <arpa/inet.h> |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 11 | |
| 12 | enum { |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 13 | P_PORT = 0, |
| 14 | P_ADDR, |
| 15 | P_MARK, |
| 16 | F_PORT = 1 << P_PORT, |
| 17 | F_ADDR = 1 << P_ADDR, |
| 18 | F_MARK = 1 << P_MARK, |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 19 | }; |
| 20 | |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 21 | #define s struct xt_tproxy_target_info |
| 22 | static const struct xt_option_entry tproxy_tg0_opts[] = { |
Jan Engelhardt | c02c92d | 2011-05-18 22:48:51 +0200 | [diff] [blame] | 23 | {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, |
| 24 | .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, |
Jan Engelhardt | d728241 | 2011-05-04 16:41:13 +0200 | [diff] [blame] | 25 | {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST}, |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 26 | {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, |
| 27 | XTOPT_TABLEEND, |
| 28 | }; |
| 29 | #undef s |
| 30 | #define s struct xt_tproxy_target_info_v1 |
| 31 | static const struct xt_option_entry tproxy_tg1_opts[] = { |
Jan Engelhardt | c02c92d | 2011-05-18 22:48:51 +0200 | [diff] [blame] | 32 | {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, |
| 33 | .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, |
Jan Engelhardt | d728241 | 2011-05-04 16:41:13 +0200 | [diff] [blame] | 34 | {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST, |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 35 | .flags = XTOPT_PUT, XTOPT_POINTER(s, laddr)}, |
| 36 | {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, |
| 37 | XTOPT_TABLEEND, |
| 38 | }; |
| 39 | #undef s |
| 40 | |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 41 | static void tproxy_tg_help(void) |
| 42 | { |
| 43 | printf( |
| 44 | "TPROXY target options:\n" |
| 45 | " --on-port port Redirect connection to port, or the original port if 0\n" |
| 46 | " --on-ip ip Optionally redirect to the given IP\n" |
| 47 | " --tproxy-mark value[/mask] Mark packets with the given value/mask\n\n"); |
| 48 | } |
| 49 | |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 50 | static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target, |
| 51 | int numeric) |
| 52 | { |
| 53 | const struct xt_tproxy_target_info *info = (const void *)target->data; |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 54 | printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", |
Jan Engelhardt | e44ea7f | 2009-01-30 03:55:09 +0100 | [diff] [blame] | 55 | xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr), |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 56 | ntohs(info->lport), (unsigned int)info->mark_value, |
| 57 | (unsigned int)info->mark_mask); |
| 58 | } |
| 59 | |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 60 | static void |
| 61 | tproxy_tg_print4(const void *ip, const struct xt_entry_target *target, |
| 62 | int numeric) |
| 63 | { |
| 64 | const struct xt_tproxy_target_info_v1 *info = |
| 65 | (const void *)target->data; |
| 66 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 67 | printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 68 | xtables_ipaddr_to_numeric(&info->laddr.in), |
| 69 | ntohs(info->lport), (unsigned int)info->mark_value, |
| 70 | (unsigned int)info->mark_mask); |
| 71 | } |
| 72 | |
| 73 | static void |
| 74 | tproxy_tg_print6(const void *ip, const struct xt_entry_target *target, |
| 75 | int numeric) |
| 76 | { |
| 77 | const struct xt_tproxy_target_info_v1 *info = |
| 78 | (const void *)target->data; |
| 79 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 80 | printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 81 | xtables_ip6addr_to_numeric(&info->laddr.in6), |
| 82 | ntohs(info->lport), (unsigned int)info->mark_value, |
| 83 | (unsigned int)info->mark_mask); |
| 84 | } |
| 85 | |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 86 | static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target) |
| 87 | { |
| 88 | const struct xt_tproxy_target_info *info = (const void *)target->data; |
| 89 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 90 | printf(" --on-port %u", ntohs(info->lport)); |
| 91 | printf(" --on-ip %s", |
Jan Engelhardt | e44ea7f | 2009-01-30 03:55:09 +0100 | [diff] [blame] | 92 | xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr)); |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 93 | printf(" --tproxy-mark 0x%x/0x%x", |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 94 | (unsigned int)info->mark_value, (unsigned int)info->mark_mask); |
| 95 | } |
| 96 | |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 97 | static void |
| 98 | tproxy_tg_save4(const void *ip, const struct xt_entry_target *target) |
| 99 | { |
| 100 | const struct xt_tproxy_target_info_v1 *info; |
| 101 | |
| 102 | info = (const void *)target->data; |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 103 | printf(" --on-port %u", ntohs(info->lport)); |
| 104 | printf(" --on-ip %s", xtables_ipaddr_to_numeric(&info->laddr.in)); |
| 105 | printf(" --tproxy-mark 0x%x/0x%x", |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 106 | (unsigned int)info->mark_value, (unsigned int)info->mark_mask); |
| 107 | } |
| 108 | |
| 109 | static void |
| 110 | tproxy_tg_save6(const void *ip, const struct xt_entry_target *target) |
| 111 | { |
| 112 | const struct xt_tproxy_target_info_v1 *info; |
| 113 | |
| 114 | info = (const void *)target->data; |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 115 | printf(" --on-port %u", ntohs(info->lport)); |
| 116 | printf(" --on-ip %s", xtables_ip6addr_to_numeric(&info->laddr.in6)); |
| 117 | printf(" --tproxy-mark 0x%x/0x%x", |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 118 | (unsigned int)info->mark_value, (unsigned int)info->mark_mask); |
| 119 | } |
| 120 | |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 121 | static void tproxy_tg0_parse(struct xt_option_call *cb) |
| 122 | { |
| 123 | struct xt_tproxy_target_info *info = cb->data; |
| 124 | |
| 125 | xtables_option_parse(cb); |
| 126 | switch (cb->entry->id) { |
| 127 | case P_MARK: |
| 128 | info->mark_value = cb->val.mark; |
| 129 | info->mark_mask = cb->val.mask; |
| 130 | break; |
| 131 | case P_ADDR: |
Jan Engelhardt | d728241 | 2011-05-04 16:41:13 +0200 | [diff] [blame] | 132 | info->laddr = cb->val.haddr.ip; |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 133 | break; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | static void tproxy_tg1_parse(struct xt_option_call *cb) |
| 138 | { |
| 139 | struct xt_tproxy_target_info_v1 *info = cb->data; |
| 140 | |
| 141 | xtables_option_parse(cb); |
| 142 | switch (cb->entry->id) { |
| 143 | case P_MARK: |
| 144 | info->mark_value = cb->val.mark; |
| 145 | info->mark_mask = cb->val.mask; |
| 146 | break; |
| 147 | } |
| 148 | } |
| 149 | |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 150 | static struct xtables_target tproxy_tg_reg[] = { |
| 151 | { |
| 152 | .name = "TPROXY", |
| 153 | .revision = 0, |
| 154 | .family = NFPROTO_IPV4, |
| 155 | .version = XTABLES_VERSION, |
| 156 | .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), |
| 157 | .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), |
| 158 | .help = tproxy_tg_help, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 159 | .print = tproxy_tg_print, |
| 160 | .save = tproxy_tg_save, |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 161 | .x6_options = tproxy_tg0_opts, |
| 162 | .x6_parse = tproxy_tg0_parse, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 163 | }, |
| 164 | { |
| 165 | .name = "TPROXY", |
| 166 | .revision = 1, |
| 167 | .family = NFPROTO_IPV4, |
| 168 | .version = XTABLES_VERSION, |
| 169 | .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), |
| 170 | .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), |
| 171 | .help = tproxy_tg_help, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 172 | .print = tproxy_tg_print4, |
| 173 | .save = tproxy_tg_save4, |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 174 | .x6_options = tproxy_tg1_opts, |
| 175 | .x6_parse = tproxy_tg1_parse, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 176 | }, |
| 177 | { |
| 178 | .name = "TPROXY", |
| 179 | .revision = 1, |
| 180 | .family = NFPROTO_IPV6, |
| 181 | .version = XTABLES_VERSION, |
| 182 | .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), |
| 183 | .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), |
| 184 | .help = tproxy_tg_help, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 185 | .print = tproxy_tg_print6, |
| 186 | .save = tproxy_tg_save6, |
Jan Engelhardt | 64cb56e | 2011-02-09 02:15:22 +0100 | [diff] [blame] | 187 | .x6_options = tproxy_tg1_opts, |
| 188 | .x6_parse = tproxy_tg1_parse, |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 189 | }, |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 190 | }; |
| 191 | |
| 192 | void _init(void) |
| 193 | { |
Jan Engelhardt | 9e152fa | 2010-12-03 22:08:32 +0100 | [diff] [blame] | 194 | xtables_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); |
KOVACS Krisztian | 92b54aa | 2008-10-15 11:49:37 +0200 | [diff] [blame] | 195 | } |