diff -Nur iptables-1.4.1.1/extensions/libxt_smack.c iptables-1.4.1.1-new/extensions/libxt_smack.c --- iptables-1.4.1.1/extensions/libxt_smack.c 1970-01-01 01:00:00.000000000 +0100 +++ iptables-1.4.1.1-new/extensions/libxt_smack.c 2008-09-11 18:15:23.000000000 +0200 @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Function which prints out usage message. */ +static void smack_help(void) +{ + printf( +"smack match options:\n" +"[!] --in label Match socket in label\n" +"[!] --out label Match socket out label\n" +"[!] --tcp-peer label Match TCP peer label (CIPSO)\n"); +} + + +static const struct option smack_opts[] = { + {.name = "in", .has_arg = true, .val = 'i'}, + {.name = "out", .has_arg = true, .val = 'o'}, + {.name = "tcp-peer", .has_arg = true, .val = 'p'}, + { .name = NULL } +}; + +static void parse_label(const char *s, char *d) +{ + int slen = strlen(s); + + if (slen >= SMK_LABELLEN) { + exit_error(PARAMETER_PROBLEM, + "SMACK label must be shorter than %i characters", SMK_LABELLEN); + } + strcpy(d, s); +} + +static int smack_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_smack_match_info *info = (void *)(*match)->data; + + switch (c) { + case 'i': + param_act(P_ONLY_ONCE, "smack", "--in", *flags & XT_SMACK_IN); + + if (invert) + info->invert |= XT_SMACK_IN; + info->mask |= XT_SMACK_IN; + parse_label(optarg, info->match_in); + *flags |= XT_SMACK_IN; + return true; + + case 'o': + param_act(P_ONLY_ONCE, "smack", "--out", *flags & XT_SMACK_OUT); + + if (invert) + info->invert |= XT_SMACK_OUT; + info->mask |= XT_SMACK_OUT; + parse_label(optarg, info->match_out); + *flags |= XT_SMACK_OUT; + return true; + + case 'p': + param_act(P_ONLY_ONCE, "smack", "--tcp-peer", *flags & XT_SMACK_PEER); + + if (invert) + info->invert |= XT_SMACK_PEER; + info->mask |= XT_SMACK_PEER; + parse_label(optarg, info->match_peer_packet); + *flags |= XT_SMACK_PEER; + return true; + } + return false; +} + +static void smack_check(unsigned int flags) +{ + if (!flags) + exit_error(PARAMETER_PROBLEM, + "SMACK match: You must at least specify one match"); +} + +static void smack_save_item(const char *param, const char *label, u_int8_t invert){ + if (invert) + printf("! "); + printf("--%s \"%s\" ", param, label); +} + +static void smack_save(const void *ip, const struct xt_entry_match *match) +{ + struct xt_smack_match_info *info = (struct xt_smack_match_info *)match->data; + + if(info->mask & XT_SMACK_IN) + smack_save_item("in", info->match_in, info->invert & XT_SMACK_IN); + if(info->mask & XT_SMACK_OUT) + smack_save_item("out", info->match_out, info->invert & XT_SMACK_OUT); + if(info->mask & XT_SMACK_PEER) + smack_save_item("tcp-peer", info->match_peer_packet, info->invert & XT_SMACK_PEER); + +} + +static void smack_print(const void *ip, const struct xt_entry_match *match, int numeric) +{ + printf("SMACK label match "); + smack_save(ip, match); + +} + +static struct xtables_match smack_match = { + .family = AF_UNSPEC, + .name = "smack", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_smack_match_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_smack_match_info)), + .help = smack_help, + .parse = smack_parse, + .final_check = smack_check, + .print = smack_print, + .save = smack_save, + .extra_opts = smack_opts, +}; + +void _init(void) +{ + xtables_register_match(&smack_match); +} diff -Nur iptables-1.4.1.1/include/linux/netfilter/xt_smack.h iptables-1.4.1.1-new/include/linux/netfilter/xt_smack.h --- iptables-1.4.1.1/include/linux/netfilter/xt_smack.h 1970-01-01 01:00:00.000000000 +0100 +++ iptables-1.4.1.1-new/include/linux/netfilter/xt_smack.h 2008-09-11 17:36:25.000000000 +0200 @@ -0,0 +1,21 @@ +#ifndef _XT_SMACK_MATCH_H +#define _XT_SMACK_MATCH_H + +#define SMK_MAXLEN 23 +#define SMK_LABELLEN (SMK_MAXLEN+1) + +enum { + XT_SMACK_IN = 1 << 0, + XT_SMACK_OUT = 1 << 1, + XT_SMACK_PEER = 1 << 2, +}; + +struct xt_smack_match_info { + u_int8_t mask, invert; + char match_in[SMK_LABELLEN]; + char match_out[SMK_LABELLEN]; + char match_peer_packet[SMK_LABELLEN]; + +}; + +#endif /* _XT_SMACK_MATCH_H */