Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 2 | #include <string.h> |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 3 | #include <xtables.h> |
Patrick McHardy | 40d5475 | 2007-04-18 07:00:36 +0000 | [diff] [blame] | 4 | #include <linux/netfilter/nf_conntrack_common.h> |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 5 | #include <linux/netfilter/xt_state.h> |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 6 | |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 7 | #ifndef XT_STATE_UNTRACKED |
| 8 | #define XT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) |
Harald Welte | 4dc734c | 2003-10-07 18:55:13 +0000 | [diff] [blame] | 9 | #endif |
| 10 | |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 11 | enum { |
| 12 | O_STATE = 0, |
| 13 | }; |
| 14 | |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 15 | static void |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 16 | state_help(void) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 17 | { |
| 18 | printf( |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 19 | "state match options:\n" |
Harald Welte | 4dc734c | 2003-10-07 18:55:13 +0000 | [diff] [blame] | 20 | " [!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...]\n" |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 21 | " State(s) to match\n"); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 22 | } |
| 23 | |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 24 | static const struct xt_option_entry state_opts[] = { |
| 25 | {.name = "state", .id = O_STATE, .type = XTTYPE_STRING, |
| 26 | .flags = XTOPT_MAND}, |
| 27 | XTOPT_TABLEEND, |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 28 | }; |
| 29 | |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 30 | static int |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 31 | state_parse_state(const char *state, size_t len, struct xt_state_info *sinfo) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 32 | { |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 33 | if (strncasecmp(state, "INVALID", len) == 0) |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 34 | sinfo->statemask |= XT_STATE_INVALID; |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 35 | else if (strncasecmp(state, "NEW", len) == 0) |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 36 | sinfo->statemask |= XT_STATE_BIT(IP_CT_NEW); |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 37 | else if (strncasecmp(state, "ESTABLISHED", len) == 0) |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 38 | sinfo->statemask |= XT_STATE_BIT(IP_CT_ESTABLISHED); |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 39 | else if (strncasecmp(state, "RELATED", len) == 0) |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 40 | sinfo->statemask |= XT_STATE_BIT(IP_CT_RELATED); |
Jan Engelhardt | dbb7754 | 2008-02-11 00:33:30 +0100 | [diff] [blame] | 41 | else if (strncasecmp(state, "UNTRACKED", len) == 0) |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 42 | sinfo->statemask |= XT_STATE_UNTRACKED; |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 43 | else |
| 44 | return 0; |
| 45 | return 1; |
| 46 | } |
| 47 | |
| 48 | static void |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 49 | state_parse_states(const char *arg, struct xt_state_info *sinfo) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 50 | { |
| 51 | const char *comma; |
| 52 | |
| 53 | while ((comma = strchr(arg, ',')) != NULL) { |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 54 | if (comma == arg || !state_parse_state(arg, comma-arg, sinfo)) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 55 | xtables_error(PARAMETER_PROBLEM, "Bad state \"%s\"", arg); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 56 | arg = comma+1; |
| 57 | } |
Pablo Neira Ayuso | 0ec8c0f | 2008-11-19 19:01:26 +0100 | [diff] [blame] | 58 | if (!*arg) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 59 | xtables_error(PARAMETER_PROBLEM, "\"--state\" requires a list of " |
Pablo Neira Ayuso | 0ec8c0f | 2008-11-19 19:01:26 +0100 | [diff] [blame] | 60 | "states with no spaces, e.g. " |
| 61 | "ESTABLISHED,RELATED"); |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 62 | if (strlen(arg) == 0 || !state_parse_state(arg, strlen(arg), sinfo)) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 63 | xtables_error(PARAMETER_PROBLEM, "Bad state \"%s\"", arg); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 64 | } |
| 65 | |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 66 | static void state_parse(struct xt_option_call *cb) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 67 | { |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 68 | struct xt_state_info *sinfo = cb->data; |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 69 | |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 70 | xtables_option_parse(cb); |
| 71 | state_parse_states(cb->arg, sinfo); |
| 72 | if (cb->invert) |
| 73 | sinfo->statemask = ~sinfo->statemask; |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 74 | } |
| 75 | |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 76 | static void state_print_state(unsigned int statemask) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 77 | { |
| 78 | const char *sep = ""; |
| 79 | |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 80 | if (statemask & XT_STATE_INVALID) { |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 81 | printf("%sINVALID", sep); |
| 82 | sep = ","; |
| 83 | } |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 84 | if (statemask & XT_STATE_BIT(IP_CT_NEW)) { |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 85 | printf("%sNEW", sep); |
| 86 | sep = ","; |
| 87 | } |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 88 | if (statemask & XT_STATE_BIT(IP_CT_RELATED)) { |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 89 | printf("%sRELATED", sep); |
| 90 | sep = ","; |
| 91 | } |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 92 | if (statemask & XT_STATE_BIT(IP_CT_ESTABLISHED)) { |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 93 | printf("%sESTABLISHED", sep); |
| 94 | sep = ","; |
| 95 | } |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 96 | if (statemask & XT_STATE_UNTRACKED) { |
Harald Welte | 4dc734c | 2003-10-07 18:55:13 +0000 | [diff] [blame] | 97 | printf("%sUNTRACKED", sep); |
| 98 | sep = ","; |
| 99 | } |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 100 | } |
| 101 | |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 102 | static void |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 103 | state_print(const void *ip, |
Yasuyuki KOZAKAI | 193df8e | 2007-07-24 05:57:28 +0000 | [diff] [blame] | 104 | const struct xt_entry_match *match, |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 105 | int numeric) |
| 106 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 107 | const struct xt_state_info *sinfo = (const void *)match->data; |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 108 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 109 | printf(" state "); |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 110 | state_print_state(sinfo->statemask); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 111 | } |
| 112 | |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 113 | static void state_save(const void *ip, const struct xt_entry_match *match) |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 114 | { |
Jan Engelhardt | 69f564e | 2009-05-26 13:14:06 +0200 | [diff] [blame] | 115 | const struct xt_state_info *sinfo = (const void *)match->data; |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 116 | |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 117 | printf(" --state "); |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 118 | state_print_state(sinfo->statemask); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 119 | } |
| 120 | |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 121 | static struct xtables_match state_match = { |
Jan Engelhardt | c5e8573 | 2009-06-12 20:55:44 +0200 | [diff] [blame] | 122 | .family = NFPROTO_UNSPEC, |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 123 | .name = "state", |
Jan Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 124 | .version = XTABLES_VERSION, |
Yasuyuki KOZAKAI | 1ff0b8d | 2007-08-04 08:09:51 +0000 | [diff] [blame] | 125 | .size = XT_ALIGN(sizeof(struct xt_state_info)), |
| 126 | .userspacesize = XT_ALIGN(sizeof(struct xt_state_info)), |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 127 | .help = state_help, |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 128 | .print = state_print, |
| 129 | .save = state_save, |
Jan Engelhardt | 72ef3d3 | 2011-03-02 22:52:04 +0100 | [diff] [blame] | 130 | .x6_parse = state_parse, |
| 131 | .x6_options = state_opts, |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 132 | }; |
| 133 | |
| 134 | void _init(void) |
| 135 | { |
László Attila Tóth | 7211888 | 2007-10-08 05:12:42 +0000 | [diff] [blame] | 136 | xtables_register_match(&state_match); |
Marc Boucher | e6869a8 | 2000-03-20 06:03:29 +0000 | [diff] [blame] | 137 | } |