2
* "ipp2p" match extension for iptables
3
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
4
* Jan Engelhardt <jengelh [at] medozas de>, 2008
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License; either
8
* version 2 of the License, or any later version, as published by the
9
* Free Software Foundation.
20
#define param_act(t, s, f) param_act((t), "ipp2p", (s), (f))
22
static void ipp2p_mt_help(void)
25
"IPP2P v%s options:\n"
26
" --edk [tcp,udp] All known eDonkey/eMule/Overnet packets\n"
27
" --dc [tcp] All known Direct Connect packets\n"
28
" --kazaa [tcp,udp] All known KaZaA packets\n"
29
" --gnu [tcp,udp] All known Gnutella packets\n"
30
" --bit [tcp,udp] All known BitTorrent packets\n"
31
" --apple [tcp] All known AppleJuice packets\n"
32
" --winmx [tcp] All known WinMX\n"
33
" --soul [tcp] All known SoulSeek\n"
34
" --ares [tcp] All known Ares\n\n"
35
"EXPERIMENTAL protocols (please send feedback to: ipp2p@ipp2p.org) :\n"
36
" --mute [tcp] All known Mute packets\n"
37
" --waste [tcp] All known Waste packets\n"
38
" --xdcc [tcp] All known XDCC packets (only xdcc login)\n\n"
39
"DEBUG SUPPPORT, use only if you know why\n"
40
" --debug Generate kernel debug output, THIS WILL SLOW DOWN THE FILTER\n"
41
"\nIPP2P was intended for TCP only. Due to increasing usage of UDP we needed to change this.\n"
42
"You can now use -p udp to search UDP packets only or without -p switch to search UDP and TCP packets.\n"
43
"\nSee README included with this package for more details or visit http://www.ipp2p.org\n"
45
" iptables -A FORWARD -m ipp2p --ipp2p -j MARK --set-mark 0x01\n"
46
" iptables -A FORWARD -p udp -m ipp2p --kazaa --bit -j DROP\n"
47
" iptables -A FORWARD -p tcp -m ipp2p --edk --soul -j DROP\n\n"
51
static const struct option ipp2p_mt_opts[] = {
52
{.name = "edk", .has_arg = false, .val = '2'},
53
{.name = "dc", .has_arg = false, .val = '7'},
54
{.name = "gnu", .has_arg = false, .val = '9'},
55
{.name = "kazaa", .has_arg = false, .val = 'a'},
56
{.name = "bit", .has_arg = false, .val = 'b'},
57
{.name = "apple", .has_arg = false, .val = 'c'},
58
{.name = "soul", .has_arg = false, .val = 'd'},
59
{.name = "winmx", .has_arg = false, .val = 'e'},
60
{.name = "ares", .has_arg = false, .val = 'f'},
61
{.name = "mute", .has_arg = false, .val = 'g'},
62
{.name = "waste", .has_arg = false, .val = 'h'},
63
{.name = "xdcc", .has_arg = false, .val = 'i'},
64
{.name = "debug", .has_arg = false, .val = 'j'},
68
static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
69
const void *entry, struct xt_entry_match **match)
71
struct ipt_p2p_info *info = (struct ipt_p2p_info *)(*match)->data;
74
case '2': /*cmd: edk*/
75
param_act(P_ONLY_ONCE, "--edk", *flags & IPP2P_EDK);
76
param_act(P_NO_INVERT, "--edk", invert);
77
if (*flags & IPP2P_DATA_EDK)
78
exit_error(PARAMETER_PROBLEM,
79
"ipp2p: use `--edk' OR `--edk-data' but not both of them!");
81
info->cmd |= IPP2P_EDK;
85
param_act(P_ONLY_ONCE, "--dc", *flags & IPP2P_DC);
86
param_act(P_NO_INVERT, "--dc", invert);
87
if (*flags & IPP2P_DATA_DC)
88
exit_error(PARAMETER_PROBLEM,
89
"ipp2p: use `--dc' OR `--dc-data' but not both of them!");
91
info->cmd |= IPP2P_DC;
94
case '9': /*cmd: gnu*/
95
param_act(P_ONLY_ONCE, "--gnu", *flags & IPP2P_GNU);
96
param_act(P_NO_INVERT, "--gnu", invert);
97
if (*flags & IPP2P_DATA_GNU)
98
exit_error(PARAMETER_PROBLEM,
99
"ipp2p: use `--gnu' OR `--gnu-data' but not both of them!");
101
info->cmd |= IPP2P_GNU;
104
case 'a': /*cmd: kazaa*/
105
param_act(P_ONLY_ONCE, "--kazaa", *flags & IPP2P_KAZAA);
106
param_act(P_NO_INVERT, "--kazaa", invert);
107
if (*flags & IPP2P_DATA_KAZAA)
108
exit_error(PARAMETER_PROBLEM,
109
"ipp2p: use `--kazaa' OR `--kazaa-data' but not both of them!");
110
*flags |= IPP2P_KAZAA;
111
info->cmd |= IPP2P_KAZAA;
114
case 'b': /*cmd: bit*/
115
param_act(P_ONLY_ONCE, "--kazaa", *flags & IPP2P_BIT);
116
param_act(P_NO_INVERT, "--kazaa", invert);
118
info->cmd |= IPP2P_BIT;
121
case 'c': /*cmd: apple*/
122
param_act(P_ONLY_ONCE, "--apple", *flags & IPP2P_APPLE);
123
param_act(P_NO_INVERT, "--apple", invert);
124
*flags |= IPP2P_APPLE;
125
info->cmd |= IPP2P_APPLE;
128
case 'd': /*cmd: soul*/
129
param_act(P_ONLY_ONCE, "--soul", *flags & IPP2P_SOUL);
130
param_act(P_NO_INVERT, "--soul", invert);
131
*flags |= IPP2P_SOUL;
132
info->cmd |= IPP2P_SOUL;
135
case 'e': /*cmd: winmx*/
136
param_act(P_ONLY_ONCE, "--winmx", *flags & IPP2P_WINMX);
137
param_act(P_NO_INVERT, "--winmx", invert);
138
*flags |= IPP2P_WINMX;
139
info->cmd |= IPP2P_WINMX;
142
case 'f': /*cmd: ares*/
143
param_act(P_ONLY_ONCE, "--ares", *flags & IPP2P_ARES);
144
param_act(P_NO_INVERT, "--ares", invert);
145
*flags |= IPP2P_ARES;
146
info->cmd |= IPP2P_ARES;
149
case 'g': /*cmd: mute*/
150
param_act(P_ONLY_ONCE, "--mute", *flags & IPP2P_MUTE);
151
param_act(P_NO_INVERT, "--mute", invert);
152
*flags |= IPP2P_MUTE;
153
info->cmd |= IPP2P_MUTE;
156
case 'h': /*cmd: waste*/
157
param_act(P_ONLY_ONCE, "--waste", *flags & IPP2P_WASTE);
158
param_act(P_NO_INVERT, "--waste", invert);
159
*flags |= IPP2P_WASTE;
160
info->cmd |= IPP2P_WASTE;
163
case 'i': /*cmd: xdcc*/
164
param_act(P_ONLY_ONCE, "--xdcc", *flags & IPP2P_XDCC);
165
param_act(P_NO_INVERT, "--xdcc", invert);
166
*flags |= IPP2P_XDCC;
167
info->cmd |= IPP2P_XDCC;
170
case 'j': /*cmd: debug*/
171
param_act(P_ONLY_ONCE, "--debug", info->debug);
172
param_act(P_NO_INVERT, "--debug", invert);
177
// exit_error(PARAMETER_PROBLEM,
178
// "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
184
static void ipp2p_mt_check(unsigned int flags)
187
exit_error(PARAMETER_PROBLEM,
188
"\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
191
static const char *const ipp2p_cmds[] = {
192
[IPP2N_EDK] = "--edk",
193
[IPP2N_DATA_KAZAA] = "--kazaa-data",
194
[IPP2N_DATA_EDK] = "--edk-data",
195
[IPP2N_DATA_DC] = "--dc-data",
197
[IPP2N_DATA_GNU] = "--gnu-data",
198
[IPP2N_GNU] = "--gnu",
199
[IPP2N_KAZAA] = "--kazaa",
200
[IPP2N_BIT] = "--bit",
201
[IPP2N_APPLE] = "--apple",
202
[IPP2N_SOUL] = "--soul",
203
[IPP2N_WINMX] = "--winmx",
204
[IPP2N_ARES] = "--ares",
205
[IPP2N_MUTE] = "--mute",
206
[IPP2N_WASTE] = "--waste",
207
[IPP2N_XDCC] = "--xdcc",
211
ipp2p_mt_print(const void *entry, const struct xt_entry_match *match,
214
const struct ipt_p2p_info *info = (const void *)match->data;
217
for (i = IPP2N_EDK; i <= IPP2N_XDCC; ++i)
218
if (info->cmd & (1 << i))
219
printf("%s ", ipp2p_cmds[i]);
221
if (info->debug != 0)
225
static void ipp2p_mt_save(const void *entry, const struct xt_entry_match *match)
227
ipp2p_mt_print(entry, match, true);
230
static struct xtables_match ipp2p_mt_reg = {
231
.version = XTABLES_VERSION,
235
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
236
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),
237
.help = ipp2p_mt_help,
238
.parse = ipp2p_mt_parse,
239
.final_check = ipp2p_mt_check,
240
.print = ipp2p_mt_print,
241
.save = ipp2p_mt_save,
242
.extra_opts = ipp2p_mt_opts,
245
static void _init(void)
247
xtables_register_match(&ipp2p_mt_reg);