libxt_TPROXY.c revision 5f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507
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 <getopt.h> 7#include <stdbool.h> 8#include <stdio.h> 9#include <string.h> 10#include <stdlib.h> 11#include <limits.h> 12 13#include <xtables.h> 14#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/xt_TPROXY.h> 16 17static const struct option tproxy_tg_opts[] = { 18 { .name = "on-port", .has_arg = 1, .val = '1'}, 19 { .name = "on-ip", .has_arg = 1, .val = '2'}, 20 { .name = "tproxy-mark", .has_arg = 1, .val = '3'}, 21 {NULL}, 22}; 23 24enum { 25 PARAM_ONPORT = 1 << 0, 26 PARAM_ONIP = 1 << 1, 27 PARAM_MARK = 1 << 2, 28}; 29 30static void tproxy_tg_help(void) 31{ 32 printf( 33"TPROXY target options:\n" 34" --on-port port Redirect connection to port, or the original port if 0\n" 35" --on-ip ip Optionally redirect to the given IP\n" 36" --tproxy-mark value[/mask] Mark packets with the given value/mask\n\n"); 37} 38 39static void parse_tproxy_lport(const char *s, struct xt_tproxy_target_info *info) 40{ 41 unsigned int lport; 42 43 if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX)) 44 info->lport = htons(lport); 45 else 46 param_act(P_BAD_VALUE, "TPROXY", "--on-port", s); 47} 48 49static void parse_tproxy_laddr(const char *s, struct xt_tproxy_target_info *info) 50{ 51 struct in_addr *laddr; 52 53 if ((laddr = numeric_to_ipaddr(s)) == NULL) 54 param_act(P_BAD_VALUE, "TPROXY", "--on-ip", s); 55 56 info->laddr = laddr->s_addr; 57} 58 59static void parse_tproxy_mark(char *s, struct xt_tproxy_target_info *info) 60{ 61 unsigned int value, mask = UINT32_MAX; 62 char *end; 63 64 if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX)) 65 param_act(P_BAD_VALUE, "TPROXY", "--tproxy-mark", s); 66 if (*end == '/') 67 if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) 68 param_act(P_BAD_VALUE, "TPROXY", "--tproxy-mark", s); 69 if (*end != '\0') 70 param_act(P_BAD_VALUE, "TPROXY", "--tproxy-mark", s); 71 72 info->mark_mask = mask; 73 info->mark_value = value; 74} 75 76static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags, 77 const void *entry, struct xt_entry_target **target) 78{ 79 struct xt_tproxy_target_info *tproxyinfo = (void *)(*target)->data; 80 81 switch (c) { 82 case '1': 83 param_act(P_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT); 84 param_act(P_NO_INVERT, "TPROXY", "--on-port", invert); 85 parse_tproxy_lport(optarg, tproxyinfo); 86 *flags |= PARAM_ONPORT; 87 return 1; 88 case '2': 89 param_act(P_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP); 90 param_act(P_NO_INVERT, "TPROXY", "--on-ip", invert); 91 parse_tproxy_laddr(optarg, tproxyinfo); 92 *flags |= PARAM_ONIP; 93 return 1; 94 case '3': 95 param_act(P_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK); 96 param_act(P_NO_INVERT, "TPROXY", "--tproxy-mark", invert); 97 parse_tproxy_mark(optarg, tproxyinfo); 98 *flags |= PARAM_MARK; 99 return 1; 100 } 101 102 return 0; 103} 104 105static void tproxy_tg_check(unsigned int flags) 106{ 107 if (!(flags & PARAM_ONPORT)) 108 exit_error(PARAMETER_PROBLEM, 109 "TPROXY target: Parameter --on-port is required"); 110} 111 112static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target, 113 int numeric) 114{ 115 const struct xt_tproxy_target_info *info = (const void *)target->data; 116 printf("TPROXY redirect %s:%u mark 0x%x/0x%x", 117 ipaddr_to_numeric((const struct in_addr *)&info->laddr), 118 ntohs(info->lport), (unsigned int)info->mark_value, 119 (unsigned int)info->mark_mask); 120} 121 122static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target) 123{ 124 const struct xt_tproxy_target_info *info = (const void *)target->data; 125 126 printf("--on-port %u ", ntohs(info->lport)); 127 printf("--on-ip %s ", 128 ipaddr_to_numeric((const struct in_addr *)&info->laddr)); 129 printf("--tproxy-mark 0x%x/0x%x ", 130 (unsigned int)info->mark_value, (unsigned int)info->mark_mask); 131} 132 133static struct xtables_target tproxy_tg_reg = { 134 .name = "TPROXY", 135 .family = NFPROTO_IPV4, 136 .version = XTABLES_VERSION, 137 .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), 138 .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), 139 .help = tproxy_tg_help, 140 .parse = tproxy_tg_parse, 141 .final_check = tproxy_tg_check, 142 .print = tproxy_tg_print, 143 .save = tproxy_tg_save, 144 .extra_opts = tproxy_tg_opts, 145}; 146 147void _init(void) 148{ 149 xtables_register_target(&tproxy_tg_reg); 150} 151