1 /* Shared library add-on to iptables to add tcp MSS matching support. */
9 #include <linux/netfilter/xt_tcpmss.h>
11 static void tcpmss_help(void)
14 "tcpmss match options:\n"
15 "[!] --mss value[:value] Match TCP MSS range.\n"
16 " (only valid for TCP SYN or SYN/ACK packets)\n");
19 static const struct option tcpmss_opts
[] = {
20 { "mss", 1, NULL
, '1' },
25 parse_tcp_mssvalue(const char *mssvalue
)
27 unsigned int mssvaluenum
;
29 if (xtables_strtoui(mssvalue
, NULL
, &mssvaluenum
, 0, UINT16_MAX
))
32 xtables_error(PARAMETER_PROBLEM
,
33 "Invalid mss `%s' specified", mssvalue
);
37 parse_tcp_mssvalues(const char *mssvaluestring
,
38 u_int16_t
*mss_min
, u_int16_t
*mss_max
)
43 buffer
= strdup(mssvaluestring
);
44 if ((cp
= strchr(buffer
, ':')) == NULL
)
45 *mss_min
= *mss_max
= parse_tcp_mssvalue(buffer
);
50 *mss_min
= buffer
[0] ? parse_tcp_mssvalue(buffer
) : 0;
51 *mss_max
= cp
[0] ? parse_tcp_mssvalue(cp
) : 0xFFFF;
57 tcpmss_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
58 const void *entry
, struct xt_entry_match
**match
)
60 struct xt_tcpmss_match_info
*mssinfo
=
61 (struct xt_tcpmss_match_info
*)(*match
)->data
;
66 xtables_error(PARAMETER_PROBLEM
,
67 "Only one `--mss' allowed");
68 xtables_check_inverse(optarg
, &invert
, &optind
, 0);
69 parse_tcp_mssvalues(argv
[optind
-1],
70 &mssinfo
->mss_min
, &mssinfo
->mss_max
);
81 static void tcpmss_check(unsigned int flags
)
84 xtables_error(PARAMETER_PROBLEM
,
85 "tcpmss match: You must specify `--mss'");
89 tcpmss_print(const void *ip
, const struct xt_entry_match
*match
, int numeric
)
91 const struct xt_tcpmss_match_info
*info
= (void *)match
->data
;
93 printf("tcpmss match %s", info
->invert
? "!" : "");
94 if (info
->mss_min
== info
->mss_max
)
95 printf("%u ", info
->mss_min
);
97 printf("%u:%u ", info
->mss_min
, info
->mss_max
);
100 static void tcpmss_save(const void *ip
, const struct xt_entry_match
*match
)
102 const struct xt_tcpmss_match_info
*info
= (void *)match
->data
;
104 printf("%s--mss ", info
->invert
? "! " : "");
105 if (info
->mss_min
== info
->mss_max
)
106 printf("%u ", info
->mss_min
);
108 printf("%u:%u ", info
->mss_min
, info
->mss_max
);
111 static struct xtables_match tcpmss_match
= {
112 .family
= NFPROTO_IPV4
,
114 .version
= XTABLES_VERSION
,
115 .size
= XT_ALIGN(sizeof(struct xt_tcpmss_match_info
)),
116 .userspacesize
= XT_ALIGN(sizeof(struct xt_tcpmss_match_info
)),
118 .parse
= tcpmss_parse
,
119 .final_check
= tcpmss_check
,
120 .print
= tcpmss_print
,
122 .extra_opts
= tcpmss_opts
,
125 static struct xtables_match tcpmss_match6
= {
126 .family
= NFPROTO_IPV6
,
128 .version
= XTABLES_VERSION
,
129 .size
= XT_ALIGN(sizeof(struct xt_tcpmss_match_info
)),
130 .userspacesize
= XT_ALIGN(sizeof(struct xt_tcpmss_match_info
)),
132 .parse
= tcpmss_parse
,
133 .final_check
= tcpmss_check
,
134 .print
= tcpmss_print
,
136 .extra_opts
= tcpmss_opts
,
141 xtables_register_match(&tcpmss_match
);
142 xtables_register_match(&tcpmss_match6
);