1/* 2 * shared library add-on to iptables to add TPROXY target support. 3 * 4 * Copyright (C) 2002-2008 BalaBit IT Ltd. 5 */ 6#include <stdio.h> 7#include <limits.h> 8#include <xtables.h> 9#include <linux/netfilter/xt_TPROXY.h> 10#include <arpa/inet.h> 11 12enum { 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, 19}; 20 21#define s struct xt_tproxy_target_info 22static const struct xt_option_entry tproxy_tg0_opts[] = { 23 {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, 24 .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, 25 {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST}, 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 31static const struct xt_option_entry tproxy_tg1_opts[] = { 32 {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT, 33 .flags = XTOPT_MAND | XTOPT_NBO | XTOPT_PUT, XTOPT_POINTER(s, lport)}, 34 {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_HOST, 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 41static 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 50static 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; 54 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", 55 xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr), 56 ntohs(info->lport), (unsigned int)info->mark_value, 57 (unsigned int)info->mark_mask); 58} 59 60static void 61tproxy_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 67 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", 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 73static void 74tproxy_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 80 printf(" TPROXY redirect %s:%u mark 0x%x/0x%x", 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 86static 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 90 printf(" --on-port %u", ntohs(info->lport)); 91 printf(" --on-ip %s", 92 xtables_ipaddr_to_numeric((const struct in_addr *)&info->laddr)); 93 printf(" --tproxy-mark 0x%x/0x%x", 94 (unsigned int)info->mark_value, (unsigned int)info->mark_mask); 95} 96 97static void 98tproxy_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; 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", 106 (unsigned int)info->mark_value, (unsigned int)info->mark_mask); 107} 108 109static void 110tproxy_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; 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", 118 (unsigned int)info->mark_value, (unsigned int)info->mark_mask); 119} 120 121static 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: 132 info->laddr = cb->val.haddr.ip; 133 break; 134 } 135} 136 137static 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 150static 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, 159 .print = tproxy_tg_print, 160 .save = tproxy_tg_save, 161 .x6_options = tproxy_tg0_opts, 162 .x6_parse = tproxy_tg0_parse, 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, 172 .print = tproxy_tg_print4, 173 .save = tproxy_tg_save4, 174 .x6_options = tproxy_tg1_opts, 175 .x6_parse = tproxy_tg1_parse, 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, 185 .print = tproxy_tg_print6, 186 .save = tproxy_tg_save6, 187 .x6_options = tproxy_tg1_opts, 188 .x6_parse = tproxy_tg1_parse, 189 }, 190}; 191 192void _init(void) 193{ 194 xtables_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); 195} 196