#include #include #include #include #include #include "xt_dns_name.h" /****************************************************************************** ************************************ API ************************************* ******************************************************************************/ static void dns_name_mt_help(void); static void dns_name_mt_init(struct xt_entry_match *match); static int dns_name_mt_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match); static void dns_name_mt_check(unsigned int flags); static void dns_name_mt_print(const void *entry, const struct xt_entry_match *match, int numeric); static void dns_name_mt_save(const void *entry, const struct xt_entry_match *match); /****************************************************************************** *********************** MODULE SPECIFICATION STRUCTURES ********************** ******************************************************************************/ /* module specific options */ const struct option dns_name_mt_opts[] = { { .name="domain", .has_arg=required_argument, .val='1' }, { NULL }, }; /* module userspace extension vtable */ static struct xtables_match dns_name_mt_reg = { .version = XTABLES_VERSION, .name = "dns_name", .revision = 0, .family = NFPROTO_IPV4, .size = XT_ALIGN(sizeof(struct xt_dns_name_mtinfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_dns_name_mtinfo)), .help = dns_name_mt_help, .init = dns_name_mt_init, .parse = dns_name_mt_parse, .final_check = dns_name_mt_check, .print = dns_name_mt_print, .save = dns_name_mt_save, .extra_opts = dns_name_mt_opts, }; /****************************************************************************** ************************* IPTABLES MODULE CALLBACKS ************************** ******************************************************************************/ /* dns_name_mt_help - prints help message for this module */ static void dns_name_mt_help(void) { printf("dns_name match options\n" "[!] --domain \t\tQueried domain name.\n"); } /* dns_name_mt_init - initializes our data struct fields before parsing * @match : pointer to our data struct */ static void dns_name_mt_init(struct xt_entry_match *match) { /* match is an internal structure; we are only interested in data */ struct xt_dns_name_mtinfo *info = (void *)match->data; /* zero out structure */ memset(info, 0, sizeof(*info)); } /* dns_name_mt_parse - called for each module-specific argument * @c : option id (see .val in dns_name_mt_opts) * @argv : argv (simple as that) * @invert : 1 if user specified "!" before argument * @flags : for parser's discretionary use * @entry : ptr to an ipt_entry struct (don't care) * @match : contains pointer to our data struct (data field) * * @return : true if option was parsed, false otherwise */ static int dns_name_mt_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { /* get reference to our xt_dns_name_mtinfo instance */ struct xt_dns_name_mtinfo *info = (void *)(*match)->data; /* option-specific parsing */ switch (c) { case '1': /* --domain */ /* check for multiple occurrences */ if (*flags & XT_DNS_NAME) xtables_error(PARAMETER_PROBLEM, "xt_dns_name: " "use \"--domain\" only once!"); /* update parser flags and match criteria flags */ *flags |= XT_DNS_NAME; info->flags |= XT_DNS_NAME; /* check for match rule inversion */ if (invert) info->flags |= XT_DNS_NAME_INV; /* initalize info->name * * NOTE: argument is in global variable * * NOTE: convert the "." characters according to QNAME specs */ /* TODO 1: initialize info->name */ return true; } /* unknown option */ return false; } /* dns_name_mt_check - verify that all required options were processed * @flags : the persistent argument from dns_name_mt_parse() */ static void dns_name_mt_check(unsigned int flags) { if (!(flags & XT_DNS_NAME)) xtables_error(PARAMETER_PROBLEM, "xt_dns_name: " "make sure to specify the \"--domain\" argument!"); } /* dns_name_mt_print - print the match criteria fields for `iptables -L` * @entry : internal stuff (don't care) * @match : contains pointer to our data struct (data field) * @numeric : do not resolve IP addresses to host names if true (don't care) */ static void dns_name_mt_print(const void *entry, const struct xt_entry_match *match, int numeric) { const struct xt_dns_name_mtinfo *info = (void *) match->data; /* check for match rule reversal */ if (info->flags & XT_DNS_NAME_INV) printf("! "); /* print domain name * * NOTE: replace length of labels with "." characters * * NOTE: do NOT print a "\n" character */ /* TODO 2: print info->name */ } /* dns_name_mt_save - print out arguments that generate this rule * @entry : internal stuff (don't care) * @match : contains pointer to our data struct (data field) */ static void dns_name_mt_save(const void *entry, const struct xt_entry_match *match) { const struct xt_dns_name_mtinfo *info = (void *) match->data; /* check for match rule reversal */ if (info->flags & XT_DNS_NAME_INV) printf("! "); /* print "--domain" and the argument */ printf("--domain "); /* TODO 3: copy paste TODO 2 here */ } /****************************************************************************** ************************ LIBRARY MANAGEMENT FUNCTIONS ************************ ******************************************************************************/ /* _init - iptables library constructor * * NOTE: the '_init' symbol is expanded as a macro by iptables */ static void _init(void) { xtables_register_match(&dns_name_mt_reg); }