diff --git a/src/libxt_ts3init.c b/src/libxt_ts3init.c index b2b49fa..aff7dd3 100644 --- a/src/libxt_ts3init.c +++ b/src/libxt_ts3init.c @@ -1,5 +1,5 @@ /* - * "ts3init" match extension for iptables + * "ts3init_get_cookie and ts3init_get_puzzle" match extension for iptables * Niels Werensteijn , 2016-10-03 * * This program is free software; you can redistribute it and/or modify it @@ -15,41 +15,86 @@ #include #include #include "ts3init_match.h" -/* -#include "compat_user.h" -*/ -#define param_act(t, s, f) xtables_param_act((t), "ts3init", (s), (f)) -static void ts3init_help(void) +#define param_act(t, s, f) xtables_param_act((t), "ts3init_get_cookie", (s), (f)) + +static void ts3init_get_cookie_help(void) { printf( -"ts3init match options:\n" -" --get-cookie Check if packet is 'get-cookie' request.\n" -" --get-puzzle Check if packet is 'get-puzzle' request.\n" -" --min-client n The sending client needs to be at least version n.\n" -"\n" -"get-cookie options:\n" -" --check-time sec Check packet send time request. May be off by sec seconds.\n" -"\n" -"get-puzzle options:\n" -" --check-cookie seed Check the cookie. Assume it was generated with seed.\n" -" seed is a 64 byte random number in lowecase hex. Could be\n" -" generated with sha512 of something.\n" -); + "ts3init_get_cookie match options:\n" + " --min-client n The sending client needs to be at least version n.\n" + " --check-time sec Check packet send time request. May be off by sec seconds.\n" + ); } -static const struct option ts3init_opts[] = { - {.name = "get-cookie", .has_arg = false, .val = '1'}, - {.name = "get-puzzle", .has_arg = false, .val = '2'}, - {.name = "min-client", .has_arg = true, .val = '3'}, - {.name = "check-time", .has_arg = true, .val = '4'}, - {.name = "check-cookie", .has_arg = true, .val = '5'}, +static const struct option ts3init_get_cookie_opts[] = { + {.name = "min-client", .has_arg = true, .val = '1'}, + {.name = "check-time", .has_arg = true, .val = '2'}, {NULL}, }; +static int ts3init_get_cookie_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_ts3init_get_cookie_mtinfo *info = (void *)(*match)->data; + int client_version; + int time_offset; + + switch (c) { + case '1': + param_act(XTF_ONLY_ONCE, "--min-client", info->common_options & CHK_COMMON_CLIENT_VERSION); + param_act(XTF_NO_INVERT, "--min-client", invert); + client_version = atoi(optarg); + if (client_version <= 0) + xtables_error(PARAMETER_PROBLEM, + "ts3init_get_cookie: invalid min-client version"); + info->common_options |= CHK_COMMON_CLIENT_VERSION; + info->min_client_version = client_version; + return true; + + case '2': + param_act(XTF_ONLY_ONCE, "--check-time", info->specific_options & CHK_GET_COOKIE_CHECK_TIMESTAMP); + param_act(XTF_NO_INVERT, "--check-time", invert); + time_offset = atoi(optarg); + if (time_offset <= 0) + xtables_error(PARAMETER_PROBLEM, + "ts3init_get_cookie: invalid time offset"); + info->specific_options |= CHK_GET_COOKIE_CHECK_TIMESTAMP; + info->max_utc_offset = time_offset; + return true; + + default: + return false; + } +} + +static void ts3init_get_cookie_save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_ts3init_get_cookie_mtinfo *info = (const void *)match->data; + if (info->common_options & CHK_COMMON_CLIENT_VERSION) + { + printf("--min-client %u ", info->min_client_version); + } + if (info->specific_options & CHK_GET_COOKIE_CHECK_TIMESTAMP) + { + printf("--check-time %u ", info->max_utc_offset); + } +} + +static void ts3init_get_cookie_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + printf(" -m ts3init_get_cookie "); + ts3init_get_cookie_save(ip, match); +} + + +#undef param_act +#define param_act(t, s, f) xtables_param_act((t), "ts3init_get_puzzle", (s), (f)) + static bool hex2int_seed(const char *src, __u8* dst) { - for (int i = 0; i < 64; ++i) + for (int i = 0; i < 60; ++i) { int v = 0; for (int j = 0; j < 2; ++j) @@ -66,75 +111,51 @@ static bool hex2int_seed(const char *src, __u8* dst) return true; } -static int ts3init_parse(int c, char **argv, int invert, unsigned int *flags, +static void ts3init_get_puzzle_help(void) +{ + printf( + "ts3init_get_puzzle match options:\n" + " --min-client n The sending client needs to be at least version n.\n" + " --check-cookie seed Check the cookie. Assume it was generated with seed.\n" + " seed is a 60 byte random number in lowecase hex. A source\n" + " could be /dev/random.\n" +); +} + +static const struct option ts3init_get_puzzle_opts[] = { + {.name = "min-client", .has_arg = true, .val = '1'}, + {.name = "check-cookie", .has_arg = true, .val = '2'}, + {NULL}, +}; + +static int ts3init_get_puzzle_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { - struct xt_ts3init_mtinfo *info = (void *)(*match)->data; + struct xt_ts3init_get_puzzle_mtinfo *info = (void *)(*match)->data; int client_version; - int time_offset; switch (c) { case '1': - param_act(XTF_ONLY_ONCE, "--get-cookie", (*flags & COMMAND_MASK) == COMMAND_CHECK_GET_COOKIE); - param_act(XTF_NO_INVERT, "--get-cookie", invert); - if ((*flags & COMMAND_MASK) == COMMAND_CHECK_GET_PUZZLE) - xtables_error(PARAMETER_PROBLEM, - "ts3init: use `--get-cookie' OR `--get-puzzle' but not both of them!"); - *flags |= COMMAND_CHECK_GET_COOKIE; - info->command_check_and_options |= COMMAND_CHECK_GET_COOKIE; - return true; - - case '2': - param_act(XTF_ONLY_ONCE, "--get-puzzle", (*flags & COMMAND_MASK) == COMMAND_CHECK_GET_PUZZLE); - param_act(XTF_NO_INVERT, "--get-puzzle", invert); - if ((*flags & COMMAND_MASK) == COMMAND_CHECK_GET_COOKIE) - xtables_error(PARAMETER_PROBLEM, - "ts3init: use `--get-cookie' OR `--get-puzzle' but not both of them!"); - *flags |= COMMAND_CHECK_GET_PUZZLE; - info->command_check_and_options |= COMMAND_CHECK_GET_PUZZLE; - return true; - - case '3': - param_act(XTF_ONLY_ONCE, "--min-client", *flags & CHK_COMMON_CLIENT_VERSION); + param_act(XTF_ONLY_ONCE, "--min-client", info->common_options & CHK_COMMON_CLIENT_VERSION); param_act(XTF_NO_INVERT, "--min-client", invert); client_version = atoi(optarg); if (client_version <= 0) xtables_error(PARAMETER_PROBLEM, - "ts3init: invalid min-client version"); - *flags |= CHK_COMMON_CLIENT_VERSION; - info->command_check_and_options |= CHK_COMMON_CLIENT_VERSION; + "ts3init_get_cookie: invalid min-client version"); + info->common_options |= CHK_COMMON_CLIENT_VERSION; info->min_client_version = client_version; return true; - case '4': - param_act(XTF_ONLY_ONCE, "--check-time", *flags & CHK_GET_COOKIE_CHECK_TIMESTAMP); - param_act(XTF_NO_INVERT, "--check-time", invert); - if ((*flags & COMMAND_MASK) != COMMAND_CHECK_GET_COOKIE) - xtables_error(PARAMETER_PROBLEM, - "ts3init: --check-time can only work together with --get-cookie"); - time_offset = atoi(optarg); - if (time_offset <= 0) - xtables_error(PARAMETER_PROBLEM, - "ts3init: invalid time offset"); - *flags |= CHK_GET_COOKIE_CHECK_TIMESTAMP; - info->command_check_and_options |= CHK_GET_COOKIE_CHECK_TIMESTAMP; - info->get_cookie_opts.max_utc_offset = time_offset; - return true; - - case '5': - param_act(XTF_ONLY_ONCE, "--check-cookie", *flags & CHK_GET_PUZZLE_CHECK_COOKIE); + case '2': + param_act(XTF_ONLY_ONCE, "--check-cookie", info->specific_options & CHK_GET_PUZZLE_CHECK_COOKIE); param_act(XTF_NO_INVERT, "--check-cookie", invert); - if ((*flags & COMMAND_MASK) != COMMAND_CHECK_GET_PUZZLE) - xtables_error(PARAMETER_PROBLEM, - "ts3init: --check-cookie can only work together with --get-puzzle"); - if (strlen(optarg) != 128) + if (strlen(optarg) != 120) xtables_error(PARAMETER_PROBLEM, - "ts3init: invalid cookie-seed length"); - if (!hex2int_seed(optarg, info->get_puzzle_opts.cookie_seed)) + "ts3init_get_puzzle: invalid cookie-seed length"); + if (!hex2int_seed(optarg, info->cookie_seed)) xtables_error(PARAMETER_PROBLEM, - "ts3init: invalid cookie-seed. (not lowercase hex)"); - *flags |= CHK_GET_PUZZLE_CHECK_COOKIE; - info->command_check_and_options |= CHK_GET_PUZZLE_CHECK_COOKIE; + "ts3init_get_puzzle: invalid cookie-seed. (not lowercase hex)"); + info->specific_options |= CHK_GET_PUZZLE_CHECK_COOKIE; return true; default: @@ -142,74 +163,63 @@ static int ts3init_parse(int c, char **argv, int invert, unsigned int *flags, } } -static void ts3init_check(unsigned int flags) +static void ts3init_get_puzzle_save(const void *ip, const struct xt_entry_match *match) { - if ((flags & COMMAND_MASK) == 0) - xtables_error(PARAMETER_PROBLEM, - "TS3init match: must specify --get-cookie or --get-puzzle"); -} - -static void ts3init_save(const void *ip, const struct xt_entry_match *match) -{ - const struct xt_ts3init_mtinfo *info = (const void *)match->data; - if ((info->command_check_and_options & COMMAND_MASK) == COMMAND_CHECK_GET_COOKIE) - { - printf("--get-cookie "); - } - else - { - printf("--get-puzzle "); - } - if (info->command_check_and_options & CHK_COMMON_CLIENT_VERSION) + const struct xt_ts3init_get_puzzle_mtinfo *info = (const void *)match->data; + if (info->common_options & CHK_COMMON_CLIENT_VERSION) { printf("--min-client %u ", info->min_client_version); } - if ((info->command_check_and_options & COMMAND_MASK) == COMMAND_CHECK_GET_COOKIE) - { - if (info->command_check_and_options & CHK_GET_COOKIE_CHECK_TIMESTAMP) - { - printf("--check-time %u ", info->get_cookie_opts.max_utc_offset); - } - } - else + if (info->specific_options & CHK_GET_PUZZLE_CHECK_COOKIE) { - if (info->command_check_and_options & CHK_GET_PUZZLE_CHECK_COOKIE) + printf("--check-cookie "); + for (int i = 0; i < 60; i++) { - printf("--check-cookie "); - for (int i = 0; i < 64; i++) - { - printf("%02X", info->get_puzzle_opts.cookie_seed[i]); - } - printf(" "); + printf("%02X", info->cookie_seed[i]); } + printf(" "); } - } -static void ts3init_print(const void *ip, const struct xt_entry_match *match, +static void ts3init_get_puzzle_print(const void *ip, const struct xt_entry_match *match, int numeric) { - printf(" -m ts3init "); - ts3init_save(ip, match); + printf(" -m ts3init_get_puzzle "); + ts3init_get_puzzle_save(ip, match); } -static struct xtables_match ts3init_mt_reg = { - .name = "ts3init", - .revision = 0, +/* register and init */ +static struct xtables_match ts3init_get_cookie_mt_reg = { + .name = "ts3init_get_cookie", + .revision = 0, + .family = NFPROTO_UNSPEC, + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_ts3init_get_cookie_mtinfo)), + .userspacesize = XT_ALIGN(sizeof(struct xt_ts3init_get_cookie_mtinfo)), + .help = ts3init_get_cookie_help, + .parse = ts3init_get_cookie_parse, + .print = ts3init_get_cookie_print, + .save = ts3init_get_cookie_save, + .extra_opts = ts3init_get_cookie_opts, +}; + +static struct xtables_match ts3init_get_puzzle_mt_reg = { + .name = "ts3init_get_puzzle", + .revision = 0, .family = NFPROTO_UNSPEC, - .version = XTABLES_VERSION, - .size = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)), - .userspacesize = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)), - .help = ts3init_help, - .parse = ts3init_parse, - .final_check = ts3init_check, - .print = ts3init_print, - .save = ts3init_save, - .extra_opts = ts3init_opts, + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_ts3init_get_puzzle_mtinfo)), + .userspacesize = XT_ALIGN(sizeof(struct xt_ts3init_get_puzzle_mtinfo)), + .help = ts3init_get_puzzle_help, + .parse = ts3init_get_puzzle_parse, + .print = ts3init_get_puzzle_print, + .save = ts3init_get_puzzle_save, + .extra_opts = ts3init_get_puzzle_opts, }; static __attribute__((constructor)) void ts3init_mt_ldr(void) { - xtables_register_match(&ts3init_mt_reg); + xtables_register_match(&ts3init_get_cookie_mt_reg); + xtables_register_match(&ts3init_get_puzzle_mt_reg); } diff --git a/src/ts3init_match.c b/src/ts3init_match.c index 35b3f8e..7131d04 100644 --- a/src/ts3init_match.c +++ b/src/ts3init_match.c @@ -31,7 +31,8 @@ struct ts3init_cache_t struct ts3_init_header_tag { - union { + union + { char tag8[8]; __aligned_u64 tag64; }; @@ -43,21 +44,58 @@ struct ts3_init_header __be16 packet_id; __be16 client_id; __u8 flags; - __u8 client_version_0; - __u8 client_version_1; - __u8 client_version_2; - __u8 client_version_3; + __u8 client_version[4]; __u8 command; __u8 payload[20]; }; -static const __u16 packet_payload_size[2] = { 34, 38 }; +struct ts3_init_checked_header_data +{ + struct udphdr *udp, udp_buf; + struct ts3_init_header* ts3_header, ts3_header_buf; +}; + +enum +{ + GET_COOKIE_PAYLOAD_SIZE = 34, + GET_PUZZLE_PAYLOAD_SIZE = 38 +}; static const struct ts3_init_header_tag header_tag_signature = { .tag8 = {'T', 'S', '3', 'I', 'N', 'I', 'T', '1'} }; DEFINE_PER_CPU(struct ts3init_cache_t, ts3init_cache); +static inline bool check_header(const struct sk_buff *skb, struct xt_action_param *par, + int payload_size, struct ts3_init_checked_header_data* header_data) +{ + unsigned int data_len; + struct udphdr *udp; + struct ts3_init_header* ts3_header; + + udp = skb_header_pointer(skb, par->thoff, sizeof(*udp), &header_data->udp_buf); + data_len = be16_to_cpu(udp->len) - sizeof(*udp); + + if (data_len != payload_size) return false; + + ts3_header = (struct ts3_init_header*) skb_header_pointer(skb, + par->thoff + sizeof(*udp), data_len, + &header_data->ts3_header_buf); + + if (!ts3_header) return false; + + if (ts3_header->tag.tag64 != header_tag_signature.tag64) return false; + if (ts3_header->packet_id != cpu_to_be16(101)) return false; + if (ts3_header->client_id != 0) return false; + if (ts3_header->flags != 0x88) return false; + + /* TODO: check min_client_version if needed */ + + header_data->udp = udp; + header_data->ts3_header = ts3_header; + return true; +} + static inline void update_cache_time(unsigned long jifs, struct ts3init_cache_t* cache) { @@ -73,176 +111,171 @@ static inline void update_cache_time(unsigned long jifs, } static bool -ts3init_mt(const struct sk_buff *skb, struct xt_action_param *par) +ts3init_get_cookie_mt(const struct sk_buff *skb, struct xt_action_param *par) { - struct udphdr *udp, udp_buf; - struct ts3init_cache_t* cache; - unsigned int data_len; - unsigned long jifs; - time_t current_unix_time, packet_unix_time; - struct ts3_init_header* ts3_header, ts3_header_buf; - const struct xt_ts3init_mtinfo *info = par->matchinfo; - __u8* cookie_seed; - __u8 cookie[8]; - - __u8 command = info->command_check_and_options & COMMAND_MASK; + const struct xt_ts3init_get_cookie_mtinfo *info = par->matchinfo; + struct ts3_init_checked_header_data header_data; + + if (!check_header(skb, par, GET_COOKIE_PAYLOAD_SIZE, &header_data)) + return false; + + if (header_data.ts3_header->command != 0) return false; + + if (info->specific_options & CHK_GET_COOKIE_CHECK_TIMESTAMP) + { + struct ts3init_cache_t* cache; + unsigned long jifs; + time_t current_unix_time, packet_unix_time; - udp = skb_header_pointer(skb, par->thoff, sizeof(*udp), &udp_buf); - data_len = be16_to_cpu(udp->len) - sizeof(*udp); + jifs = jiffies; + + cache = &get_cpu_var(ts3init_cache); + + update_cache_time(jifs, cache); + + current_unix_time = cache->unix_time; + + put_cpu_var(ts3init_cache); - if (data_len != packet_payload_size[command-1]) return false; + packet_unix_time = + header_data.ts3_header->payload[0] << 24 | + header_data.ts3_header->payload[1] << 16 | + header_data.ts3_header->payload[2] << 8 | + header_data.ts3_header->payload[3]; - ts3_header = (struct ts3_init_header*) skb_header_pointer(skb, - par->thoff + sizeof(*udp), data_len, &ts3_header_buf); + if (abs(current_unix_time - packet_unix_time) > info->max_utc_offset) + return false; + } + return true; +} - if (!ts3_header) return false; +static int ts3init_get_cookie_mt_check(const struct xt_mtchk_param *par) +{ + struct xt_ts3init_get_cookie_mtinfo *info = par->matchinfo; - if (ts3_header->tag.tag64 != header_tag_signature.tag64) return false; - if (ts3_header->packet_id != cpu_to_be16(101)) return false; - if (ts3_header->client_id != 0) return false; - if (ts3_header->flags != 0x88) return false; + if (info->common_options & ~(CHK_COMMON_VALID_MASK)) + { + printk(KERN_INFO KBUILD_MODNAME ": invalid (common) options for get_cookie\n"); + return -EINVAL; + } - /* TODO: check min_client_version if needed */ - - switch (command) + if (info->specific_options & ~(CHK_GET_COOKIE_VALID_MASK)) { - case COMMAND_CHECK_GET_COOKIE: - { - if (ts3_header->command != 0) return false; + printk(KERN_INFO KBUILD_MODNAME ": invalid (specific) options for get_cookie\n"); + return -EINVAL; + } + + return 0; +} - if (info->command_check_and_options & CHK_GET_COOKIE_CHECK_TIMESTAMP) - { - jifs = jiffies; - - cache = &get_cpu_var(ts3init_cache); - - update_cache_time(jifs, cache); - - current_unix_time = cache->unix_time; - - put_cpu_var(ts3init_cache); - - packet_unix_time = - ts3_header->payload[0] << 24 | - ts3_header->payload[1] << 16 | - ts3_header->payload[2] << 8 | - ts3_header->payload[3]; - - if (abs(current_unix_time - packet_unix_time) > - info->get_cookie_opts.max_utc_offset) return false; - } - return true; - } +static bool +ts3init_get_puzzle_mt(const struct sk_buff *skb, struct xt_action_param *par) +{ + const struct xt_ts3init_get_puzzle_mtinfo *info = par->matchinfo; + struct ts3_init_checked_header_data header_data; + + if (!check_header(skb, par, GET_PUZZLE_PAYLOAD_SIZE, &header_data)) + return false; - case COMMAND_CHECK_GET_PUZZLE: - { - if (ts3_header->command != 2) return false; + if (header_data.ts3_header->command != 2) return false; + + if (info->specific_options & CHK_GET_PUZZLE_CHECK_COOKIE) + { + struct ts3init_cache_t* cache; + struct ts3_init_header* ts3_header = header_data.ts3_header; + __u8* cookie_seed; + /*__u8 cookie[8];*/ + unsigned long jifs; + time_t current_unix_time; - if (info->command_check_and_options & CHK_GET_PUZZLE_CHECK_COOKIE) - { - jifs = jiffies; - cache = &get_cpu_var(ts3init_cache); + jifs = jiffies; + cache = &get_cpu_var(ts3init_cache); - update_cache_time(jifs, cache); + update_cache_time(jifs, cache); - current_unix_time = cache->unix_time; + current_unix_time = cache->unix_time; - cookie_seed = get_cookie_seed(current_unix_time, - ts3_header->payload[8], &cache->cookie_cache, - info->get_puzzle_opts.cookie_seed); + cookie_seed = get_cookie_seed(current_unix_time, + ts3_header->payload[8], &cache->cookie_cache, + info->cookie_seed); - if (!cookie_seed) - { - put_cpu_var(ts3init_cache); - return false; - } - - /* use cookie_seed and ipaddress and port to create a hash - * (cookie) for this connection */ - /* TODO: implement using sipHash */ - put_cpu_var(ts3init_cache); - - /* compare cookie with payload bytes 0-7. if equal, cookie - * is valid */ - /*if (memcmp(cookie, ts3_header->payload, 8) != 0) return false;*/ - - } - return true; - } - - default: + if (!cookie_seed) + { + put_cpu_var(ts3init_cache); return false; - }; + } + + /* use cookie_seed and ipaddress and port to create a hash + * (cookie) for this connection */ + /* TODO: implement using sipHash */ + put_cpu_var(ts3init_cache); + + /* compare cookie with payload bytes 0-7. if equal, cookie + * is valid */ + /*if (memcmp(cookie, ts3_header->payload, 8) != 0) return false;*/ + + } + return true; } -static int ts3init_mt_check(const struct xt_mtchk_param *par) +static int ts3init_get_puzzle_mt_check(const struct xt_mtchk_param *par) { - struct xt_ts3init_mtinfo *info = par->matchinfo; - __u8 command; - - if (info->command_check_and_options & - ~(COMMAND_AND_CHK_COMMON_MASK | COMMAND_SPECIFIC_OPTIONS_MASK)) + struct xt_ts3init_get_puzzle_mtinfo *info = par->matchinfo; + if (info->common_options & ~(CHK_COMMON_VALID_MASK)) { - printk(KERN_INFO KBUILD_MODNAME ": invalid command or common options\n"); + printk(KERN_INFO KBUILD_MODNAME ": invalid (common) options for get_puzzle\n"); return -EINVAL; } - command = info->command_check_and_options & COMMAND_MASK; - switch (command) + if (info->specific_options & ~(CHK_GET_PUZZLE_VALID_MASK)) { - case COMMAND_CHECK_GET_COOKIE: - { - if (info->command_check_and_options & - ~(COMMAND_AND_CHK_COMMON_MASK | CHK_GET_COOKIE_MASK)) - { - printk(KERN_INFO KBUILD_MODNAME ": invalid get_cookie options\n"); - return -EINVAL; - } - return 0; - } - case COMMAND_CHECK_GET_PUZZLE: - { - if (info->command_check_and_options & - ~(COMMAND_AND_CHK_COMMON_MASK | CHK_GET_PUZZLE_MASK)) - { - printk(KERN_INFO KBUILD_MODNAME ": invalid get_puzzle options\n"); - return -EINVAL; - } - return 0; - } - default: - { - printk(KERN_INFO KBUILD_MODNAME ": invalid command value\n"); - return -EINVAL; - } + printk(KERN_INFO KBUILD_MODNAME ": invalid (specific) options for get_cookie\n"); + return -EINVAL; } + + return 0; } -static void ts3init_mt_destroy(const struct xt_mtdtor_param *par) -{ -} static struct xt_match ts3init_mt_reg[] __read_mostly = { { - .name = "ts3init", + .name = "ts3init_get_cookie", + .revision = 0, + .family = NFPROTO_IPV4, + .proto = IPPROTO_UDP, + .matchsize = sizeof(struct xt_ts3init_get_cookie_mtinfo), + .match = ts3init_get_cookie_mt, + .checkentry = ts3init_get_cookie_mt_check, + .me = THIS_MODULE, + }, + { + .name = "ts3init_get_cookie", + .revision = 0, + .family = NFPROTO_IPV6, + .proto = IPPROTO_UDP, + .matchsize = sizeof(struct xt_ts3init_get_cookie_mtinfo), + .match = ts3init_get_cookie_mt, + .checkentry = ts3init_get_cookie_mt_check, + .me = THIS_MODULE, + }, + { + .name = "ts3init_get_puzzle", .revision = 0, .family = NFPROTO_IPV4, .proto = IPPROTO_UDP, - .matchsize = sizeof(struct xt_ts3init_mtinfo), - .match = ts3init_mt, - .checkentry = ts3init_mt_check, - .destroy = ts3init_mt_destroy, + .matchsize = sizeof(struct xt_ts3init_get_puzzle_mtinfo), + .match = ts3init_get_puzzle_mt, + .checkentry = ts3init_get_puzzle_mt_check, .me = THIS_MODULE, }, { - .name = "ts3init", + .name = "ts3init_get_puzzle", .revision = 0, .family = NFPROTO_IPV6, .proto = IPPROTO_UDP, - .matchsize = sizeof(struct xt_ts3init_mtinfo), - .match = ts3init_mt, - .checkentry = ts3init_mt_check, - .destroy = ts3init_mt_destroy, + .matchsize = sizeof(struct xt_ts3init_get_puzzle_mtinfo), + .match = ts3init_get_puzzle_mt, + .checkentry = ts3init_get_puzzle_mt_check, .me = THIS_MODULE, }, }; diff --git a/src/ts3init_match.h b/src/ts3init_match.h index 5e5152e..269c356 100644 --- a/src/ts3init_match.h +++ b/src/ts3init_match.h @@ -1,43 +1,46 @@ #ifndef _TS3INIT_MATCH_H #define _TS3INIT_MATCH_H -enum { - SEED_SHA512_LEN = 512 / 8 +/* Enums for get_cookie and get_puzzle matches */ +enum +{ + CHK_COMMON_CLIENT_VERSION = 1 << 0, + CHK_COMMON_VALID_MASK = (1 << 1) -1 }; -enum { - COMMAND_CHECK_GET_COOKIE = 1, - COMMAND_CHECK_GET_PUZZLE = 2, - COMMAND_MASK = 3, - - CHK_COMMON_CLIENT_VERSION = 1 << 2, - CHK_COMMON_MASK = 1 << 2, - - COMMAND_AND_CHK_COMMON_MASK = COMMAND_MASK | CHK_COMMON_MASK, - COMMAND_SPECIFIC_OPTIONS_MASK = 0xf0 +/* Enums and structs for get_cookie */ +enum +{ + CHK_GET_COOKIE_CHECK_TIMESTAMP = 1 << 0, + CHK_GET_COOKIE_VALID_MASK = (1 << 1) -1 }; -enum { - CHK_GET_COOKIE_CHECK_TIMESTAMP = 1 << 4, - CHK_GET_COOKIE_MASK = 1 << 4 +struct xt_ts3init_get_cookie_mtinfo +{ + __u8 common_options; + __u8 specific_options; + __u16 reserved1; + __u32 min_client_version; + __u32 max_utc_offset; }; -enum{ - CHK_GET_PUZZLE_CHECK_COOKIE = 1 << 4, - CHK_GET_PUZZLE_MASK = 1 << 4 + +/* Enums and structs for get_puzzle */ +enum +{ + CHK_GET_PUZZLE_CHECK_COOKIE = 1 << 0, + CHK_GET_PUZZLE_VALID_MASK = (1 << 1) - 1, + + SEED_LEN = 60 }; -struct xt_ts3init_mtinfo { - __u8 command_check_and_options; +struct xt_ts3init_get_puzzle_mtinfo +{ + __u8 common_options; + __u8 specific_options; + __u16 reserved1; __u32 min_client_version; - union{ - struct { - __u32 max_utc_offset; - } get_cookie_opts; - struct { - __u8 cookie_seed[SEED_SHA512_LEN]; - } get_puzzle_opts; - }; + __u8 cookie_seed[SEED_LEN]; }; #endif /* _TS3INIT_MATCH_H */