mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
851 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
48ebf55444 | ||
![]() |
57c3cc1722 | ||
![]() |
29141b6e95 | ||
![]() |
cdac8506c3 | ||
![]() |
5494bc40f4 | ||
![]() |
bcdb7ed4e9 | ||
![]() |
1ed86c6bbd | ||
![]() |
2a5f1099c8 | ||
![]() |
c243c78af4 | ||
![]() |
91da2a0dbd | ||
![]() |
a160a2aa36 | ||
![]() |
b25e96fd49 | ||
![]() |
6d74f76a29 | ||
![]() |
78e47758c6 | ||
![]() |
bcdd42f556 | ||
![]() |
acf92ff914 | ||
![]() |
0e845bf23f | ||
![]() |
158e6a26eb | ||
![]() |
693c32f414 | ||
![]() |
3e337562d7 | ||
![]() |
bb25bc08c4 | ||
![]() |
ea3e4b2ed5 | ||
![]() |
557af2177f | ||
![]() |
60f5239630 | ||
![]() |
3ba7d8c3a9 | ||
![]() |
28d12faba8 | ||
![]() |
cf7a3d4342 | ||
![]() |
fabad77f8f | ||
![]() |
5e020d380c | ||
![]() |
a7fbf4f4de | ||
![]() |
4137f6c111 | ||
![]() |
04d8ebe31c | ||
![]() |
6ab4c02a54 | ||
![]() |
a66e4510b8 | ||
![]() |
31aebc134e | ||
![]() |
e640a15ec9 | ||
![]() |
66f213e324 | ||
![]() |
0dcc56bc62 | ||
![]() |
8db01220fd | ||
![]() |
95ff9a2de3 | ||
![]() |
2f1e094125 | ||
![]() |
37b000182f | ||
![]() |
255a310536 | ||
![]() |
3a6e73e986 | ||
![]() |
0a97126f5b | ||
![]() |
2ba833fe47 | ||
![]() |
77240e0918 | ||
![]() |
651e60f8d7 | ||
![]() |
54ac2a899a | ||
![]() |
61d2be172d | ||
![]() |
093f3b0a97 | ||
![]() |
57d25f22f1 | ||
![]() |
2f18ab31ec | ||
![]() |
12d0a8702c | ||
![]() |
35ce1adf5e | ||
![]() |
e5fe0b9c14 | ||
![]() |
cd7fc84b29 | ||
![]() |
4ff5a8fbf6 | ||
![]() |
37e3a543a9 | ||
![]() |
5f6cbbc663 | ||
![]() |
a2676585da | ||
![]() |
4a8aab6aed | ||
![]() |
dec7d7fc4d | ||
![]() |
5c615a3c73 | ||
![]() |
0c1375414d | ||
![]() |
7e5a8b0501 | ||
![]() |
cb8050172a | ||
![]() |
5be4ac8b2b | ||
![]() |
8d5b7c5b7d | ||
![]() |
f9aca7621c | ||
![]() |
af940bcbae | ||
![]() |
06b82c649d | ||
![]() |
e5093b61cd | ||
![]() |
7cd01e0b14 | ||
![]() |
4eb97c7a01 | ||
![]() |
48fbc6783e | ||
![]() |
a9f383daf8 | ||
![]() |
cbe58f55d0 | ||
![]() |
d11218815f | ||
![]() |
911d3d146a | ||
![]() |
e2ecff2071 | ||
![]() |
b2bcedd1ef | ||
![]() |
36c349054e | ||
![]() |
95da880d39 | ||
![]() |
3be26a731b | ||
![]() |
38db58adc1 | ||
![]() |
0f302b7b2f | ||
![]() |
d66d07d01d | ||
![]() |
3736a265d8 | ||
![]() |
5b2649b1a2 | ||
![]() |
f6b8767228 | ||
![]() |
ac58f2e94b | ||
![]() |
7cc774641a | ||
![]() |
492236f931 | ||
![]() |
1e8da7c31c | ||
![]() |
3f1202c211 | ||
![]() |
759546f8d0 | ||
![]() |
72b1421783 | ||
![]() |
0b3d1bc4f0 | ||
![]() |
3679e0efa6 | ||
![]() |
517b8c66b5 | ||
![]() |
7ee9feb20e | ||
![]() |
f830dbd34e | ||
![]() |
916013cd89 | ||
![]() |
a6b06502ca | ||
![]() |
aee5aedc63 | ||
![]() |
54d784ffdf | ||
![]() |
076610e3af | ||
![]() |
7a1ad32d1a | ||
![]() |
40094379dd | ||
![]() |
ce37dd6984 | ||
![]() |
31fdd86247 | ||
![]() |
36df60c940 | ||
![]() |
2b671829d8 | ||
![]() |
9ab6a0ee0d | ||
![]() |
365d5edfb3 | ||
![]() |
75cd1d7d6a | ||
![]() |
b0dc0e6f4c | ||
![]() |
bc1c37618a | ||
![]() |
d7aeb7da4b | ||
![]() |
487da26146 | ||
![]() |
434dea2b53 | ||
![]() |
30d227135b | ||
![]() |
a508ec048c | ||
![]() |
3069c9a3a2 | ||
![]() |
5245220246 | ||
![]() |
ec97cd6d89 | ||
![]() |
dc58126e37 | ||
![]() |
d509951fcf | ||
![]() |
6ef91897b2 | ||
![]() |
c7f60a33c5 | ||
![]() |
65b75fc19c | ||
![]() |
bac406bff5 | ||
![]() |
aa53733851 | ||
![]() |
9ccd32d840 | ||
![]() |
939d3c8b27 | ||
![]() |
c2d93e16fd | ||
![]() |
04aed87cb6 | ||
![]() |
5ef3a7c436 | ||
![]() |
27a77b62f5 | ||
![]() |
c10e974bd6 | ||
![]() |
01d864f4fc | ||
![]() |
071c95b750 | ||
![]() |
a141cc311c | ||
![]() |
7e92ce7ce6 | ||
![]() |
21da1dfea5 | ||
![]() |
6c17eb46b5 | ||
![]() |
74ea647303 | ||
![]() |
e0154bfa4c | ||
![]() |
cd18e2479c | ||
![]() |
d2f3541cda | ||
![]() |
1fed8bbf09 | ||
![]() |
6e8fb7f231 | ||
![]() |
eceaee3431 | ||
![]() |
77b29a62ee | ||
![]() |
33db992c39 | ||
![]() |
85d8f98dd7 | ||
![]() |
e84391ce66 | ||
![]() |
ef7fb0db7f | ||
![]() |
4203259e5a | ||
![]() |
e3956498ac | ||
![]() |
6f730f3ab2 | ||
![]() |
2b590a35fd | ||
![]() |
3dd33dfe93 | ||
![]() |
d417077816 | ||
![]() |
d057f6d6f0 | ||
![]() |
b2fc85c589 | ||
![]() |
fa1348455d | ||
![]() |
1a5c079e6b | ||
![]() |
75b3762ef4 | ||
![]() |
cfb72bf468 | ||
![]() |
1b0790d151 | ||
![]() |
a5355e74ea | ||
![]() |
757bf0e993 | ||
![]() |
cea4817a46 | ||
![]() |
2dc79fe008 | ||
![]() |
b60f8f1de2 | ||
![]() |
499c6db75e | ||
![]() |
509953daec | ||
![]() |
c53a86874d | ||
![]() |
309b960012 | ||
![]() |
f4882ca029 | ||
![]() |
8fd3eb56eb | ||
![]() |
94574fb829 | ||
![]() |
32871bad39 | ||
![]() |
0ba44bd461 | ||
![]() |
d4e6e3d155 | ||
![]() |
18043f3e3a | ||
![]() |
ff27f61477 | ||
![]() |
9f59f21614 | ||
![]() |
7a8bfed52c | ||
![]() |
1edc9b943b | ||
![]() |
ebfa77795a | ||
![]() |
4a8aa505c4 | ||
![]() |
4654ee127f | ||
![]() |
a7a77d7146 | ||
![]() |
2a61ca7d4b | ||
![]() |
39de351a91 | ||
![]() |
07bf41a294 | ||
![]() |
07cd29d9ce | ||
![]() |
eb9634aee6 | ||
![]() |
19f241a09c | ||
![]() |
0a29c1d32f | ||
![]() |
93a17fdde0 | ||
![]() |
80444b0d31 | ||
![]() |
f180c0e5c6 | ||
![]() |
ca8ebe4467 | ||
![]() |
e82410735a | ||
![]() |
89e72bb0f4 | ||
![]() |
77b9f2024c | ||
![]() |
0edb572f6e | ||
![]() |
8b1ff64b8b | ||
![]() |
ebb61aa3c9 | ||
![]() |
bd2e6108f3 | ||
![]() |
288492c820 | ||
![]() |
e425c8f277 | ||
![]() |
e3e88827fb | ||
![]() |
6c709fd682 | ||
![]() |
1b53724a61 | ||
![]() |
983b28fe8e | ||
![]() |
3141b2ff86 | ||
![]() |
980a53348f | ||
![]() |
8ea781e257 | ||
![]() |
7e39ee66e0 | ||
![]() |
65e97a66e6 | ||
![]() |
d82b20ead7 | ||
![]() |
c5d4dd0bcf | ||
![]() |
0168f8e8a2 | ||
![]() |
dc22ec7bd1 | ||
![]() |
80ded69d77 | ||
![]() |
af1bfd7684 | ||
![]() |
b05712a14d | ||
![]() |
7d8ffffd85 | ||
![]() |
75212f3972 | ||
![]() |
77027ff8d3 | ||
![]() |
e9a70bbf15 | ||
![]() |
25bf680ead | ||
![]() |
4d547c2bfc | ||
![]() |
f7c7264a65 | ||
![]() |
0f42828fd6 | ||
![]() |
e2da87230a | ||
![]() |
1dc1ae3ec5 | ||
![]() |
3bbea41b30 | ||
![]() |
549508499c | ||
![]() |
748498038a | ||
![]() |
3ee2b5fb93 | ||
![]() |
5bcdf7f10e | ||
![]() |
6599996ccc | ||
![]() |
bf8d44cca4 | ||
![]() |
1721b76a0f | ||
![]() |
81ad2519a9 | ||
![]() |
f65ea59795 | ||
![]() |
baf7b1091a | ||
![]() |
2ae0413e31 | ||
![]() |
db76ea9a5c | ||
![]() |
3ed1a3cbf0 | ||
![]() |
9c4c76f9e2 | ||
![]() |
7f33590df8 | ||
![]() |
6733265358 | ||
![]() |
f757049112 | ||
![]() |
21cdf786f7 | ||
![]() |
7c248871f8 | ||
![]() |
3500a38767 | ||
![]() |
cf9b60a57e | ||
![]() |
e5eedb25c2 | ||
![]() |
e3ae8dcb81 | ||
![]() |
aca381d3b6 | ||
![]() |
bb15becc88 | ||
![]() |
14458b3a7e | ||
![]() |
2d36632d4a | ||
![]() |
b5e2c7255a | ||
![]() |
376a89e7d1 | ||
![]() |
03ec8a7696 | ||
![]() |
442982f04e | ||
![]() |
98b853cea3 | ||
![]() |
59401339b8 | ||
![]() |
121836ce80 | ||
![]() |
c23df41f6e | ||
![]() |
fb2eea69af | ||
![]() |
4815e3a8a6 | ||
![]() |
f9922c6f85 | ||
![]() |
24491d55d7 | ||
![]() |
7ab69a17fa | ||
![]() |
d2339410b2 | ||
![]() |
649caf61e8 | ||
![]() |
922a9be87d | ||
![]() |
4d48511f01 | ||
![]() |
6dedbef3d4 | ||
![]() |
fe49f9b6a4 | ||
![]() |
283974cbbe | ||
![]() |
7deca86132 | ||
![]() |
7d6435f422 | ||
![]() |
748f5cfdd0 | ||
![]() |
d402cec807 | ||
![]() |
b42190c04b | ||
![]() |
4dcefe4b95 | ||
![]() |
a2662b0121 | ||
![]() |
03354eed44 | ||
![]() |
ddda6972a4 | ||
![]() |
8e7359bb92 | ||
![]() |
40786af1c0 | ||
![]() |
f6e2fb815e | ||
![]() |
f171a0f07e | ||
![]() |
d17ddb9c94 | ||
![]() |
54d80a73b4 | ||
![]() |
43921c5834 | ||
![]() |
9a18a05d02 | ||
![]() |
5b472be9bb | ||
![]() |
4dd35fb564 | ||
![]() |
b32d6dad90 | ||
![]() |
5b2cb97c06 | ||
![]() |
ca894d6687 | ||
![]() |
db717ec479 | ||
![]() |
a46ca95078 | ||
![]() |
8b2a266db0 | ||
![]() |
03e10ff544 | ||
![]() |
37986fd785 | ||
![]() |
8ff64f4ef4 | ||
![]() |
93f6c1a312 | ||
![]() |
b535abce2e | ||
![]() |
5db988626f | ||
![]() |
c6f8f72bf1 | ||
![]() |
47cbb07162 | ||
![]() |
79c55ab325 | ||
![]() |
11ab4d0acc | ||
![]() |
8ae9ac5433 | ||
![]() |
2060a58912 | ||
![]() |
e1eed2b05e | ||
![]() |
7b077c7459 | ||
![]() |
ad146dbeef | ||
![]() |
fb4c49d794 | ||
![]() |
a17203e036 | ||
![]() |
987402dc61 | ||
![]() |
295b6b6d73 | ||
![]() |
7338a2a400 | ||
![]() |
ba35636718 | ||
![]() |
fd19a40dbe | ||
![]() |
937571bb9d | ||
![]() |
346fc1a376 | ||
![]() |
56535551b3 | ||
![]() |
dd8fdd09c8 | ||
![]() |
beb3358297 | ||
![]() |
02d8bdc3d9 | ||
![]() |
42b77a386a | ||
![]() |
6340363394 | ||
![]() |
c9b4e9c518 | ||
![]() |
8dd316ed56 | ||
![]() |
48327605c6 | ||
![]() |
414e95ffb1 | ||
![]() |
749e0b788a | ||
![]() |
7512101bca | ||
![]() |
1a17ed6a45 | ||
![]() |
1aeaadd740 | ||
![]() |
0acbe528ac | ||
![]() |
f5fe2dc801 | ||
![]() |
524201adcc | ||
![]() |
7cfd3b1dbb | ||
![]() |
ab13e58f96 | ||
![]() |
548922388c | ||
![]() |
43864ac6f1 | ||
![]() |
2ef714cc93 | ||
![]() |
8b71d90002 | ||
![]() |
457e86b908 | ||
![]() |
9b99211326 | ||
![]() |
c96845a311 | ||
![]() |
01e4bace4d | ||
![]() |
84704346e7 | ||
![]() |
77bd7953fb | ||
![]() |
8c02b00a33 | ||
![]() |
1f8b91ce53 | ||
![]() |
dac1b7d506 | ||
![]() |
40d0345f1e | ||
![]() |
3e70d6289d | ||
![]() |
d99c8570f3 | ||
![]() |
cf7a40fbe7 | ||
![]() |
0de9f38412 | ||
![]() |
b4b0ab9ef4 | ||
![]() |
b20e02869e | ||
![]() |
ebd603b8fb | ||
![]() |
1945c545dd | ||
![]() |
7952a7d253 | ||
![]() |
c82da14d2b | ||
![]() |
9f1af79901 | ||
![]() |
50c4ee1a5e | ||
![]() |
351b040f4a | ||
![]() |
6ed735a810 | ||
![]() |
d643fc4b6c | ||
![]() |
0fe32e7443 | ||
![]() |
3c0397867b | ||
![]() |
16e4968343 | ||
![]() |
8c910aa82b | ||
![]() |
6340d999d7 | ||
![]() |
11af976e8b | ||
![]() |
a4afc4159e | ||
![]() |
24bb655130 | ||
![]() |
2eaa5c5606 | ||
![]() |
0593b96c2c | ||
![]() |
6f1c1ef0ce | ||
![]() |
d5ff452ea5 | ||
![]() |
c012379e0b | ||
![]() |
15de3beb63 | ||
![]() |
160e04d13e | ||
![]() |
359ecc7a8c | ||
![]() |
6ee71ed485 | ||
![]() |
7bd0157a9a | ||
![]() |
6f8582eb5e | ||
![]() |
df7168bb4d | ||
![]() |
0aa7be2f1d | ||
![]() |
d9cd40e9fa | ||
![]() |
8bd6ef78f9 | ||
![]() |
578af6f726 | ||
![]() |
22edc7a24d | ||
![]() |
304e5e52ca | ||
![]() |
3f7288abfe | ||
![]() |
aad0cafd19 | ||
![]() |
17a0312848 | ||
![]() |
c66d291eb8 | ||
![]() |
cb407ce7c4 | ||
![]() |
3f426f3b43 | ||
![]() |
0b3ae22673 | ||
![]() |
bc5a7d8e3a | ||
![]() |
0628857068 | ||
![]() |
de4f6e8994 | ||
![]() |
439dd913f1 | ||
![]() |
9568747d94 | ||
![]() |
20365cf762 | ||
![]() |
fa601c0fa7 | ||
![]() |
00573d0172 | ||
![]() |
c7036a88f1 | ||
![]() |
af21c1d369 | ||
![]() |
b132101b63 | ||
![]() |
71beab548d | ||
![]() |
6de54e5fcd | ||
![]() |
a921427746 | ||
![]() |
2b2b6246f0 | ||
![]() |
98e5dfd6ef | ||
![]() |
9e5c2e7ee9 | ||
![]() |
284c0e9493 | ||
![]() |
5284b5db92 | ||
![]() |
36035d52d3 | ||
![]() |
4d94687c15 | ||
![]() |
7070678ab4 | ||
![]() |
f6281d498c | ||
![]() |
2cab32596a | ||
![]() |
08f6a82bdc | ||
![]() |
82a8524f1a | ||
![]() |
6bb354d3f0 | ||
![]() |
5184176c3b | ||
![]() |
430723ece1 | ||
![]() |
f1dc7f960c | ||
![]() |
370f47b000 | ||
![]() |
8e812620f0 | ||
![]() |
204b612e23 | ||
![]() |
c2c86f4b3d | ||
![]() |
379e685b0f | ||
![]() |
69dd0686e2 | ||
![]() |
48325a209e | ||
![]() |
96f501ab89 | ||
![]() |
3c1bf73e8e | ||
![]() |
e0276b4875 | ||
![]() |
1bc7f1be67 | ||
![]() |
3c3adcbd07 | ||
![]() |
da6a9b932c | ||
![]() |
5f290cd4a0 | ||
![]() |
181a9cab43 | ||
![]() |
a819458cba | ||
![]() |
654862af21 | ||
![]() |
0d8ae29a60 | ||
![]() |
e05a4d9586 | ||
![]() |
0541154a5e | ||
![]() |
00199427ac | ||
![]() |
35b00f8c3f | ||
![]() |
1f3150bdf9 | ||
![]() |
13c73af796 | ||
![]() |
ba9a3efec1 | ||
![]() |
f474c7d4d4 | ||
![]() |
4a350ddd03 | ||
![]() |
628d137f12 | ||
![]() |
28ecf45548 | ||
![]() |
58839b9b86 | ||
![]() |
e436948ebd | ||
![]() |
79d54ebd7c | ||
![]() |
0b64b27172 | ||
![]() |
d116000784 | ||
![]() |
4b5f0b12d9 | ||
![]() |
c8dde526f2 | ||
![]() |
3058e42a21 | ||
![]() |
40b30f7f27 | ||
![]() |
aaad5f53ac | ||
![]() |
db1057158f | ||
![]() |
713c31e8f7 | ||
![]() |
e5ffb39750 | ||
![]() |
19067393b6 | ||
![]() |
1de82a88a1 | ||
![]() |
9928c864ab | ||
![]() |
45515a0afd | ||
![]() |
75f80fa8f8 | ||
![]() |
d8dc72d151 | ||
![]() |
cee3d25d49 | ||
![]() |
afbeb2fb47 | ||
![]() |
c0dc0858de | ||
![]() |
b04317576b | ||
![]() |
af2bbf0352 | ||
![]() |
db9bb2778d | ||
![]() |
674560d2d9 | ||
![]() |
7ab033e64c | ||
![]() |
3131448443 | ||
![]() |
71322e614c | ||
![]() |
d3fdfe08dd | ||
![]() |
46f9ddbf59 | ||
![]() |
e37985b527 | ||
![]() |
0ccd55abd9 | ||
![]() |
60123a8c07 | ||
![]() |
504f1089fb | ||
![]() |
e119350000 | ||
![]() |
a260e3349f | ||
![]() |
5cb36ed213 | ||
![]() |
1a5b9f0e02 | ||
![]() |
2c53605084 | ||
![]() |
537f25dbad | ||
![]() |
63a1e5329f | ||
![]() |
b0a6111054 | ||
![]() |
b07434386b | ||
![]() |
0c963dee06 | ||
![]() |
09bfb8496e | ||
![]() |
9d1afc4268 | ||
![]() |
342ccf62b2 | ||
![]() |
adabd647b1 | ||
![]() |
26f25a43a9 | ||
![]() |
bcda21a2b0 | ||
![]() |
4e6bc8af95 | ||
![]() |
bd4be0d991 | ||
![]() |
1f736c8203 | ||
![]() |
90fa3ab9e2 | ||
![]() |
fd82a312d6 | ||
![]() |
27c1676821 | ||
![]() |
3e26335cbd | ||
![]() |
f4b96672ef | ||
![]() |
c3d080f21a | ||
![]() |
cb268031b7 | ||
![]() |
ac44a5a1fe | ||
![]() |
a3baa78ae2 | ||
![]() |
47e002127c | ||
![]() |
03363a528a | ||
![]() |
58b016f0af | ||
![]() |
8d64e7bd50 | ||
![]() |
dd6cb27da4 | ||
![]() |
06c01131e8 | ||
![]() |
a44c4e4b1d | ||
![]() |
1fb6f187d3 | ||
![]() |
83e474f9ab | ||
![]() |
efd4c91557 | ||
![]() |
65a257a67d | ||
![]() |
5b07e04600 | ||
![]() |
6b175b40cb | ||
![]() |
0887365f8b | ||
![]() |
cebadbfcd7 | ||
![]() |
380b1b6997 | ||
![]() |
8e5219636a | ||
![]() |
760edd3db6 | ||
![]() |
502c1c05aa | ||
![]() |
a7ceccc0f4 | ||
![]() |
10bd08d0f3 | ||
![]() |
1e5315d338 | ||
![]() |
579484ed70 | ||
![]() |
2aa32d4bce | ||
![]() |
5aee8738ed | ||
![]() |
1111edfd85 | ||
![]() |
0d47cb8b37 | ||
![]() |
1c55aec64a | ||
![]() |
dd26ab476c | ||
![]() |
4bf667d8eb | ||
![]() |
0a88bd3435 | ||
![]() |
62fb261265 | ||
![]() |
d97f77a8f5 | ||
![]() |
822c6bebe2 | ||
![]() |
fdf42a3a50 | ||
![]() |
6b2ca78af7 | ||
![]() |
ee24cd1ac1 | ||
![]() |
71812a2053 | ||
![]() |
31e4e18998 | ||
![]() |
9fb2ffe1d3 | ||
![]() |
23e83aa04c | ||
![]() |
77ee63ba8b | ||
![]() |
49e59a6dce | ||
![]() |
137ecb9814 | ||
![]() |
7e25254e93 | ||
![]() |
0c9ae3cb1b | ||
![]() |
471e747fc0 | ||
![]() |
fe7a66f3cb | ||
![]() |
a13650f94d | ||
![]() |
73e7b5ead1 | ||
![]() |
e5920cc577 | ||
![]() |
39655fe83b | ||
![]() |
9df309a14a | ||
![]() |
5e2085a45f | ||
![]() |
4bcb7077c0 | ||
![]() |
000c2d73fd | ||
![]() |
e89c5d976a | ||
![]() |
f5ed98fbf5 | ||
![]() |
60c4162087 | ||
![]() |
074a7d6cb7 | ||
![]() |
a6ba463c43 | ||
![]() |
be2061c520 | ||
![]() |
3f96deb0f0 | ||
![]() |
6d8ce3acae | ||
![]() |
f6c317710f | ||
![]() |
6799806300 | ||
![]() |
0d36136f54 | ||
![]() |
e1fc5f2086 | ||
![]() |
9d5f4bf468 | ||
![]() |
637516f2d4 | ||
![]() |
b427c930f2 | ||
![]() |
34f39756ec | ||
![]() |
e36c7575fc | ||
![]() |
0a23bd2580 | ||
![]() |
03aeed615d | ||
![]() |
49018e2ff7 | ||
![]() |
50d14a33c0 | ||
![]() |
c64a78ffcc | ||
![]() |
1aae519356 | ||
![]() |
af5823b407 | ||
![]() |
9b198fe6e7 | ||
![]() |
4997b326f6 | ||
![]() |
c288ecdb9c | ||
![]() |
f21e372402 | ||
![]() |
927dd88dc4 | ||
![]() |
7dd96ec357 | ||
![]() |
ba6aa51f91 | ||
![]() |
beb7546e20 | ||
![]() |
67579079e0 | ||
![]() |
3a632a9bc5 | ||
![]() |
45b2e64d82 | ||
![]() |
538d74b5d8 | ||
![]() |
e3988b50b5 | ||
![]() |
f4b8440fba | ||
![]() |
d3ee3a0c3c | ||
![]() |
f96bc08f35 | ||
![]() |
a0c791dc88 | ||
![]() |
f717a91bc5 | ||
![]() |
8bd5fc14ba | ||
![]() |
a51b16097b | ||
![]() |
0bb538ba69 | ||
![]() |
e11a07b230 | ||
![]() |
d263cfbd50 | ||
![]() |
36f80be2f7 | ||
![]() |
7b9ca945d4 | ||
![]() |
ffeb1da7d7 | ||
![]() |
d2d8712980 | ||
![]() |
621cef39f5 | ||
![]() |
08e6f23655 | ||
![]() |
4a25321191 | ||
![]() |
8c322a0119 | ||
![]() |
bd39e4671e | ||
![]() |
3d6bb5f86f | ||
![]() |
ce03d0ee8e | ||
![]() |
bca90ca2a7 | ||
![]() |
08cb9e5584 | ||
![]() |
1a8cc305af | ||
![]() |
47a34e0ccf | ||
![]() |
36dab67658 | ||
![]() |
7bb2957e47 | ||
![]() |
c168a2f142 | ||
![]() |
68af6989b1 | ||
![]() |
446c67018a | ||
![]() |
0fe8e180c4 | ||
![]() |
7cdfc0ac3d | ||
![]() |
85cab10371 | ||
![]() |
61d8425cb6 | ||
![]() |
d49b6244c1 | ||
![]() |
10c2b97786 | ||
![]() |
9ed364ed36 | ||
![]() |
b95e5f6417 | ||
![]() |
4afebf88eb | ||
![]() |
d523158e92 | ||
![]() |
1fd1787a1c | ||
![]() |
fbbca68790 | ||
![]() |
4cdfd49637 | ||
![]() |
31c01cf107 | ||
![]() |
879e964f60 | ||
![]() |
019c9de291 | ||
![]() |
af370f81f0 | ||
![]() |
598c7ede37 | ||
![]() |
2f66755226 | ||
![]() |
d01a5f3d17 | ||
![]() |
bbda3e53da | ||
![]() |
22e73ea31f | ||
![]() |
6b37f201d7 | ||
![]() |
94ecf3847b | ||
![]() |
ee968691d7 | ||
![]() |
22db3bcb9c | ||
![]() |
7da803e908 | ||
![]() |
4aad07bdc4 | ||
![]() |
7a3f874753 | ||
![]() |
f77a8e2eda | ||
![]() |
bd99e950f5 | ||
![]() |
fdb7f34bc8 | ||
![]() |
85e3c24167 | ||
![]() |
aab8dd360f | ||
![]() |
a8f60d0d4b | ||
![]() |
5b1bfedb82 | ||
![]() |
ee7e4f5a42 | ||
![]() |
d20d1922db | ||
![]() |
be6fbee56a | ||
![]() |
3c0b26c4b9 | ||
![]() |
25e2fbdf7d | ||
![]() |
5bd67db123 | ||
![]() |
f3737502bd | ||
![]() |
74e7eb283a | ||
![]() |
f3f0741469 | ||
![]() |
9c43965a86 | ||
![]() |
3a4e719b8c | ||
![]() |
e87dc5d5e1 | ||
![]() |
a0d3ee45ea | ||
![]() |
38343af9e6 | ||
![]() |
53abb1e735 | ||
![]() |
8a7354d8d5 | ||
![]() |
f30793f591 | ||
![]() |
ab27472eb4 | ||
![]() |
213acdffda | ||
![]() |
a47e6623b8 | ||
![]() |
d894a3dd15 | ||
![]() |
75e9afbc4a | ||
![]() |
003591fe6f | ||
![]() |
fd83fefad1 | ||
![]() |
e601fd61f9 | ||
![]() |
8fe612e43f | ||
![]() |
6737682e82 | ||
![]() |
fd9c6ffb03 | ||
![]() |
4f25eab39d | ||
![]() |
006147a21e | ||
![]() |
c18fae4f2f | ||
![]() |
b4784a48e8 | ||
![]() |
039741e022 | ||
![]() |
74880dd6ca | ||
![]() |
5956a3354e | ||
![]() |
419006eff9 | ||
![]() |
f43ac442e1 | ||
![]() |
1c902893b5 | ||
![]() |
b1b6180e0b | ||
![]() |
5120ab0079 | ||
![]() |
35783b5c51 | ||
![]() |
29aea5a87b | ||
![]() |
e456c864c1 | ||
![]() |
df6d795d22 | ||
![]() |
e987e2118c | ||
![]() |
a1e915a984 | ||
![]() |
74b20f5b73 | ||
![]() |
6d80c3adfe | ||
![]() |
9d696b727a | ||
![]() |
98e88e2d01 | ||
![]() |
a48469ec5b | ||
![]() |
ca482e8add | ||
![]() |
38198b257d | ||
![]() |
0959b60b07 | ||
![]() |
02a65e0af8 | ||
![]() |
84624f66cb | ||
![]() |
5f098b2c5a | ||
![]() |
086c8def12 | ||
![]() |
176e829e9f | ||
![]() |
d5ee47e9da | ||
![]() |
2c2527bdc4 | ||
![]() |
f931e34365 | ||
![]() |
f34be8445f | ||
![]() |
37e51dc44d | ||
![]() |
a680c1bcde | ||
![]() |
1060138f77 | ||
![]() |
03eeabb4bd | ||
![]() |
2c7b1d5330 | ||
![]() |
b63ac3be45 | ||
![]() |
4b8ec990b8 | ||
![]() |
59ef68fecc | ||
![]() |
3bf45b60b2 | ||
![]() |
e037035bd4 | ||
![]() |
d432d8041a | ||
![]() |
05359d1ab2 | ||
![]() |
29139c1414 | ||
![]() |
585cfd49ab | ||
![]() |
54f78ac3ef | ||
![]() |
376d41618c | ||
![]() |
01df89eb8b | ||
![]() |
a1d307e336 | ||
![]() |
0712d0fdca | ||
![]() |
3c8131b976 | ||
![]() |
569643ac8c | ||
![]() |
cc23d0a2e7 | ||
![]() |
c237fe2486 | ||
![]() |
edcbcee84e | ||
![]() |
44d6f47ad6 | ||
![]() |
20f6e47525 | ||
![]() |
e304252f4b | ||
![]() |
32f06cbedf | ||
![]() |
75f6f14aaf | ||
![]() |
7dd8b1a678 | ||
![]() |
f5f17a27c5 | ||
![]() |
c9579115c3 | ||
![]() |
586353342f | ||
![]() |
317a944fec | ||
![]() |
24dad368dd | ||
![]() |
7d0efafdb3 | ||
![]() |
330c1fe783 | ||
![]() |
72dc73e6a5 | ||
![]() |
d7c5473cf6 | ||
![]() |
0ee80e4147 | ||
![]() |
9778022c37 | ||
![]() |
2f6bc4c8cb | ||
![]() |
5fbc01b991 | ||
![]() |
b749916313 | ||
![]() |
818cd3b47e | ||
![]() |
8302faad44 | ||
![]() |
8fa47480f8 | ||
![]() |
463dceb709 | ||
![]() |
cd323565d7 | ||
![]() |
a39bfdf98e | ||
![]() |
cd7c8fc4fa | ||
![]() |
5d431b45f1 | ||
![]() |
f4c4208e75 | ||
![]() |
52a0ed7f15 | ||
![]() |
000d813171 | ||
![]() |
e45cb21ad6 | ||
![]() |
7aae90da5a | ||
![]() |
fd5321c7d8 | ||
![]() |
65eeb7f1f6 | ||
![]() |
848484c08c | ||
![]() |
8c58a61f52 | ||
![]() |
93c7d0ac47 | ||
![]() |
df063ab61c | ||
![]() |
d480ea2b1f | ||
![]() |
205a006ac9 | ||
![]() |
9f45aa737a | ||
![]() |
f1615a03f3 | ||
![]() |
3554e348bc | ||
![]() |
5fd97e9973 | ||
![]() |
10e3d8fe0d | ||
![]() |
6c06796e3b | ||
![]() |
98f943cb6c | ||
![]() |
cedbb110e1 | ||
![]() |
c703be229a | ||
![]() |
c338e8f827 | ||
![]() |
7c09f5db2f | ||
![]() |
6177839a04 | ||
![]() |
4d22fbd97a | ||
![]() |
dd42c61581 | ||
![]() |
2fbfbe6cd4 | ||
![]() |
ec9663f680 | ||
![]() |
75e88a7321 | ||
![]() |
1e34f02034 | ||
![]() |
b69d3de40e | ||
![]() |
c1592673fb | ||
![]() |
da011c8871 | ||
![]() |
f360ec3c85 |
27
.gitignore
vendored
27
.gitignore
vendored
@@ -1,25 +1,26 @@
|
||||
.*.cmd
|
||||
*.ko
|
||||
*.la
|
||||
*.lo
|
||||
*.loT
|
||||
*.mod.c
|
||||
*.o
|
||||
.deps
|
||||
.libs
|
||||
.tmp_versions
|
||||
.deps/
|
||||
.dirstamp
|
||||
.libs/
|
||||
Makefile
|
||||
Makefile.in
|
||||
Module.symvers
|
||||
|
||||
/downloads
|
||||
|
||||
/Makefile.iptrules
|
||||
/Makefile.mans
|
||||
/.*.lst
|
||||
/matches.man
|
||||
/targets.man
|
||||
|
||||
/aclocal.m4
|
||||
/autom4te*.cache
|
||||
/compile
|
||||
/autom4te.cache/
|
||||
/build-aux/
|
||||
/config.*
|
||||
/configure
|
||||
/depcomp
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/missing
|
||||
/stamp-h1
|
||||
/xtables-addons.8
|
||||
|
90
INSTALL
90
INSTALL
@@ -9,12 +9,26 @@ in combination with the kernel's Kbuild system.
|
||||
# make install
|
||||
|
||||
|
||||
Prerequirements
|
||||
===============
|
||||
Supported configurations for this release
|
||||
=========================================
|
||||
|
||||
* xtables(-devel) 1.5.0
|
||||
* iptables >= 1.4.5
|
||||
|
||||
* kernel-source >= 2.6.19 with prepared output directory
|
||||
* kernel-devel >= 3.7
|
||||
with prepared build/output directory
|
||||
- CONFIG_NF_CONNTRACK
|
||||
- CONFIG_NF_CONNTRACK_MARK enabled =y or as module (=m)
|
||||
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||
notifications from pknock through netlink/connector
|
||||
|
||||
(Use xtables-addons-1.x if you need support for Linux < 3.7.)
|
||||
|
||||
|
||||
Selecting extensions
|
||||
====================
|
||||
|
||||
You can edit the "mconfig" file to select what modules to build and
|
||||
install. By default, all modules are enabled.
|
||||
|
||||
|
||||
Configuring and compiling
|
||||
@@ -22,6 +36,10 @@ Configuring and compiling
|
||||
|
||||
./configure [options]
|
||||
|
||||
--without-kbuild
|
||||
|
||||
Deactivate building kernel modules, and just do userspace parts.
|
||||
|
||||
--with-kbuild=
|
||||
|
||||
Specifies the path to the kernel build output directory. We need
|
||||
@@ -29,32 +47,18 @@ Configuring and compiling
|
||||
/lib/modules/$(running version)/build, which usually points to
|
||||
the right directory. (If not, you need to install something.)
|
||||
|
||||
--with-ksource=
|
||||
For RPM building, it should be /usr/src/linux-obj/...
|
||||
or whatever location the distro makes use of.
|
||||
|
||||
Specifies the path to the kernel source directory. This is
|
||||
currently needed for building the userspace extensions because
|
||||
we use unsanitized kernel headers, but the option MAY
|
||||
DISAPPEAR IN FUTURE.
|
||||
|
||||
--with-ksource=/usr/src/linux
|
||||
|
||||
--with-xtables=
|
||||
|
||||
Specifies the path to the directory where we may find
|
||||
xtables.h, should it not be within the standard C compiler
|
||||
include path (/usr/include), or if you want to override it.
|
||||
The directory will be checked for xtables.h and
|
||||
include/xtables.h. (This is to support the following specs:)
|
||||
|
||||
--with-xtables=/usr/src/xtables
|
||||
--with-xtables=/usr/src/xtables/include
|
||||
--with-xtables=/opt/xtables/include
|
||||
|
||||
--with-libxtdir=
|
||||
--with-xtlibdir=
|
||||
|
||||
Specifies the path to where the newly built extensions should
|
||||
be installed when `make install` is run. It uses the same
|
||||
default as the Xtables package, ${libexecdir}/xtables.
|
||||
be installed when `make install` is run. The default is to
|
||||
use the same path that Xtables/iptables modules use, as
|
||||
determined by `pkg-config xtables --variable xtlibdir`.
|
||||
Thus, this option normally does NOT need to be specified
|
||||
anymore, even if your distribution put modules in a strange
|
||||
location.
|
||||
|
||||
If you want to enable debugging, use
|
||||
|
||||
@@ -63,6 +67,33 @@ If you want to enable debugging, use
|
||||
(-O0 is used to turn off instruction reordering, which makes debugging
|
||||
much easier.)
|
||||
|
||||
To make use of a libxtables that is not in the default path, either
|
||||
|
||||
a) append the location of the pkg-config files like:
|
||||
|
||||
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
|
||||
|
||||
(Assuming that files have been installed)
|
||||
or,
|
||||
|
||||
b) override the pkg-config variables, for example:
|
||||
|
||||
./configure libxtables_CFLAGS="-I../iptables/include" \
|
||||
libxtables_LIBS="-L../iptables/.libs \
|
||||
-Wl,-rpath,../iptables/.libs -lxtables"
|
||||
|
||||
(Use this in case you wish to use it without having to
|
||||
run `make install`. This is because the libxtables.pc pkgconfig
|
||||
file in ../iptables would already point to e.g. /usr/local.)
|
||||
|
||||
|
||||
Build-time options
|
||||
==================
|
||||
|
||||
V= controls the verbosity of make commands.
|
||||
V=0 "silent" (output filename)
|
||||
V=1 "verbose" (entire gcc command line)
|
||||
|
||||
|
||||
Note to distribution packagers
|
||||
==============================
|
||||
@@ -70,5 +101,6 @@ Note to distribution packagers
|
||||
Except for --with-kbuild, distributions should not have a need to
|
||||
supply any other flags (besides --prefix=/usr and perhaps
|
||||
--libdir=/usr/lib64, etc.) to configure when all prerequired packages
|
||||
are installed. If xtables-devel is installed, necessary headers should
|
||||
be in /usr/include, so --with-xtables is not needed.
|
||||
are installed. If iptables-devel is installed, necessary headers should
|
||||
already be in /usr/include, so that overriding PKG_CONFIG_PATH,
|
||||
libxtables_CFLAGS and libxtables_LIBS variables should not be needed.
|
||||
|
339
LICENSE
Normal file
339
LICENSE
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
30
Makefile.am
30
Makefile.am
@@ -1,4 +1,30 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
SUBDIRS = extensions
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = extensions geoip
|
||||
|
||||
man_MANS := xtables-addons.8
|
||||
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
||||
|
||||
xtables-addons.8: FORCE
|
||||
${MAKE} -f Makefile.mans all;
|
||||
|
||||
install-exec-hook:
|
||||
depmod -a || :;
|
||||
|
||||
config.status: Makefile.iptrules.in
|
||||
|
||||
tmpdir := $(shell mktemp -dtu)
|
||||
packer = xz
|
||||
packext = .tar.xz
|
||||
|
||||
.PHONY: tarball
|
||||
tarball:
|
||||
# do not use mkdir_p here.
|
||||
mkdir ${tmpdir}
|
||||
pushd ${top_srcdir} && git archive --prefix=${PACKAGE_NAME}-${PACKAGE_VERSION}/ HEAD | tar -C ${tmpdir} -x && popd;
|
||||
pushd ${tmpdir}/${PACKAGE_NAME}-${PACKAGE_VERSION} && ./autogen.sh && popd;
|
||||
tar --use=${packer} -C ${tmpdir} -cf ${PACKAGE_NAME}-${PACKAGE_VERSION}${packext} --owner=root --group=root ${PACKAGE_NAME}-${PACKAGE_VERSION}/;
|
||||
rm -Rf ${tmpdir};
|
||||
|
31
Makefile.extra
Normal file
31
Makefile.extra
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- Makefile -*-
|
||||
# AUTOMAKE
|
||||
|
||||
export AM_CPPFLAGS
|
||||
export AM_CFLAGS
|
||||
XA_SRCDIR = ${srcdir}
|
||||
XA_TOPSRCDIR = ${top_srcdir}
|
||||
XA_ABSTOPSRCDIR = ${abs_top_srcdir}
|
||||
export XA_SRCDIR
|
||||
export XA_TOPSRCDIR
|
||||
export XA_ABSTOPSRCDIR
|
||||
|
||||
_mcall = -f ${top_builddir}/Makefile.iptrules
|
||||
|
||||
all-local: user-all-local
|
||||
|
||||
install-exec-local: user-install-local
|
||||
|
||||
clean-local: user-clean-local
|
||||
|
||||
user-all-local:
|
||||
${MAKE} ${_mcall} all;
|
||||
|
||||
# Have no user-install-data-local ATM
|
||||
user-install-local: user-install-exec-local
|
||||
|
||||
user-install-exec-local:
|
||||
${MAKE} ${_mcall} install;
|
||||
|
||||
user-clean-local:
|
||||
${MAKE} ${_mcall} clean;
|
62
Makefile.iptrules.in
Normal file
62
Makefile.iptrules.in
Normal file
@@ -0,0 +1,62 @@
|
||||
# -*- Makefile -*-
|
||||
# MANUAL
|
||||
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libexecdir = @libexecdir@
|
||||
xtlibdir = @xtlibdir@
|
||||
|
||||
CC = @CC@
|
||||
CCLD = ${CC}
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
libxtables_CFLAGS = @libxtables_CFLAGS@
|
||||
libxtables_LIBS = @libxtables_LIBS@
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
AM_DEFAULT_VERBOSITY = 0
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_SILENT_0 = @
|
||||
am__v_CC_ = ${am__v_CC_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_CCLD_ = ${am__v_CCLD_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_GEN_ = ${am__v_GEN_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_SILENT_ = ${am__v_SILENT_${AM_DEFAULT_VERBOSITY}}
|
||||
AM_V_CC = ${am__v_CC_${V}}
|
||||
AM_V_CCLD = ${am__v_CCLD_${V}}
|
||||
AM_V_GEN = ${am__v_GEN_${V}}
|
||||
AM_V_silent = ${am__v_GEN_${V}}
|
||||
|
||||
include ${XA_TOPSRCDIR}/mconfig
|
||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||
include ${XA_SRCDIR}/Mbuild
|
||||
-include ${XA_SRCDIR}/Mbuild.*
|
||||
|
||||
targets := $(filter-out %/,${obj-m})
|
||||
subdirs_list := $(filter %/,${obj-m})
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
all: ${targets}
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i || exit $$?; done;
|
||||
|
||||
install: ${targets}
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@ || exit $$?; done;
|
||||
install -dm0755 "${DESTDIR}/${xtlibdir}";
|
||||
@for i in $^; do install -pm0755 $$i "${DESTDIR}/${xtlibdir}"; done;
|
||||
|
||||
clean:
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@ || exit $$?; done;
|
||||
rm -f *.oo *.so;
|
||||
|
||||
lib%.so: lib%.oo
|
||||
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $< ${libxtables_LIBS} ${LDLIBS};
|
||||
|
||||
%.oo: ${XA_SRCDIR}/%.c
|
||||
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CPPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CPPFLAGS} ${CFLAGS} -o $@ -c $<;
|
40
Makefile.mans.in
Normal file
40
Makefile.mans.in
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- Makefile -*-
|
||||
# MANUAL
|
||||
|
||||
srcdir := @srcdir@
|
||||
|
||||
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man' | sort)
|
||||
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man' | sort)
|
||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
FORCE:
|
||||
|
||||
.manpages.lst: FORCE
|
||||
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
man_run = \
|
||||
${AM_V_GEN}for ext in $(1); do \
|
||||
name="$${ext%.man}"; \
|
||||
name="$${name\#\#*/libxt_}"; \
|
||||
if [ -f "$$ext" ]; then \
|
||||
echo ".SS $$name"; \
|
||||
cat "$$ext" || exit $$?; \
|
||||
continue; \
|
||||
fi; \
|
||||
done >$@;
|
||||
|
||||
all: xtables-addons.8
|
||||
|
||||
xtables-addons.8: ${srcdir}/xtables-addons.8.in matches.man targets.man
|
||||
${AM_V_GEN}sed -e '/@MATCHES@/ r matches.man' -e '/@TARGET@/ r targets.man' $< >$@;
|
||||
|
||||
matches.man: .manpages.lst ${wcman_matches}
|
||||
$(call man_run,${wlist_matches})
|
||||
|
||||
targets.man: .manpages.lst ${wcman_targets}
|
||||
$(call man_run,${wlist_targets})
|
53
README
53
README
@@ -5,6 +5,53 @@ Xtables-addons is the proclaimed successor to patch-o-matic(-ng). It
|
||||
contains extensions that were not accepted in the main Xtables
|
||||
package.
|
||||
|
||||
Xtables-addons is different from patch-o-matic in that you do not have
|
||||
to patch or recompile either kernel or Xtables(iptables). But please
|
||||
see the INSTALL file for the minimum requirements of this package.
|
||||
Xtables-addons is different from patch-o-matic in that you do not
|
||||
have to patch or recompile either kernel or Xtables(iptables). But
|
||||
please see the INSTALL file for the minimum requirements of this
|
||||
package.
|
||||
|
||||
All code imported from patch-o-matic has been reviewed and all
|
||||
apparent bugs like binary stability across multiarches, missing
|
||||
sanity checks and incorrect endianess handling have been fixed,
|
||||
simplified, and sped up.
|
||||
|
||||
|
||||
Included in this package
|
||||
========================
|
||||
- xt_ACCOUNT 1.16, libxt_ACCOUNT 1.3
|
||||
|
||||
|
||||
Inclusion into a kernel tree
|
||||
============================
|
||||
|
||||
|
||||
|
||||
|
||||
External extensions
|
||||
===================
|
||||
|
||||
The program "xa-download-more" can be used to download more
|
||||
extensions from 3rd parties into the source tree. The URLs are listed
|
||||
in the "sources" file. If the "sources" file contains an entry like
|
||||
|
||||
http://foobar.org/xa/
|
||||
|
||||
xa-download-more will inspect http://foobar.org/xa/xa-index.txt for
|
||||
files to download. That file may contain
|
||||
|
||||
foobar.tar.bz2
|
||||
|
||||
and xa-download-more will then retrieve and unpack
|
||||
http://foobar.org/xa/foobar.tar.bz2.
|
||||
|
||||
Files that should be contained in the tarball are an mconfig and
|
||||
Kbuild files to control building the extension, libxt_foobar.c for
|
||||
the userspace extension and xt_foobar.c for the kernel extension.
|
||||
|
||||
mconfig.foobar
|
||||
extensions/Kbuild.foobar
|
||||
extensions/Mbuild.foobar
|
||||
extensions/libxt_foobar.c
|
||||
extensions/libxt_foobar.man
|
||||
extensions/xt_foobar.c
|
||||
extensions/xt_foobar.h
|
||||
|
113
configure.ac
113
configure.ac
@@ -1,62 +1,83 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.5.0])
|
||||
AC_INIT([xtables-addons], [2.1])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_INSTALL
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_INIT_AUTOMAKE([1.10b -Wall foreign subdir-objects])
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
kbuilddir="/lib/modules/$(uname -r)/build";
|
||||
ksourcedir="/lib/modules/$(uname -r)/source";
|
||||
AC_ARG_WITH([kbuild],
|
||||
AS_HELP_STRING([--with-kbuild=PATH],
|
||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
||||
[kbuilddir="$withval"])
|
||||
AC_ARG_WITH([ksource],
|
||||
AS_HELP_STRING([--with-ksource=PATH],
|
||||
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
|
||||
[ksourcedir="$withval"])
|
||||
AC_ARG_WITH([xtables],
|
||||
AS_HELP_STRING([--with-xtables=PATH],
|
||||
[Path to the Xtables includes [[none]]]),
|
||||
[xtables_location="$withval"])
|
||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]])
|
||||
AS_HELP_STRING([--without-kbuild],
|
||||
[Build only userspace tools]),
|
||||
[kbuilddir="$withval"],
|
||||
[kbuilddir="/lib/modules/$(uname -r)/build"])
|
||||
#
|
||||
# check for --without-kbuild
|
||||
#
|
||||
if [[ "$kbuilddir" == no ]]; then
|
||||
kbuilddir="";
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
|
||||
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, see INSTALL file for details])])
|
||||
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.5])
|
||||
xtlibdir="$(pkg-config --variable=xtlibdir xtables)"
|
||||
|
||||
AC_ARG_WITH([xtlibdir],
|
||||
AS_HELP_STRING([--with-xtlibdir=PATH],
|
||||
[Path where to install Xtables extensions [[LIBEXECDIR/xtables]]]),
|
||||
[xtlibdir="$withval"],
|
||||
[xtlibdir='${libexecdir}/xtables'])
|
||||
[Path where to install Xtables extensions [[autodetect]]]),
|
||||
[xtlibdir="$withval"])
|
||||
AC_MSG_CHECKING([Xtables module directory])
|
||||
AC_MSG_RESULT([$xtlibdir])
|
||||
|
||||
AC_CHECK_HEADER([netinet/ip6.h], [], [AC_MSG_ERROR(but we need that for IPv6)])
|
||||
|
||||
AC_MSG_CHECKING([xtables.h presence])
|
||||
if [[ -n "$xtables_location" ]]; then
|
||||
if [[ -f "$xtables_location/xtables.h" ]]; then
|
||||
AC_MSG_RESULT([$xtables_location/xtables.h])
|
||||
xtables_CFLAGS="-I $xtables_location";
|
||||
elif [[ -f "$xtables_location/include/xtables.h" ]]; then
|
||||
AC_MSG_RESULT([$xtables_location/include/xtables.h])
|
||||
xtables_CFLAGS="-I $xtables_location/include";
|
||||
fi;
|
||||
fi;
|
||||
if [[ -z "$xtables_CFLAGS" ]]; then
|
||||
if [[ -f "$includedir/xtables.h" ]]; then
|
||||
AC_MSG_RESULT([$includedir/xtables.h])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi;
|
||||
fi;
|
||||
|
||||
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
||||
regular_CPPFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||
-D_REENTRANT -I\${XA_TOPSRCDIR}/include"
|
||||
regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
|
||||
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
|
||||
-Winline -pipe -DIPTABLES_VERSION=\\\"$PACKAGE_VERSION\\\" \
|
||||
-DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\"";
|
||||
kinclude_CFLAGS="-I $kbuilddir/include -I $ksourcedir/include";
|
||||
-Winline -pipe";
|
||||
|
||||
AC_SUBST([regular_CFLAGS xtables_CFLAGS kinclude_CFLAGS])
|
||||
if test -n "$kbuilddir"; then
|
||||
AC_MSG_CHECKING([kernel version that we will build against])
|
||||
krel="$(make -sC "$kbuilddir" M=$PWD kernelrelease)";
|
||||
kmajor="${krel%%[[^0-9]]*}";
|
||||
kmajor="$(($kmajor+0))";
|
||||
krel="${krel:${#kmajor}}";
|
||||
krel="${krel#.}";
|
||||
kminor="${krel%%[[^0-9]]*}";
|
||||
kminor="$(($kminor+0))";
|
||||
krel="${krel:${#kminor}}";
|
||||
krel="${krel#.}";
|
||||
kmicro="${krel%%[[^0-9]]*}";
|
||||
kmicro="$(($kmicro+0))";
|
||||
krel="${krel:${#kmicro}}";
|
||||
krel="${krel#.}";
|
||||
kstable="${krel%%[[^0-9]]*}";
|
||||
kstable="$(($kstable+0))";
|
||||
if test -z "$kmajor" -o -z "$kminor" -o -z "$kmicro"; then
|
||||
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
||||
else
|
||||
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||
if test "$kmajor" -gt 3 -o "$kmajor" -eq 3 -a "$kminor" -gt 8; then
|
||||
echo "WARNING: That kernel version is not officially supported.";
|
||||
elif test "$kmajor" -eq 3 -a "$kminor" -ge 7; then
|
||||
:;
|
||||
else
|
||||
echo "WARNING: That kernel version is not officially supported.";
|
||||
fi;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
AC_SUBST([regular_CPPFLAGS])
|
||||
AC_SUBST([regular_CFLAGS])
|
||||
AC_SUBST([kbuilddir])
|
||||
AC_SUBST([ksourcedir])
|
||||
AC_SUBST([xtlibdir])
|
||||
AC_OUTPUT([Makefile extensions/Makefile])
|
||||
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans geoip/Makefile
|
||||
extensions/Makefile extensions/ACCOUNT/Makefile
|
||||
extensions/pknock/Makefile])
|
||||
AC_OUTPUT
|
||||
|
4
doc/README.psd
Normal file
4
doc/README.psd
Normal file
@@ -0,0 +1,4 @@
|
||||
PSD (Portscan Detection) External extensions for Xtables-addons
|
||||
|
||||
Example:
|
||||
iptables -A INPUT -m psd --psd-weight-threshold 21 --psd-delay-threshold 300 --psd-lo-ports-weight 1 --psd-hi-ports-weight 10 -j LOG --log-prefix "PSD: "
|
39
doc/api/2.6.35.c
Normal file
39
doc/api/2.6.35.c
Normal file
@@ -0,0 +1,39 @@
|
||||
match:
|
||||
|
||||
/* true/false */
|
||||
bool
|
||||
(*match)(
|
||||
const struct sk_buff *skb,
|
||||
struct xt_action_param *,
|
||||
);
|
||||
|
||||
/* error code */
|
||||
int
|
||||
(*checkentry)(
|
||||
const struct xt_mtchk_param *,
|
||||
);
|
||||
|
||||
void
|
||||
(*destroy)(
|
||||
const struct xt_mtdtor_param *,
|
||||
);
|
||||
|
||||
target:
|
||||
|
||||
/* verdict */
|
||||
unsigned int
|
||||
(*target)(
|
||||
struct sk_buff *skb,
|
||||
const struct xt_action_param *,
|
||||
);
|
||||
|
||||
/* error code */
|
||||
int
|
||||
(*checkentry)(
|
||||
const struct xt_tgchk_param *,
|
||||
);
|
||||
|
||||
void
|
||||
(*destroy)(
|
||||
const struct xt_tgdtor_param *,
|
||||
);
|
39
doc/api/xt-a.c
Normal file
39
doc/api/xt-a.c
Normal file
@@ -0,0 +1,39 @@
|
||||
match:
|
||||
|
||||
/* true/false */
|
||||
bool
|
||||
(*match)(
|
||||
const struct sk_buff *skb,
|
||||
struct xt_action_param *,
|
||||
);
|
||||
|
||||
/* error code */
|
||||
int
|
||||
(*checkentry)(
|
||||
const struct xt_mtchk_param *,
|
||||
);
|
||||
|
||||
void
|
||||
(*destroy)(
|
||||
const struct xt_mtdtor_param *,
|
||||
);
|
||||
|
||||
target:
|
||||
|
||||
/* verdict */
|
||||
unsigned int
|
||||
(*target)(
|
||||
struct sk_buff **pskb,
|
||||
const struct xt_action_param *,
|
||||
);
|
||||
|
||||
/* error code */
|
||||
int
|
||||
(*checkentry)(
|
||||
const struct xt_tgchk_param *,
|
||||
);
|
||||
|
||||
void
|
||||
(*destroy)(
|
||||
const struct xt_tgdtor_param *,
|
||||
);
|
533
doc/changelog.txt
Normal file
533
doc/changelog.txt
Normal file
@@ -0,0 +1,533 @@
|
||||
|
||||
HEAD
|
||||
====
|
||||
|
||||
|
||||
v2.1 (2012-11-27)
|
||||
=================
|
||||
Fixes:
|
||||
- DNETMAP: fix compile error with Linux 3.7
|
||||
Enhancements:
|
||||
- Support for Linux 3.8
|
||||
|
||||
|
||||
v2.0 (2012-11-12)
|
||||
=================
|
||||
Changes:
|
||||
- remove support for Linux 2.6.17–3.6
|
||||
- remove xt_TEE (this is available upstream since 2.6.35)
|
||||
- remove xt_CHECKSUM (this is available upstream since 2.6.36)
|
||||
Enhancements:
|
||||
- Support for Linux 3.7
|
||||
|
||||
If you want to use Xtables-addons with kernels older than 3.7,
|
||||
use the addons 1.x series, which continues to be maintained for
|
||||
the time being.
|
||||
|
||||
|
||||
v1.47.1 (2010-10-15)
|
||||
====================
|
||||
Enhancements:
|
||||
- xt_psd gained IPv6 support
|
||||
Notes for this release:
|
||||
- Linux 3.7+ is expressly unsupported by this release.
|
||||
|
||||
|
||||
v1.46 (2012-08-23)
|
||||
==================
|
||||
Fixes:
|
||||
- length2, SYSRQ, RAWNAT: preinitialize values for ipv6_find_hdr
|
||||
- TARPIT: fix memory leak when tarpit_generic() fails
|
||||
- build: remove extraneous closing bracket in configure.ac
|
||||
- doc: update xt_SYSRQ.man to reflect that the full IPv6 address is needed
|
||||
Enhancements:
|
||||
- Support for Linux 3.6
|
||||
|
||||
|
||||
v1.45 (2012-07-16)
|
||||
==================
|
||||
Fixes:
|
||||
- build: export missing functions
|
||||
(fixes: "WARNING 'xtnu_ipv6_find_hdr' [xt_TARPIT.ko] not found")
|
||||
- build: avoid use of unexported functions
|
||||
(fixes: "WARNING 'ipv6_find_hdr' [xt_TARPIT.ko] not found"
|
||||
in <= linux-2.6.37)
|
||||
|
||||
|
||||
v1.44 (2012-07-15)
|
||||
==================
|
||||
Fixes:
|
||||
- SYSRQ: fix double target initialization at module load
|
||||
- build: do not attempt to build IPv6 parts if CONFIG_IP6_NF_IPTABLES=n
|
||||
Enhancements:
|
||||
- TARPIT gained IPv6 support
|
||||
|
||||
|
||||
v1.43 (2012-06-30)
|
||||
==================
|
||||
Fixes:
|
||||
- xt_psd: avoid crash due to curr->next corruption
|
||||
Changes:
|
||||
- xt_psd: reject invalid match options
|
||||
Enhancements:
|
||||
- Support for Linux 3.5
|
||||
- DNETMAP: new type: static binding
|
||||
- DNETMAP: new persistent flag option for prefix
|
||||
- DNETMAP: add write support to procfs interface
|
||||
|
||||
|
||||
v1.42 (2012-04-05)
|
||||
==================
|
||||
Fixes:
|
||||
- compat_xtables: fixed mistranslation of checkentry return values
|
||||
(affected kernels < 2.6.23)
|
||||
- xt_SYSRQ: fix compile error when crypto is turned off
|
||||
Changes:
|
||||
- ipset6-genl has been dropped from the tree;
|
||||
the libmnl build-time dependency is thus no longer needed
|
||||
Enhancements:
|
||||
- Support for Linux 3.3, 3.4
|
||||
|
||||
|
||||
v1.41 (2012-01-04)
|
||||
==================
|
||||
Changes:
|
||||
- Deactivate build of ipset-genl by default.
|
||||
I think the original ipset package can now take over, given there are
|
||||
a handful of kernels (2.6.39 onwards) that do not need patching.
|
||||
Enhancements:
|
||||
- Support for Linux 3.2
|
||||
|
||||
|
||||
v1.40 (2011-11-30)
|
||||
==================
|
||||
Fixes:
|
||||
- build: the code actually requires at least iptables 1.4.5 (would yield a
|
||||
compile error otherwise), make sure configure checks for it; update INSTALL
|
||||
- xt_ECHO: fix kernel warning about RTAX_HOPLIMIT being used
|
||||
- xt_ipv4options: fix an infinite loop
|
||||
Changes:
|
||||
- xt_ECHO: now calculates UDP checksum
|
||||
- Linux kernel versions below 2.6.32 are no longer officially
|
||||
supported, and will not be part of compilation testing.
|
||||
- update to ipset 6.10
|
||||
Enhancements:
|
||||
- xt_ECHO: IPv6 support
|
||||
|
||||
|
||||
v1.39 (2011-09-21)
|
||||
==================
|
||||
Fixes:
|
||||
- libxt_ACCOUNT: fix compilation after missing libxtables_CFLAGS
|
||||
- build: fix compilation after missing libxtables_CFLAGS in submodules
|
||||
- build: add missing linux/version.h includes where needed
|
||||
Changes:
|
||||
- Remove unsupported ipset 4.x from the Xtables-addons distribution
|
||||
- ipset: move ipset_errcode from src to library to avoid undefined reference
|
||||
- update to ipset 6.9.1
|
||||
|
||||
|
||||
v1.38 (2011-08-20)
|
||||
==================
|
||||
- xt_CHECKSUM: abort build when the feature is already provided by mainline
|
||||
- xt_SYSRQ: fix UDPLITE header lookup in IPv6
|
||||
- xt_TARPIT: fix kernel warning about RTAX_HOPLIMIT being used
|
||||
- xt_TEE: abort build when the feature is already provided by mainline
|
||||
- xt_ipp2p: support UDPLITE
|
||||
- xt_pknock: support UDPLITE
|
||||
- xt_psd: restore functionality with UDP
|
||||
- xt_psd: support UDPLITE
|
||||
- update to ipset 6.8
|
||||
- support for Linux 3.1
|
||||
|
||||
|
||||
v1.37 (2011-06-25)
|
||||
==================
|
||||
Fixes:
|
||||
- xt_SYSRQ: make IPv6 trigger work again
|
||||
- xt_SYSRQ: improve security: include host address in digest
|
||||
- xt_TARPIT: fix a kernel oops in --reset mode
|
||||
|
||||
|
||||
v1.36 (2011-06-03)
|
||||
==================
|
||||
Changes:
|
||||
- xt_geoip: avoid recursive function calls
|
||||
- xt_TARPIT: unlock for use in all tables
|
||||
- xt_TARPIT: honeypot and reset modes
|
||||
- update to ipset 6.7
|
||||
- support for Linux 3.0
|
||||
|
||||
|
||||
v1.35 (2011-04-11)
|
||||
==================
|
||||
Enhancements:
|
||||
- update to ipset 6.3
|
||||
* allow "new" as a commad alias to "create"
|
||||
* resolving IP addresses did not work at listing/saving sets, fixed
|
||||
* check ICMP and ICMPv6 with the set match and target in the testsuite
|
||||
* avoid possible syntax clashing at saving hostnames
|
||||
* fix linking with CONFIG_IPV6=n
|
||||
* sctp, udplite support for the hash:*port* types
|
||||
- ipset-genl: handle EAGAIN return value emitted from autoloader
|
||||
- ipset-genl: resolve nfgenmsg remains and fix spurious protocol abort
|
||||
|
||||
|
||||
v1.34 (2011-04-07)
|
||||
==================
|
||||
Fixes:
|
||||
- xt_pknock: avoid crash when hash TFM could not be allocated
|
||||
- xt_pknock: avoid inversion of rule lookup that led to warnings
|
||||
- xt_DNETMAP: add missing module alias
|
||||
- xt_DNETMAP: support for kernels below 2.6.34
|
||||
Changes:
|
||||
- Linux kernel versions below 2.6.29 are no longer officially
|
||||
supported, and will not be part of compilation testing.
|
||||
|
||||
|
||||
v1.33 (2011-02-02)
|
||||
==================
|
||||
Fixes:
|
||||
- build: restore functionality of `configure --without-kbuild`
|
||||
- build: fix objdir builds for ipset-5 (xt-a specific)
|
||||
- build: fix missing inclusion of dependency rules
|
||||
- xt_LOGMARK: fix detection of untracked connection for Linux >= 2.6.36
|
||||
Enhancements:
|
||||
- IPv6 support for xt_geoip
|
||||
- Update to ipset 5.3
|
||||
* make IPv4 and IPv6 address handling similar
|
||||
* show correct line numbers in restore output for parser errors
|
||||
- Update to ipset 5.4
|
||||
* fixed ICMP and ICMPv6 handling
|
||||
* fixed trailing whitespaces and pr_* messages
|
||||
* fixed module loading at create/header commands
|
||||
- build: support for Linux up to 2.6.38
|
||||
- build: preliminary support for iptables 1.4.11
|
||||
|
||||
|
||||
v1.32 (2011-01-04)
|
||||
==================
|
||||
Fixes:
|
||||
- Update to ipset 4.5
|
||||
* the iptreemap type used wrong gfp flags when deleting entries
|
||||
- Include ipset 5.2 with genetlink patch (beta)
|
||||
* no kernel patch needed, but requires Linux >= 2.6.35
|
||||
and thus needs to be manually enabled in mconfig
|
||||
|
||||
|
||||
v1.31 (2010-11-05)
|
||||
==================
|
||||
Fixes:
|
||||
- build: improve detection of kernel version and error handling
|
||||
Changes:
|
||||
- build: automatically derive Xtables module directory, thus
|
||||
--with-xtlibdir is no longer needed for ./configure in most cases
|
||||
(If I still see a distro using it, I will scold you for not
|
||||
reading this changelog.)
|
||||
Enhancements:
|
||||
- LOGMARK: print remaining lifetime of cts
|
||||
- xt_iface: allow matching against incoming/outgoing interface
|
||||
- libxt_gradm: match packets based on status of grsecurity RBAC
|
||||
(userspace part only - xt_gradm is in the grsec patch)
|
||||
|
||||
|
||||
v1.30 (2010-010-02)
|
||||
===================
|
||||
Fixes:
|
||||
- update to ipset 4.4
|
||||
* ipport{,ip,net}hash did not work with mixed "src" and "dst"
|
||||
destination parameters
|
||||
Changes:
|
||||
- deactivate building xt_TEE and xt_CHECKSUM by default, as these have been
|
||||
merged upstream in Linux 2.6.35 and 2.6.36, respectively.
|
||||
Distros still wishing to build this need to enable it in their build
|
||||
script, e.g. perl -i -pe 's{^build_TEE=.*}{build_TEE=m}' mconfig;
|
||||
|
||||
|
||||
v1.29 (2010-09-29)
|
||||
==================
|
||||
- compat_xtables: return bool for match_check and target_check in 2.6.23..34
|
||||
- ipset: enable building of ip_set_ipport{ip,net}hash.ko
|
||||
- support for Linux 2.6.36
|
||||
- SYSRQ: resolve compile error with Linux 2.6.36
|
||||
- TEE: resolve compile error with Linux 2.6.36
|
||||
- add workaround for broken linux-glibc-devel 2.6.34 userspace headers
|
||||
("implicit declaration of function 'ALIGN'")
|
||||
|
||||
|
||||
v1.28 (2010-07-24)
|
||||
==================
|
||||
- RAWNAT: IPv6 variants erroneously rejected masks /33-/128
|
||||
- new target xt_CHECKSUM
|
||||
- xt_length2: add support for IPv6 jumbograms
|
||||
- xt_geoip: fix possible out-of-bounds access
|
||||
- import xt_geoip database scripts
|
||||
|
||||
|
||||
v1.27 (2010-05-16)
|
||||
==================
|
||||
- further updates for the upcoming 2.6.35 changes
|
||||
|
||||
|
||||
v1.26 (2010-04-30)
|
||||
==================
|
||||
- compat_xtables: fix 2.6.34 compile error due to a typo
|
||||
|
||||
|
||||
v1.25 (2010-04-26)
|
||||
==================
|
||||
- TEE: do rechecksumming in PREROUTING too
|
||||
- TEE: decrease TTL on cloned packet
|
||||
- TEE: set dont-fragment on cloned packets
|
||||
- TEE: free skb when route lookup failed
|
||||
- TEE: do not limit use to mangle table
|
||||
- TEE: do not retain iif and mark on cloned packet
|
||||
- TEE: new loop detection logic
|
||||
- TEE: use less expensive pskb_copy
|
||||
- condition: remove unnecessary RCU protection
|
||||
|
||||
|
||||
v1.24 (2010-03-17)
|
||||
==================
|
||||
- build: fix build of userspace modules against old (pre-2.6.25)
|
||||
headers from linux-glibc-devel (/usr/include/linux)
|
||||
- ipp2p: updated bittorent command recognition
|
||||
- SYSRQ: let module load when crypto is unavailable
|
||||
- SYSRQ: allow processing of UDP-Lite
|
||||
|
||||
|
||||
v1.23 (2010-02-24)
|
||||
==================
|
||||
- build: support for Linux 2.6.34
|
||||
- build: remove unused --with-ksource option
|
||||
- build: remove unneeded --with-xtables option
|
||||
- build: fix compilations in RAWNAT, SYSRQ and length2 when CONFIG_IPV6=n
|
||||
- ipset: update to 4.2
|
||||
- ECHO: fix compilation w.r.t. skb_dst
|
||||
|
||||
|
||||
v1.22 (2010-01-22)
|
||||
==================
|
||||
- compat_xtables: support for 2.6.33 skb_iif changes
|
||||
- geoip: for FHS compliance use /usr/share/xt_geoip instead of /var/geoip
|
||||
- ipset: enable build of ip_set_setlist.ko
|
||||
- quota2: add the --no-change mode
|
||||
|
||||
|
||||
v1.21 (2009-12-09)
|
||||
==================
|
||||
- ACCOUNT: avoid collision with arp_tables setsockopt numbers
|
||||
- doc: fix option mismatch --gw/--gateway in libxt_TEE.man
|
||||
|
||||
|
||||
v1.20 (2009-11-19)
|
||||
==================
|
||||
- ipp2p: add more boundary checks
|
||||
- ipp2p: fix Gnutelle line ending detection
|
||||
- LOGMARK: remove unknown options from manpage
|
||||
- ACCOUNT: endianess-correctness
|
||||
- ipset: install manpage
|
||||
- ipset: fast forward to v4.1
|
||||
|
||||
|
||||
v1.19 (2009-10-12)
|
||||
==================
|
||||
- build: compile fixes for 2.6.31-rt
|
||||
- build: support for Linux 2.6.32
|
||||
- ipp2p: try to address underflows
|
||||
- psd: avoid potential crash when dealing with non-linear skbs
|
||||
- merge xt_ACCOUNT userspace utilities
|
||||
- added reworked xt_pknock module
|
||||
Changes from pknock v0.5:
|
||||
- pknock: "strict" and "checkip" flags were not displayed in `iptables -L`
|
||||
- pknock: the GC expire time's lower bound is now the default gc time
|
||||
(65000 msec) to avoid rendering anti-spoof protection in SPA mode useless
|
||||
- pknock: avoid crash on memory allocation failure and fix memleak
|
||||
- pknock: avoid fillup of peer table during DDoS
|
||||
- pknock: automatic closing of ports
|
||||
- pknock: make non-zero time mandatory for TCP mode
|
||||
- pknock: display only pknock mode and state relevant information in procfs
|
||||
- pknock: check interknock time only for !ST_ALLOWED peers
|
||||
- pknock: preserve time/autoclose values for rules added in
|
||||
reverse/arbitrary order
|
||||
- pknock: add a manpage
|
||||
|
||||
|
||||
v1.18 (2009-09-09)
|
||||
==================
|
||||
- build: support for Linux 2.6.31
|
||||
- ipset: fast forward to v3.2
|
||||
- quota2: support anonymous counters
|
||||
- quota2: reduce memory footprint for anonymous counters
|
||||
- quota2: extend locked period during cleanup (locking bugfix)
|
||||
- quota2: use strtoull instead of strtoul
|
||||
- merged xt_ACCOUNT module
|
||||
- merged xt_psd module
|
||||
|
||||
|
||||
v1.17 (2009-06-16)
|
||||
==================
|
||||
- IPMARK: print missing --shift parameter
|
||||
- build: use readlink -f in extensions/ipset/
|
||||
- build: support for Linux 2.6.30
|
||||
|
||||
|
||||
v1.16 (2009-05-27)
|
||||
==================
|
||||
- RAWNAT: make iptable_rawpost compile with 2.6.30-rc5
|
||||
- ipset: fast forward to 3.0
|
||||
|
||||
|
||||
v1.15 (2009-04-30)
|
||||
==================
|
||||
- build: add kernel version check to configure
|
||||
- condition: compile fix for 2.6.30-rc
|
||||
- condition: fix intrapositional negation sign
|
||||
- fuzzy: fix bogus comparison logic leftover from move to new 1.4.3 API
|
||||
- ipp2p: fix bogus varargs call
|
||||
- ipp2p: fix typo in error message
|
||||
- added "iface" match
|
||||
- added rawpost table (for use with RAWNAT)
|
||||
- added RAWSNAT/RAWDNAT targets
|
||||
|
||||
|
||||
v1.14 (2009-03-31)
|
||||
==================
|
||||
- fuzzy: need to account for kernel-level modified variables in .userspacesize
|
||||
- geoip: remove XT_ALIGN from .userspacesize when used with offsetof
|
||||
- SYSRQ: ignore non-UDP packets
|
||||
- SYSRQ: do proper L4 header access in IPv6 code
|
||||
(must not use tcp/udp_hdr in input path)
|
||||
- add "STEAL" target
|
||||
- dhcpmac: rename from dhcpaddr
|
||||
|
||||
|
||||
v1.13 (2009-03-23)
|
||||
==================
|
||||
- added a reworked ipv4options match
|
||||
- upgrade to iptables 1.4.3 API
|
||||
|
||||
|
||||
v1.12 (2009-03-07)
|
||||
==================
|
||||
- ipset: fix for compilation with 2.6.29-rt
|
||||
- ipset: fast forward to 2.5.0
|
||||
- rename xt_portscan to xt_lscan ("low-level scan") because
|
||||
"portscan" as a word caused confusion
|
||||
- xt_LOGMARK: print incoming interface index
|
||||
- revert "TEE: do not use TOS for routing"
|
||||
- xt_TEE: resolve unknown symbol error with CONFIG_IPV6=n
|
||||
- xt_TEE: enable routing by iif, nfmark and flowlabel
|
||||
|
||||
|
||||
v1.10 (2009-02-18)
|
||||
==================
|
||||
- compat: compile fixes for 2.6.29
|
||||
- ipset: upgrade to ipset 2.4.9
|
||||
|
||||
|
||||
v1.9 (2009-01-30)
|
||||
=================
|
||||
- add the xt_length2 extension
|
||||
- xt_TEE: remove intrapositional '!' support
|
||||
- ipset: upgrade to ipset 2.4.7
|
||||
|
||||
|
||||
v1.8 (2009-01-10)
|
||||
=================
|
||||
- xt_TEE: IPv6 support
|
||||
- xt_TEE: do not include TOS value in routing decision
|
||||
- xt_TEE: fix switch-case inversion for name/IP display
|
||||
- xt_ipp2p: update manpages and help text
|
||||
- xt_ipp2p: remove log flooding
|
||||
- xt_portscan: update manpage about --grscan option caveats
|
||||
|
||||
|
||||
v1.7 (2008-12-25)
|
||||
=================
|
||||
- xt_ECHO: compile fix
|
||||
- avoid the use of "_init" which led to compile errors on some installations
|
||||
- build: do not unconditionally install ipset
|
||||
- doc: add manpages for xt_ECHO and xt_TEE
|
||||
- xt_ipp2p: kazaa detection code cleanup
|
||||
- xt_ipp2p: fix newline inspection in kazaa detection
|
||||
- xt_ipp2p: ensure better array bounds checking
|
||||
- xt_SYSRQ: improve security by hashing password
|
||||
|
||||
|
||||
v1.6 (2008-11-18)
|
||||
=================
|
||||
- build: support for Linux 2.6.17
|
||||
- build: compile fixes for 2.6.18 and 2.6.19
|
||||
- xt_ECHO: resolve compile errors in xt_ECHO
|
||||
- xt_ipp2p: parenthesize unaligned-access macros
|
||||
|
||||
|
||||
v1.5.7 (2008-09-01)
|
||||
===================
|
||||
- API layer: fix use of uninitialized 'hotdrop' variable
|
||||
- API layer: move to pskb-based signatures
|
||||
- xt_SYSRQ: compile fixes for Linux <= 2.6.19
|
||||
- ipset: adjust semaphore.h include for Linux >= 2.6.27
|
||||
- build: automatically run `depmod -a` on installation
|
||||
- add reworked xt_fuzzy module
|
||||
- add DHCP address match and mangle module
|
||||
- xt_portscan: IPv6 support
|
||||
- xt_SYSRQ: add missing module aliases
|
||||
|
||||
|
||||
v1.5.5 (2008-08-03)
|
||||
===================
|
||||
- manpage updates for xt_CHAOS, xt_IPMARK; README updates
|
||||
- build: properly recognize external Kbuild/Mbuild files
|
||||
- build: remove dependency on CONFIG_NETWORK_SECMARK
|
||||
- add the xt_SYSRQ target
|
||||
- add the xt_quota2 extension
|
||||
- import ipset extension group
|
||||
|
||||
|
||||
v1.5.4.1 (2008-04-26)
|
||||
=====================
|
||||
- build: fix compile error for 2.6.18-stable
|
||||
|
||||
|
||||
v1.5.4 (2008-04-09)
|
||||
===================
|
||||
- build: support building multiple files with one config option
|
||||
- API layer: add check for pskb relocation
|
||||
- doc: generate manpages
|
||||
- xt_ECHO: catch skb_linearize out-of-memory condition
|
||||
- xt_LOGMARK: add hook= and ctdir= fields in dump
|
||||
- xt_LOGMARK: fix comma output in ctstatus= list
|
||||
- xt_TEE: fix address copying bug
|
||||
- xt_TEE: make skb writable before attempting checksum update
|
||||
- add reworked xt_condition match
|
||||
- add reworked xt_ipp2p match
|
||||
- add reworked xt_IPMARK target
|
||||
|
||||
|
||||
v1.5.3 (2008-03-22)
|
||||
===================
|
||||
- support for Linux 2.6.18
|
||||
- add xt_ECHO sample target
|
||||
- add reworked xt_geoip match
|
||||
|
||||
|
||||
v1.5.2 (2008-03-04)
|
||||
===================
|
||||
- build: support for GNU make < 3.81 which does not have $(realpath)
|
||||
|
||||
|
||||
v1.5.1 (2008-02-21)
|
||||
===================
|
||||
- build: allow user to select what extensions to compile and install
|
||||
- build: allow external proejcts to be downloaded into the tree
|
||||
- xt_LOGMARK: dump classify mark, ctstate and ctstatus
|
||||
- add xt_CHAOS, xt_DELUDE and xt_portscan from Chaostables
|
||||
|
||||
|
||||
v1.5.0 (2008-02-11)
|
||||
===================
|
||||
Initial release with:
|
||||
- extensions: xt_LOGMARK, xt_TARPIT, xt_TEE
|
||||
- support for Linux >= 2.6.19
|
12
extensions/.gitignore
vendored
Normal file
12
extensions/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.*.cmd
|
||||
.*.d
|
||||
.tmp_versions/
|
||||
*.ko
|
||||
*.mod.c
|
||||
Module.markers
|
||||
Module.symvers
|
||||
Modules.symvers
|
||||
modules.order
|
||||
|
||||
*.so
|
||||
*.oo
|
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/iptaccount
|
5
extensions/ACCOUNT/Kbuild
Normal file
5
extensions/ACCOUNT/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
EXTRA_CFLAGS = -I${src}/..
|
||||
|
||||
obj-m += xt_ACCOUNT.o
|
13
extensions/ACCOUNT/Makefile.am
Normal file
13
extensions/ACCOUNT/Makefile.am
Normal file
@@ -0,0 +1,13 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${abs_top_srcdir}/extensions
|
||||
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
|
||||
|
||||
include ../../Makefile.extra
|
||||
|
||||
sbin_PROGRAMS = iptaccount
|
||||
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
||||
|
||||
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
||||
|
||||
man_MANS = iptaccount.8
|
3
extensions/ACCOUNT/Mbuild
Normal file
3
extensions/ACCOUNT/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
1
extensions/ACCOUNT/VERSION.txt
Normal file
1
extensions/ACCOUNT/VERSION.txt
Normal file
@@ -0,0 +1 @@
|
||||
1.16
|
26
extensions/ACCOUNT/iptaccount.8
Normal file
26
extensions/ACCOUNT/iptaccount.8
Normal file
@@ -0,0 +1,26 @@
|
||||
.TH iptaccount 8 "v1.16" "" "v1.16"
|
||||
.SH Name
|
||||
iptaccount \(em administrative utility to access xt_ACCOUNT statistics
|
||||
.SH Syntax
|
||||
\fBiptaccount\fP [\fB\-acfhu\fP] [\fB\-l\fP \fIname\fP]
|
||||
.SH Options
|
||||
.PP
|
||||
\fB\-a\fP
|
||||
List all (accounting) table names.
|
||||
.PP
|
||||
\fB\-c\fP
|
||||
Loop every second (abort with CTRL+C).
|
||||
.PP
|
||||
\fB\-f\fP
|
||||
Flush data after display.
|
||||
.PP
|
||||
\fB\-h\fP
|
||||
Free all kernel handles. (Experts only!)
|
||||
.PP
|
||||
\fB\-l\fP \fIname\fP
|
||||
Show data in accounting table called by \fIname\fP.
|
||||
.TP
|
||||
\fB\-u\fP
|
||||
Show kernel handle usage.
|
||||
.SH "See also"
|
||||
\fBxtables-addons\fP(8)
|
224
extensions/ACCOUNT/iptaccount.c
Normal file
224
extensions/ACCOUNT/iptaccount.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004-2006 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/types.h>
|
||||
#include <libxt_ACCOUNT_cl.h>
|
||||
|
||||
bool exit_now;
|
||||
static void sig_term(int signr)
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
exit_now = true;
|
||||
}
|
||||
|
||||
static char *addr_to_dotted(unsigned int addr)
|
||||
{
|
||||
static char buf[16];
|
||||
const unsigned char *bytep;
|
||||
|
||||
addr = htonl(addr);
|
||||
bytep = (const unsigned char *)&addr;
|
||||
snprintf(buf, sizeof(buf), "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void show_usage(void)
|
||||
{
|
||||
printf("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-c] [-s] [-l name]\n");
|
||||
printf("[-u] show kernel handle usage\n");
|
||||
printf("[-h] free all kernel handles (experts only!)\n\n");
|
||||
printf("[-a] list all table names\n");
|
||||
printf("[-l name] show data in table <name>\n");
|
||||
printf("[-f] flush data after showing\n");
|
||||
printf("[-c] loop every second (abort with CTRL+C)\n");
|
||||
printf("[-s] CSV output (for spreadsheet import)\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct ipt_ACCOUNT_context ctx;
|
||||
struct ipt_acc_handle_ip *entry;
|
||||
int i;
|
||||
char optchar;
|
||||
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
||||
bool doFlush = false, doContinue = false, doCSV = false;
|
||||
|
||||
char *table_name = NULL;
|
||||
const char *name;
|
||||
|
||||
printf("\nlibxt_ACCOUNT_cl userspace accounting tool v%s\n\n",
|
||||
LIBXT_ACCOUNT_VERSION);
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while ((optchar = getopt(argc, argv, "uhacfsl:")) != -1)
|
||||
{
|
||||
switch (optchar)
|
||||
{
|
||||
case 'u':
|
||||
doHandleUsage = true;
|
||||
break;
|
||||
case 'h':
|
||||
doHandleFree = true;
|
||||
break;
|
||||
case 'a':
|
||||
doTableNames = true;
|
||||
break;
|
||||
case 'f':
|
||||
doFlush = true;
|
||||
break;
|
||||
case 'c':
|
||||
doContinue = true;
|
||||
break;
|
||||
case 's':
|
||||
doCSV = true;
|
||||
break;
|
||||
case 'l':
|
||||
table_name = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
show_usage();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// install exit handler
|
||||
if (signal(SIGTERM, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGTERM\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (signal(SIGINT, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGINT\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (signal(SIGQUIT, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGQUIT\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (ipt_ACCOUNT_init(&ctx))
|
||||
{
|
||||
printf("Init failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Get handle usage?
|
||||
if (doHandleUsage)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("get_handle_usage failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
|
||||
}
|
||||
|
||||
if (doHandleFree)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("handle_free_all failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Freed all handles in kernel space\n");
|
||||
}
|
||||
|
||||
if (doTableNames)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_get_table_names(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("get_table_names failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
|
||||
printf("Found table: %s\n", name);
|
||||
}
|
||||
|
||||
if (table_name)
|
||||
{
|
||||
// Read out data
|
||||
if (doCSV)
|
||||
printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
|
||||
else
|
||||
printf("Showing table: %s\n", table_name);
|
||||
|
||||
i = 0;
|
||||
while (!exit_now)
|
||||
{
|
||||
// Get entries from table test
|
||||
if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
|
||||
{
|
||||
printf("Read failed: %s\n", ctx.error_str);
|
||||
ipt_ACCOUNT_deinit(&ctx);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!doCSV)
|
||||
printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
|
||||
ctx.handle.itemcount == 1 ? "item" : "items");
|
||||
|
||||
// Output and free entries
|
||||
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
||||
{
|
||||
if (doCSV)
|
||||
printf("%s;%u;%u;%u;%u\n",
|
||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||
entry->dst_packets, entry->dst_bytes);
|
||||
else
|
||||
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
|
||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||
entry->dst_packets, entry->dst_bytes);
|
||||
}
|
||||
|
||||
if (doContinue)
|
||||
{
|
||||
sleep(1);
|
||||
i++;
|
||||
} else
|
||||
exit_now = true;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Finished.\n");
|
||||
ipt_ACCOUNT_deinit(&ctx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
162
extensions/ACCOUNT/libxt_ACCOUNT.c
Normal file
162
extensions/ACCOUNT/libxt_ACCOUNT.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* Shared library add-on to iptables to add ACCOUNT(ing) support.
|
||||
Author: Intra2net AG <opensource@intra2net.com>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <getopt.h>
|
||||
#include <stddef.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_ACCOUNT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static struct option account_tg_opts[] = {
|
||||
{.name = "addr", .has_arg = true, .val = 'a'},
|
||||
{.name = "tname", .has_arg = true, .val = 't'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/* Function which prints out usage message. */
|
||||
static void account_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"ACCOUNT target options:\n"
|
||||
" --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
|
||||
" --%s name\t\t\tTable name for the userspace library\n",
|
||||
account_tg_opts[0].name, account_tg_opts[1].name);
|
||||
}
|
||||
|
||||
/* Initialize the target. */
|
||||
static void
|
||||
account_tg_init(struct xt_entry_target *t)
|
||||
{
|
||||
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
|
||||
|
||||
accountinfo->table_nr = -1;
|
||||
}
|
||||
|
||||
#define IPT_ACCOUNT_OPT_ADDR 0x01
|
||||
#define IPT_ACCOUNT_OPT_TABLE 0x02
|
||||
|
||||
/* Function which parses command options; returns true if it
|
||||
ate an option */
|
||||
|
||||
static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
|
||||
struct in_addr *addrs = NULL, mask;
|
||||
unsigned int naddrs = 0;
|
||||
|
||||
switch (c) {
|
||||
case 'a':
|
||||
if (*flags & IPT_ACCOUNT_OPT_ADDR)
|
||||
xtables_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
|
||||
account_tg_opts[0].name);
|
||||
|
||||
xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);
|
||||
if (naddrs > 1)
|
||||
xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
|
||||
|
||||
accountinfo->net_ip = addrs[0].s_addr;
|
||||
accountinfo->net_mask = mask.s_addr;
|
||||
|
||||
*flags |= IPT_ACCOUNT_OPT_ADDR;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (*flags & IPT_ACCOUNT_OPT_TABLE)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Can't specify --%s twice",
|
||||
account_tg_opts[1].name);
|
||||
|
||||
if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Maximum table name length %u for --%s",
|
||||
ACCOUNT_TABLE_NAME_LEN - 1,
|
||||
account_tg_opts[1].name);
|
||||
|
||||
strcpy(accountinfo->table_name, optarg);
|
||||
*flags |= IPT_ACCOUNT_OPT_TABLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void account_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & IPT_ACCOUNT_OPT_ADDR) || !(flags & IPT_ACCOUNT_OPT_TABLE))
|
||||
xtables_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
|
||||
account_tg_opts[0].name, account_tg_opts[1].name);
|
||||
}
|
||||
|
||||
static void account_tg_print_it(const void *ip,
|
||||
const struct xt_entry_target *target, bool do_prefix)
|
||||
{
|
||||
const struct ipt_acc_info *accountinfo
|
||||
= (const struct ipt_acc_info *)target->data;
|
||||
struct in_addr a;
|
||||
|
||||
if (!do_prefix)
|
||||
printf(" ACCOUNT ");
|
||||
|
||||
// Network information
|
||||
if (do_prefix)
|
||||
printf(" --");
|
||||
printf("%s ", account_tg_opts[0].name);
|
||||
|
||||
a.s_addr = accountinfo->net_ip;
|
||||
printf("%s", xtables_ipaddr_to_numeric(&a));
|
||||
a.s_addr = accountinfo->net_mask;
|
||||
printf("%s", xtables_ipmask_to_numeric(&a));
|
||||
|
||||
printf(" ");
|
||||
if (do_prefix)
|
||||
printf(" --");
|
||||
|
||||
printf("%s %s", account_tg_opts[1].name, accountinfo->table_name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
account_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
account_tg_print_it(ip, target, false);
|
||||
}
|
||||
|
||||
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
||||
static void
|
||||
account_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
account_tg_print_it(ip, target, true);
|
||||
}
|
||||
|
||||
static struct xtables_target account_tg_reg = {
|
||||
.name = "ACCOUNT",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
|
||||
.userspacesize = offsetof(struct ipt_acc_info, table_nr),
|
||||
.help = account_tg_help,
|
||||
.init = account_tg_init,
|
||||
.parse = account_tg_parse,
|
||||
.final_check = account_tg_check,
|
||||
.print = account_tg_print,
|
||||
.save = account_tg_save,
|
||||
.extra_opts = account_tg_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void account_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&account_tg_reg);
|
||||
}
|
60
extensions/ACCOUNT/libxt_ACCOUNT.man
Normal file
60
extensions/ACCOUNT/libxt_ACCOUNT.man
Normal file
@@ -0,0 +1,60 @@
|
||||
The ACCOUNT target is a high performance accounting system for large
|
||||
local networks. It allows per-IP accounting in whole prefixes of IPv4
|
||||
addresses with size of up to /8 without the need to add individual
|
||||
accouting rule for each IP address.
|
||||
.PP
|
||||
The ACCOUNT is designed to be queried for data every second or at
|
||||
least every ten seconds. It is written as kernel module to handle high
|
||||
bandwidths without packet loss.
|
||||
.PP
|
||||
The largest possible subnet size is 24 bit, meaning for example 10.0.0.0/8
|
||||
network. ACCOUNT uses fixed internal data structures
|
||||
which speeds up the processing of each packet. Furthermore,
|
||||
accounting data for one complete 192.168.1.X/24 network takes 4 KB of
|
||||
memory. Memory for 16 or 24 bit networks is only allocated when
|
||||
needed.
|
||||
.PP
|
||||
To optimize the kernel<->userspace data transfer a bit more, the
|
||||
kernel module only transfers information about IPs, where the src/dst
|
||||
packet counter is not 0. This saves precious kernel time.
|
||||
.PP
|
||||
There is no /proc interface as it would be too slow for continuous access.
|
||||
The read-and-flush query operation is the fastest, as no internal data
|
||||
snapshot needs to be created&copied for all data. Use the "read"
|
||||
operation without flush only for debugging purposes!
|
||||
.PP
|
||||
Usage:
|
||||
.PP
|
||||
ACCOUNT takes two mandatory parameters:
|
||||
.TP
|
||||
\fB\-\-addr\fR \fInetwork\fP\fB/\fP\fInetmask\fR
|
||||
where \fInetwork\fP\fB/\fP\fInetmask\fP is the subnet to account for, in CIDR syntax
|
||||
.TP
|
||||
\fB\-\-tname\fP \fINAME\fP
|
||||
where \fINAME\fP is the name of the table where the accounting information
|
||||
should be stored
|
||||
.PP
|
||||
The subnet 0.0.0.0/0 is a special case: all data are then stored in the src_bytes
|
||||
and src_packets structure of slot "0". This is useful if you want
|
||||
to account the overall traffic to/from your internet provider.
|
||||
.PP
|
||||
The data can be queried using the userspace libxt_ACCOUNT_cl library,
|
||||
and by the reference implementation to show usage of this library,
|
||||
the \fBiptaccount\fP(8) tool.
|
||||
.PP
|
||||
Here is an example of use:
|
||||
.PP
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing;
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales;
|
||||
.PP
|
||||
This creates two tables called "all_outgoing" and "sales" which can be
|
||||
queried using the userspace library/iptaccount tool.
|
||||
.PP
|
||||
Note that this target is non-terminating \(em the packet destined to it
|
||||
will continue traversing the chain in which it has been used.
|
||||
.PP
|
||||
Also note that once a table has been defined for specific CIDR address/netmask
|
||||
block, it can be referenced multiple times using \-j ACCOUNT, provided
|
||||
that both the original table name and address/netmask block are specified.
|
||||
.PP
|
||||
For more information go to http://www.intra2net.com/en/developer/ipt_ACCOUNT/
|
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include <libxt_ACCOUNT_cl.h>
|
||||
|
||||
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(struct ipt_ACCOUNT_context));
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
if (ctx->sockfd < 0) {
|
||||
ctx->sockfd = -1;
|
||||
ctx->error_str = "Can't open socket to kernel. "
|
||||
"Permission denied or ipt_ACCOUNT module not loaded";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4096 bytes default buffer should save us from reallocations
|
||||
// as it fits 200 concurrent active clients
|
||||
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
|
||||
close(ctx->sockfd);
|
||||
ctx->sockfd = -1;
|
||||
ctx->error_str = "Out of memory for data buffer";
|
||||
return -1;
|
||||
}
|
||||
ctx->data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
if (ctx->handle.handle_nr != -1) {
|
||||
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
ctx->handle.handle_nr = -1;
|
||||
}
|
||||
|
||||
ctx->handle.itemcount = 0;
|
||||
ctx->pos = 0;
|
||||
}
|
||||
|
||||
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
free(ctx->data);
|
||||
ctx->data = NULL;
|
||||
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
|
||||
close(ctx->sockfd);
|
||||
ctx->sockfd = -1;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||
const char *table, char dont_flush)
|
||||
{
|
||||
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||
unsigned int new_size;
|
||||
int rtn;
|
||||
|
||||
strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
|
||||
|
||||
// Get table information
|
||||
if (!dont_flush)
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
|
||||
else
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
|
||||
&ctx->handle, &s);
|
||||
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get table information from kernel. "
|
||||
"Does it exist?";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check data buffer size
|
||||
ctx->pos = 0;
|
||||
new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
|
||||
// We want to prevent reallocations all the time
|
||||
if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
|
||||
new_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
|
||||
// Reallocate if it's too small or twice as big
|
||||
if (ctx->data_size < new_size || ctx->data_size > new_size * 2) {
|
||||
// Free old buffer
|
||||
free(ctx->data);
|
||||
ctx->data_size = 0;
|
||||
|
||||
if ((ctx->data = malloc(new_size)) == NULL) {
|
||||
ctx->error_str = "Out of memory for data buffer";
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->data_size = new_size;
|
||||
}
|
||||
|
||||
// Copy data from kernel
|
||||
memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
|
||||
ctx->data, &ctx->data_size);
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get data from kernel. "
|
||||
"Check /var/log/messages for details.";
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Free kernel handle but don't reset pos/itemcount
|
||||
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
struct ipt_acc_handle_ip *rtn;
|
||||
|
||||
// Empty or no more items left to return?
|
||||
if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
|
||||
return NULL;
|
||||
|
||||
// Get next entry
|
||||
rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
|
||||
* sizeof(struct ipt_acc_handle_ip));
|
||||
ctx->pos++;
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||
if (getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
|
||||
ctx->error_str = "Can't get handle usage information from kernel";
|
||||
return -1;
|
||||
}
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
return ctx->handle.itemcount;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
if (setsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
|
||||
ctx->error_str = "Can't free all kernel handles";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
|
||||
ctx->data, &ctx->data_size);
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get table names from kernel. Out of memory, "
|
||||
"MINBUFISZE too small?";
|
||||
return -1;
|
||||
}
|
||||
ctx->pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
const char *rtn;
|
||||
if (((char *)ctx->data)[ctx->pos] == 0)
|
||||
return 0;
|
||||
|
||||
rtn = ctx->data + ctx->pos;
|
||||
ctx->pos += strlen(ctx->data + ctx->pos) + 1;
|
||||
|
||||
return rtn;
|
||||
}
|
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _xt_ACCOUNT_cl_H
|
||||
#define _xt_ACCOUNT_cl_H
|
||||
|
||||
#include <xt_ACCOUNT.h>
|
||||
|
||||
#define LIBXT_ACCOUNT_VERSION "1.3"
|
||||
|
||||
/* Don't set this below the size of struct ipt_account_handle_sockopt */
|
||||
#define IPT_ACCOUNT_MIN_BUFSIZE 4096
|
||||
|
||||
struct ipt_ACCOUNT_context
|
||||
{
|
||||
int sockfd;
|
||||
struct ipt_acc_handle_sockopt handle;
|
||||
|
||||
unsigned int data_size;
|
||||
void *data;
|
||||
unsigned int pos;
|
||||
|
||||
char *error_str;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx);
|
||||
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||
const char *table, char dont_flush);
|
||||
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(
|
||||
struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
/* ipt_ACCOUNT_free_entries is for internal use only function as this library
|
||||
is constructed to be used in a loop -> Don't allocate memory all the time.
|
||||
The data buffer is freed on deinit() */
|
||||
|
||||
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx);
|
||||
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
1165
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
1165
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
File diff suppressed because it is too large
Load Diff
69
extensions/ACCOUNT/xt_ACCOUNT.h
Normal file
69
extensions/ACCOUNT/xt_ACCOUNT.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004-2006 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License *
|
||||
* version 2 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _IPT_ACCOUNT_H
|
||||
#define _IPT_ACCOUNT_H
|
||||
|
||||
/*
|
||||
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
|
||||
* library (libxt_ACCOUNT_cl). Hopefully we are unique at least within our
|
||||
* kernel & xtables-addons space.
|
||||
*
|
||||
* Turned out often enough we are not.
|
||||
* 64-67 used by ip_tables, ip6_tables
|
||||
* 96-100 used by arp_tables
|
||||
* 128-131 used by ebtables
|
||||
*/
|
||||
#define SO_ACCOUNT_BASE_CTL 70
|
||||
|
||||
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE (SO_ACCOUNT_BASE_CTL + 1)
|
||||
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL (SO_ACCOUNT_BASE_CTL + 2)
|
||||
#define IPT_SO_SET_ACCOUNT_MAX IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL
|
||||
|
||||
#define IPT_SO_GET_ACCOUNT_PREPARE_READ (SO_ACCOUNT_BASE_CTL + 4)
|
||||
#define IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH (SO_ACCOUNT_BASE_CTL + 5)
|
||||
#define IPT_SO_GET_ACCOUNT_GET_DATA (SO_ACCOUNT_BASE_CTL + 6)
|
||||
#define IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE (SO_ACCOUNT_BASE_CTL + 7)
|
||||
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
|
||||
#define IPT_SO_GET_ACCOUNT_MAX IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES
|
||||
|
||||
#define ACCOUNT_MAX_TABLES 128
|
||||
#define ACCOUNT_TABLE_NAME_LEN 32
|
||||
#define ACCOUNT_MAX_HANDLES 10
|
||||
|
||||
/* Structure for the userspace part of ipt_ACCOUNT */
|
||||
struct ipt_acc_info {
|
||||
__be32 net_ip;
|
||||
__be32 net_mask;
|
||||
char table_name[ACCOUNT_TABLE_NAME_LEN];
|
||||
int32_t table_nr;
|
||||
};
|
||||
|
||||
/* Handle structure for communication with the userspace library */
|
||||
struct ipt_acc_handle_sockopt {
|
||||
uint32_t handle_nr; /* Used for HANDLE_FREE */
|
||||
char name[ACCOUNT_TABLE_NAME_LEN]; /* Used for HANDLE_PREPARE_READ/
|
||||
HANDLE_READ_FLUSH */
|
||||
uint32_t itemcount; /* Used for HANDLE_PREPARE_READ/
|
||||
HANDLE_READ_FLUSH */
|
||||
};
|
||||
|
||||
/*
|
||||
Used for every IP when returning data
|
||||
*/
|
||||
struct ipt_acc_handle_ip {
|
||||
__be32 ip;
|
||||
uint32_t src_packets;
|
||||
uint32_t src_bytes;
|
||||
uint32_t dst_packets;
|
||||
uint32_t dst_bytes;
|
||||
};
|
||||
|
||||
#endif /* _IPT_ACCOUNT_H */
|
@@ -1,6 +1,38 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-m += xt_LOGMARK.o
|
||||
obj-m += xt_TARPIT.o
|
||||
obj-m += xt_TEE.o
|
||||
obj-m += compat_xtables.o
|
||||
include ${XA_ABSTOPSRCDIR}/mconfig
|
||||
-include ${XA_ABSTOPSRCDIR}/mconfig.*
|
||||
|
||||
obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_ACCOUNT} += ACCOUNT/
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||
obj-${build_DNETMAP} += xt_DNETMAP.o
|
||||
ifeq (${VERSION},3)
|
||||
obj-${build_ECHO} += xt_ECHO.o
|
||||
endif
|
||||
obj-${build_IPMARK} += xt_IPMARK.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
obj-${build_RAWNAT} += xt_RAWNAT.o iptable_rawpost.o
|
||||
ifneq (${CONFIG_IP6_NF_IPTABLES},)
|
||||
obj-${build_RAWNAT} += ip6table_rawpost.o
|
||||
endif
|
||||
obj-${build_SYSRQ} += xt_SYSRQ.o
|
||||
obj-${build_STEAL} += xt_STEAL.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
obj-${build_condition} += xt_condition.o
|
||||
obj-${build_fuzzy} += xt_fuzzy.o
|
||||
obj-${build_geoip} += xt_geoip.o
|
||||
obj-${build_iface} += xt_iface.o
|
||||
obj-${build_ipp2p} += xt_ipp2p.o
|
||||
obj-${build_ipv4options} += xt_ipv4options.o
|
||||
obj-${build_length2} += xt_length2.o
|
||||
obj-${build_lscan} += xt_lscan.o
|
||||
obj-${build_pknock} += pknock/
|
||||
obj-${build_psd} += xt_psd.o
|
||||
obj-${build_quota2} += xt_quota2.o
|
||||
|
||||
-include ${M}/*.Kbuild
|
||||
-include ${M}/Kbuild.*
|
||||
|
@@ -1,36 +1,29 @@
|
||||
# -*- Makefile -*-
|
||||
# AUTOMAKE
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
abssrcdir = $(shell readlink -f ${srcdir})
|
||||
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${abs_top_srcdir}/extensions
|
||||
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
|
||||
|
||||
regular_CFLAGS := @regular_CFLAGS@
|
||||
xtables_CFLAGS := @xtables_CFLAGS@
|
||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
||||
AM_CFLAGS = ${regular_CFLAGS} -I ${top_srcdir}/include \
|
||||
${xtables_CFLAGS} ${kinclude_CFLAGS} \
|
||||
-D_INIT=$*_init
|
||||
AM_LDFLAGS = -module -avoid-version
|
||||
xtlib_LTLIBRARIES = \
|
||||
libxt_LOGMARK.la \
|
||||
libxt_TARPIT.la \
|
||||
libxt_TEE.la
|
||||
|
||||
#
|
||||
# Call out to kbuild
|
||||
#
|
||||
# Not having Kbuild in Makefile.extra because it will already recurse
|
||||
.PHONY: modules modules_install clean_modules
|
||||
|
||||
_kcall = -C ${kbuilddir} M=${abs_srcdir}
|
||||
|
||||
modules:
|
||||
@echo -n "Xtables-addons ${PACKAGE_VERSION} - Linux "
|
||||
@if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} --no-print-directory -s kernelrelease; fi;
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
|
||||
|
||||
modules_install:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} INSTALL_MOD_PATH=${DESTDIR} ext-mod-dir='$${INSTALL_MOD_DIR}' modules_install; fi;
|
||||
|
||||
clean_modules:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} clean; fi;
|
||||
|
||||
all-local: modules
|
||||
|
||||
install-exec-local: modules_install
|
||||
|
||||
clean-local: clean_modules
|
||||
|
||||
modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} modules;
|
||||
|
||||
modules_install:
|
||||
make -C ${kbuilddir} M=${abssrcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install;
|
||||
|
||||
clean_modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} clean;
|
||||
include ../Makefile.extra
|
||||
|
26
extensions/Mbuild
Normal file
26
extensions/Mbuild
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_ACCOUNT} += ACCOUNT/
|
||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||
obj-${build_DNETMAP} += libxt_DNETMAP.so
|
||||
obj-${build_ECHO} += libxt_ECHO.so
|
||||
obj-${build_IPMARK} += libxt_IPMARK.so
|
||||
obj-${build_LOGMARK} += libxt_LOGMARK.so
|
||||
obj-${build_RAWNAT} += libxt_RAWDNAT.so libxt_RAWSNAT.so
|
||||
obj-${build_STEAL} += libxt_STEAL.so
|
||||
obj-${build_SYSRQ} += libxt_SYSRQ.so
|
||||
obj-${build_TARPIT} += libxt_TARPIT.so
|
||||
obj-${build_condition} += libxt_condition.so
|
||||
obj-${build_fuzzy} += libxt_fuzzy.so
|
||||
obj-${build_geoip} += libxt_geoip.so
|
||||
obj-${build_iface} += libxt_iface.so
|
||||
obj-${build_ipp2p} += libxt_ipp2p.so
|
||||
obj-${build_ipv4options} += libxt_ipv4options.so
|
||||
obj-${build_length2} += libxt_length2.so
|
||||
obj-${build_lscan} += libxt_lscan.so
|
||||
obj-${build_pknock} += pknock/
|
||||
obj-${build_psd} += libxt_psd.so
|
||||
obj-${build_quota2} += libxt_quota2.so
|
||||
obj-${build_gradm} += libxt_gradm.so
|
6
extensions/compat_rawpost.h
Normal file
6
extensions/compat_rawpost.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef XTA_COMPAT_RAWPOST_H
|
||||
#define XTA_COMPAT_RAWPOST_H 1
|
||||
|
||||
typedef struct sk_buff sk_buff_t;
|
||||
|
||||
#endif /* XTA_COMPAT_RAWPOST_H */
|
16
extensions/compat_skbuff.h
Normal file
16
extensions/compat_skbuff.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef COMPAT_SKBUFF_H
|
||||
#define COMPAT_SKBUFF_H 1
|
||||
|
||||
struct tcphdr;
|
||||
struct udphdr;
|
||||
|
||||
#define skb_ifindex(skb) (skb)->skb_iif
|
||||
#define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
||||
|
||||
#ifdef CONFIG_NETWORK_SECMARK
|
||||
# define skb_secmark(skb) ((skb)->secmark)
|
||||
#else
|
||||
# define skb_secmark(skb) 0
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_SKBUFF_H */
|
12
extensions/compat_user.h
Normal file
12
extensions/compat_user.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Userspace-level compat hacks
|
||||
*/
|
||||
#ifndef _XTABLES_COMPAT_USER_H
|
||||
#define _XTABLES_COMPAT_USER_H 1
|
||||
|
||||
/* linux-glibc-devel 2.6.34 header screwup */
|
||||
#ifndef ALIGN
|
||||
# define ALIGN(s, n) (((s) + ((n) - 1)) & ~((n) - 1))
|
||||
#endif
|
||||
|
||||
#endif /* _XTABLES_COMPAT_USER_H */
|
@@ -1,164 +1,39 @@
|
||||
/*
|
||||
* API compat layer
|
||||
* written by Jan Engelhardt, 2008 - 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License, either
|
||||
* version 2 of the License, or any later version.
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/route.h>
|
||||
#include <linux/export.h>
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
|
||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_match_run(const struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const struct xt_match *cm, const void *matchinfo, int offset,
|
||||
unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
bool lo_drop, lo_ret;
|
||||
|
||||
if (nm == NULL || nm->match == NULL)
|
||||
return false;
|
||||
lo_ret = nm->match(skb, in, out, nm, matchinfo,
|
||||
offset, protoff, &lo_drop);
|
||||
*hotdrop = lo_drop;
|
||||
return lo_ret;
|
||||
}
|
||||
|
||||
static int xtnu_match_check(const char *table, const void *entry,
|
||||
const struct xt_match *cm, void *matchinfo, unsigned int hook_mask)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
|
||||
if (nm == NULL)
|
||||
return false;
|
||||
if (nm->checkentry == NULL)
|
||||
return true;
|
||||
return nm->checkentry(table, entry, nm, matchinfo, hook_mask);
|
||||
}
|
||||
|
||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
|
||||
if (nm != NULL && nm->destroy != NULL)
|
||||
nm->destroy(nm, matchinfo);
|
||||
}
|
||||
|
||||
int xtnu_register_match(struct xtnu_match *nt)
|
||||
{
|
||||
struct xt_match *ct;
|
||||
char *tmp;
|
||||
int ret;
|
||||
|
||||
ct = kzalloc(sizeof(struct xt_match), GFP_KERNEL);
|
||||
if (ct == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
tmp = (char *)ct->name;
|
||||
memcpy(tmp, nt->name, sizeof(nt->name));
|
||||
tmp = (char *)(ct->name + sizeof(ct->name) - sizeof(void *));
|
||||
*(tmp-1) = '\0';
|
||||
memcpy(tmp, &nt, sizeof(void *));
|
||||
|
||||
ct->revision = nt->revision;
|
||||
ct->family = nt->family;
|
||||
ct->table = (char *)nt->table;
|
||||
ct->hooks = nt->hooks;
|
||||
ct->proto = nt->proto;
|
||||
ct->match = xtnu_match_run;
|
||||
ct->checkentry = xtnu_match_check;
|
||||
ct->destroy = xtnu_match_destroy;
|
||||
ct->matchsize = nt->matchsize;
|
||||
ct->me = nt->me;
|
||||
|
||||
nt->__compat_match = ct;
|
||||
ret = xt_register_match(ct);
|
||||
if (ret != 0)
|
||||
kfree(ct);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_register_match);
|
||||
|
||||
int xtnu_register_matches(struct xtnu_match *nt, unsigned int num)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < num; ++i) {
|
||||
ret = xtnu_register_match(&nt[i]);
|
||||
if (ret < 0) {
|
||||
if (i > 0)
|
||||
xtnu_unregister_matches(nt, i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_register_matches);
|
||||
|
||||
void xtnu_unregister_match(struct xtnu_match *nt)
|
||||
{
|
||||
xt_unregister_match(nt->__compat_match);
|
||||
kfree(nt->__compat_match);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_match);
|
||||
|
||||
void xtnu_unregister_matches(struct xtnu_match *nt, unsigned int num)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
xtnu_unregister_match(&nt[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_matches);
|
||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||
# define WITH_IPV6 1
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
static unsigned int
|
||||
xtnu_target_run(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
/* this is valid, just like if there was no function */
|
||||
return true;
|
||||
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
struct xtnu_target *nt = xtcompat_nutarget(par->target);
|
||||
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 23)
|
||||
static bool xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
/* this is valid, just like if there was no function */
|
||||
return true;
|
||||
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
|
||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt != NULL && nt->target != NULL)
|
||||
return nt->target(*pskb, in, out, hooknum, nt, targinfo);
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt != NULL && nt->destroy != NULL)
|
||||
nt->destroy(nt, targinfo);
|
||||
return nt->target(&skb, par);
|
||||
}
|
||||
|
||||
int xtnu_register_target(struct xtnu_target *nt)
|
||||
@@ -183,8 +58,8 @@ int xtnu_register_target(struct xtnu_target *nt)
|
||||
ct->hooks = nt->hooks;
|
||||
ct->proto = nt->proto;
|
||||
ct->target = xtnu_target_run;
|
||||
ct->checkentry = xtnu_target_check;
|
||||
ct->destroy = xtnu_target_destroy;
|
||||
ct->checkentry = nt->checkentry;
|
||||
ct->destroy = nt->destroy;
|
||||
ct->targetsize = nt->targetsize;
|
||||
ct->me = nt->me;
|
||||
|
||||
@@ -228,14 +103,55 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
|
||||
xtnu_unregister_target(&nt[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
int xtnu_ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type)
|
||||
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
||||
uint8_t revision)
|
||||
{
|
||||
return ip_route_me_harder(&skb, addr_type);
|
||||
static const char *const xt_prefix[] = {
|
||||
[AF_UNSPEC] = "x",
|
||||
[AF_INET] = "ip",
|
||||
[AF_INET6] = "ip6",
|
||||
#ifdef AF_ARP
|
||||
[AF_ARP] = "arp",
|
||||
#elif defined(NF_ARP) && NF_ARP != AF_UNSPEC
|
||||
[NF_ARP] = "arp",
|
||||
#endif
|
||||
};
|
||||
struct xt_match *match;
|
||||
|
||||
match = try_then_request_module(xt_find_match(af, name, revision),
|
||||
"%st_%s", xt_prefix[af], name);
|
||||
if (IS_ERR(match) || match == NULL)
|
||||
return NULL;
|
||||
|
||||
return match;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_request_find_match);
|
||||
|
||||
int xtnu_ip_route_me_harder(struct sk_buff **pskb, unsigned int addr_type)
|
||||
{
|
||||
return ip_route_me_harder(*pskb, addr_type);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
|
||||
#endif
|
||||
|
||||
int xtnu_skb_make_writable(struct sk_buff **pskb, unsigned int len)
|
||||
{
|
||||
return skb_make_writable(*pskb, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
|
||||
|
||||
void *HX_memmem(const void *space, size_t spacesize,
|
||||
const void *point, size_t pointsize)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (pointsize > spacesize)
|
||||
return NULL;
|
||||
for (i = 0; i <= spacesize - pointsize; ++i)
|
||||
if (memcmp(space + i, point, pointsize) == 0)
|
||||
return (void *)space + i;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(HX_memmem);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -1,37 +1,60 @@
|
||||
#ifndef _XTABLES_COMPAT_H
|
||||
#define _XTABLES_COMPAT_H 1
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
|
||||
# define NF_INET_PRE_ROUTING NF_IP_PRE_ROUTING
|
||||
# define NF_INET_LOCAL_IN NF_IP_LOCAL_IN
|
||||
# define NF_INET_FORWARD NF_IP_FORWARD
|
||||
# define NF_INET_LOCAL_OUT NF_IP_LOCAL_OUT
|
||||
# define NF_INET_POST_ROUTING NF_IP_POST_ROUTING
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
# include "compat_nfinetaddr.h"
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
# define xt_match xtnu_match
|
||||
# define xt_register_match xtnu_register_match
|
||||
# define xt_unregister_match xtnu_unregister_match
|
||||
# define xt_register_matches xtnu_register_matches
|
||||
# define xt_unregister_matches xtnu_unregister_matches
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
# define xt_target xtnu_target
|
||||
# define ip_route_me_harder xtnu_ip_route_me_harder
|
||||
# define xt_register_target xtnu_register_target
|
||||
# define xt_unregister_target xtnu_unregister_target
|
||||
# define xt_register_targets xtnu_register_targets
|
||||
# define xt_unregister_targets xtnu_unregister_targets
|
||||
#endif
|
||||
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#define DEBUGP Use__pr_debug__instead
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
|
||||
# warning Kernels below 3.7 not supported.
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
# if !defined(CONFIG_NF_CONNTRACK_MARK)
|
||||
# warning You have CONFIG_NF_CONNTRACK enabled, but CONFIG_NF_CONNTRACK_MARK is not (please enable).
|
||||
# endif
|
||||
# include <net/netfilter/nf_conntrack.h>
|
||||
#else
|
||||
# warning You need CONFIG_NF_CONNTRACK.
|
||||
#endif
|
||||
|
||||
#define ipt_unregister_table(tbl) ipt_unregister_table(&init_net, (tbl))
|
||||
#define ip6t_unregister_table(tbl) ip6t_unregister_table(&init_net, (tbl))
|
||||
|
||||
#define rt_dst(rt) (&(rt)->dst)
|
||||
|
||||
#if !defined(NIP6) && !defined(NIP6_FMT)
|
||||
# define NIP6(addr) \
|
||||
ntohs((addr).s6_addr16[0]), \
|
||||
ntohs((addr).s6_addr16[1]), \
|
||||
ntohs((addr).s6_addr16[2]), \
|
||||
ntohs((addr).s6_addr16[3]), \
|
||||
ntohs((addr).s6_addr16[4]), \
|
||||
ntohs((addr).s6_addr16[5]), \
|
||||
ntohs((addr).s6_addr16[6]), \
|
||||
ntohs((addr).s6_addr16[7])
|
||||
# define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
|
||||
#endif
|
||||
#if !defined(NIPQUAD) && !defined(NIPQUAD_FMT)
|
||||
# define NIPQUAD(addr) \
|
||||
((const unsigned char *)&addr)[0], \
|
||||
((const unsigned char *)&addr)[1], \
|
||||
((const unsigned char *)&addr)[2], \
|
||||
((const unsigned char *)&addr)[3]
|
||||
# define NIPQUAD_FMT "%u.%u.%u.%u"
|
||||
#endif
|
||||
|
||||
#define ip_route_me_harder xtnu_ip_route_me_harder
|
||||
#define skb_make_writable xtnu_skb_make_writable
|
||||
#define xt_target xtnu_target
|
||||
#define xt_register_target xtnu_register_target
|
||||
#define xt_unregister_target xtnu_unregister_target
|
||||
#define xt_register_targets xtnu_register_targets
|
||||
#define xt_unregister_targets xtnu_unregister_targets
|
||||
|
||||
#define xt_request_find_match xtnu_request_find_match
|
||||
|
||||
#endif /* _XTABLES_COMPAT_H */
|
||||
|
@@ -5,42 +5,41 @@
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct flowi;
|
||||
struct module;
|
||||
struct net_device;
|
||||
struct rtable;
|
||||
struct sk_buff;
|
||||
|
||||
struct xtnu_match {
|
||||
struct list_head list;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
|
||||
bool (*match)(const struct sk_buff *, const struct net_device *,
|
||||
const struct net_device *, const struct xtnu_match *,
|
||||
const void *, int, unsigned int, bool *);
|
||||
bool (*checkentry)(const char *, const void *,
|
||||
const struct xtnu_match *, void *, unsigned int);
|
||||
void (*destroy)(const struct xtnu_match *, void *);
|
||||
/*
|
||||
* Making it smaller by sizeof(void *) on purpose to catch
|
||||
* lossy translation, if any.
|
||||
*/
|
||||
char name[sizeof(((struct xt_match *)NULL)->name) - 1 - sizeof(void *)];
|
||||
uint8_t revision;
|
||||
bool (*match)(const struct sk_buff *, struct xt_action_param *);
|
||||
int (*checkentry)(const struct xt_mtchk_param *);
|
||||
void (*destroy)(const struct xt_mtdtor_param *);
|
||||
struct module *me;
|
||||
const char *table;
|
||||
unsigned int matchsize, hooks;
|
||||
unsigned short proto, family;
|
||||
uint8_t revision;
|
||||
|
||||
void *__compat_match;
|
||||
};
|
||||
|
||||
struct xtnu_target {
|
||||
struct list_head list;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
|
||||
unsigned int (*target)(struct sk_buff *, const struct net_device *,
|
||||
const struct net_device *, unsigned int,
|
||||
const struct xtnu_target *, const void *);
|
||||
bool (*checkentry)(const char *, const void *,
|
||||
const struct xtnu_target *, void *, unsigned int);
|
||||
void (*destroy)(const struct xtnu_target *, void *);
|
||||
char name[sizeof(((struct xt_target *)NULL)->name) - 1 - sizeof(void *)];
|
||||
uint8_t revision;
|
||||
unsigned int (*target)(struct sk_buff **,
|
||||
const struct xt_action_param *);
|
||||
int (*checkentry)(const struct xt_tgchk_param *);
|
||||
void (*destroy)(const struct xt_tgdtor_param *);
|
||||
struct module *me;
|
||||
const char *table;
|
||||
unsigned int targetsize, hooks;
|
||||
unsigned short proto, family;
|
||||
uint8_t revision;
|
||||
|
||||
void *__compat_target;
|
||||
};
|
||||
@@ -59,8 +58,11 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
||||
return q;
|
||||
}
|
||||
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff *, unsigned int);
|
||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
||||
extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int);
|
||||
extern int xtnu_register_match(struct xtnu_match *);
|
||||
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
|
||||
extern void xtnu_unregister_match(struct xtnu_match *);
|
||||
extern int xtnu_register_matches(struct xtnu_match *, unsigned int);
|
||||
extern void xtnu_unregister_matches(struct xtnu_match *, unsigned int);
|
||||
@@ -68,5 +70,15 @@ extern int xtnu_register_target(struct xtnu_target *);
|
||||
extern void xtnu_unregister_target(struct xtnu_target *);
|
||||
extern int xtnu_register_targets(struct xtnu_target *, unsigned int);
|
||||
extern void xtnu_unregister_targets(struct xtnu_target *, unsigned int);
|
||||
extern struct xt_match *xtnu_request_find_match(unsigned int,
|
||||
const char *, uint8_t);
|
||||
extern void xtnu_proto_csum_replace4(__u16 __bitwise *, struct sk_buff *,
|
||||
__be32, __be32, bool);
|
||||
extern int xtnu_ipv6_skip_exthdr(const struct sk_buff *, int,
|
||||
uint8_t *, __be16 *);
|
||||
extern int xtnu_ipv6_find_hdr(const struct sk_buff *, unsigned int *,
|
||||
int, unsigned short *, int *);
|
||||
|
||||
extern void *HX_memmem(const void *, size_t, const void *, size_t);
|
||||
|
||||
#endif /* _COMPAT_XTNU_H */
|
||||
|
93
extensions/ip6table_rawpost.c
Normal file
93
extensions/ip6table_rawpost.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* rawpost table for ip6_tables
|
||||
* written by Jan Engelhardt, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[1];
|
||||
struct ip6t_error term;
|
||||
} rawpost6_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ip6t_standard) +
|
||||
sizeof(struct ip6t_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost6_ptable;
|
||||
|
||||
static struct xt_table rawpost6_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV6,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost6_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ip6t_do_table(skb, hook, in, out, rawpost6_ptable);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost6_hook_ops __read_mostly = {
|
||||
.hook = rawpost6_hook_fn,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost6_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable,
|
||||
&rawpost6_initial.repl);
|
||||
if (IS_ERR(rawpost6_ptable))
|
||||
return PTR_ERR(rawpost6_ptable);
|
||||
|
||||
ret = nf_register_hook(&rawpost6_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost6_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost6_hook_ops);
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost6_table_init);
|
||||
module_exit(rawpost6_table_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
95
extensions/iptable_rawpost.c
Normal file
95
extensions/iptable_rawpost.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* rawpost table for ip_tables
|
||||
* written by Jan Engelhardt, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/version.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ipt_replace repl;
|
||||
struct ipt_standard entries[1];
|
||||
struct ipt_error term;
|
||||
} rawpost4_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ipt_standard) +
|
||||
sizeof(struct ipt_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IPT_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost4_ptable;
|
||||
|
||||
static struct xt_table rawpost4_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV4,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost4_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out, rawpost4_ptable);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost4_hook_ops __read_mostly = {
|
||||
.hook = rawpost4_hook_fn,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost4_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable,
|
||||
&rawpost4_initial.repl);
|
||||
if (IS_ERR(rawpost4_ptable))
|
||||
return PTR_ERR(rawpost4_ptable);
|
||||
|
||||
ret = nf_register_hook(&rawpost4_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost4_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost4_hook_ops);
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost4_table_init);
|
||||
module_exit(rawpost4_table_exit);
|
||||
MODULE_DESCRIPTION("Xtables: rawpost table for use with RAWNAT");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
113
extensions/libxt_CHAOS.c
Normal file
113
extensions/libxt_CHAOS.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* "CHAOS" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_CHAOS.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_DELUDE = 1 << 0,
|
||||
F_TARPIT = 1 << 1,
|
||||
};
|
||||
|
||||
static const struct option chaos_tg_opts[] = {
|
||||
{.name = "delude", .has_arg = false, .val = 'd'},
|
||||
{.name = "tarpit", .has_arg = false, .val = 't'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void chaos_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"CHAOS target options:\n"
|
||||
" --delude Enable DELUDE processing for TCP\n"
|
||||
" --tarpit Enable TARPIT processing for TCP\n");
|
||||
}
|
||||
|
||||
static int chaos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_chaos_tginfo *info = (void *)((*target)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
info->variant = XTCHAOS_DELUDE;
|
||||
*flags |= F_DELUDE;
|
||||
return true;
|
||||
case 't':
|
||||
info->variant = XTCHAOS_TARPIT;
|
||||
*flags |= F_TARPIT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void chaos_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == (F_DELUDE | F_TARPIT))
|
||||
/* If flags == 0x03, both were specified, which should not be. */
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"CHAOS: only one of --tarpit or --delude "
|
||||
"may be specified");
|
||||
}
|
||||
|
||||
static void chaos_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf(" DELUDE ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf(" TARPIT ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf(" --delude ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf(" --tarpit ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct xtables_target chaos_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "CHAOS",
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.help = chaos_tg_help,
|
||||
.parse = chaos_tg_parse,
|
||||
.final_check = chaos_tg_check,
|
||||
.print = chaos_tg_print,
|
||||
.save = chaos_tg_save,
|
||||
.extra_opts = chaos_tg_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void chaos_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&chaos_tg_reg);
|
||||
}
|
21
extensions/libxt_CHAOS.man
Normal file
21
extensions/libxt_CHAOS.man
Normal file
@@ -0,0 +1,21 @@
|
||||
Causes confusion on the other end by doing odd things with incoming packets.
|
||||
CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
||||
.TP
|
||||
\fB\-\-delude\fP
|
||||
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
||||
connection reset, fooling some network scanners to return non-deterministic
|
||||
(randomly open/closed) results, and in case it is deemed open, it is actually
|
||||
closed/filtered.
|
||||
.TP
|
||||
\fB\-\-tarpit\fP
|
||||
Use the REJECT and TARPIT target as a base to hold the connection until it
|
||||
times out. This consumes conntrack entries when connection tracking is loaded
|
||||
(which usually is on most machines), and routers inbetween you and the Internet
|
||||
may fail to do their connection tracking if they have to handle more
|
||||
connections than they can.
|
||||
.PP
|
||||
The randomness factor of not replying vs. replying can be set during load-time
|
||||
of the xt_CHAOS module or during runtime in /sys/modules/xt_CHAOS/parameters.
|
||||
.PP
|
||||
See http://inai.de/projects/chaostables/ for more information
|
||||
about CHAOS, DELUDE and lscan.
|
46
extensions/libxt_DELUDE.c
Normal file
46
extensions/libxt_DELUDE.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* "DELUDE" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "compat_user.h"
|
||||
|
||||
static void delude_tg_help(void)
|
||||
{
|
||||
printf("DELUDE takes no options\n");
|
||||
}
|
||||
|
||||
static int delude_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void delude_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target delude_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.help = delude_tg_help,
|
||||
.parse = delude_tg_parse,
|
||||
.final_check = delude_tg_check,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void delude_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&delude_tg_reg);
|
||||
}
|
4
extensions/libxt_DELUDE.man
Normal file
4
extensions/libxt_DELUDE.man
Normal file
@@ -0,0 +1,4 @@
|
||||
The DELUDE target will reply to a SYN packet with SYN-ACK, and to all other
|
||||
packets with an RST. This will terminate the connection much like REJECT, but
|
||||
network scanners doing TCP half-open discovery can be spoofed to make them
|
||||
belive the port is open rather than closed/filtered.
|
102
extensions/libxt_DHCPMAC.c
Normal file
102
extensions/libxt_DHCPMAC.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* "DHCPMAC" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_DHCPMAC.h"
|
||||
#include "mac.c"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_MAC = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option dhcpmac_tg_opts[] = {
|
||||
{.name = "set-mac", .has_arg = true, .val = 'M'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void dhcpmac_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"DHCPMAC target options:\n"
|
||||
" --set-mac lladdr[/mask] Set MAC address in DHCP Client Host field\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int dhcpmac_tg_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct dhcpmac_info *info = (void *)(*target)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'M':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "DHCPMAC", "--set-mac", *flags & F_MAC);
|
||||
xtables_param_act(XTF_NO_INVERT, "DHCPMAC", "--set-mac", invert);
|
||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||
xtables_param_act(XTF_BAD_VALUE, "DHCPMAC", "--set-mac", optarg);
|
||||
*flags |= F_MAC;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dhcpmac_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, "DHCPMAC target: "
|
||||
"--set-mac parameter required");
|
||||
}
|
||||
|
||||
static void dhcpmac_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct dhcpmac_info *info = (void *)target->data;
|
||||
|
||||
printf(" DHCPMAC %s" DH_MAC_FMT "/%u ",
|
||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static void dhcpmac_tg_save(const void *ip,
|
||||
const struct xt_entry_target *target)
|
||||
{
|
||||
const struct dhcpmac_info *info = (const void *)target->data;
|
||||
|
||||
if (info->invert)
|
||||
printf(" !");
|
||||
printf(" --set-mac " DH_MAC_FMT "/%u ",
|
||||
DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target dhcpmac_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DHCPMAC",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.help = dhcpmac_tg_help,
|
||||
.parse = dhcpmac_tg_parse,
|
||||
.final_check = dhcpmac_tg_check,
|
||||
.print = dhcpmac_tg_print,
|
||||
.save = dhcpmac_tg_save,
|
||||
.extra_opts = dhcpmac_tg_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void dhcpmac_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&dhcpmac_tg_reg);
|
||||
}
|
25
extensions/libxt_DHCPMAC.man
Normal file
25
extensions/libxt_DHCPMAC.man
Normal file
@@ -0,0 +1,25 @@
|
||||
In conjunction with ebtables, DHCPMAC can be used to completely change all MAC
|
||||
addresses from and to a VMware-based virtual machine. This is needed because
|
||||
VMware does not allow to set a non-VMware MAC address before an operating
|
||||
system is booted (and the MAC be changed with `ip link set eth0 address
|
||||
aa:bb..`).
|
||||
.TP
|
||||
\fB\-\-set\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Replace the client host MAC address field in the DHCP message with the given
|
||||
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
||||
prefix length of bits to change.
|
||||
.PP
|
||||
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
||||
(00:50:56) addresses with something else:
|
||||
.PP
|
||||
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 67 \-m physdev
|
||||
\-\-physdev\-in vmnet1 \-m dhcpmac \-\-mac 00:50:56:00:00:00/24 \-j DHCPMAC
|
||||
\-\-set\-mac ab:cd:ef:00:00:00/24
|
||||
.PP
|
||||
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 68 \-m physdev
|
||||
\-\-physdev\-out vmnet1 \-m dhcpmac \-\-mac ab:cd:ef:00:00:00/24 \-j DHCPMAC
|
||||
\-\-set\-mac 00:50:56:00:00:00/24
|
||||
.PP
|
||||
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
||||
also need to add appropriate ebtables rules to change the MAC address of the
|
||||
Ethernet headers.)
|
265
extensions/libxt_DNETMAP.c
Normal file
265
extensions/libxt_DNETMAP.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/* Shared library add-on to iptables to add DNETMAP support.
|
||||
* (C) 2010 Marek Kierdelewicz <marek@koba.pl>
|
||||
*
|
||||
* uses some code from libipt_NETMAP by:
|
||||
* Svenning Soerensen <svenning@post5.tele.dk>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/nf_nat.h>
|
||||
#include "xt_DNETMAP.h"
|
||||
|
||||
#define MODULENAME "DNETMAP"
|
||||
|
||||
static const struct option DNETMAP_opts[] = {
|
||||
{"prefix", 1, NULL, 'p'},
|
||||
{"reuse", 0, NULL, 'r'},
|
||||
{"ttl", 1, NULL, 't'},
|
||||
{"static", 0, NULL, 's'},
|
||||
{"persistent", 0, NULL, 'e'},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static void DNETMAP_help(void)
|
||||
{
|
||||
printf(MODULENAME " target options:\n"
|
||||
" --%s address[/mask]\n"
|
||||
" Network subnet to map to. If not specified, all existing prefixes are used.\n"
|
||||
" --%s\n"
|
||||
" Reuse entry for given prenat-ip from any prefix despite bindings ttl < 0.\n"
|
||||
" --%s seconds\n"
|
||||
" Regenerate bindings ttl value to seconds. If negative value is specified,\n"
|
||||
" bindings ttl is kept unchanged. If not specified then default ttl value (600s)\n"
|
||||
" is used\n"
|
||||
" --%s\n"
|
||||
" Match only static entries for this rule. Dynamic entries won't be created.\n"
|
||||
" --%s\n"
|
||||
" Set prefix persistent. It won't be removed after deleting last iptables rule.\n\n",
|
||||
DNETMAP_opts[0].name, DNETMAP_opts[1].name,
|
||||
DNETMAP_opts[2].name, DNETMAP_opts[3].name,
|
||||
DNETMAP_opts[4].name);
|
||||
}
|
||||
|
||||
static u_int32_t bits2netmask(int bits)
|
||||
{
|
||||
u_int32_t netmask, bm;
|
||||
|
||||
if (bits >= 32 || bits < 0)
|
||||
return ~0;
|
||||
for (netmask = 0, bm = 0x80000000; bits; bits--, bm >>= 1)
|
||||
netmask |= bm;
|
||||
return htonl(netmask);
|
||||
}
|
||||
|
||||
static int netmask2bits(u_int32_t netmask)
|
||||
{
|
||||
u_int32_t bm;
|
||||
int bits;
|
||||
|
||||
netmask = ntohl(netmask);
|
||||
for (bits = 0, bm = 0x80000000; netmask & bm; netmask <<= 1)
|
||||
bits++;
|
||||
if (netmask)
|
||||
return -1; /* holes in netmask */
|
||||
return bits;
|
||||
}
|
||||
|
||||
/* Parses network address */
|
||||
static void parse_prefix(char *arg, struct nf_nat_range *range)
|
||||
{
|
||||
char *slash;
|
||||
const struct in_addr *ip;
|
||||
u_int32_t netmask;
|
||||
unsigned int bits;
|
||||
|
||||
range->flags |= NF_NAT_RANGE_MAP_IPS;
|
||||
slash = strchr(arg, '/');
|
||||
if (slash)
|
||||
*slash = '\0';
|
||||
|
||||
ip = xtables_numeric_to_ipaddr(arg);
|
||||
if (ip == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||
arg);
|
||||
range->min_addr.in = *ip;
|
||||
if (slash) {
|
||||
if (strchr(slash + 1, '.')) {
|
||||
ip = xtables_numeric_to_ipmask(slash + 1);
|
||||
if (ip == NULL)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Bad netmask \"%s\"\n",
|
||||
slash + 1);
|
||||
netmask = ip->s_addr;
|
||||
} else {
|
||||
if (!xtables_strtoui(slash + 1, NULL, &bits, 0, 32))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Bad netmask \"%s\"\n",
|
||||
slash + 1);
|
||||
netmask = bits2netmask(bits);
|
||||
}
|
||||
/* Don't allow /0 (/1 is probably insane, too) */
|
||||
if (netmask == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, "Netmask needed\n");
|
||||
/* Mask should be <= then /16 */
|
||||
if (bits < 16)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Max netmask size is /16\n");
|
||||
} else
|
||||
netmask = ~0;
|
||||
|
||||
if (range->min_addr.ip & ~netmask) {
|
||||
if (slash)
|
||||
*slash = '/';
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad network address \"%s\"\n",
|
||||
arg);
|
||||
}
|
||||
range->max_addr.ip = range->min_addr.ip | ~netmask;
|
||||
}
|
||||
|
||||
static int DNETMAP_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_DNETMAP_tginfo *tginfo = (void *)(*target)->data;
|
||||
struct nf_nat_range *mr = &tginfo->prefix;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 'p':
|
||||
xtables_param_act(XTF_ONLY_ONCE, MODULENAME, "--prefix",
|
||||
*flags & XT_DNETMAP_PREFIX);
|
||||
xtables_param_act(XTF_NO_INVERT, MODULENAME, "--prefix",
|
||||
invert);
|
||||
|
||||
/* TO-DO use xtables_ipparse_any instead? */
|
||||
parse_prefix(optarg, mr);
|
||||
*flags |= XT_DNETMAP_PREFIX;
|
||||
tginfo->flags |= XT_DNETMAP_PREFIX;
|
||||
return 1;
|
||||
case 'r':
|
||||
xtables_param_act(XTF_ONLY_ONCE, MODULENAME, "--reuse",
|
||||
*flags & XT_DNETMAP_REUSE);
|
||||
xtables_param_act(XTF_NO_INVERT, MODULENAME, "--reuse", invert);
|
||||
*flags |= XT_DNETMAP_REUSE;
|
||||
tginfo->flags |= XT_DNETMAP_REUSE;
|
||||
return 1;
|
||||
case 's':
|
||||
xtables_param_act(XTF_ONLY_ONCE, MODULENAME, "--static",
|
||||
*flags & XT_DNETMAP_STATIC);
|
||||
xtables_param_act(XTF_NO_INVERT, MODULENAME, "--static", invert);
|
||||
*flags |= XT_DNETMAP_STATIC;
|
||||
tginfo->flags |= XT_DNETMAP_STATIC;
|
||||
return 1;
|
||||
case 'e':
|
||||
xtables_param_act(XTF_ONLY_ONCE, MODULENAME, "--persistent",
|
||||
*flags & XT_DNETMAP_PERSISTENT);
|
||||
xtables_param_act(XTF_NO_INVERT, MODULENAME, "--persistent", invert);
|
||||
*flags |= XT_DNETMAP_PERSISTENT;
|
||||
tginfo->flags |= XT_DNETMAP_PERSISTENT;
|
||||
return 1;
|
||||
case 't':
|
||||
xtables_param_act(XTF_ONLY_ONCE, MODULENAME, "--ttl",
|
||||
*flags & XT_DNETMAP_TTL);
|
||||
xtables_param_act(XTF_NO_INVERT, MODULENAME, "--ttl", invert);
|
||||
*flags |= XT_DNETMAP_TTL;
|
||||
tginfo->flags |= XT_DNETMAP_TTL;
|
||||
tginfo->ttl = strtol(optarg, &end, 10);
|
||||
if (*end != '\0')
|
||||
return 0;
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void DNETMAP_print_addr(const void *ip,
|
||||
const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
||||
const struct nf_nat_range *r = &tginfo->prefix;
|
||||
struct in_addr a;
|
||||
int bits;
|
||||
|
||||
a = r->min_addr.in;
|
||||
printf("%s", xtables_ipaddr_to_numeric(&a));
|
||||
a.s_addr = ~(r->min_addr.ip ^ r->max_addr.ip);
|
||||
bits = netmask2bits(a.s_addr);
|
||||
if (bits < 0)
|
||||
printf("/%s", xtables_ipaddr_to_numeric(&a));
|
||||
else
|
||||
printf("/%d", bits);
|
||||
}
|
||||
|
||||
static void DNETMAP_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
||||
const __u8 *flags = &tginfo->flags;
|
||||
|
||||
printf(" prefix ");
|
||||
if (*flags & XT_DNETMAP_PREFIX)
|
||||
DNETMAP_print_addr(ip, target, numeric);
|
||||
else
|
||||
printf("any");
|
||||
|
||||
if (*flags & XT_DNETMAP_REUSE)
|
||||
printf(" reuse");
|
||||
|
||||
if (*flags & XT_DNETMAP_STATIC)
|
||||
printf(" static");
|
||||
|
||||
if (*flags & XT_DNETMAP_PERSISTENT)
|
||||
printf(" persistent");
|
||||
|
||||
if (*flags & XT_DNETMAP_TTL)
|
||||
printf(" ttl %i", tginfo->ttl);
|
||||
else
|
||||
printf(" ttl default");
|
||||
}
|
||||
|
||||
static void DNETMAP_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
||||
const __u8 *flags = &tginfo->flags;
|
||||
|
||||
if (*flags & XT_DNETMAP_PREFIX) {
|
||||
printf(" --%s ", DNETMAP_opts[0].name);
|
||||
DNETMAP_print_addr(ip, target, 0);
|
||||
}
|
||||
|
||||
if (*flags & XT_DNETMAP_REUSE)
|
||||
printf(" --reuse ");
|
||||
|
||||
if (*flags & XT_DNETMAP_STATIC)
|
||||
printf(" --static ");
|
||||
|
||||
if (*flags & XT_DNETMAP_PERSISTENT)
|
||||
printf(" --persistent ");
|
||||
|
||||
/* ommited because default value can change as kernel mod param */
|
||||
if (*flags & XT_DNETMAP_TTL)
|
||||
printf(" --ttl %i ", tginfo->ttl);
|
||||
}
|
||||
|
||||
static struct xtables_target dnetmap_tg_reg = {
|
||||
.name = MODULENAME,
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
||||
.help = DNETMAP_help,
|
||||
.parse = DNETMAP_parse,
|
||||
.print = DNETMAP_print,
|
||||
.save = DNETMAP_save,
|
||||
.extra_opts = DNETMAP_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&dnetmap_tg_reg);
|
||||
}
|
172
extensions/libxt_DNETMAP.man
Normal file
172
extensions/libxt_DNETMAP.man
Normal file
@@ -0,0 +1,172 @@
|
||||
The \fBDNETMAP\fR target allows dynamic two-way 1:1 mapping of IPv4 subnets.
|
||||
Single rule can map private subnet to shorter public subnet creating and
|
||||
maintaining unambigeous private-public ip bindings. Second rule can be used to
|
||||
map new flows to private subnet according to maintained bindings. Target allows
|
||||
efficient public IPv4 space usage and unambigeous NAT at the same time.
|
||||
|
||||
Target can be used only in \fBnat\fR table in \fBPOSTROUTING\fR or \fBOUTPUT\fR
|
||||
chains for SNAT and in \fBPREROUTING\fR for DNAT. Only flows directed to bound
|
||||
IPs will be DNATed. Packet continues chain traversal if there is no free
|
||||
postnat-ip to be assigned to prenat-ip. Default binding \fBttl\fR is \fI10
|
||||
minutes\fR and can be changed using \fBdefault_ttl\fR module option. Default ip
|
||||
hash size is 256 and can be changed using \fBhash_size\fR module option.
|
||||
|
||||
.TP
|
||||
\fB\-\-prefix\fR \fIaddr\fR\fB/\fR\fImask\fR
|
||||
Network subnet to map to. If not specified, all existing prefixes are used.
|
||||
.TP
|
||||
\fB\-\-reuse\fR
|
||||
Reuse entry for given prenat-ip from any prefix despite bindings ttl < 0.
|
||||
.TP
|
||||
\fB\-\-persistent\fR
|
||||
Set prefix persistent. It won't be removed after deleting last iptables rule.
|
||||
Option is effective only in the first rule for a given prefix. If you
|
||||
need to change persistency for existing prefix, please use proc interface
|
||||
described below.
|
||||
.TP
|
||||
\fB\-\-static\fR
|
||||
Don't create dynamic mappings using this rule. Use static mappings only. Note
|
||||
that you need to create static mappings via proc interface for this rule with
|
||||
this option to have any effect.
|
||||
.TP
|
||||
\fB\-\-ttl\fR \fIseconds\fR
|
||||
Regenerate bindings ttl value to \fIseconds\fR. If negative value is specified,
|
||||
bindings ttl is kept unchanged. If not specified then default ttl value (600s)
|
||||
is used.
|
||||
.PP
|
||||
\fB* /proc interface\fR
|
||||
|
||||
Module creates following entries for each new specified subnet:
|
||||
.TP
|
||||
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR
|
||||
Contains binding table for subnet/mask. Each line contains \fBprenat-ip\fR,
|
||||
\fBpostnat-ip\fR,\fBttl\fR (seconds till entry times out), \fBlasthit\fR (last
|
||||
entry hit in seconds relative to system boot time). Please note that \fBttl\fR
|
||||
and \fBlasthit\fR entries contain \fBS\fR in case of static binding.
|
||||
.TP
|
||||
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR
|
||||
Contains statistics for given subnet/mask. Line contains contains four
|
||||
numerical values separated by spaces. First one is number of currently used
|
||||
dynamic addresses (bindings with negative ttl excluded), second one is number
|
||||
static assignments, third one is number of all usable addresses in subnet and
|
||||
the fourth one is mean \fBttl\fR value for all active entries. If prefix has
|
||||
persistent flag set it'll be noted as fifth entry.
|
||||
.PP
|
||||
Following write operations are supported via proc interface:
|
||||
.TP
|
||||
echo "+\fIprenatIP\fR:\fIpostnatIP\fR" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||
Adds static binding between prenatIP nad postnatIP. If postnatIP is already
|
||||
bound, previous binding will be timedout immediatelly. Static binding is never
|
||||
timedout.
|
||||
.TP
|
||||
echo "-\fIIP\fR" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||
Removes binding with \fIIP\fR as prenat or postnat address. If removed binding
|
||||
is currently static, it'll make entry available for dynamic allocation.
|
||||
.TP
|
||||
echo "+persistent" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||
Sets persistent flag for prefix. It's usefull if you don't want bindings to get
|
||||
flushed when firewall is restarted. You can check if prefix is persistent by
|
||||
printing \fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR
|
||||
contents.
|
||||
.TP
|
||||
echo "-persistent" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||
Unsets persistent flag for prefix. In this mode prefix will be deleted if the
|
||||
last iptables rule for that prefix is removed.
|
||||
.TP
|
||||
echo "flush" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||
Flushes all bindings for specific prefix. All static entries are also flushed
|
||||
and are available for dynamic bindings.
|
||||
.PP
|
||||
Note! Entries are removed if the last iptables rule for a specific prefix is
|
||||
deleted unless there's persistent flag set.
|
||||
.PP
|
||||
|
||||
\fB* Logging\fR
|
||||
|
||||
Module logs binding add/timeout events to klog. This behaviour can be disabled
|
||||
using \fBdisable_log\fR module parameter.
|
||||
|
||||
\fB* Examples\fR
|
||||
|
||||
\fB1.\fR Map subnet 192.168.0.0/24 to subnets 20.0.0.0/26. SNAT only:
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
||||
|
||||
Active hosts from 192.168.0.0/24 subnet are mapped to 20.0.0.0/26. If packet
|
||||
from not yet bound prenat-ip hits the rule and there are no free or timed-out
|
||||
(ttl<0) entries in prefix 20.0.0.0/28, then notice is logged to klog and chain
|
||||
traversal continues. If packet from already bound prenat-ip hits the rule,
|
||||
bindings ttl value is regenerated to default_ttl and SNAT is performed.
|
||||
|
||||
\fB2.\fR Use of \fB\-\-reuse\fR and \fB\-\-ttl\fR switches, multiple rule
|
||||
interaction:
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix
|
||||
20.0.0.0/26 --reuse --ttl 200
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 30.0.0.0/26
|
||||
|
||||
Active hosts from 192.168.0.0/24 subnet are mapped to 20.0.0.0/26 with ttl =
|
||||
200 seconds. If there are no free addresses in first prefix the next one
|
||||
(30.0.0.0/26) is used with default ttl. It's important to note that the first
|
||||
rule SNATs all flows whose source IP is already actively (ttl>0) bound to ANY
|
||||
prefix. Parameter \fB\-\-reuse\fR makes this functionality work even for
|
||||
inactive (ttl<0) entries.
|
||||
|
||||
If both subnets are exhaused, then chain traversal continues.
|
||||
|
||||
\fB3.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 bidirectional way:
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
||||
|
||||
iptables -t nat -A PREROUTING -j DNETMAP
|
||||
|
||||
If host 192.168.0.10 generates some traffic, it gets bound to first free IP in
|
||||
subnet - 20.0.0.0. Now any traffic directed to 20.0.0.0 gets DNATed to
|
||||
192.168.0.10 as long as there's an active (ttl>0) binding. There's no need to
|
||||
specify \fB\-\-prefix\fR parameter in PREROUTING rule, because this way it DNATs
|
||||
traffic to all active prefixes. You could specify prefix it you'd like to make
|
||||
DNAT work for specific prefix only.
|
||||
|
||||
\fB4.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 with static assignments only:
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
||||
--static
|
||||
|
||||
echo "+192.168.0.10:20.0.0.1" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||
.br
|
||||
echo "+192.168.0.11:20.0.0.2" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||
.br
|
||||
echo "+192.168.0.51:20.0.0.3" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||
|
||||
This configuration will allow only preconfigured static bindings to work due to
|
||||
\fBstatic\fR rule option. Without this flag dynamic bindings would be created
|
||||
using non-static entries.
|
||||
|
||||
\fB5.\fR Persistent prefix:
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
||||
--persistent
|
||||
.br
|
||||
\fBor\fR
|
||||
.br
|
||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
||||
.br
|
||||
echo "+persistent" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||
|
||||
Now we can check persistent flag of the prefix:
|
||||
.br
|
||||
cat /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||
.br
|
||||
0 0 64 0 \fBpersistent\fR
|
||||
|
||||
Flush iptables nat table and see that prefix is still in existence:
|
||||
.br
|
||||
iptables -F -t nat
|
||||
.br
|
||||
ls -l /proc/net/xt_DNETMAP
|
||||
.br
|
||||
-rw-r--r-- 1 root root 0 06-10 09:01 20.0.0.0_26
|
||||
.br
|
||||
-rw-r--r-- 1 root root 0 06-10 09:01 20.0.0.0_26_stat
|
||||
.
|
42
extensions/libxt_ECHO.c
Normal file
42
extensions/libxt_ECHO.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* "ECHO" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include "compat_user.h"
|
||||
|
||||
static void echo_tg_help(void)
|
||||
{
|
||||
printf("ECHO takes no options\n\n");
|
||||
}
|
||||
|
||||
static int echo_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void echo_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target echo_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ECHO",
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = echo_tg_help,
|
||||
.parse = echo_tg_parse,
|
||||
.final_check = echo_tg_check,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void echo_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&echo_tg_reg);
|
||||
}
|
4
extensions/libxt_ECHO.man
Normal file
4
extensions/libxt_ECHO.man
Normal file
@@ -0,0 +1,4 @@
|
||||
The \fBECHO\fP target will send back all packets it received. It serves as an
|
||||
examples for an Xtables target.
|
||||
.PP
|
||||
ECHO takes no options.
|
171
extensions/libxt_IPMARK.c
Normal file
171
extensions/libxt_IPMARK.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* "IPMARK" target extension for iptables
|
||||
* Copyright © Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>, 2003
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_IPMARK.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FL_ADDR_USED = 1 << 0,
|
||||
FL_AND_MASK_USED = 1 << 1,
|
||||
FL_OR_MASK_USED = 1 << 2,
|
||||
FL_SHIFT = 1 << 3,
|
||||
};
|
||||
|
||||
/* Function which prints out usage message. */
|
||||
static void ipmark_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"IPMARK target options:\n"
|
||||
" --addr {src|dst} use source or destination ip address\n"
|
||||
" --and-mask value logical AND ip address with this value becomes MARK\n"
|
||||
" --or-mask value logical OR ip address with this value becomes MARK\n"
|
||||
" --shift value shift address right by value before copying to mark\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static const struct option ipmark_tg_opts[] = {
|
||||
{.name = "addr", .has_arg = true, .val = '1'},
|
||||
{.name = "and-mask", .has_arg = true, .val = '2'},
|
||||
{.name = "or-mask", .has_arg = true, .val = '3'},
|
||||
{.name = "shift", .has_arg = true, .val = '4'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/* Initialize the target. */
|
||||
static void ipmark_tg_init(struct xt_entry_target *t)
|
||||
{
|
||||
struct xt_ipmark_tginfo *info = (void *)t->data;
|
||||
|
||||
info->andmask = ~0U;
|
||||
}
|
||||
|
||||
static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_ipmark_tginfo *info = (void *)(*target)->data;
|
||||
unsigned int n;
|
||||
|
||||
switch (c) {
|
||||
case '1':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "addr", *flags & FL_ADDR_USED);
|
||||
xtables_param_act(XTF_NO_INVERT, "IPMARK", "addr", invert);
|
||||
if (strcmp(optarg, "src") == 0)
|
||||
info->selector = XT_IPMARK_SRC;
|
||||
else if (strcmp(optarg, "dst") == 0)
|
||||
info->selector = XT_IPMARK_DST;
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
|
||||
*flags |= FL_ADDR_USED;
|
||||
return true;
|
||||
|
||||
case '2':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "and-mask", *flags & FL_AND_MASK_USED);
|
||||
xtables_param_act(XTF_NO_INVERT, "IPMARK", "and-mask", invert);
|
||||
if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "and-mask", optarg);
|
||||
info->andmask = n;
|
||||
*flags |= FL_AND_MASK_USED;
|
||||
return true;
|
||||
|
||||
case '3':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "or-mask", *flags & FL_OR_MASK_USED);
|
||||
xtables_param_act(XTF_NO_INVERT, "IPMARK", "or-mask", invert);
|
||||
if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "or-mask", optarg);
|
||||
info->ormask = n;
|
||||
*flags |= FL_OR_MASK_USED;
|
||||
return true;
|
||||
|
||||
case '4':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "--shift", *flags & FL_SHIFT);
|
||||
xtables_param_act(XTF_NO_INVERT, "IPMARK", "--shift", invert);
|
||||
/*
|
||||
* Anything >31 does not make sense for IPv4, but it still
|
||||
* does the right thing.
|
||||
*/
|
||||
if (!xtables_strtoui(optarg, NULL, &n, 0, 128))
|
||||
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg);
|
||||
info->shift = n;
|
||||
*flags |= FL_SHIFT;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ipmark_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FL_ADDR_USED))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"IPMARK target: Parameter --addr is required");
|
||||
}
|
||||
|
||||
static void
|
||||
ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_ipmark_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (info->selector == XT_IPMARK_SRC)
|
||||
printf(" IPMARK src ip ");
|
||||
else
|
||||
printf(" IPMARK dst ip ");
|
||||
|
||||
if (info->shift != 0)
|
||||
printf(" shift %u ", (unsigned int)info->shift);
|
||||
if (info->andmask != ~0U)
|
||||
printf(" and 0x%x ", (unsigned int)info->andmask);
|
||||
if (info->ormask != 0)
|
||||
printf(" or 0x%x ", (unsigned int)info->ormask);
|
||||
}
|
||||
|
||||
static void
|
||||
ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_ipmark_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (info->selector == XT_IPMARK_SRC)
|
||||
printf(" --addr src ");
|
||||
else
|
||||
printf(" --addr dst ");
|
||||
|
||||
if (info->shift != 0)
|
||||
printf(" --shift %u ", (unsigned int)info->shift);
|
||||
if (info->andmask != ~0U)
|
||||
printf(" --and-mask 0x%x ", (unsigned int)info->andmask);
|
||||
if (info->ormask != 0)
|
||||
printf(" --or-mask 0x%x ", (unsigned int)info->ormask);
|
||||
}
|
||||
|
||||
static struct xtables_target ipmark_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "IPMARK",
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.revision = 1,
|
||||
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.help = ipmark_tg_help,
|
||||
.init = ipmark_tg_init,
|
||||
.parse = ipmark_tg_parse,
|
||||
.final_check = ipmark_tg_check,
|
||||
.print = ipmark_tg_print,
|
||||
.save = ipmark_tg_save,
|
||||
.extra_opts = ipmark_tg_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void ipmark_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&ipmark_tg_reg);
|
||||
}
|
56
extensions/libxt_IPMARK.man
Normal file
56
extensions/libxt_IPMARK.man
Normal file
@@ -0,0 +1,56 @@
|
||||
Allows you to mark a received packet basing on its IP address. This
|
||||
can replace many mangle/mark entries with only one, if you use
|
||||
firewall based classifier.
|
||||
|
||||
This target is to be used inside the \fBmangle\fP table.
|
||||
.TP
|
||||
\fB\-\-addr\fP {\fBsrc\fP|\fBdst\fP}
|
||||
Select source or destination IP address as a basis for the mark.
|
||||
.TP
|
||||
\fB\-\-and\-mask\fP \fImask\fP
|
||||
Perform bitwise AND on the IP address and this bitmask.
|
||||
.TP
|
||||
\fB\-\-or\-mask\fP \fImask\fP
|
||||
Perform bitwise OR on the IP address and this bitmask.
|
||||
.TP
|
||||
\fB\-\-shift\fP \fIvalue\fP
|
||||
Shift addresses to the right by the given number of bits before taking it
|
||||
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
||||
to select part of an IPv6 address, because marks are only 32 bits in size.
|
||||
.PP
|
||||
The order of IP address bytes is reversed to meet "human order of bytes":
|
||||
192.168.0.1 is 0xc0a80001. At first the "AND" operation is performed, then
|
||||
"OR".
|
||||
.PP
|
||||
Examples:
|
||||
.PP
|
||||
We create a queue for each user, the queue number is adequate
|
||||
to the IP address of the user, e.g.: all packets going to/from 192.168.5.2
|
||||
are directed to 1:0502 queue, 192.168.5.12 -> 1:050c etc.
|
||||
.PP
|
||||
We have one classifier rule:
|
||||
.IP
|
||||
tc filter add dev eth3 parent 1:0 protocol ip fw
|
||||
.PP
|
||||
Earlier we had many rules just like below:
|
||||
.IP
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.2 \-j MARK
|
||||
\-\-set\-mark 0x10502
|
||||
.IP
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.3 \-j MARK
|
||||
\-\-set\-mark 0x10503
|
||||
.PP
|
||||
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
||||
.IP
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-j IPMARK \-\-addr dst
|
||||
\-\-and\-mask 0xffff \-\-or\-mask 0x10000
|
||||
.PP
|
||||
On the routers with hundreds of users there should be significant load
|
||||
decrease (e.g. twice).
|
||||
.PP
|
||||
(IPv6 example) If the source address is of the form
|
||||
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
||||
then a right-shift of 16 is needed first:
|
||||
.IP
|
||||
\-t mangle \-A PREROUTING \-s 2001:db8::/32 \-j IPMARK \-\-addr src \-\-shift
|
||||
16 \-\-and\-mask 0xFFFF
|
@@ -1,25 +1,29 @@
|
||||
/*
|
||||
* "LOGMARK" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_LOGMARK.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_LEVEL = 1 << 0,
|
||||
F_PREFIX = 1 << 1,
|
||||
F_NFMARK = 1 << 2,
|
||||
F_CTMARK = 1 << 3,
|
||||
F_SECMARK = 1 << 4,
|
||||
F_LEVEL = 1 << 0,
|
||||
F_PREFIX = 1 << 1,
|
||||
};
|
||||
|
||||
static const struct option logmark_tg_opts[] = {
|
||||
{.name = "log-level", .has_arg = true, .val = 'l'},
|
||||
{.name = "log-prefix", .has_arg = true, .val = 'p'},
|
||||
{.name = "log-nfmark", .has_arg = false, .val = 'n'},
|
||||
{.name = "log-ctmark", .has_arg = false, .val = 'c'},
|
||||
{.name = "log-secmark", .has_arg = false, .val = 's'},
|
||||
{},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void logmark_tg_help(void)
|
||||
@@ -28,9 +32,6 @@ static void logmark_tg_help(void)
|
||||
"LOGMARK target options:\n"
|
||||
" --log-level level Level of logging (numeric, 0-8)\n"
|
||||
" --log-prefix prefix Prefix log messages with this string\n"
|
||||
" --log-nfmark Log the packet mark\n"
|
||||
" --log-ctmark Log the connection mark\n"
|
||||
" --log-secmark Log the security mark of the packet\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,48 +52,27 @@ logmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
|
||||
switch (c) {
|
||||
case 'l': /* --log-level */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-level", *flags & F_LEVEL);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-level", invert);
|
||||
if (!strtonum(optarg, NULL, &x, 0, 8))
|
||||
param_act(P_BAD_VALUE, "LOGMARK", "--log-level", optarg);
|
||||
xtables_param_act(XTF_ONLY_ONCE, "LOGMARK", "--log-level", *flags & F_LEVEL);
|
||||
xtables_param_act(XTF_NO_INVERT, "LOGMARK", "--log-level", invert);
|
||||
if (!xtables_strtoui(optarg, NULL, &x, 0, 8))
|
||||
xtables_param_act(XTF_BAD_VALUE, "LOGMARK", "--log-level", optarg);
|
||||
info->level = x;
|
||||
*flags |= F_LEVEL;
|
||||
return true;
|
||||
|
||||
case 'p': /* --log-prefix */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-prefix", *flags & F_PREFIX);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-prefix", invert);
|
||||
xtables_param_act(XTF_ONLY_ONCE, "LOGMARK", "--log-prefix", *flags & F_PREFIX);
|
||||
xtables_param_act(XTF_NO_INVERT, "LOGMARK", "--log-prefix", invert);
|
||||
if (strlen(optarg) > sizeof(info->prefix))
|
||||
exit_error(PARAMETER_PROBLEM, "LOGMARK: Maximum "
|
||||
xtables_error(PARAMETER_PROBLEM, "LOGMARK: Maximum "
|
||||
"prefix length is %zu",
|
||||
sizeof(info->prefix));
|
||||
if (strchr(optarg, '\n'))
|
||||
exit_error(PARAMETER_PROBLEM, "LOGMARK: Newlines not "
|
||||
xtables_error(PARAMETER_PROBLEM, "LOGMARK: Newlines not "
|
||||
"allowed in log prefix");
|
||||
strncpy(info->prefix, optarg, sizeof(info->prefix));
|
||||
*flags |= F_PREFIX;
|
||||
return true;
|
||||
|
||||
case 'n': /* --log-nfmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-nfmark", *flags & F_NFMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-nfmark", invert);
|
||||
info->flags |= XT_LOGMARK_NFMARK;
|
||||
*flags |= F_NFMARK;
|
||||
return true;
|
||||
|
||||
case 'c': /* --log-ctmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-ctmark", *flags & F_CTMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-ctmark", invert);
|
||||
info->flags |= XT_LOGMARK_CTMARK;
|
||||
*flags |= F_CTMARK;
|
||||
return true;
|
||||
|
||||
case 's': /* --log-secmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-secmark", *flags & F_SECMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-secmark", invert);
|
||||
info->flags |= XT_LOGMARK_SECMARK;
|
||||
*flags |= F_SECMARK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -103,14 +83,7 @@ logmark_tg_print(const void *ip, const struct xt_entry_target *target,
|
||||
{
|
||||
const struct xt_logmark_tginfo *info = (void *)target->data;
|
||||
|
||||
printf("LOGMARK level %u prefix \"%s\"", info->level, info->prefix);
|
||||
if (info->flags & XT_LOGMARK_NFMARK)
|
||||
printf(" nfmark");
|
||||
if (info->flags & XT_LOGMARK_CTMARK)
|
||||
printf(" ctmark");
|
||||
if (info->flags & XT_LOGMARK_SECMARK)
|
||||
printf(" secmark");
|
||||
printf("; ");
|
||||
printf(" LOGMARK level %u prefix \"%s\" ", info->level, info->prefix);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -119,22 +92,16 @@ logmark_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
const struct xt_logmark_tginfo *info = (void *)target->data;
|
||||
|
||||
if (info->level != 4)
|
||||
printf("--log-level %u ", info->level);
|
||||
printf(" --log-level %u ", info->level);
|
||||
if (*info->prefix != '\0')
|
||||
printf("--log-prefix \"%s\" ", info->prefix);
|
||||
if (info->flags & XT_LOGMARK_NFMARK)
|
||||
printf("--log-nfmark ");
|
||||
if (info->flags & XT_LOGMARK_CTMARK)
|
||||
printf("--log-ctmark ");
|
||||
if (info->flags & XT_LOGMARK_SECMARK)
|
||||
printf("--log-secmark ");
|
||||
printf(" --log-prefix \"%s\" ", info->prefix);
|
||||
}
|
||||
|
||||
static struct xtables_target logmark_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "LOGMARK",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.help = logmark_tg_help,
|
||||
@@ -145,24 +112,7 @@ static struct xtables_target logmark_tg_reg = {
|
||||
.extra_opts = logmark_tg_opts,
|
||||
};
|
||||
|
||||
static struct xtables_target logmark_tg6_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.name = "LOGMARK",
|
||||
.revision = 0,
|
||||
.family = AF_INET6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.help = logmark_tg_help,
|
||||
.init = logmark_tg_init,
|
||||
.parse = logmark_tg_parse,
|
||||
.print = logmark_tg_print,
|
||||
.save = logmark_tg_save,
|
||||
.extra_opts = logmark_tg_opts,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
static __attribute__((constructor)) void logmark_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&logmark_tg_reg);
|
||||
xtables_register_target(&logmark_tg6_reg);
|
||||
}
|
||||
|
@@ -1,17 +1,8 @@
|
||||
The LOGMARK target will log packet and connection marks to syslog.
|
||||
.TP
|
||||
\fB--log-level\fR \fIlevel\fR
|
||||
\fB\-\-log\-level\fR \fIlevel\fR
|
||||
A logging level between 0 and 8 (inclusive).
|
||||
.TP
|
||||
\fB--log-prefix\fR \fIstring\fR
|
||||
\fB\-\-log\-prefix\fR \fIstring\fR
|
||||
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
||||
for distinguishing messages in the logs.
|
||||
.TP
|
||||
\fB--log-nfmark\fR
|
||||
Include the packet mark in the log.
|
||||
.TP
|
||||
\fB--log-ctmark\fR
|
||||
Include the connection mark in the log.
|
||||
.TP
|
||||
\fB--log-secmark\fR
|
||||
Include the packet secmark in the log.
|
||||
|
189
extensions/libxt_RAWDNAT.c
Normal file
189
extensions/libxt_RAWDNAT.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawdnat_tg_opts[] = {
|
||||
{.name = "to-destination", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawdnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWDNAT target options:\n"
|
||||
" --to-destination addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawdnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWDNAT: "
|
||||
"\"--to-destination\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf(" to-destination %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf(" to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf(" to-destination %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf(" to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawdnat_tg_reg[] = {
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg4_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg4_print,
|
||||
.save = rawdnat_tg4_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
},
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg6_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg6_print,
|
||||
.save = rawdnat_tg6_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
},
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_targets(rawdnat_tg_reg,
|
||||
sizeof(rawdnat_tg_reg) / sizeof(*rawdnat_tg_reg));
|
||||
}
|
10
extensions/libxt_RAWDNAT.man
Normal file
10
extensions/libxt_RAWDNAT.man
Normal file
@@ -0,0 +1,10 @@
|
||||
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
|
||||
much like the \fBNETMAP\fR target.
|
||||
.TP
|
||||
\fB\-\-to\-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
See the \fBRAWSNAT\fR help entry for examples and constraints.
|
189
extensions/libxt_RAWSNAT.c
Normal file
189
extensions/libxt_RAWSNAT.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawsnat_tg_opts[] = {
|
||||
{.name = "to-source", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawsnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWSNAT target options:\n"
|
||||
" --to-source addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawsnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWSNAT: "
|
||||
"\"--to-source\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf(" to-source %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf(" to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf(" to-source %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf(" to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawsnat_tg_reg[] = {
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg4_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg4_print,
|
||||
.save = rawsnat_tg4_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
},
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg6_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg6_print,
|
||||
.save = rawsnat_tg6_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
},
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_targets(rawsnat_tg_reg,
|
||||
sizeof(rawsnat_tg_reg) / sizeof(*rawsnat_tg_reg));
|
||||
}
|
38
extensions/libxt_RAWSNAT.man
Normal file
38
extensions/libxt_RAWSNAT.man
Normal file
@@ -0,0 +1,38 @@
|
||||
The \fBRAWSNAT\fR and \fBRAWDNAT\fP targets provide stateless network address
|
||||
translation.
|
||||
.PP
|
||||
The \fBRAWSNAT\fR target will rewrite the source address in the IP header, much
|
||||
like the \fBNETMAP\fP target. \fBRAWSNAT\fP (and \fBRAWDNAT\fP) may only be
|
||||
used in the \fBraw\fP or \fBrawpost\fP tables, but can be used in all chains,
|
||||
which makes it possible to change the source address either when the packet
|
||||
enters the machine or when it leaves it. The reason for this table constraint
|
||||
is that RAWNAT must happen outside of connection tracking.
|
||||
.TP
|
||||
\fB\-\-to\-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
As an example, changing the destination for packets forwarded from an internal
|
||||
LAN to the internet:
|
||||
.IP
|
||||
\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
|
||||
\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
|
||||
.PP
|
||||
Note that changing addresses may influence the route selection! Specifically,
|
||||
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
||||
would do. Also note that it can transform already-NATed connections \(em as
|
||||
said, it is completely external to Netfilter's connection tracking/NAT.
|
||||
.PP
|
||||
If the machine itself generates packets that are to be rawnat'ed, you need a
|
||||
rule in the OUTPUT chain instead, just like you would with the stateful NAT
|
||||
targets.
|
||||
.PP
|
||||
It may be necessary that in doing so, you also need an extra RAWSNAT rule, to
|
||||
override the automatic source address selection that the routing code does
|
||||
before passing packets to iptables. If the connecting socket has not been
|
||||
explicitly bound to an address, as is the common mode of operation, the address
|
||||
that will be chosen is the primary address of the device through which the
|
||||
packet would be routed with its initial destination address - the address as
|
||||
seen before any RAWNAT takes place.
|
32
extensions/libxt_STEAL.c
Normal file
32
extensions/libxt_STEAL.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <xtables.h>
|
||||
#include "compat_user.h"
|
||||
|
||||
static void steal_tg_help(void)
|
||||
{
|
||||
printf("STEAL takes no options\n\n");
|
||||
}
|
||||
|
||||
static int steal_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void steal_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target steal_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "STEAL",
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = steal_tg_help,
|
||||
.parse = steal_tg_parse,
|
||||
.final_check = steal_tg_check,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&steal_tg_reg);
|
||||
}
|
2
extensions/libxt_STEAL.man
Normal file
2
extensions/libxt_STEAL.man
Normal file
@@ -0,0 +1,2 @@
|
||||
Like the DROP target, but does not throw an error like DROP when used in the
|
||||
\fBOUTPUT\fP chain.
|
38
extensions/libxt_SYSRQ.c
Normal file
38
extensions/libxt_SYSRQ.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* "SYSRQ" target extension to iptables
|
||||
* this file is in the Public Domain
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include "compat_user.h"
|
||||
|
||||
static void sysrq_tg_help(void)
|
||||
{
|
||||
printf("SYSRQ takes no options\n\n");
|
||||
}
|
||||
|
||||
static int sysrq_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sysrq_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target sysrq_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "SYSRQ",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = sysrq_tg_help,
|
||||
.parse = sysrq_tg_parse,
|
||||
.final_check = sysrq_tg_check,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void sysrq_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&sysrq_tg_reg);
|
||||
}
|
83
extensions/libxt_SYSRQ.man
Normal file
83
extensions/libxt_SYSRQ.man
Normal file
@@ -0,0 +1,83 @@
|
||||
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
|
||||
network. This can be useful when vital parts of the machine hang, for example
|
||||
an oops in a filesystem causing locks to be not released and processes to get
|
||||
stuck as a result \(em if still possible, use /proc/sysrq-trigger. Even when
|
||||
processes are stuck, interrupts are likely to be still processed, and as such,
|
||||
sysrq can be triggered through incoming network packets.
|
||||
.PP
|
||||
The xt_SYSRQ implementation uses a salted hash and a sequence number to prevent
|
||||
network sniffers from either guessing the password or replaying earlier
|
||||
requests. The initial sequence number comes from the time of day so you will
|
||||
have a small window of vulnerability should time go backwards at a reboot.
|
||||
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
||||
update the current sequence number. Also, you should limit as to who can issue
|
||||
commands using \fB\-s\fP and/or \fB\-m mac\fP, and also that the destination is
|
||||
correct using \fB\-d\fP (to protect against potential broadcast packets),
|
||||
noting that it is still short of MAC/IP spoofing:
|
||||
.IP
|
||||
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||
.IP
|
||||
(with IPsec) \-A INPUT \-s 10.10.25.1 \-d 10.10.25.7 \-m policy \-\-dir in
|
||||
\-\-pol ipsec \-\-proto esp \-\-tunnel\-src 10.10.25.1 \-\-tunnel\-dst
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||
.PP
|
||||
You should also limit the rate at which connections can be received to limit
|
||||
the CPU time taken by illegal requests, for example:
|
||||
.IP
|
||||
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-m limit \-\-limit 5/minute \-j SYSRQ
|
||||
.PP
|
||||
This extension does not take any options. The \fB\-p udp\fP options are
|
||||
required.
|
||||
.PP
|
||||
The SYSRQ password can be changed through
|
||||
/sys/module/xt_SYSRQ/parameters/password, for example:
|
||||
.IP
|
||||
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||
.PP
|
||||
The module will not respond to sysrq requests until a password has been set.
|
||||
.PP
|
||||
Alternatively, the password may be specified at modprobe time, but this is
|
||||
insecure as people can possible see it through ps(1). You can use an option
|
||||
line in e.g. /etc/modprobe.d/xt_sysrq if it is properly guarded, that is, only
|
||||
readable by root.
|
||||
.IP
|
||||
options xt_SYSRQ password=cookies
|
||||
.PP
|
||||
The hash algorithm can also be specified as a module option, for example, to
|
||||
use SHA-256 instead of the default SHA-1:
|
||||
.IP
|
||||
options xt_SYSRQ hash=sha256
|
||||
.PP
|
||||
The xt_SYSRQ module is normally silent unless a successful request is received,
|
||||
but the \fIdebug\fP module parameter can be used to find exactly why a
|
||||
seemingly correct request is not being processed.
|
||||
.PP
|
||||
To trigger SYSRQ from a remote host, just use socat:
|
||||
.PP
|
||||
.nf
|
||||
sysrq_key="s" # the SysRq key(s)
|
||||
password="password"
|
||||
seqno="$(date +%s)"
|
||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||
openssl enc \-base64)"
|
||||
ipaddr="2001:0db8:0000:0000:0000:ff00:0042:8329"
|
||||
req="$sysrq_key,$seqno,$salt"
|
||||
req="$req,$(echo \-n "$req,$ipaddr,$password" | sha1sum | cut \-c1\-40)"
|
||||
|
||||
echo "$req" | socat stdin udp\-sendto:$ipaddr:9
|
||||
.fi
|
||||
.PP
|
||||
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
||||
power(o)ff, (s)ync filesystems, (u)mount and remount readonly. More than one
|
||||
sysrq key can be used at once, but bear in mind that, for example, a sync may
|
||||
not complete before a subsequent reboot or poweroff.
|
||||
.PP
|
||||
An IPv4 address should have no leading zeros, an IPv6 address should
|
||||
be in the full expanded form (as shown above). The debug option will cause
|
||||
output to be emitted in the same form.
|
||||
.PP
|
||||
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
||||
environments, but it is not perfect: take reasonable precautions to
|
||||
protect your machines.
|
@@ -1,34 +1,123 @@
|
||||
/*
|
||||
* "TARPIT" target extension to iptables
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_TARPIT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_TARPIT = 1 << 0,
|
||||
F_HONEYPOT = 1 << 1,
|
||||
F_RESET = 1 << 2,
|
||||
};
|
||||
|
||||
static const struct option tarpit_tg_opts[] = {
|
||||
{.name = "tarpit", .has_arg = false, .val = 't'},
|
||||
{.name = "honeypot", .has_arg = false, .val = 'h'},
|
||||
{.name = "reset", .has_arg = false, .val = 'r'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void tarpit_tg_help(void)
|
||||
{
|
||||
printf("TARPIT takes no options\n\n");
|
||||
printf(
|
||||
"TARPIT target options:\n"
|
||||
" --tarpit Enable classic 0-window tarpit (default)\n"
|
||||
" --honeypot Enable honeypot option\n"
|
||||
" --reset Enable inline resets\n");
|
||||
}
|
||||
|
||||
static int tarpit_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
struct xt_tarpit_tginfo *info = (void *)(*target)->data;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->variant = XTTARPIT_TARPIT;
|
||||
*flags |= F_TARPIT;
|
||||
return true;
|
||||
case 'h':
|
||||
info->variant = XTTARPIT_HONEYPOT;
|
||||
*flags |= F_HONEYPOT;
|
||||
return true;
|
||||
case 'r':
|
||||
info->variant = XTTARPIT_RESET;
|
||||
*flags |= F_RESET;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void tarpit_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == (F_TARPIT | F_HONEYPOT | F_RESET))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"TARPIT: only one action can be used at a time");
|
||||
}
|
||||
|
||||
static void tarpit_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct xt_tarpit_tginfo *info = (void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTTARPIT_HONEYPOT:
|
||||
printf(" honeypot mode ");
|
||||
break;
|
||||
case XTTARPIT_RESET:
|
||||
printf(" reset mode ");
|
||||
break;
|
||||
default:
|
||||
printf(" tarpit mode ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tarpit_tg_save(const void *ip,
|
||||
const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_tarpit_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTTARPIT_TARPIT:
|
||||
printf(" --tarpit ");
|
||||
break;
|
||||
case XTTARPIT_HONEYPOT:
|
||||
printf(" --honeypot ");
|
||||
break;
|
||||
case XTTARPIT_RESET:
|
||||
printf(" --reset ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct xtables_target tarpit_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "TARPIT",
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_tarpit_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tarpit_tginfo)),
|
||||
.help = tarpit_tg_help,
|
||||
.parse = tarpit_tg_parse,
|
||||
.final_check = tarpit_tg_check,
|
||||
.print = tarpit_tg_print,
|
||||
.save = tarpit_tg_save,
|
||||
.extra_opts = tarpit_tg_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
static __attribute__((constructor)) void tarpit_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&tarpit_tg_reg);
|
||||
}
|
||||
|
@@ -1,33 +1,59 @@
|
||||
+Captures and holds incoming TCP connections using no local per-connection
|
||||
+resources. Connections are accepted, but immediately switched to the persist
|
||||
+state (0 byte window), in which the remote side stops sending data and asks to
|
||||
+continue every 60-240 seconds. Attempts to close the connection are ignored,
|
||||
+forcing the remote side to time out the connection in 12-24 minutes.
|
||||
+
|
||||
+This offers similar functionality to LaBrea
|
||||
+<http://www.hackbusters.net/LaBrea/> but does not require dedicated hardware or
|
||||
+IPs. Any TCP port that you would normally DROP or REJECT can instead become a
|
||||
+tarpit.
|
||||
+
|
||||
+To tarpit connections to TCP port 80 destined for the current machine:
|
||||
+.IP
|
||||
+-A INPUT -p tcp -m tcp --dport 80 -j TARPIT
|
||||
+.P
|
||||
+To significantly slow down Code Red/Nimda-style scans of unused address space,
|
||||
+forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
||||
+route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
||||
+the Linux box, and add:
|
||||
+.IP
|
||||
+-A FORWARD -p tcp -j TARPIT
|
||||
+.IP
|
||||
+-A FORWARD -j DROP
|
||||
+.TP
|
||||
+NOTE:
|
||||
+If you use the conntrack module while you are using TARPIT, you should also use
|
||||
+the NOTRACK target, or the kernel will unnecessarily allocate resources for
|
||||
+each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
||||
+port while using conntrack, you could:
|
||||
+.IP
|
||||
+-t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
|
||||
+.IP
|
||||
+-A INPUT -p tcp --dport 6667 -j TARPIT
|
||||
Captures and holds incoming TCP connections using no local per-connection
|
||||
resources.
|
||||
.PP
|
||||
TARPIT only works at the TCP level, and is totally application agnostic. This
|
||||
module will answer a TCP request and play along like a listening server, but
|
||||
aside from sending an ACK or RST, no data is sent. Incoming packets are ignored
|
||||
and dropped. The attacker will terminate the session eventually. This module
|
||||
allows the initial packets of an attack to be captured by other software for
|
||||
inspection. In most cases this is sufficient to determine the nature of the
|
||||
attack.
|
||||
.PP
|
||||
This offers similar functionality to LaBrea
|
||||
<http://www.hackbusters.net/LaBrea/> but does not require dedicated hardware or
|
||||
IPs. Any TCP port that you would normally DROP or REJECT can instead become a
|
||||
tarpit.
|
||||
.TP
|
||||
\fB\-\-tarpit\fP
|
||||
This mode completes a connection with the attacker but limits the window size
|
||||
to 0, thus keeping the attacker waiting long periods of time. While he is
|
||||
maintaining state of the connection and trying to continue every 60-240
|
||||
seconds, we keep none, so it is very lightweight. Attempts to close the
|
||||
connection are ignored, forcing the remote side to time out the connection in
|
||||
12-24 minutes. This mode is the default.
|
||||
.TP
|
||||
\fB\-\-honeypot\fP
|
||||
This mode completes a connection with the attacker, but signals a normal window
|
||||
size, so that the remote side will attempt to send data, often with some very
|
||||
nasty exploit attempts. We can capture these packets for decoding and further
|
||||
analysis. The module does not send any data, so if the remote expects an
|
||||
application level response, the game is up.
|
||||
.TP
|
||||
\fB\-\-reset\fP
|
||||
This mode is handy because we can send an inline RST (reset). It has no other
|
||||
function.
|
||||
.PP
|
||||
To tarpit connections to TCP port 80 destined for the current machine:
|
||||
.IP
|
||||
\-A INPUT \-p tcp \-m tcp \-\-dport 80 \-j TARPIT
|
||||
.PP
|
||||
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
||||
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
||||
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
||||
the Linux box, and add:
|
||||
.IP
|
||||
\-A FORWARD \-p tcp \-j TARPIT
|
||||
.IP
|
||||
\-A FORWARD \-j DROP
|
||||
.PP
|
||||
NOTE:
|
||||
If you use the conntrack module while you are using TARPIT, you should also use
|
||||
unset tracking on the packet, or the kernel will unnecessarily allocate
|
||||
resources for each TARPITted connection. To TARPIT incoming connections to the
|
||||
standard IRC port while using conntrack, you could:
|
||||
.IP
|
||||
\-t raw \-A PREROUTING \-p tcp \-\-dport 6667 \-j CT \-\-notrack
|
||||
.IP
|
||||
\-A INPUT \-p tcp \-\-dport 6667 \-j NFLOG
|
||||
.IP
|
||||
\-A INPUT \-p tcp \-\-dport 6667 \-j TARPIT
|
||||
|
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* libxt_TEE
|
||||
*
|
||||
* Copyright © Sebastian Claßen <sebastian.classen@freenet.ag>, 2007
|
||||
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
|
||||
* Jan Engelhardt <jengelh@computergmbh.de>
|
||||
*/
|
||||
#include <sys/socket.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_TEE.h"
|
||||
|
||||
enum {
|
||||
FLAG_GATEWAY = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option tee_tg_opts[] = {
|
||||
{.name = "gateway", .has_arg = true, .val = 'g'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void tee_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"TEE target options:\n"
|
||||
" --gateway IPADDR Route packet via the gateway given by address\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_tee_tginfo *info = (void *)(*target)->data;
|
||||
const struct in_addr *ia;
|
||||
|
||||
switch (c) {
|
||||
case 'g':
|
||||
if (*flags & FLAG_GATEWAY)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Cannot specify --gw more than once");
|
||||
|
||||
if (check_inverse(optarg, &invert, NULL, 0))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Unexpected \"!\" after --gateway");
|
||||
|
||||
ia = numeric_to_ipaddr(optarg);
|
||||
if (ia == NULL)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Invalid IP address %s", optarg);
|
||||
|
||||
memcpy(&info->gw, &ia, sizeof(ia));
|
||||
*flags |= FLAG_GATEWAY;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void tee_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
exit_error(PARAMETER_PROBLEM, "TEE target: "
|
||||
"--gateway parameter required");
|
||||
}
|
||||
|
||||
static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (numeric)
|
||||
printf("TEE gw:%s ", ipaddr_to_anyname(&info->gw.in));
|
||||
else
|
||||
printf("TEE gw:%s ", ipaddr_to_numeric(&info->gw.in));
|
||||
}
|
||||
|
||||
static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf("--gateway %s ", ipaddr_to_numeric(&info->gw.in));
|
||||
}
|
||||
|
||||
static struct xtables_target tee_tg_reg = {
|
||||
.name = "TEE",
|
||||
.version = IPTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.help = tee_tg_help,
|
||||
.parse = tee_tg_parse,
|
||||
.final_check = tee_tg_check,
|
||||
.print = tee_tg_print,
|
||||
.save = tee_tg_save,
|
||||
.extra_opts = tee_tg_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&tee_tg_reg);
|
||||
}
|
99
extensions/libxt_condition.c
Normal file
99
extensions/libxt_condition.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* "condition" match extension for iptables
|
||||
* Stephane Ouellette <ouellettes [at] videotron ca>, 2002-10-22
|
||||
* Massimiliano Hofer <max [at] nucleus it>, 2006-05-15
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License; either version 2
|
||||
* or 3 of the License, as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_condition.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static void condition_help(void)
|
||||
{
|
||||
printf(
|
||||
"condition match options:\n"
|
||||
"[!] --condition name Match on boolean value stored in procfs file\n"
|
||||
);
|
||||
}
|
||||
|
||||
static const struct option condition_opts[] = {
|
||||
{.name = "condition", .has_arg = true, .val = 'X'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static int condition_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_condition_mtinfo *info = (void *)(*match)->data;
|
||||
|
||||
if (c == 'X') {
|
||||
if (*flags)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Can't specify multiple conditions");
|
||||
|
||||
if (strlen(optarg) < sizeof(info->name))
|
||||
strcpy(info->name, optarg);
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"File name too long");
|
||||
|
||||
info->invert = invert;
|
||||
*flags = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void condition_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Condition match: must specify --condition");
|
||||
}
|
||||
|
||||
static void condition_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_condition_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf(" condition %s%s ", (info->invert) ? "!" : "", info->name);
|
||||
}
|
||||
|
||||
|
||||
static void condition_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_condition_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf("%s --condition \"%s\" ", info->invert ? " !" : "", info->name);
|
||||
}
|
||||
|
||||
static struct xtables_match condition_mt_reg = {
|
||||
.name = "condition",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.help = condition_help,
|
||||
.parse = condition_parse,
|
||||
.final_check = condition_check,
|
||||
.print = condition_print,
|
||||
.save = condition_save,
|
||||
.extra_opts = condition_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void condition_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&condition_mt_reg);
|
||||
}
|
4
extensions/libxt_condition.man
Normal file
4
extensions/libxt_condition.man
Normal file
@@ -0,0 +1,4 @@
|
||||
This matches if a specific condition variable is (un)set.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-condition\fP \fIname\fP
|
||||
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
103
extensions/libxt_dhcpmac.c
Normal file
103
extensions/libxt_dhcpmac.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* "dhcpmac" match extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_DHCPMAC.h"
|
||||
#include "mac.c"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_MAC = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option dhcpmac_mt_opts[] = {
|
||||
{.name = "mac", .has_arg = true, .val = 'M'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void dhcpmac_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"dhcpmac match options:\n"
|
||||
"[!] --mac lladdr[/mask] Match on MAC address in DHCP Client Host field\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int dhcpmac_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct dhcpmac_info *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'M':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "dhcpmac", "--mac", *flags & F_MAC);
|
||||
xtables_param_act(XTF_NO_INVERT, "dhcpmac", "--mac", invert);
|
||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||
xtables_param_act(XTF_BAD_VALUE, "dhcpmac", "--mac", optarg);
|
||||
if (invert)
|
||||
info->invert = true;
|
||||
*flags |= F_MAC;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dhcpmac_mt_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, "dhcpmac match: "
|
||||
"--mac parameter required");
|
||||
}
|
||||
|
||||
static void dhcpmac_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct dhcpmac_info *info = (void *)match->data;
|
||||
|
||||
printf(" dhcpmac %s" DH_MAC_FMT "/%u ",
|
||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static void dhcpmac_mt_save(const void *ip,
|
||||
const struct xt_entry_match *match)
|
||||
{
|
||||
const struct dhcpmac_info *info = (void *)match->data;
|
||||
|
||||
if (info->invert)
|
||||
printf(" !");
|
||||
printf(" --mac " DH_MAC_FMT "/%u ",
|
||||
DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_match dhcpmac_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "dhcpmac",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||
.help = dhcpmac_mt_help,
|
||||
.parse = dhcpmac_mt_parse,
|
||||
.final_check = dhcpmac_mt_check,
|
||||
.print = dhcpmac_mt_print,
|
||||
.save = dhcpmac_mt_save,
|
||||
.extra_opts = dhcpmac_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void dhcpmac_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&dhcpmac_mt_reg);
|
||||
}
|
4
extensions/libxt_dhcpmac.man
Normal file
4
extensions/libxt_dhcpmac.man
Normal file
@@ -0,0 +1,4 @@
|
||||
.TP
|
||||
\fB\-\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
|
||||
\fImask\fP specifies the prefix length of the initial portion to match.
|
122
extensions/libxt_fuzzy.c
Normal file
122
extensions/libxt_fuzzy.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* "fuzzy" match extension for iptables
|
||||
* Hime Aguiar e Oliveira Jr. <hime@engineer.com>, 2002 - 2003
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License;
|
||||
* either version 2 of the License, or any later version, as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_fuzzy.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static void fuzzy_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"fuzzy match options:\n"
|
||||
" --lower-limit number (in packets per second)\n"
|
||||
" --upper-limit number\n");
|
||||
};
|
||||
|
||||
static const struct option fuzzy_mt_opts[] = {
|
||||
{.name = "lower-limit", .has_arg = true, .val = '1'},
|
||||
{.name = "upper-limit", .has_arg = true, .val = '2'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/* Initialize data structures */
|
||||
static void fuzzy_mt_init(struct xt_entry_match *m)
|
||||
{
|
||||
struct xt_fuzzy_mtinfo *info = (void *)m->data;
|
||||
|
||||
/*
|
||||
* Default rates (I will improve this very soon with something based
|
||||
* on real statistics of the running machine).
|
||||
*/
|
||||
info->minimum_rate = 1000;
|
||||
info->maximum_rate = 2000;
|
||||
}
|
||||
|
||||
#define IPT_FUZZY_OPT_MINIMUM 0x01
|
||||
#define IPT_FUZZY_OPT_MAXIMUM 0x02
|
||||
|
||||
static int fuzzy_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_fuzzy_mtinfo *info = (void *)(*match)->data;
|
||||
uint32_t num;
|
||||
|
||||
switch (c) {
|
||||
case '1':
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MINIMUM)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||
xtables_error(PARAMETER_PROBLEM,"BAD --lower-limit");
|
||||
info->minimum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MINIMUM;
|
||||
return true;
|
||||
|
||||
case '2':
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MAXIMUM)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||
xtables_error(PARAMETER_PROBLEM,"BAD --upper-limit");
|
||||
info->maximum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MAXIMUM;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void fuzzy_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void fuzzy_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",
|
||||
info->minimum_rate, info->maximum_rate);
|
||||
}
|
||||
|
||||
static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf(" --lower-limit %u ", info->minimum_rate);
|
||||
printf(" --upper-limit %u ", info->maximum_rate);
|
||||
}
|
||||
|
||||
static struct xtables_match fuzzy_mt_reg = {
|
||||
.name = "fuzzy",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total),
|
||||
.help = fuzzy_mt_help,
|
||||
.init = fuzzy_mt_init,
|
||||
.parse = fuzzy_mt_parse,
|
||||
.final_check = fuzzy_mt_check,
|
||||
.print = fuzzy_mt_print,
|
||||
.save = fuzzy_mt_save,
|
||||
.extra_opts = fuzzy_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void fuzzy_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&fuzzy_mt_reg);
|
||||
}
|
7
extensions/libxt_fuzzy.man
Normal file
7
extensions/libxt_fuzzy.man
Normal file
@@ -0,0 +1,7 @@
|
||||
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
||||
.TP
|
||||
\fB\-\-lower\-limit\fP \fInumber\fP
|
||||
Specifies the lower limit, in packets per second.
|
||||
.TP
|
||||
\fB\-\-upper\-limit\fP \fInumber\fP
|
||||
Specifies the upper limit, also in packets per second.
|
333
extensions/libxt_geoip.c
Normal file
333
extensions/libxt_geoip.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* "geoip" match extension for iptables
|
||||
* Copyright © Samuel Jean <peejix [at] people netfilter org>, 2004 - 2008
|
||||
* Copyright © Nicolas Bouliane <acidfu [at] people netfilter org>, 2004 - 2008
|
||||
* Jan Engelhardt, 2008-2011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_geoip.h"
|
||||
#include "compat_user.h"
|
||||
#define GEOIP_DB_DIR "/usr/share/xt_geoip"
|
||||
|
||||
static void geoip_help(void)
|
||||
{
|
||||
printf (
|
||||
"geoip match options:\n"
|
||||
"[!] --src-cc, --source-country country[,country...]\n"
|
||||
" Match packet coming from (one of) the specified country(ies)\n"
|
||||
"[!] --dst-cc, --destination-country country[,country...]\n"
|
||||
" Match packet going to (one of) the specified country(ies)\n"
|
||||
"\n"
|
||||
"NOTE: The country is inputed by its ISO3166 code.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
static struct option geoip_opts[] = {
|
||||
{.name = "dst-cc", .has_arg = true, .val = '2'},
|
||||
{.name = "destination-country", .has_arg = true, .val = '2'},
|
||||
{.name = "src-cc", .has_arg = true, .val = '1'},
|
||||
{.name = "source-country", .has_arg = true, .val = '1'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void *
|
||||
geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
|
||||
{
|
||||
void *subnets;
|
||||
struct stat sb;
|
||||
char buf[256];
|
||||
int fd;
|
||||
|
||||
/* Use simple integer vector files */
|
||||
if (nfproto == NFPROTO_IPV6) {
|
||||
#if __BYTE_ORDER == _BIG_ENDIAN
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv6", code);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv6", code);
|
||||
#endif
|
||||
} else {
|
||||
#if __BYTE_ORDER == _BIG_ENDIAN
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv4", code);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv4", code);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
||||
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
||||
xtables_error(OTHER_PROBLEM, "Could not read geoip database");
|
||||
}
|
||||
|
||||
fstat(fd, &sb);
|
||||
*count = sb.st_size;
|
||||
switch (nfproto) {
|
||||
case NFPROTO_IPV6:
|
||||
if (sb.st_size % sizeof(struct geoip_subnet6) != 0)
|
||||
xtables_error(OTHER_PROBLEM,
|
||||
"Database file %s seems to be corrupted", buf);
|
||||
*count /= sizeof(struct geoip_subnet6);
|
||||
break;
|
||||
case NFPROTO_IPV4:
|
||||
if (sb.st_size % sizeof(struct geoip_subnet4) != 0)
|
||||
xtables_error(OTHER_PROBLEM,
|
||||
"Database file %s seems to be corrupted", buf);
|
||||
*count /= sizeof(struct geoip_subnet4);
|
||||
break;
|
||||
}
|
||||
subnets = malloc(sb.st_size);
|
||||
if (subnets == NULL)
|
||||
xtables_error(OTHER_PROBLEM, "geoip: insufficient memory");
|
||||
read(fd, subnets, sb.st_size);
|
||||
close(fd);
|
||||
return subnets;
|
||||
}
|
||||
|
||||
static struct geoip_country_user *geoip_load_cc(const char *code,
|
||||
unsigned short cc, uint8_t nfproto)
|
||||
{
|
||||
struct geoip_country_user *ginfo;
|
||||
ginfo = malloc(sizeof(struct geoip_country_user));
|
||||
|
||||
if (!ginfo)
|
||||
return NULL;
|
||||
|
||||
ginfo->subnets = (unsigned long)geoip_get_subnets(code,
|
||||
&ginfo->count, nfproto);
|
||||
ginfo->cc = cc;
|
||||
|
||||
return ginfo;
|
||||
}
|
||||
|
||||
static u_int16_t
|
||||
check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
||||
{
|
||||
u_int8_t i;
|
||||
u_int16_t cc_int16;
|
||||
|
||||
if (strlen(cc) != 2) /* Country must be 2 chars long according
|
||||
to the ISO3166 standard */
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: invalid country code '%s'", cc);
|
||||
|
||||
// Verification will fail if chars aren't uppercased.
|
||||
// Make sure they are..
|
||||
for (i = 0; i < 2; i++)
|
||||
if (isalnum(cc[i]) != 0)
|
||||
cc[i] = toupper(cc[i]);
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: invalid country code '%s'", cc);
|
||||
|
||||
/* Convert chars into a single 16 bit integer.
|
||||
* FIXME: This assumes that a country code is
|
||||
* exactly 2 chars long. If this is
|
||||
* going to change someday, this whole
|
||||
* match will need to be rewritten, anyway.
|
||||
* - SJ */
|
||||
cc_int16 = (cc[0] << 8) | cc[1];
|
||||
|
||||
// Check for presence of value in cc_used
|
||||
for (i = 0; i < count; i++)
|
||||
if (cc_int16 == cc_used[i])
|
||||
return 0; // Present, skip it!
|
||||
|
||||
return cc_int16;
|
||||
}
|
||||
|
||||
static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
||||
union geoip_country_group *mem, uint8_t nfproto)
|
||||
{
|
||||
char *buffer, *cp, *next;
|
||||
u_int8_t i, count = 0;
|
||||
u_int16_t cctmp;
|
||||
|
||||
buffer = strdup(ccstr);
|
||||
if (!buffer)
|
||||
xtables_error(OTHER_PROBLEM,
|
||||
"geoip: insufficient memory available");
|
||||
|
||||
for (cp = buffer, i = 0; cp && i < XT_GEOIP_MAX; cp = next, i++)
|
||||
{
|
||||
next = strchr(cp, ',');
|
||||
if (next) *next++ = '\0';
|
||||
|
||||
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
||||
if ((mem[count++].user =
|
||||
(unsigned long)geoip_load_cc(cp, cctmp, nfproto)) == 0)
|
||||
xtables_error(OTHER_PROBLEM,
|
||||
"geoip: insufficient memory available");
|
||||
cc[count-1] = cctmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (cp)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: too many countries specified");
|
||||
free(buffer);
|
||||
|
||||
if (count == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: don't know what happened");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int geoip_parse(int c, bool invert, unsigned int *flags,
|
||||
const char *arg, struct xt_geoip_match_info *info, uint8_t nfproto)
|
||||
{
|
||||
switch (c) {
|
||||
case '1':
|
||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: Only exactly one of --source-country "
|
||||
"or --destination-country must be specified!");
|
||||
|
||||
*flags |= XT_GEOIP_SRC;
|
||||
if (invert)
|
||||
*flags |= XT_GEOIP_INV;
|
||||
|
||||
info->count = parse_geoip_cc(arg, info->cc, info->mem,
|
||||
nfproto);
|
||||
info->flags = *flags;
|
||||
return true;
|
||||
|
||||
case '2':
|
||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: Only exactly one of --source-country "
|
||||
"or --destination-country must be specified!");
|
||||
|
||||
*flags |= XT_GEOIP_DST;
|
||||
if (invert)
|
||||
*flags |= XT_GEOIP_INV;
|
||||
|
||||
info->count = parse_geoip_cc(arg, info->cc, info->mem,
|
||||
nfproto);
|
||||
info->flags = *flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int geoip_parse6(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
return geoip_parse(c, invert, flags, optarg,
|
||||
(void *)(*match)->data, NFPROTO_IPV6);
|
||||
}
|
||||
|
||||
static int geoip_parse4(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
return geoip_parse(c, invert, flags, optarg,
|
||||
(void *)(*match)->data, NFPROTO_IPV4);
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"geoip: missing arguments");
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_geoip_match_info *info = (void*)match->data;
|
||||
|
||||
u_int8_t i;
|
||||
|
||||
if (info->flags & XT_GEOIP_SRC)
|
||||
printf(" Source ");
|
||||
else
|
||||
printf(" Destination ");
|
||||
|
||||
if (info->count > 1)
|
||||
printf("countries: ");
|
||||
else
|
||||
printf("country: ");
|
||||
|
||||
if (info->flags & XT_GEOIP_INV)
|
||||
printf("! ");
|
||||
|
||||
for (i = 0; i < info->count; i++)
|
||||
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_geoip_match_info *info = (void *)match->data;
|
||||
u_int8_t i;
|
||||
|
||||
if (info->flags & XT_GEOIP_INV)
|
||||
printf(" !");
|
||||
|
||||
if (info->flags & XT_GEOIP_SRC)
|
||||
printf(" --source-country ");
|
||||
else
|
||||
printf(" --destination-country ");
|
||||
|
||||
for (i = 0; i < info->count; i++)
|
||||
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static struct xtables_match geoip_match[] = {
|
||||
{
|
||||
.family = NFPROTO_IPV6,
|
||||
.name = "geoip",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
||||
.userspacesize = offsetof(struct xt_geoip_match_info, mem),
|
||||
.help = geoip_help,
|
||||
.parse = geoip_parse6,
|
||||
.final_check = geoip_final_check,
|
||||
.print = geoip_print,
|
||||
.save = geoip_save,
|
||||
.extra_opts = geoip_opts,
|
||||
},
|
||||
{
|
||||
.family = NFPROTO_IPV4,
|
||||
.name = "geoip",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
||||
.userspacesize = offsetof(struct xt_geoip_match_info, mem),
|
||||
.help = geoip_help,
|
||||
.parse = geoip_parse4,
|
||||
.final_check = geoip_final_check,
|
||||
.print = geoip_print,
|
||||
.save = geoip_save,
|
||||
.extra_opts = geoip_opts,
|
||||
},
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void geoip_mt_ldr(void)
|
||||
{
|
||||
xtables_register_matches(geoip_match,
|
||||
sizeof(geoip_match) / sizeof(*geoip_match));
|
||||
}
|
22
extensions/libxt_geoip.man
Normal file
22
extensions/libxt_geoip.man
Normal file
@@ -0,0 +1,22 @@
|
||||
Match a packet by its source or destination country.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-src\-cc\fP, \fB\-\-source\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
Match packet coming from (one of) the specified country(ies)
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dst\-cc\fP, \fB\-\-destination\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
Match packet going to (one of) the specified country(ies)
|
||||
.TP
|
||||
NOTE:
|
||||
The country is inputed by its ISO-3166 code.
|
||||
.PP
|
||||
The extra files you will need is the binary database files. They are generated
|
||||
from a country-subnet database with the geoip_build_db.pl tool that is shipped
|
||||
with the source package, and which should be available in compiled packages in
|
||||
/usr/lib(exec)/xtables-addons/. The first command retrieves CSV files from
|
||||
MaxMind, while the other two build packed bisectable range files:
|
||||
.PP
|
||||
mkdir -p /usr/share/xt_geoip; cd /tmp; $path/to/xt_geoip_dl;
|
||||
.PP
|
||||
$path/to/xt_geoip_build -D /usr/share/xt_geoip GeoIP*.csv;
|
||||
.PP
|
||||
The shared library is hardcoded to look in these paths, so use them.
|
99
extensions/libxt_gradm.c
Normal file
99
extensions/libxt_gradm.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* "gradm" match extension for iptables
|
||||
* Zbigniew Krzystolik <zbyniu@destrukcja.pl>, 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License;
|
||||
* either version 2 of the License, or any later version, as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_gradm.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static void gradm_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"gradm match options:\n"
|
||||
" [!] --enabled is Grsecurity RBAC enabled\n"
|
||||
" [!] --disabled is Grsecurity RBAC disabled\n");
|
||||
};
|
||||
|
||||
static const struct option gradm_mt_opts[] = {
|
||||
{.name = "enabled", .has_arg = false, .val = '1'},
|
||||
{.name = "disabled", .has_arg = false, .val = '2'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void gradm_mt_init(struct xt_entry_match *m)
|
||||
{
|
||||
}
|
||||
|
||||
static int gradm_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_gradm_mtinfo *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case '1':
|
||||
if (invert)
|
||||
info->invflags |= 1;
|
||||
return true;
|
||||
case '2':
|
||||
if (!invert)
|
||||
info->invflags |= 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gradm_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void gradm_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_gradm_mtinfo *info = (const void *)match->data;
|
||||
|
||||
if (info->invflags)
|
||||
printf("gradm: disabled");
|
||||
else
|
||||
printf("gradm: enabled");
|
||||
}
|
||||
|
||||
static void gradm_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_gradm_mtinfo *info = (const void *)match->data;
|
||||
|
||||
if (info->invflags)
|
||||
printf(" --disabled ");
|
||||
else
|
||||
printf(" --enabled ");
|
||||
}
|
||||
|
||||
static struct xtables_match gradm_mt_reg = {
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.name = "gradm",
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_gradm_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_gradm_mtinfo)),
|
||||
.help = gradm_mt_help,
|
||||
.init = gradm_mt_init,
|
||||
.parse = gradm_mt_parse,
|
||||
.final_check = gradm_mt_check,
|
||||
.print = gradm_mt_print,
|
||||
.save = gradm_mt_save,
|
||||
.extra_opts = gradm_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void gradm_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&gradm_mt_reg);
|
||||
}
|
7
extensions/libxt_gradm.man
Normal file
7
extensions/libxt_gradm.man
Normal file
@@ -0,0 +1,7 @@
|
||||
This module matches packets based on grsecurity RBAC status.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-enabled\fP
|
||||
Matches packets if grsecurity RBAC is enabled.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-disabled\fP
|
||||
Matches packets if grsecurity RBAC is disabled.
|
247
extensions/libxt_iface.c
Normal file
247
extensions/libxt_iface.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Shared library add-on to iptables to add interface state matching
|
||||
* support.
|
||||
*
|
||||
* (C) 2008 Gáspár Lajos <gaspar.lajos@glsys.eu>
|
||||
*
|
||||
* This program is released under the terms of GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include "xt_iface.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
XT_IFACE_IFACE = 1 << 16,
|
||||
};
|
||||
|
||||
static const struct option iface_mt_opts[] = {
|
||||
{.name = "iface", .has_arg = true, .val = 'i'},
|
||||
{.name = "dev-in", .has_arg = false, .val = 'I'},
|
||||
{.name = "dev-out", .has_arg = false, .val = 'O'},
|
||||
{.name = "up", .has_arg = false, .val = 'u'},
|
||||
{.name = "down", .has_arg = false, .val = 'U'}, /* not up */
|
||||
{.name = "broadcast", .has_arg = false, .val = 'b'},
|
||||
{.name = "loopback", .has_arg = false, .val = 'l'},
|
||||
{.name = "pointopoint", .has_arg = false, .val = 'p'},
|
||||
{.name = "pointtopoint", .has_arg = false, .val = 'p'}, /* eq pointopoint */
|
||||
{.name = "running", .has_arg = false, .val = 'r'},
|
||||
{.name = "noarp", .has_arg = false, .val = 'n'},
|
||||
{.name = "arp", .has_arg = false, .val = 'N'}, /* not noarp */
|
||||
{.name = "promisc", .has_arg = false, .val = 'o'},
|
||||
{.name = "multicast", .has_arg = false, .val = 'm'},
|
||||
{.name = "dynamic", .has_arg = false, .val = 'd'},
|
||||
{.name = "lower-up", .has_arg = false, .val = 'w'},
|
||||
{.name = "dormant", .has_arg = false, .val = 'a'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void iface_print_opt(const struct xt_iface_mtinfo *info,
|
||||
const unsigned int option, const char *command)
|
||||
{
|
||||
if (info->flags & option)
|
||||
printf(" %s%s", (info->invflags & option) ? "! " : "", command);
|
||||
}
|
||||
|
||||
static void iface_setflag(struct xt_iface_mtinfo *info,
|
||||
unsigned int *flags, int invert, u_int16_t flag, const char *command)
|
||||
{
|
||||
if (*flags & flag)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: \"--%s\" flag already specified", command);
|
||||
info->flags |= flag;
|
||||
if (invert)
|
||||
info->invflags |= flag;
|
||||
*flags |= flag;
|
||||
}
|
||||
|
||||
static bool iface_valid_name(const char *name)
|
||||
{
|
||||
static const char invalid_chars[] = ".+!*";
|
||||
|
||||
return strlen(name) < IFNAMSIZ && strpbrk(name, invalid_chars) == NULL;
|
||||
}
|
||||
|
||||
static void iface_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"iface match options:\n"
|
||||
" --iface interface Name of interface\n"
|
||||
" --dev-in / --dev-out Use incoming/outgoing interface instead\n"
|
||||
"[!] --up / --down match if UP flag (not) set\n"
|
||||
"[!] --broadcast match if BROADCAST flag (not) set\n"
|
||||
"[!] --loopback match if LOOPBACK flag (not) set\n"
|
||||
"[!] --pointopoint\n"
|
||||
"[!] --pointtopoint match if POINTOPOINT flag (not) set\n"
|
||||
"[!] --running match if RUNNING flag (not) set\n"
|
||||
"[!] --noarp / --arp match if NOARP flag (not) set\n"
|
||||
"[!] --promisc match if PROMISC flag (not) set\n"
|
||||
"[!] --multicast match if MULTICAST flag (not) set\n"
|
||||
"[!] --dynamic match if DYNAMIC flag (not) set\n"
|
||||
"[!] --lower-up match if LOWER_UP flag (not) set\n"
|
||||
"[!] --dormant match if DORMANT flag (not) set\n");
|
||||
}
|
||||
|
||||
static int iface_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_iface_mtinfo *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'U':
|
||||
c = 'u';
|
||||
invert = !invert;
|
||||
break;
|
||||
case 'N':
|
||||
c = 'n';
|
||||
invert = !invert;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'i': /* interface name */
|
||||
if (*flags & XT_IFACE_IFACE)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: Interface name already specified");
|
||||
if (!iface_valid_name(optarg))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: Invalid interface name!");
|
||||
strcpy(info->ifname, optarg);
|
||||
*flags |= XT_IFACE_IFACE;
|
||||
return true;
|
||||
case 'I': /* --dev-in */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "iface", "--dev-in",
|
||||
*flags & XT_IFACE_IFACE);
|
||||
*flags |= XT_IFACE_IFACE;
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DEV_IN, "dev-in");
|
||||
return true;
|
||||
case 'O': /* --dev-out */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "iface", "--dev-out",
|
||||
*flags & XT_IFACE_IFACE);
|
||||
*flags |= XT_IFACE_IFACE;
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DEV_OUT, "dev-out");
|
||||
return true;
|
||||
case 'u': /* UP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_UP, "up");
|
||||
return true;
|
||||
case 'b': /* BROADCAST */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_BROADCAST, "broadcast");
|
||||
return true;
|
||||
case 'l': /* LOOPBACK */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_LOOPBACK, "loopback");
|
||||
return true;
|
||||
case 'p': /* POINTOPOINT */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_POINTOPOINT, "pointopoint");
|
||||
return true;
|
||||
case 'r': /* RUNNING */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_RUNNING, "running");
|
||||
return true;
|
||||
case 'n': /* NOARP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_NOARP, "noarp");
|
||||
return true;
|
||||
case 'o': /* PROMISC */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_PROMISC, "promisc");
|
||||
return true;
|
||||
case 'm': /* MULTICAST */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_MULTICAST, "multicast");
|
||||
return true;
|
||||
case 'd': /* DYNAMIC */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DYNAMIC, "dynamic");
|
||||
return true;
|
||||
case 'w': /* LOWER_UP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_LOWER_UP, "lower_up");
|
||||
return true;
|
||||
case 'a': /* DORMANT */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DORMANT, "dormant");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void iface_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & XT_IFACE_IFACE))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: You must specify an interface");
|
||||
if ((flags & ~(XT_IFACE_IFACE | XT_IFACE_DEV_IN |
|
||||
XT_IFACE_DEV_OUT)) == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: You must specify at least one option");
|
||||
}
|
||||
|
||||
static void iface_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf(" iface: ");
|
||||
if (info->flags & XT_IFACE_DEV_IN)
|
||||
printf("(in)");
|
||||
else if (info->flags & XT_IFACE_DEV_OUT)
|
||||
printf("(out)");
|
||||
else
|
||||
printf("%s", info->ifname);
|
||||
printf(" [state:");
|
||||
iface_print_opt(info, XT_IFACE_UP, "up");
|
||||
iface_print_opt(info, XT_IFACE_BROADCAST, "broadcast");
|
||||
iface_print_opt(info, XT_IFACE_LOOPBACK, "loopback");
|
||||
iface_print_opt(info, XT_IFACE_POINTOPOINT, "pointopoint");
|
||||
iface_print_opt(info, XT_IFACE_RUNNING, "running");
|
||||
iface_print_opt(info, XT_IFACE_NOARP, "noarp");
|
||||
iface_print_opt(info, XT_IFACE_PROMISC, "promisc");
|
||||
iface_print_opt(info, XT_IFACE_MULTICAST, "multicast");
|
||||
iface_print_opt(info, XT_IFACE_DYNAMIC, "dynamic");
|
||||
iface_print_opt(info, XT_IFACE_LOWER_UP, "lower_up");
|
||||
iface_print_opt(info, XT_IFACE_DORMANT, "dormant");
|
||||
printf("] ");
|
||||
}
|
||||
|
||||
static void iface_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
||||
|
||||
if (info->flags & XT_IFACE_DEV_IN)
|
||||
printf(" --dev-in");
|
||||
else if (info->flags & XT_IFACE_DEV_OUT)
|
||||
printf(" --dev-out");
|
||||
else
|
||||
printf(" --iface %s", info->ifname);
|
||||
iface_print_opt(info, XT_IFACE_UP, "--up");
|
||||
iface_print_opt(info, XT_IFACE_BROADCAST, "--broadcast");
|
||||
iface_print_opt(info, XT_IFACE_LOOPBACK, "--loopback");
|
||||
iface_print_opt(info, XT_IFACE_POINTOPOINT, "--pointopoint");
|
||||
iface_print_opt(info, XT_IFACE_RUNNING, "--running");
|
||||
iface_print_opt(info, XT_IFACE_NOARP, "--noarp");
|
||||
iface_print_opt(info, XT_IFACE_PROMISC, "--promisc");
|
||||
iface_print_opt(info, XT_IFACE_MULTICAST, "--multicast");
|
||||
iface_print_opt(info, XT_IFACE_DYNAMIC, "--dynamic");
|
||||
iface_print_opt(info, XT_IFACE_LOWER_UP, "--lower_up");
|
||||
iface_print_opt(info, XT_IFACE_DORMANT, "--dormant");
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static struct xtables_match iface_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.help = iface_mt_help,
|
||||
.parse = iface_mt_parse,
|
||||
.final_check = iface_mt_check,
|
||||
.print = iface_mt_print,
|
||||
.save = iface_mt_save,
|
||||
.extra_opts = iface_mt_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_match(&iface_mt_reg);
|
||||
}
|
50
extensions/libxt_iface.man
Normal file
50
extensions/libxt_iface.man
Normal file
@@ -0,0 +1,50 @@
|
||||
Allows you to check interface states. First, an interface needs to be selected
|
||||
for comparison. Exactly one option of the following three must be specified:
|
||||
.TP
|
||||
\fB\-\-iface\fP \fIname\fP
|
||||
Check the states on the given interface.
|
||||
.TP
|
||||
\fB\-\-dev\-in\fP
|
||||
Check the states on the interface on which the packet came in. If the input
|
||||
device is not set, because for example you are using \-m iface in the OUTPUT
|
||||
chain, this submatch returns false.
|
||||
.TP
|
||||
\fB\-\-dev\-out\fP
|
||||
Check the states on the interface on which the packet will go out. If the
|
||||
output device is not set, because for example you are using \-m iface in the
|
||||
INPUT chain, this submatch returns false.
|
||||
.PP
|
||||
Following that, one can select the interface properties to check for:
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-up\fP, [\fB!\fP] \fB\-\-down\fP
|
||||
Check the UP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-broadcast\fP
|
||||
Check the BROADCAST flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-loopback\fP
|
||||
Check the LOOPBACK flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-pointtopoint\fP
|
||||
Check the POINTTOPOINT flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-running\fP
|
||||
Check the RUNNING flag. Do NOT rely on it!
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-noarp\fP, [\fB!\fP] \fB\-\-arp\fP
|
||||
Check the NOARP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-promisc\fP
|
||||
Check the PROMISC flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-multicast\fP
|
||||
Check the MULTICAST flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dynamic\fP
|
||||
Check the DYNAMIC flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-lower\-up\fP
|
||||
Check the LOWER_UP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dormant\fP
|
||||
Check the DORMANT flag.
|
247
extensions/libxt_ipp2p.c
Normal file
247
extensions/libxt_ipp2p.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* "ipp2p" match extension for iptables
|
||||
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
|
||||
* Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <ctype.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_ipp2p.h"
|
||||
#include "compat_user.h"
|
||||
#define param_act(t, s, f) xtables_param_act((t), "ipp2p", (s), (f))
|
||||
|
||||
static void ipp2p_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"ipp2p v%s match options:\n"
|
||||
" --edk [tcp,udp] All known eDonkey/eMule/Overnet packets\n"
|
||||
" --dc [tcp] All known Direct Connect packets\n"
|
||||
" --kazaa [tcp,udp] All known KaZaA packets\n"
|
||||
" --gnu [tcp,udp] All known Gnutella packets\n"
|
||||
" --bit [tcp,udp] All known BitTorrent packets\n"
|
||||
" --apple [tcp] All known AppleJuice packets\n"
|
||||
" --winmx [tcp] All known WinMX\n"
|
||||
" --soul [tcp] All known SoulSeek\n"
|
||||
" --ares [tcp] All known Ares\n\n"
|
||||
"EXPERIMENTAL protocols:\n"
|
||||
" --mute [tcp] All known Mute packets\n"
|
||||
" --waste [tcp] All known Waste packets\n"
|
||||
" --xdcc [tcp] All known XDCC packets (only xdcc login)\n\n"
|
||||
, IPP2P_VERSION);
|
||||
}
|
||||
|
||||
static const struct option ipp2p_mt_opts[] = {
|
||||
{.name = "edk", .has_arg = false, .val = '2'},
|
||||
{.name = "dc", .has_arg = false, .val = '7'},
|
||||
{.name = "gnu", .has_arg = false, .val = '9'},
|
||||
{.name = "kazaa", .has_arg = false, .val = 'a'},
|
||||
{.name = "bit", .has_arg = false, .val = 'b'},
|
||||
{.name = "apple", .has_arg = false, .val = 'c'},
|
||||
{.name = "soul", .has_arg = false, .val = 'd'},
|
||||
{.name = "winmx", .has_arg = false, .val = 'e'},
|
||||
{.name = "ares", .has_arg = false, .val = 'f'},
|
||||
{.name = "mute", .has_arg = false, .val = 'g'},
|
||||
{.name = "waste", .has_arg = false, .val = 'h'},
|
||||
{.name = "xdcc", .has_arg = false, .val = 'i'},
|
||||
{.name = "debug", .has_arg = false, .val = 'j'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct ipt_p2p_info *info = (struct ipt_p2p_info *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case '2': /*cmd: edk*/
|
||||
param_act(XTF_ONLY_ONCE, "--edk", *flags & IPP2P_EDK);
|
||||
param_act(XTF_NO_INVERT, "--edk", invert);
|
||||
if (*flags & IPP2P_DATA_EDK)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--edk' OR `--edk-data' but not both of them!");
|
||||
*flags |= IPP2P_EDK;
|
||||
info->cmd |= IPP2P_EDK;
|
||||
break;
|
||||
|
||||
case '7': /*cmd: dc*/
|
||||
param_act(XTF_ONLY_ONCE, "--dc", *flags & IPP2P_DC);
|
||||
param_act(XTF_NO_INVERT, "--dc", invert);
|
||||
if (*flags & IPP2P_DATA_DC)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--dc' OR `--dc-data' but not both of them!");
|
||||
*flags |= IPP2P_DC;
|
||||
info->cmd |= IPP2P_DC;
|
||||
break;
|
||||
|
||||
case '9': /*cmd: gnu*/
|
||||
param_act(XTF_ONLY_ONCE, "--gnu", *flags & IPP2P_GNU);
|
||||
param_act(XTF_NO_INVERT, "--gnu", invert);
|
||||
if (*flags & IPP2P_DATA_GNU)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--gnu' OR `--gnu-data' but not both of them!");
|
||||
*flags |= IPP2P_GNU;
|
||||
info->cmd |= IPP2P_GNU;
|
||||
break;
|
||||
|
||||
case 'a': /*cmd: kazaa*/
|
||||
param_act(XTF_ONLY_ONCE, "--kazaa", *flags & IPP2P_KAZAA);
|
||||
param_act(XTF_NO_INVERT, "--kazaa", invert);
|
||||
if (*flags & IPP2P_DATA_KAZAA)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--kazaa' OR `--kazaa-data' but not both of them!");
|
||||
*flags |= IPP2P_KAZAA;
|
||||
info->cmd |= IPP2P_KAZAA;
|
||||
break;
|
||||
|
||||
case 'b': /*cmd: bit*/
|
||||
param_act(XTF_ONLY_ONCE, "--bit", *flags & IPP2P_BIT);
|
||||
param_act(XTF_NO_INVERT, "--bit", invert);
|
||||
*flags |= IPP2P_BIT;
|
||||
info->cmd |= IPP2P_BIT;
|
||||
break;
|
||||
|
||||
case 'c': /*cmd: apple*/
|
||||
param_act(XTF_ONLY_ONCE, "--apple", *flags & IPP2P_APPLE);
|
||||
param_act(XTF_NO_INVERT, "--apple", invert);
|
||||
*flags |= IPP2P_APPLE;
|
||||
info->cmd |= IPP2P_APPLE;
|
||||
break;
|
||||
|
||||
case 'd': /*cmd: soul*/
|
||||
param_act(XTF_ONLY_ONCE, "--soul", *flags & IPP2P_SOUL);
|
||||
param_act(XTF_NO_INVERT, "--soul", invert);
|
||||
*flags |= IPP2P_SOUL;
|
||||
info->cmd |= IPP2P_SOUL;
|
||||
break;
|
||||
|
||||
case 'e': /*cmd: winmx*/
|
||||
param_act(XTF_ONLY_ONCE, "--winmx", *flags & IPP2P_WINMX);
|
||||
param_act(XTF_NO_INVERT, "--winmx", invert);
|
||||
*flags |= IPP2P_WINMX;
|
||||
info->cmd |= IPP2P_WINMX;
|
||||
break;
|
||||
|
||||
case 'f': /*cmd: ares*/
|
||||
param_act(XTF_ONLY_ONCE, "--ares", *flags & IPP2P_ARES);
|
||||
param_act(XTF_NO_INVERT, "--ares", invert);
|
||||
*flags |= IPP2P_ARES;
|
||||
info->cmd |= IPP2P_ARES;
|
||||
break;
|
||||
|
||||
case 'g': /*cmd: mute*/
|
||||
param_act(XTF_ONLY_ONCE, "--mute", *flags & IPP2P_MUTE);
|
||||
param_act(XTF_NO_INVERT, "--mute", invert);
|
||||
*flags |= IPP2P_MUTE;
|
||||
info->cmd |= IPP2P_MUTE;
|
||||
break;
|
||||
|
||||
case 'h': /*cmd: waste*/
|
||||
param_act(XTF_ONLY_ONCE, "--waste", *flags & IPP2P_WASTE);
|
||||
param_act(XTF_NO_INVERT, "--waste", invert);
|
||||
*flags |= IPP2P_WASTE;
|
||||
info->cmd |= IPP2P_WASTE;
|
||||
break;
|
||||
|
||||
case 'i': /*cmd: xdcc*/
|
||||
param_act(XTF_ONLY_ONCE, "--xdcc", *flags & IPP2P_XDCC);
|
||||
param_act(XTF_NO_INVERT, "--xdcc", invert);
|
||||
*flags |= IPP2P_XDCC;
|
||||
info->cmd |= IPP2P_XDCC;
|
||||
break;
|
||||
|
||||
case 'j': /*cmd: debug*/
|
||||
param_act(XTF_ONLY_ONCE, "--debug", info->debug);
|
||||
param_act(XTF_NO_INVERT, "--debug", invert);
|
||||
info->debug = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
// xtables_error(PARAMETER_PROBLEM,
|
||||
// "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ipp2p_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n");
|
||||
}
|
||||
|
||||
static const char *const ipp2p_cmds[] = {
|
||||
[IPP2N_EDK] = "--edk",
|
||||
[IPP2N_DATA_KAZAA] = "--kazaa-data",
|
||||
[IPP2N_DATA_EDK] = "--edk-data",
|
||||
[IPP2N_DATA_DC] = "--dc-data",
|
||||
[IPP2N_DC] = "--dc",
|
||||
[IPP2N_DATA_GNU] = "--gnu-data",
|
||||
[IPP2N_GNU] = "--gnu",
|
||||
[IPP2N_KAZAA] = "--kazaa",
|
||||
[IPP2N_BIT] = "--bit",
|
||||
[IPP2N_APPLE] = "--apple",
|
||||
[IPP2N_SOUL] = "--soul",
|
||||
[IPP2N_WINMX] = "--winmx",
|
||||
[IPP2N_ARES] = "--ares",
|
||||
[IPP2N_MUTE] = "--mute",
|
||||
[IPP2N_WASTE] = "--waste",
|
||||
[IPP2N_XDCC] = "--xdcc",
|
||||
};
|
||||
|
||||
static void
|
||||
ipp2p_mt_print1(const void *entry, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct ipt_p2p_info *info = (const void *)match->data;
|
||||
unsigned int i;
|
||||
|
||||
for (i = IPP2N_EDK; i <= IPP2N_XDCC; ++i)
|
||||
if (info->cmd & (1 << i))
|
||||
printf(" %s ", ipp2p_cmds[i]);
|
||||
|
||||
if (info->debug != 0)
|
||||
printf(" --debug ");
|
||||
}
|
||||
|
||||
static void ipp2p_mt_print(const void *entry,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
printf(" ipp2p ");
|
||||
ipp2p_mt_print1(entry, match, true);
|
||||
}
|
||||
|
||||
static void ipp2p_mt_save(const void *entry, const struct xt_entry_match *match)
|
||||
{
|
||||
ipp2p_mt_print1(entry, match, true);
|
||||
}
|
||||
|
||||
static struct xtables_match ipp2p_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ipp2p",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
.help = ipp2p_mt_help,
|
||||
.parse = ipp2p_mt_parse,
|
||||
.final_check = ipp2p_mt_check,
|
||||
.print = ipp2p_mt_print,
|
||||
.save = ipp2p_mt_save,
|
||||
.extra_opts = ipp2p_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void ipp2p_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&ipp2p_mt_reg);
|
||||
}
|
48
extensions/libxt_ipp2p.man
Normal file
48
extensions/libxt_ipp2p.man
Normal file
@@ -0,0 +1,48 @@
|
||||
This module matches certain packets in P2P flows. It is not
|
||||
designed to match all packets belonging to a P2P connection \(em
|
||||
use IPP2P together with CONNMARK for this purpose.
|
||||
.PP
|
||||
Use it together with \-p tcp or \-p udp to search these protocols
|
||||
only or without \-p switch to search packets of both protocols.
|
||||
.PP
|
||||
IPP2P provides the following options, of which one or more may be specified
|
||||
on the command line:
|
||||
.TP
|
||||
\fB\-\-edk\fP
|
||||
Matches as many eDonkey/eMule packets as possible.
|
||||
.TP
|
||||
\fB\-\-kazaa\fP
|
||||
Matches as many KaZaA packets as possible.
|
||||
.TP
|
||||
\fB\-\-gnu\fP
|
||||
Matches as many Gnutella packets as possible.
|
||||
.TP
|
||||
\fB\-\-dc\fP
|
||||
Matches as many Direct Connect packets as possible.
|
||||
.TP
|
||||
\fB\-\-bit\fP
|
||||
Matches BitTorrent packets.
|
||||
.TP
|
||||
\fB\-\-apple\fP
|
||||
Matches AppleJuice packets.
|
||||
.TP
|
||||
\fB\-\-soul\fP
|
||||
Matches some SoulSeek packets. Considered as beta, use careful!
|
||||
.TP
|
||||
\fB\-\-winmx\fP
|
||||
Matches some WinMX packets. Considered as beta, use careful!
|
||||
.TP
|
||||
\fB\-\-ares\fP
|
||||
Matches Ares and AresLite packets. Use together with \-j DROP only.
|
||||
.TP
|
||||
\fB\-\-debug\fP
|
||||
Prints some information about each hit into kernel logfile. May
|
||||
produce huge logfiles so beware!
|
||||
.PP
|
||||
Note that ipp2p may not (and often, does not) identify all packets that are
|
||||
exchanged as a result of running filesharing programs.
|
||||
.PP
|
||||
There is more information on http://ipp2p.org/ , but it has not been updated
|
||||
since September 2006, and the syntax there is different from the ipp2p.c
|
||||
provided in Xtables-addons; most importantly, the \-\-ipp2p flag was removed
|
||||
due to its ambiguity to match "all known" protocols.
|
178
extensions/libxt_ipv4options.c
Normal file
178
extensions/libxt_ipv4options.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* "ipv4options" match extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_ipv4options.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
/*
|
||||
* Overview from http://www.networksorcery.com/enp/protocol/ip.htm
|
||||
* Not providing strings for options that seem to be most distant in the past.
|
||||
*/
|
||||
static const char *const v4opt_names[32] = {
|
||||
[ 1] = "nop",
|
||||
[ 2] = "security", /* RFC 1108 */
|
||||
[ 3] = "lsrr", /* RFC 791 */
|
||||
[ 4] = "timestamp", /* RFC 781, 791 */
|
||||
[ 7] = "record-route", /* RFC 791 */
|
||||
[ 9] = "ssrr", /* RFC 791 */
|
||||
[11] = "mtu-probe", /* RFC 1063 */
|
||||
[12] = "mtu-reply", /* RFC 1063 */
|
||||
[18] = "traceroute", /* RFC 1393 */
|
||||
[20] = "router-alert", /* RFC 2113 */
|
||||
};
|
||||
|
||||
static void ipv4options_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"ipv4options match options:\n"
|
||||
"--flags [!]symbol[,...] Match presence/absence (!) of option\n"
|
||||
" (either by name or number)\n"
|
||||
"--any Interpret --flags as OR-combined\n\n");
|
||||
}
|
||||
|
||||
static const struct option ipv4options_mt_opts[] = {
|
||||
{.name = "flags", .has_arg = true, .val = 'f'},
|
||||
{.name = "any", .has_arg = false, .val = 'a'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void ipv4options_parse_flagspec(struct xt_ipv4options_mtinfo1 *info,
|
||||
char *arg)
|
||||
{
|
||||
unsigned int i, opt;
|
||||
bool inv;
|
||||
char *p;
|
||||
|
||||
while (true) {
|
||||
p = strchr(arg, ',');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
|
||||
inv = false;
|
||||
opt = 0;
|
||||
if (*arg == '!') {
|
||||
inv = true;
|
||||
++arg;
|
||||
}
|
||||
|
||||
for (i = 1; i < 32;++i)
|
||||
if (v4opt_names[i] != NULL &&
|
||||
strcmp(v4opt_names[i], arg) == 0) {
|
||||
opt = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (opt == 0 &&
|
||||
!xtables_strtoui(arg, NULL, &opt, 0, UINT8_MAX))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipv4options: Bad option value \"%s\"", arg);
|
||||
|
||||
if (opt == 0)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipv4options: Option value may not be zero");
|
||||
|
||||
info->map |= (1 << opt);
|
||||
if (inv)
|
||||
info->invert |= (1 << opt);
|
||||
if (p == NULL)
|
||||
break;
|
||||
arg = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int ipv4options_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_ipv4options_mtinfo1 *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'a': /* --any */
|
||||
xtables_param_act(XTF_NO_INVERT, "ipv4options", "--any", invert);
|
||||
info->flags |= XT_V4OPTS_ANY;
|
||||
return true;
|
||||
case 'f': /* --flags */
|
||||
xtables_param_act(XTF_NO_INVERT, "ipv4options", "--flags", invert);
|
||||
ipv4options_parse_flagspec(info, optarg);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* no checking of *flags - no IPv4 options is also valid */
|
||||
|
||||
static void ipv4options_print_flags(const struct xt_ipv4options_mtinfo1 *info,
|
||||
bool numeric)
|
||||
{
|
||||
uint32_t tmp = info->map;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < 32; ++i)
|
||||
if (tmp & (1 << i)) {
|
||||
if (info->invert & (1 << i))
|
||||
printf("!");
|
||||
if (!numeric && v4opt_names[i] != NULL)
|
||||
printf("%s", v4opt_names[i]);
|
||||
else
|
||||
printf("%u", i);
|
||||
tmp &= ~(1 << i);
|
||||
if (tmp)
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
|
||||
static void ipv4options_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_ipv4options_mtinfo1 *info = (void *)match->data;
|
||||
|
||||
printf(" ipv4options %s ",
|
||||
(info->flags & XT_V4OPTS_ANY) ? "any-of" : "all-of");
|
||||
ipv4options_print_flags(info, numeric);
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void ipv4options_mt_save(const void *ip,
|
||||
const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_ipv4options_mtinfo1 *info = (void *)match->data;
|
||||
|
||||
if (info->map != 0) {
|
||||
printf(" --flags ");
|
||||
ipv4options_print_flags(info, true);
|
||||
}
|
||||
if (info->flags & XT_V4OPTS_ANY)
|
||||
printf(" --any");
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static struct xtables_match ipv4options_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ipv4options",
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_ipv4options_mtinfo1)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipv4options_mtinfo1)),
|
||||
.help = ipv4options_mt_help,
|
||||
.parse = ipv4options_mt_parse,
|
||||
.print = ipv4options_mt_print,
|
||||
.save = ipv4options_mt_save,
|
||||
.extra_opts = ipv4options_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void ipv4options_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&ipv4options_mt_reg);
|
||||
}
|
47
extensions/libxt_ipv4options.man
Normal file
47
extensions/libxt_ipv4options.man
Normal file
@@ -0,0 +1,47 @@
|
||||
The "ipv4options" module allows to match against a set of IPv4 header options.
|
||||
.TP
|
||||
\fB\-\-flags\fP [\fB!\fP]\fIsymbol\fP[\fB,\fP[\fB!\fP]\fIsymbol...\fP]
|
||||
Specify the options that shall appear or not appear in the header. Each
|
||||
symbol specification is delimited by a comma, and a '!' can be prefixed to
|
||||
a symbol to negate its presence. Symbols are either the name of an IPv4 option
|
||||
or its number. See examples below.
|
||||
.TP
|
||||
\fB\-\-any\fP
|
||||
By default, all of the flags specified must be present/absent, that is, they
|
||||
form an AND condition. Use the \-\-any flag instead to use an OR condition
|
||||
where only at least one symbol spec must be true.
|
||||
.PP
|
||||
Known symbol names (and their number):
|
||||
.PP
|
||||
1 \(em \fBnop\fP
|
||||
.PP
|
||||
2 \(em \fBsecurity\fP \(em RFC 1108
|
||||
.PP
|
||||
3 \(em \fBlsrr\fP \(em Loose Source Routing, RFC 791
|
||||
.PP
|
||||
4 \(em \fBtimestamp\fP \(em RFC 781, 791
|
||||
.PP
|
||||
7 \(em \fBrecord\-route\fP \(em RFC 791
|
||||
.PP
|
||||
9 \(em \fBssrr\fP \(em Strict Source Routing, RFC 791
|
||||
.PP
|
||||
11 \(em \fBmtu\-probe\fP \(em RFC 1063
|
||||
.PP
|
||||
12 \(em \fBmtu\-reply\fP \(em RFC 1063
|
||||
.PP
|
||||
18 \(em \fBtraceroute\fP \(em RFC 1393
|
||||
.PP
|
||||
20 \(em \fBrouter-alert\fP \(em RFC 2113
|
||||
.PP
|
||||
Examples:
|
||||
.PP
|
||||
Match packets that have both Timestamp and NOP:
|
||||
\-m ipv4options \-\-flags nop,timestamp
|
||||
.PP
|
||||
~ that have either of Timestamp or NOP, or both:
|
||||
\-\-flags nop,timestamp \-\-any
|
||||
.PP
|
||||
~ that have Timestamp and no NOP: \-\-flags '!nop,timestamp'
|
||||
.PP
|
||||
~ that have either no NOP or a timestamp (or both conditions):
|
||||
\-\-flags '!nop,timestamp' \-\-any
|
174
extensions/libxt_length2.c
Normal file
174
extensions/libxt_length2.c
Normal file
@@ -0,0 +1,174 @@
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_length2.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
F_LAYER = 1 << 0,
|
||||
F_LENGTH = 1 << 1,
|
||||
|
||||
XT_LENGTH_LAYER_MASK = XT_LENGTH_LAYER3 | XT_LENGTH_LAYER4 |
|
||||
XT_LENGTH_LAYER5 | XT_LENGTH_LAYER7,
|
||||
};
|
||||
|
||||
static void length_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"length match options:\n"
|
||||
" --layer3 Match against layer3 size (e.g. L4 + IPv6 header)\n"
|
||||
" --layer4 Match against layer4 size (e.g. L5 + SCTP header)\n"
|
||||
" --layer5 Match against layer5 size (e.g. L7 + chunk headers)\n"
|
||||
" --layer7 Match against layer7 payload (e.g. SCTP payload)\n"
|
||||
"[!] --length n[:n] Match packet length against value or range\n"
|
||||
" of values (inclusive)\n"
|
||||
);
|
||||
}
|
||||
|
||||
static const struct option length_mt_opts[] = {
|
||||
{.name = "layer3", .has_arg = false, .val = '3'},
|
||||
{.name = "layer4", .has_arg = false, .val = '4'},
|
||||
{.name = "layer5", .has_arg = false, .val = '5'},
|
||||
{.name = "layer7", .has_arg = false, .val = '7'},
|
||||
{.name = "length", .has_arg = true, .val = '='},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void length_mt_init(struct xt_entry_match *match)
|
||||
{
|
||||
struct xt_length_mtinfo2 *info = (void *)match->data;
|
||||
|
||||
info->flags = XT_LENGTH_LAYER3;
|
||||
}
|
||||
|
||||
static int length_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_length_mtinfo2 *info = (void *)(*match)->data;
|
||||
unsigned int from, to;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case '3': /* --layer3 */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
|
||||
info->flags &= ~XT_LENGTH_LAYER_MASK;
|
||||
info->flags |= XT_LENGTH_LAYER3;
|
||||
*flags |= F_LAYER;
|
||||
return true;
|
||||
case '4': /* --layer4 */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
|
||||
info->flags &= ~XT_LENGTH_LAYER_MASK;
|
||||
info->flags |= XT_LENGTH_LAYER4;
|
||||
*flags |= F_LAYER;
|
||||
return true;
|
||||
case '5': /* --layer5 */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
|
||||
info->flags &= ~XT_LENGTH_LAYER_MASK;
|
||||
info->flags |= XT_LENGTH_LAYER5;
|
||||
*flags |= F_LAYER;
|
||||
return true;
|
||||
case '7': /* --layer7 */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "length", "--layer*", *flags & F_LAYER);
|
||||
info->flags &= ~XT_LENGTH_LAYER_MASK;
|
||||
info->flags |= XT_LENGTH_LAYER7;
|
||||
*flags |= F_LAYER;
|
||||
return true;
|
||||
case '=': /* --length */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "length", "--length", *flags & F_LENGTH);
|
||||
if (invert)
|
||||
info->flags |= XT_LENGTH_INVERT;
|
||||
if (!xtables_strtoui(optarg, &end, &from, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg);
|
||||
to = from;
|
||||
if (*end == ':')
|
||||
if (!xtables_strtoui(end + 1, &end, &to, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, "length",
|
||||
"--length", optarg);
|
||||
if (*end != '\0')
|
||||
xtables_param_act(XTF_BAD_VALUE, "length", "--length", optarg);
|
||||
info->min = from;
|
||||
info->max = to;
|
||||
*flags |= F_LENGTH;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void length_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & F_LENGTH))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"length: You must specify \"--length\"");
|
||||
if (!(flags & F_LAYER))
|
||||
fprintf(stderr, "iptables: length match: Defaulting to "
|
||||
"--layer3. Consider specifying it explicitly.\n");
|
||||
}
|
||||
|
||||
static void length_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_length_mtinfo2 *info = (const void *)match->data;
|
||||
|
||||
if (info->flags & XT_LENGTH_LAYER3)
|
||||
printf(" layer3 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER4)
|
||||
printf(" layer4 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER5)
|
||||
printf(" layer5 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER7)
|
||||
printf(" layer7 ");
|
||||
printf(" length ");
|
||||
if (info->flags & XT_LENGTH_INVERT)
|
||||
printf("! ");
|
||||
if (info->min == info->max)
|
||||
printf("%u ", (unsigned int)info->min);
|
||||
else
|
||||
printf("%u-%u ", (unsigned int)info->min,
|
||||
(unsigned int)info->max);
|
||||
}
|
||||
|
||||
static void length_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_length_mtinfo2 *info = (const void *)match->data;
|
||||
|
||||
if (info->flags & XT_LENGTH_LAYER3)
|
||||
printf(" --layer3 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER4)
|
||||
printf(" --layer4 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER5)
|
||||
printf(" --layer5 ");
|
||||
else if (info->flags & XT_LENGTH_LAYER7)
|
||||
printf(" --layer7 ");
|
||||
if (info->flags & XT_LENGTH_INVERT)
|
||||
printf(" !");
|
||||
printf(" --length ");
|
||||
if (info->min == info->max)
|
||||
printf("%u ", (unsigned int)info->min);
|
||||
else
|
||||
printf("%u:%u ", (unsigned int)info->min,
|
||||
(unsigned int)info->max);
|
||||
}
|
||||
|
||||
static struct xtables_match length2_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "length2",
|
||||
.revision = 2,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_length_mtinfo2)),
|
||||
.init = length_mt_init,
|
||||
.help = length_mt_help,
|
||||
.parse = length_mt_parse,
|
||||
.final_check = length_mt_check,
|
||||
.print = length_mt_print,
|
||||
.save = length_mt_save,
|
||||
.extra_opts = length_mt_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_match(&length2_mt_reg);
|
||||
}
|
19
extensions/libxt_length2.man
Normal file
19
extensions/libxt_length2.man
Normal file
@@ -0,0 +1,19 @@
|
||||
This module matches the length of a packet against a specific value or range of
|
||||
values.
|
||||
.TP
|
||||
[\fB!\fR] \fB\-\-length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
|
||||
Match exact length or length range.
|
||||
.TP
|
||||
\fB\-\-layer3\fR
|
||||
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
|
||||
.TP
|
||||
\fB\-\-layer4\fR
|
||||
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
|
||||
.TP
|
||||
\fB\-\-layer5\fR
|
||||
Match the layer5 frame size (e.g. TCP/UDP payload, often called layer7).
|
||||
.PP
|
||||
If no \-\-layer* option is given, \-\-layer3 is assumed by default. Note that
|
||||
using \-\-layer5 may not match a packet if it is not one of the recognized
|
||||
types (currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th
|
||||
layer.
|
123
extensions/libxt_lscan.c
Normal file
123
extensions/libxt_lscan.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* LSCAN match extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2006 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_lscan.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static const struct option lscan_mt_opts[] = {
|
||||
{.name = "stealth", .has_arg = false, .val = 'x'},
|
||||
{.name = "synscan", .has_arg = false, .val = 's'},
|
||||
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
||||
{.name = "grscan", .has_arg = false, .val = 'g'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void lscan_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"lscan match options:\n"
|
||||
"(Combining them will make them match by OR-logic)\n"
|
||||
" --stealth Match TCP Stealth packets\n"
|
||||
" --synscan Match TCP SYN scans\n"
|
||||
" --cnscan Match TCP Connect scans\n"
|
||||
" --grscan Match Banner Grabbing scans\n");
|
||||
}
|
||||
|
||||
static int lscan_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_lscan_mtinfo *info = (void *)((*match)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
info->match_cn = true;
|
||||
return true;
|
||||
case 'g':
|
||||
info->match_gr = true;
|
||||
return true;
|
||||
case 's':
|
||||
info->match_syn = true;
|
||||
return true;
|
||||
case 'x':
|
||||
info->match_stealth = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void lscan_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void lscan_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
||||
const char *s = "";
|
||||
|
||||
printf(" lscan ");
|
||||
if (info->match_stealth) {
|
||||
printf("STEALTH");
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_syn) {
|
||||
printf("%sSYNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_cn) {
|
||||
printf("%sCNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_gr)
|
||||
printf("%sGRSCAN", s);
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
||||
|
||||
if (info->match_stealth)
|
||||
printf(" --stealth ");
|
||||
if (info->match_syn)
|
||||
printf(" --synscan ");
|
||||
if (info->match_cn)
|
||||
printf(" --cnscan ");
|
||||
if (info->match_gr)
|
||||
printf(" --grscan ");
|
||||
}
|
||||
|
||||
static struct xtables_match lscan_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "lscan",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_lscan_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_lscan_mtinfo)),
|
||||
.help = lscan_mt_help,
|
||||
.parse = lscan_mt_parse,
|
||||
.final_check = lscan_mt_check,
|
||||
.print = lscan_mt_print,
|
||||
.save = lscan_mt_save,
|
||||
.extra_opts = lscan_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void lscan_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&lscan_mt_reg);
|
||||
}
|
32
extensions/libxt_lscan.man
Normal file
32
extensions/libxt_lscan.man
Normal file
@@ -0,0 +1,32 @@
|
||||
Detects simple low-level scan attemps based upon the packet's contents.
|
||||
(This is
|
||||
different from other implementations, which also try to match the rate of new
|
||||
connections.) Note that an attempt is only discovered after it has been carried
|
||||
out, but this information can be used in conjunction with other rules to block
|
||||
the remote host's future connections. So this match module will match on the
|
||||
(probably) last packet the remote side will send to your machine.
|
||||
.TP
|
||||
\fB\-\-stealth\fR
|
||||
Match if the packet did not belong to any known TCP connection
|
||||
(Stealth/FIN/XMAS/NULL scan).
|
||||
.TP
|
||||
\fB\-\-synscan\fR
|
||||
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
|
||||
connection was torn down after the 2nd packet in the 3-way handshake.
|
||||
.TP
|
||||
\fB\-\-cnscan\fR
|
||||
Match if the connection was a TCP full open discovery (connect scan), i.e. the
|
||||
connection was torn down after completion of the 3-way handshake.
|
||||
.TP
|
||||
\fB\-\-grscan\fR
|
||||
Match if data in the connection only flew in the direction of the remote side,
|
||||
e.g. if the connection was terminated after a locally running daemon sent its
|
||||
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on
|
||||
warranted single-direction data flows, usually bulk data transfers such as
|
||||
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
|
||||
ports where a protocol runs that is guaranteed to do a bidirectional exchange
|
||||
of bytes.
|
||||
.PP
|
||||
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
||||
so be advised to carefully use xt_lscan in conjunction with blocking rules,
|
||||
as it may lock out your very own internal network.
|
161
extensions/libxt_psd.c
Normal file
161
extensions/libxt_psd.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
Shared library add-on to iptables to add PSD support
|
||||
|
||||
Copyright (C) 2000,2001 astaro AG
|
||||
|
||||
This file is distributed under the terms of the GNU General Public
|
||||
License (GPL). Copies of the GPL can be obtained from:
|
||||
ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||
|
||||
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||
2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
|
||||
2008-04-03 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4 code
|
||||
2008-06-24 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4.1 code
|
||||
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_psd.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
#define SCAN_DELAY_THRESHOLD 300
|
||||
|
||||
/* Function which prints out usage message. */
|
||||
static void psd_mt_help(void) {
|
||||
printf(
|
||||
"psd match options:\n"
|
||||
" --psd-weight-threshold threshhold Portscan detection weight threshold\n"
|
||||
" --psd-delay-threshold delay Portscan detection delay threshold\n"
|
||||
" --psd-lo-ports-weight lo Privileged ports weight\n"
|
||||
" --psd-hi-ports-weight hi High ports weight\n\n");
|
||||
}
|
||||
|
||||
static const struct option psd_mt_opts[] = {
|
||||
{.name = "psd-weight-threshold", .has_arg = true, .val = '1'},
|
||||
{.name = "psd-delay-threshold", .has_arg = true, .val = '2'},
|
||||
{.name = "psd-lo-ports-weight", .has_arg = true, .val = '3'},
|
||||
{.name = "psd-hi-ports-weight", .has_arg = true, .val = '4'},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
/* Initialize the target. */
|
||||
static void psd_mt_init(struct xt_entry_match *match) {
|
||||
struct xt_psd_info *psdinfo = (struct xt_psd_info *)match->data;
|
||||
psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;
|
||||
psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
|
||||
psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
|
||||
psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
|
||||
}
|
||||
|
||||
#define XT_PSD_OPT_CTRESH 0x01
|
||||
#define XT_PSD_OPT_DTRESH 0x02
|
||||
#define XT_PSD_OPT_LPWEIGHT 0x04
|
||||
#define XT_PSD_OPT_HPWEIGHT 0x08
|
||||
|
||||
static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_psd_info *psdinfo = (struct xt_psd_info *)(*match)->data;
|
||||
unsigned int num;
|
||||
|
||||
switch (c) {
|
||||
/* PSD-weight-threshold */
|
||||
case '1':
|
||||
if (*flags & XT_PSD_OPT_CTRESH)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify --psd-weight-threshold twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||
xtables_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold '%s'", optarg);
|
||||
psdinfo->weight_threshold = num;
|
||||
*flags |= XT_PSD_OPT_CTRESH;
|
||||
return true;
|
||||
|
||||
/* PSD-delay-threshold */
|
||||
case '2':
|
||||
if (*flags & XT_PSD_OPT_DTRESH)
|
||||
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||
xtables_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold '%s'", optarg);
|
||||
psdinfo->delay_threshold = num;
|
||||
*flags |= XT_PSD_OPT_DTRESH;
|
||||
return true;
|
||||
|
||||
/* PSD-lo-ports-weight */
|
||||
case '3':
|
||||
if (*flags & XT_PSD_OPT_LPWEIGHT)
|
||||
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||
xtables_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight '%s'", optarg);
|
||||
psdinfo->lo_ports_weight = num;
|
||||
*flags |= XT_PSD_OPT_LPWEIGHT;
|
||||
return true;
|
||||
|
||||
/* PSD-hi-ports-weight */
|
||||
case '4':
|
||||
if (*flags & XT_PSD_OPT_HPWEIGHT)
|
||||
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||
xtables_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight '%s'", optarg);
|
||||
psdinfo->hi_ports_weight = num;
|
||||
*flags |= XT_PSD_OPT_HPWEIGHT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Final check; nothing. */
|
||||
static void psd_mt_final_check(unsigned int flags) {}
|
||||
|
||||
/* Prints out the targinfo. */
|
||||
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
||||
printf(" psd ");
|
||||
printf("weight-threshold: %u ", psdinfo->weight_threshold);
|
||||
printf("delay-threshold: %u ", psdinfo->delay_threshold);
|
||||
printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
|
||||
printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
|
||||
}
|
||||
|
||||
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
||||
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
||||
printf(" --psd-weight-threshold %u ", psdinfo->weight_threshold);
|
||||
printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
|
||||
printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
|
||||
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
|
||||
}
|
||||
|
||||
static struct xtables_match psd_mt_reg = {
|
||||
.name = "psd",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.help = psd_mt_help,
|
||||
.init = psd_mt_init,
|
||||
.parse = psd_mt_parse,
|
||||
.final_check = psd_mt_final_check,
|
||||
.print = psd_mt_print,
|
||||
.save = psd_mt_save,
|
||||
.extra_opts = psd_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void psd_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&psd_mt_reg);
|
||||
}
|
||||
|
18
extensions/libxt_psd.man
Normal file
18
extensions/libxt_psd.man
Normal file
@@ -0,0 +1,18 @@
|
||||
Attempt to detect TCP and UDP port scans. This match was derived from
|
||||
Solar Designer's scanlogd.
|
||||
.TP
|
||||
\fB\-\-psd\-weight\-threshold\fP \fIthreshold\fP
|
||||
Total weight of the latest TCP/UDP packets with different
|
||||
destination ports coming from the same host to be treated as port
|
||||
scan sequence.
|
||||
.TP
|
||||
\fB\-\-psd\-delay\-threshold\fP \fIdelay\fP
|
||||
Delay (in hundredths of second) for the packets with different
|
||||
destination ports coming from the same host to be treated as
|
||||
possible port scan subsequence.
|
||||
.TP
|
||||
\fB\-\-psd\-lo\-ports\-weight\fP \fIweight\fP
|
||||
Weight of the packet with privileged (<=1024) destination port.
|
||||
.TP
|
||||
\fB\-\-psd\-hi\-ports\-weight\fP \fIweight\fP
|
||||
Weight of the packet with non-priviliged destination port.
|
153
extensions/libxt_quota2.c
Normal file
153
extensions/libxt_quota2.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* "quota2" match extension for iptables
|
||||
* Sam Johnston <samj [at] samj net>
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_quota2.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FL_QUOTA = 1 << 0,
|
||||
FL_NAME = 1 << 1,
|
||||
FL_GROW = 1 << 2,
|
||||
FL_PACKET = 1 << 3,
|
||||
FL_NO_CHANGE = 1 << 4,
|
||||
};
|
||||
|
||||
static const struct option quota_mt2_opts[] = {
|
||||
{.name = "grow", .has_arg = false, .val = 'g'},
|
||||
{.name = "no-change", .has_arg = false, .val = 'c'},
|
||||
{.name = "name", .has_arg = true, .val = 'n'},
|
||||
{.name = "quota", .has_arg = true, .val = 'q'},
|
||||
{.name = "packets", .has_arg = false, .val = 'p'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void quota_mt2_help(void)
|
||||
{
|
||||
printf(
|
||||
"quota match options:\n"
|
||||
" --grow provide an increasing counter\n"
|
||||
" --no-change never change counter/quota value for matching packets\n"
|
||||
" --name name name for the file in sysfs\n"
|
||||
"[!] --quota quota initial quota (bytes or packets)\n"
|
||||
" --packets count packets instead of bytes\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
quota_mt2_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_quota_mtinfo2 *info = (void *)(*match)->data;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 'g':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--grow", *flags & FL_GROW);
|
||||
xtables_param_act(XTF_NO_INVERT, "quota", "--grow", invert);
|
||||
info->flags |= XT_QUOTA_GROW;
|
||||
*flags |= FL_GROW;
|
||||
return true;
|
||||
case 'c': /* no-change */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--no-change", *flags & FL_NO_CHANGE);
|
||||
xtables_param_act(XTF_NO_INVERT, "quota", "--no-change", invert);
|
||||
info->flags |= XT_QUOTA_NO_CHANGE;
|
||||
*flags |= FL_NO_CHANGE;
|
||||
return true;
|
||||
case 'n':
|
||||
/* zero termination done on behalf of the kernel module */
|
||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--name", *flags & FL_NAME);
|
||||
xtables_param_act(XTF_NO_INVERT, "quota", "--name", invert);
|
||||
strncpy(info->name, optarg, sizeof(info->name));
|
||||
*flags |= FL_NAME;
|
||||
return true;
|
||||
case 'p':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--packets", *flags & FL_PACKET);
|
||||
xtables_param_act(XTF_NO_INVERT, "quota", "--packets", invert);
|
||||
info->flags |= XT_QUOTA_PACKET;
|
||||
*flags |= FL_PACKET;
|
||||
return true;
|
||||
case 'q':
|
||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--quota", *flags & FL_QUOTA);
|
||||
if (invert)
|
||||
info->flags |= XT_QUOTA_INVERT;
|
||||
info->quota = strtoull(optarg, &end, 0);
|
||||
if (*end != '\0')
|
||||
xtables_error(PARAMETER_PROBLEM, "quota match: "
|
||||
"invalid value for --quota");
|
||||
*flags |= FL_QUOTA;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
quota_mt2_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_quota_mtinfo2 *q = (void *)match->data;
|
||||
|
||||
if (q->flags & XT_QUOTA_INVERT)
|
||||
printf(" !");
|
||||
if (q->flags & XT_QUOTA_GROW)
|
||||
printf(" --grow ");
|
||||
if (q->flags & XT_QUOTA_NO_CHANGE)
|
||||
printf(" --no-change ");
|
||||
if (q->flags & XT_QUOTA_PACKET)
|
||||
printf(" --packets ");
|
||||
if (*q->name != '\0')
|
||||
printf(" --name %s ", q->name);
|
||||
printf(" --quota %llu ", (unsigned long long)q->quota);
|
||||
}
|
||||
|
||||
static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_quota_mtinfo2 *q = (const void *)match->data;
|
||||
|
||||
if (q->flags & XT_QUOTA_INVERT)
|
||||
printf(" !");
|
||||
if (q->flags & XT_QUOTA_GROW)
|
||||
printf(" counter");
|
||||
else
|
||||
printf(" quota");
|
||||
if (*q->name != '\0')
|
||||
printf(" %s:", q->name);
|
||||
printf(" %llu ", (unsigned long long)q->quota);
|
||||
if (q->flags & XT_QUOTA_PACKET)
|
||||
printf("packets ");
|
||||
else
|
||||
printf("bytes ");
|
||||
if (q->flags & XT_QUOTA_NO_CHANGE)
|
||||
printf("(no-change mode) ");
|
||||
}
|
||||
|
||||
static struct xtables_match quota_mt2_reg = {
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.revision = 3,
|
||||
.name = "quota2",
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
|
||||
.userspacesize = offsetof(struct xt_quota_mtinfo2, quota),
|
||||
.help = quota_mt2_help,
|
||||
.parse = quota_mt2_parse,
|
||||
.print = quota_mt2_print,
|
||||
.save = quota_mt2_save,
|
||||
.extra_opts = quota_mt2_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void quota2_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match("a_mt2_reg);
|
||||
}
|
37
extensions/libxt_quota2.man
Normal file
37
extensions/libxt_quota2.man
Normal file
@@ -0,0 +1,37 @@
|
||||
The "quota2" implements a named counter which can be increased or decreased
|
||||
on a per-match basis. Available modes are packet counting or byte counting.
|
||||
The value of the counter can be read and reset through procfs, thereby making
|
||||
this match a minimalist accounting tool.
|
||||
.PP
|
||||
When counting down from the initial quota, the counter will stop at 0 and
|
||||
the match will return false, just like the original "quota" match. In growing
|
||||
(upcounting) mode, it will always return true.
|
||||
.TP
|
||||
\fB\-\-grow\fP
|
||||
Count upwards instead of downwards.
|
||||
.TP
|
||||
\fB\-\-no\-change\fP
|
||||
Makes it so the counter or quota amount is never changed by packets matching
|
||||
this rule. This is only really useful in "quota" mode, as it will allow you to
|
||||
use complex prerouting rules in association with the quota system, without
|
||||
counting a packet twice.
|
||||
.TP
|
||||
\fB\-\-name\fP \fIname\fP
|
||||
Assign the counter a specific name. This option must be present, as an empty
|
||||
name is not allowed. Names starting with a dot or names containing a slash are
|
||||
prohibited.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
|
||||
Specify the initial quota for this counter. If the counter already exists,
|
||||
it is not reset. An "!" may be used to invert the result of the match. The
|
||||
negation has no effect when \fB\-\-grow\fP is used.
|
||||
.TP
|
||||
\fB\-\-packets\fP
|
||||
Count packets instead of bytes that passed the quota2 match.
|
||||
.PP
|
||||
Because counters in quota2 can be shared, you can combine them for various
|
||||
purposes, for example, a bytebucket filter that only lets as much traffic go
|
||||
out as has come in:
|
||||
.PP
|
||||
\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
|
||||
\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;
|
29
extensions/mac.c
Normal file
29
extensions/mac.c
Normal file
@@ -0,0 +1,29 @@
|
||||
static bool mac_parse(const char *addr, unsigned char *dest, uint8_t *mask)
|
||||
{
|
||||
unsigned int i = 0, value;
|
||||
char *end;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; ++i) {
|
||||
value = strtoul(addr, &end, 16);
|
||||
if (addr == end || value > 0xFF)
|
||||
return false;
|
||||
if (i == ETH_ALEN - 1) {
|
||||
if (*end != '\0' && *end != '/')
|
||||
return false;
|
||||
} else if (*end != ':') {
|
||||
return false;
|
||||
}
|
||||
dest[i] = value;
|
||||
addr = end + 1;
|
||||
}
|
||||
|
||||
*mask = 48;
|
||||
if (*end == '/') {
|
||||
if (!xtables_strtoui(end + 1, &end, &value, 0, 48))
|
||||
return false;
|
||||
if (*end != '\0')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
1
extensions/pknock/.gitignore
vendored
Normal file
1
extensions/pknock/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/pknlusr
|
5
extensions/pknock/Kbuild
Normal file
5
extensions/pknock/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
EXTRA_CFLAGS = -I${src}/..
|
||||
|
||||
obj-m += xt_pknock.o
|
8
extensions/pknock/Makefile.am
Normal file
8
extensions/pknock/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${abs_top_srcdir}/extensions
|
||||
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
|
||||
|
||||
include ../../Makefile.extra
|
||||
|
||||
noinst_PROGRAMS = pknlusr
|
3
extensions/pknock/Mbuild
Normal file
3
extensions/pknock/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_pknock} += libxt_pknock.so
|
344
extensions/pknock/libxt_pknock.c
Normal file
344
extensions/pknock/libxt_pknock.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Shared library add-on to iptables to add Port Knocking and SPA matching
|
||||
* support.
|
||||
*
|
||||
* (C) 2006-2009 J. Federico Hernandez <fede.hernandez@gmail.com>
|
||||
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
|
||||
*
|
||||
* This program is released under the terms of GNU GPL version 2.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include "xt_pknock.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
static const struct option pknock_mt_opts[] = {
|
||||
/* .name, .has_arg, .flag, .val */
|
||||
{.name = "knockports", .has_arg = true, .val = 'k'},
|
||||
{.name = "time", .has_arg = true, .val = 't'},
|
||||
{.name = "autoclose", .has_arg = true, .val = 'a'},
|
||||
{.name = "name", .has_arg = true, .val = 'n'},
|
||||
{.name = "opensecret", .has_arg = true, .val = 'o'},
|
||||
{.name = "closesecret", .has_arg = true, .val = 'z'},
|
||||
{.name = "strict", .has_arg = false, .val = 'x'},
|
||||
{.name = "checkip", .has_arg = false, .val = 'c'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void pknock_mt_help(void)
|
||||
{
|
||||
printf("pknock match options:\n"
|
||||
" --knockports port[,port,port,...] "
|
||||
"Matches destination port(s).\n"
|
||||
" --time seconds\n"
|
||||
"Max allowed time between knocks.\n"
|
||||
" --autoclose minutes\n"
|
||||
"Time after which to automatically close opened\n"
|
||||
"\t\t\t\t\tport(s).\n"
|
||||
" --strict "
|
||||
"Knocks sequence must be exact.\n"
|
||||
" --name rule_name "
|
||||
"Rule name.\n"
|
||||
" --checkip "
|
||||
"Matches if the source ip is in the list.\n"
|
||||
);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
parse_ports(const char *portstring, uint16_t *ports, const char *proto)
|
||||
{
|
||||
char *buffer, *cp, *next;
|
||||
unsigned int i;
|
||||
|
||||
buffer = strdup(portstring);
|
||||
if (buffer == NULL)
|
||||
xtables_error(OTHER_PROBLEM, "strdup failed");
|
||||
|
||||
for (cp = buffer, i = 0; cp != NULL && i < XT_PKNOCK_MAX_PORTS; cp = next, ++i)
|
||||
{
|
||||
next=strchr(cp, ',');
|
||||
if (next != NULL)
|
||||
*next++ = '\0';
|
||||
ports[i] = xtables_parse_port(cp, proto);
|
||||
}
|
||||
|
||||
if (cp != NULL)
|
||||
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
|
||||
|
||||
free(buffer);
|
||||
return i;
|
||||
}
|
||||
|
||||
static char *
|
||||
proto_to_name(uint8_t proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
return "tcp";
|
||||
case IPPROTO_UDP:
|
||||
return "udp";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
check_proto(uint16_t pnum, uint8_t invflags)
|
||||
{
|
||||
char *proto;
|
||||
|
||||
if (invflags & XT_INV_PROTO)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||
|
||||
if ((proto = proto_to_name(pnum)) != NULL)
|
||||
return proto;
|
||||
else if (pnum == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||
}
|
||||
|
||||
static int
|
||||
__pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
struct xt_entry_match **match, uint16_t pnum,
|
||||
uint16_t invflags)
|
||||
{
|
||||
const char *proto;
|
||||
struct xt_pknock_mtinfo *info = (void *)(*match)->data;
|
||||
unsigned int tmp;
|
||||
|
||||
switch (c) {
|
||||
case 'k': /* --knockports */
|
||||
if (*flags & XT_PKNOCK_KNOCKPORT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --knockports twice.\n");
|
||||
proto = check_proto(pnum, invflags);
|
||||
|
||||
info->ports_count = parse_ports(optarg, info->port, proto);
|
||||
info->option |= XT_PKNOCK_KNOCKPORT;
|
||||
*flags |= XT_PKNOCK_KNOCKPORT;
|
||||
#if DEBUG
|
||||
printf("ports_count: %d\n", info->ports_count);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 't': /* --time */
|
||||
if (*flags & XT_PKNOCK_TIME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --time twice.\n");
|
||||
info->max_time = atoi(optarg);
|
||||
if (info->max_time == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--time number must be > 0.\n");
|
||||
info->option |= XT_PKNOCK_TIME;
|
||||
*flags |= XT_PKNOCK_TIME;
|
||||
break;
|
||||
|
||||
case 'a': /* --autoclose */
|
||||
if (*flags & XT_PKNOCK_AUTOCLOSE)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --autoclose twice.\n");
|
||||
if (!xtables_strtoui(optarg, NULL, &tmp, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, PKNOCK,
|
||||
"--autoclose", optarg);
|
||||
info->autoclose_time = tmp;
|
||||
info->option |= XT_PKNOCK_AUTOCLOSE;
|
||||
*flags |= XT_PKNOCK_AUTOCLOSE;
|
||||
break;
|
||||
|
||||
case 'n': /* --name */
|
||||
if (*flags & XT_PKNOCK_NAME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --name twice.\n");
|
||||
memset(info->rule_name, 0, sizeof(info->rule_name));
|
||||
strncpy(info->rule_name, optarg, sizeof(info->rule_name) - 1);
|
||||
|
||||
info->rule_name_len = strlen(info->rule_name);
|
||||
info->option |= XT_PKNOCK_NAME;
|
||||
*flags |= XT_PKNOCK_NAME;
|
||||
#if DEBUG
|
||||
printf("info->rule_name: %s\n", info->rule_name);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'o': /* --opensecret */
|
||||
if (*flags & XT_PKNOCK_OPENSECRET)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --opensecret twice.\n");
|
||||
memset(info->open_secret, 0, sizeof(info->open_secret));
|
||||
strncpy(info->open_secret, optarg, sizeof(info->open_secret) - 1);
|
||||
|
||||
info->open_secret_len = strlen(info->open_secret);
|
||||
info->option |= XT_PKNOCK_OPENSECRET;
|
||||
*flags |= XT_PKNOCK_OPENSECRET;
|
||||
break;
|
||||
|
||||
case 'z': /* --closesecret */
|
||||
if (*flags & XT_PKNOCK_CLOSESECRET)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --closesecret twice.\n");
|
||||
memset(info->close_secret, 0, sizeof(info->close_secret));
|
||||
strncpy(info->close_secret, optarg, sizeof(info->close_secret) - 1);
|
||||
|
||||
info->close_secret_len = strlen(info->close_secret);
|
||||
info->option |= XT_PKNOCK_CLOSESECRET;
|
||||
*flags |= XT_PKNOCK_CLOSESECRET;
|
||||
break;
|
||||
|
||||
case 'c': /* --checkip */
|
||||
if (*flags & XT_PKNOCK_CHECKIP)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --checkip twice.\n");
|
||||
info->option |= XT_PKNOCK_CHECKIP;
|
||||
*flags |= XT_PKNOCK_CHECKIP;
|
||||
break;
|
||||
|
||||
case 'x': /* --strict */
|
||||
if (*flags & XT_PKNOCK_STRICT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --strict twice.\n");
|
||||
info->option |= XT_PKNOCK_STRICT;
|
||||
*flags |= XT_PKNOCK_STRICT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pknock_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *e, struct xt_entry_match **match)
|
||||
{
|
||||
const struct ipt_entry *entry = e;
|
||||
return __pknock_parse(c, argv, invert, flags, match,
|
||||
entry->ip.proto, entry->ip.invflags);
|
||||
}
|
||||
|
||||
static void pknock_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & XT_PKNOCK_NAME))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--name option is required.\n");
|
||||
|
||||
if (flags & XT_PKNOCK_KNOCKPORT) {
|
||||
if (flags & XT_PKNOCK_CHECKIP)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --knockports with --checkip.\n");
|
||||
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||
&& !(flags & XT_PKNOCK_CLOSESECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--opensecret must go with --closesecret.\n");
|
||||
if ((flags & XT_PKNOCK_CLOSESECRET)
|
||||
&& !(flags & XT_PKNOCK_OPENSECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--closesecret must go with --opensecret.\n");
|
||||
}
|
||||
|
||||
if (flags & XT_PKNOCK_CHECKIP) {
|
||||
if (flags & XT_PKNOCK_KNOCKPORT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --checkip with --knockports.\n");
|
||||
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||
|| (flags & XT_PKNOCK_CLOSESECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --opensecret and"
|
||||
" --closesecret with --checkip.\n");
|
||||
if (flags & XT_PKNOCK_TIME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --time with --checkip.\n");
|
||||
if (flags & XT_PKNOCK_AUTOCLOSE)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --autoclose with --checkip.\n");
|
||||
} else if (!(flags & (XT_PKNOCK_OPENSECRET | XT_PKNOCK_TIME))) {
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"you must specify --time.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void pknock_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||
int i;
|
||||
|
||||
printf(" pknock ");
|
||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||
printf("knockports ");
|
||||
for (i = 0; i < info->ports_count; ++i)
|
||||
printf("%s%d", i ? "," : "", info->port[i]);
|
||||
printf(" ");
|
||||
}
|
||||
if (info->option & XT_PKNOCK_TIME)
|
||||
printf("time %ld ", (long)info->max_time);
|
||||
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||
printf("autoclose %lu ", (unsigned long)info->autoclose_time);
|
||||
if (info->option & XT_PKNOCK_NAME)
|
||||
printf("name %s ", info->rule_name);
|
||||
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||
printf("opensecret ");
|
||||
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||
printf("closesecret ");
|
||||
if (info->option & XT_PKNOCK_STRICT)
|
||||
printf("strict ");
|
||||
if (info->option & XT_PKNOCK_CHECKIP)
|
||||
printf("checkip ");
|
||||
}
|
||||
|
||||
static void pknock_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
int i;
|
||||
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||
|
||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||
printf(" --knockports ");
|
||||
for (i = 0; i < info->ports_count; ++i)
|
||||
printf("%s%d", i ? "," : "", info->port[i]);
|
||||
printf(" ");
|
||||
}
|
||||
if (info->option & XT_PKNOCK_TIME)
|
||||
printf(" --time %ld ", (long)info->max_time);
|
||||
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||
printf(" --autoclose %lu ",
|
||||
(unsigned long)info->autoclose_time);
|
||||
if (info->option & XT_PKNOCK_NAME)
|
||||
printf(" --name %s ", info->rule_name);
|
||||
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||
printf(" --opensecret ");
|
||||
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||
printf(" --closesecret ");
|
||||
if (info->option & XT_PKNOCK_STRICT)
|
||||
printf(" --strict ");
|
||||
if (info->option & XT_PKNOCK_CHECKIP)
|
||||
printf(" --checkip ");
|
||||
}
|
||||
|
||||
static struct xtables_match pknock_mt_reg = {
|
||||
.name = "pknock",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.help = pknock_mt_help,
|
||||
.parse = pknock_mt_parse,
|
||||
.final_check = pknock_mt_check,
|
||||
.print = pknock_mt_print,
|
||||
.save = pknock_mt_save,
|
||||
.extra_opts = pknock_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void pknock_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&pknock_mt_reg);
|
||||
}
|
113
extensions/pknock/libxt_pknock.man
Normal file
113
extensions/pknock/libxt_pknock.man
Normal file
@@ -0,0 +1,113 @@
|
||||
Pknock match implements so-called "port knocking", a stealthy system
|
||||
for network authentication: a client sends packets to selected
|
||||
ports in a specific sequence (= simple mode, see example 1 below), or a HMAC
|
||||
payload to a single port (= complex mode, see example 2 below),
|
||||
to a target machine that has pknock rule(s) installed. The target machine
|
||||
then decides whether to unblock or block (again) the pknock-protected port(s).
|
||||
This can be used, for instance, to avoid brute force
|
||||
attacks on ssh or ftp services.
|
||||
.PP
|
||||
Example prerequisites:
|
||||
.IP
|
||||
modprobe cn
|
||||
.IP
|
||||
modprobe xt_pknock
|
||||
.PP
|
||||
Example 1 (TCP mode, manual closing of opened port not possible):
|
||||
.IP
|
||||
iptables -P INPUT DROP
|
||||
.IP
|
||||
iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict
|
||||
--name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT
|
||||
.PP
|
||||
The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets
|
||||
to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking).
|
||||
Port numbers in the connect sequence must follow the exact specification, no
|
||||
other ports may be "knocked" inbetween. The rule is named '\fBSSH\fP' \(em a file of
|
||||
the same name for tracking port knocking states will be created in
|
||||
\fB/proc/net/xt_pknock\fP .
|
||||
Successive port knocks must occur with delay of at most 10 seconds. Port 22 (from the example) will
|
||||
be automatiaclly dropped after 60 minutes after it was previously allowed.
|
||||
.PP
|
||||
Example 2 (UDP mode \(em non-replayable and non-spoofable, manual closing
|
||||
of opened port possible, secure, also called "SPA" = Secure Port
|
||||
Authorization):
|
||||
.IP
|
||||
iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP
|
||||
--opensecret foo --closesecret bar --autoclose 240 -j DROP
|
||||
.IP
|
||||
iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT
|
||||
.PP
|
||||
The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after
|
||||
the successful reception of an UDP packet to port 4000. The packet payload must be
|
||||
constructed as a HMAC256 using "foo" as a key. The HMAC content is the particular client's IP address as a 32-bit network byteorder quantity,
|
||||
plus the number of minutes since the Unix epoch, also as a 32-bit value.
|
||||
(This is known as Simple Packet Authorization, also called "SPA".)
|
||||
In such case, any subsequent attempt to connect to port 21 from the client's IP
|
||||
address will cause such packets to be accepted in the second rule.
|
||||
.PP
|
||||
Similarly, upon reception of an UDP packet constructed the same way, but with
|
||||
the key "bar", the first rule will remove a previously installed "ALLOWED" state
|
||||
record from /proc/net/xt_pknock/FTP, which means that the second rule will
|
||||
stop matching for subsequent connection attempts to port 21.
|
||||
In case no close-secret packet is received within 4 hours, the first rule
|
||||
will remove "ALLOWED" record from /proc/net/xt_pknock/FTP itself.
|
||||
.PP
|
||||
Things worth noting:
|
||||
.PP
|
||||
\fBGeneral\fP:
|
||||
.PP
|
||||
Specifying \fB--autoclose 0\fP means that no automatic close will be performed at all.
|
||||
.PP
|
||||
xt_pknock is capable of sending information about successful matches
|
||||
via a netlink socket to userspace, should you need to implement your own
|
||||
way of receiving and handling portknock notifications.
|
||||
Be sure to read the documentation in the doc/pknock/ directory,
|
||||
or visit the original site \(em http://portknocko.berlios.de/ .
|
||||
.PP
|
||||
\fBTCP mode\fP:
|
||||
.PP
|
||||
This mode is not immune against eavesdropping, spoofing and
|
||||
replaying of the port knock sequence by someone else (but its use may still
|
||||
be sufficient for scenarios where these factors are not necessarily
|
||||
this important, such as bare shielding of the SSH port from brute-force attacks).
|
||||
However, if you need these features, you should use UDP mode.
|
||||
.PP
|
||||
It is always wise to specify three or more ports that are not monotonically
|
||||
increasing or decreasing with a small stepsize (e.g. 1024,1025,1026)
|
||||
to avoid accidentally triggering
|
||||
the rule by a portscan.
|
||||
.PP
|
||||
Specifying the inter-knock timeout with \fB--time\fP is mandatory in TCP mode,
|
||||
to avoid permanent denial of services by clogging up the peer knock-state tracking table
|
||||
that xt_pknock internally keeps, should there be a DDoS on the
|
||||
first-in-row knock port from more hostile IP addresses than what the actual size
|
||||
of this table is (defaults to 16, can be changed via the "peer_hasht_ents" module parameter).
|
||||
It is also wise to use as short a time as possible (1 second) for \fB--time\fP
|
||||
for this very reason. You may also consider increasing the size
|
||||
of the peer knock-state tracking table. Using \fB--strict\fP also helps,
|
||||
as it requires the knock sequence to be exact. This means that if the
|
||||
hostile client sends more knocks to the same port, xt_pknock will
|
||||
mark such attempt as failed knock sequence and will forget it immediately.
|
||||
To completely thwart this kind of DDoS, knock-ports would need to have
|
||||
an additional rate-limit protection. Or you may consider using UDP mode.
|
||||
.PP
|
||||
\fBUDP mode\fP:
|
||||
.PP
|
||||
This mode is immune against eavesdropping, replaying and spoofing attacks.
|
||||
It is also immune against DDoS attack on the knockport.
|
||||
.PP
|
||||
For this mode to work, the clock difference on the client and on the server
|
||||
must be below 1 minute. Synchronizing time on both ends by means
|
||||
of NTP or rdate is strongly suggested.
|
||||
.PP
|
||||
There is a rate limiter built into xt_pknock which blocks any subsequent
|
||||
open attempt in UDP mode should the request arrive within less than one
|
||||
minute since the first successful open. This is intentional;
|
||||
it thwarts eventual spoofing attacks.
|
||||
.PP
|
||||
Because the payload value of an UDP knock packet is influenced by client's IP address,
|
||||
UDP mode cannot be used across NAT.
|
||||
.PP
|
||||
For sending UDP "SPA" packets, you may use either \fBknock.sh\fP or
|
||||
\fBknock-orig.sh\fP. These may be found in doc/pknock/util.
|
91
extensions/pknock/pknlusr.c
Normal file
91
extensions/pknock/pknlusr.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/connector.h>
|
||||
|
||||
#include "xt_pknock.h"
|
||||
|
||||
#define GROUP 1
|
||||
|
||||
static struct sockaddr_nl src_addr, dest_addr;
|
||||
static int sock_fd;
|
||||
|
||||
static unsigned char *buf;
|
||||
|
||||
static struct xt_pknock_nl_msg *nlmsg;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
socklen_t addrlen;
|
||||
int status;
|
||||
int group = GROUP;
|
||||
|
||||
int buf_size;
|
||||
|
||||
const char *ip;
|
||||
char ipbuf[48];
|
||||
|
||||
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||
|
||||
if (sock_fd == -1) {
|
||||
perror("socket()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&src_addr, 0, sizeof(src_addr));
|
||||
src_addr.nl_family = AF_NETLINK;
|
||||
src_addr.nl_pid = getpid();
|
||||
src_addr.nl_groups = group;
|
||||
|
||||
status = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
|
||||
|
||||
if (status == -1) {
|
||||
close(sock_fd);
|
||||
perror("bind()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&dest_addr, 0, sizeof(dest_addr));
|
||||
dest_addr.nl_family = AF_NETLINK;
|
||||
dest_addr.nl_pid = 0;
|
||||
dest_addr.nl_groups = group;
|
||||
|
||||
buf_size = sizeof(struct xt_pknock_nl_msg) + sizeof(struct cn_msg) + sizeof(struct nlmsghdr);
|
||||
buf = malloc(buf_size);
|
||||
|
||||
if (!buf) {
|
||||
perror("malloc()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
addrlen = sizeof(dest_addr);
|
||||
|
||||
while(1) {
|
||||
|
||||
memset(buf, 0, buf_size);
|
||||
|
||||
status = recvfrom(sock_fd, buf, buf_size, 0, (struct sockaddr *)&dest_addr, &addrlen);
|
||||
|
||||
if (status <= 0) {
|
||||
perror("recvfrom()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nlmsg = (struct xt_pknock_nl_msg *) (buf + sizeof(struct cn_msg) + sizeof(struct nlmsghdr));
|
||||
|
||||
ip = inet_ntop(AF_INET, &nlmsg->peer_ip, ipbuf, sizeof(ipbuf));
|
||||
printf("rule_name: %s - ip %s\n", nlmsg->rule_name, ip);
|
||||
|
||||
}
|
||||
|
||||
close(sock_fd);
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
1169
extensions/pknock/xt_pknock.c
Normal file
1169
extensions/pknock/xt_pknock.c
Normal file
File diff suppressed because it is too large
Load Diff
53
extensions/pknock/xt_pknock.h
Normal file
53
extensions/pknock/xt_pknock.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Kernel module to implement Port Knocking and SPA matching support.
|
||||
*
|
||||
* (C) 2006-2008 J. Federico Hernandez <fede.hernandez@gmail.com>
|
||||
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* This program is released under the terms of GNU GPL version 2.
|
||||
*/
|
||||
#ifndef _XT_PKNOCK_H
|
||||
#define _XT_PKNOCK_H
|
||||
|
||||
#define PKNOCK "xt_pknock: "
|
||||
|
||||
enum {
|
||||
XT_PKNOCK_KNOCKPORT = 1 << 0,
|
||||
XT_PKNOCK_TIME = 1 << 1,
|
||||
XT_PKNOCK_NAME = 1 << 2,
|
||||
XT_PKNOCK_STRICT = 1 << 3,
|
||||
XT_PKNOCK_CHECKIP = 1 << 4,
|
||||
XT_PKNOCK_OPENSECRET = 1 << 5,
|
||||
XT_PKNOCK_CLOSESECRET = 1 << 6,
|
||||
XT_PKNOCK_AUTOCLOSE = 1 << 7,
|
||||
|
||||
/* Can never change these, as they are make up the user protocol. */
|
||||
XT_PKNOCK_MAX_PORTS = 15,
|
||||
XT_PKNOCK_MAX_BUF_LEN = 31,
|
||||
XT_PKNOCK_MAX_PASSWD_LEN = 31,
|
||||
};
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
struct xt_pknock_mtinfo {
|
||||
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||
uint32_t rule_name_len;
|
||||
char open_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
|
||||
uint32_t open_secret_len;
|
||||
char close_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
|
||||
uint32_t close_secret_len;
|
||||
uint8_t option; /* --time, --knock-port, ... */
|
||||
uint8_t ports_count; /* number of ports */
|
||||
uint16_t port[XT_PKNOCK_MAX_PORTS]; /* port[,port,port,...] */
|
||||
uint32_t max_time; /* max matching time between ports */
|
||||
uint32_t autoclose_time;
|
||||
};
|
||||
|
||||
struct xt_pknock_nl_msg {
|
||||
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||
__be32 peer_ip;
|
||||
};
|
||||
|
||||
#endif /* _XT_PKNOCK_H */
|
217
extensions/xt_CHAOS.c
Normal file
217
extensions/xt_CHAOS.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* "CHAOS" target extension for Xtables
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
#include <linux/netfilter_ipv4/ipt_REJECT.h>
|
||||
#include <net/ip.h>
|
||||
#include "xt_CHAOS.h"
|
||||
static struct xt_match *xm_tcp;
|
||||
static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
/* Module parameters */
|
||||
static unsigned int reject_percentage = ~0U * .01;
|
||||
static unsigned int delude_percentage = ~0U * .0101;
|
||||
module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
|
||||
/* References to other matches/targets */
|
||||
|
||||
static int have_delude, have_tarpit;
|
||||
|
||||
/* Static data for other matches/targets */
|
||||
static const struct ipt_reject_info reject_params = {
|
||||
.with = ICMP_HOST_UNREACH,
|
||||
};
|
||||
|
||||
static const struct xt_tcp tcp_params = {
|
||||
.spts = {0, ~0},
|
||||
.dpts = {0, ~0},
|
||||
};
|
||||
|
||||
/* CHAOS functions */
|
||||
static void
|
||||
xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = par->targinfo;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const int thoff = 4 * iph->ihl;
|
||||
const int fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
||||
typeof(xt_tarpit) destiny;
|
||||
bool ret;
|
||||
bool hotdrop = false;
|
||||
|
||||
{
|
||||
struct xt_action_param local_par;
|
||||
local_par.in = par->in,
|
||||
local_par.out = par->out,
|
||||
local_par.match = xm_tcp;
|
||||
local_par.matchinfo = &tcp_params;
|
||||
local_par.fragoff = fragoff;
|
||||
local_par.thoff = thoff;
|
||||
local_par.hotdrop = false;
|
||||
ret = xm_tcp->match(skb, &local_par);
|
||||
hotdrop = local_par.hotdrop;
|
||||
}
|
||||
if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
|
||||
return;
|
||||
|
||||
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
||||
{
|
||||
struct xt_action_param local_par;
|
||||
local_par.in = par->in;
|
||||
local_par.out = par->out;
|
||||
local_par.hooknum = par->hooknum;
|
||||
local_par.target = destiny;
|
||||
local_par.targinfo = par->targinfo;
|
||||
local_par.family = par->family;
|
||||
destiny->target(skb, &local_par);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
chaos_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
/*
|
||||
* Equivalent to:
|
||||
* -A chaos -m statistic --mode random --probability \
|
||||
* $reject_percentage -j REJECT --reject-with host-unreach;
|
||||
* -A chaos -p tcp -m statistic --mode random --probability \
|
||||
* $delude_percentage -j DELUDE;
|
||||
* -A chaos -j DROP;
|
||||
*/
|
||||
const struct xt_chaos_tginfo *info = par->targinfo;
|
||||
struct sk_buff *skb = *pskb;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if ((unsigned int)net_random() <= reject_percentage) {
|
||||
struct xt_action_param local_par;
|
||||
local_par.in = par->in;
|
||||
local_par.out = par->out;
|
||||
local_par.hooknum = par->hooknum;
|
||||
local_par.target = xt_reject;
|
||||
local_par.targinfo = &reject_params;
|
||||
return xt_reject->target(skb, &local_par);
|
||||
}
|
||||
|
||||
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||
if (iph->protocol == IPPROTO_TCP &&
|
||||
info->variant != XTCHAOS_NORMAL &&
|
||||
par->hooknum != NF_INET_LOCAL_OUT)
|
||||
xt_chaos_total(skb, par);
|
||||
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static int chaos_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = par->targinfo;
|
||||
|
||||
if (info->variant == XTCHAOS_DELUDE && !have_delude) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --delude when "
|
||||
"DELUDE module not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
|
||||
"TARPIT module not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_target chaos_tg_reg = {
|
||||
.name = "CHAOS",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT),
|
||||
.target = chaos_tg,
|
||||
.checkentry = chaos_tg_check,
|
||||
.targetsize = sizeof(struct xt_chaos_tginfo),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init chaos_tg_init(void)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
xm_tcp = xt_request_find_match(NFPROTO_IPV4, "tcp", 0);
|
||||
if (xm_tcp == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"tcp\" match\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xt_reject = xt_request_find_target(NFPROTO_IPV4, "REJECT", 0);
|
||||
if (xt_reject == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"REJECT\" target\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
xt_tarpit = xt_request_find_target(NFPROTO_IPV4, "TARPIT", 0);
|
||||
have_tarpit = xt_tarpit != NULL;
|
||||
if (!have_tarpit)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"TARPIT\" target\n");
|
||||
|
||||
xt_delude = xt_request_find_target(NFPROTO_IPV4, "DELUDE", 0);
|
||||
have_delude = xt_delude != NULL;
|
||||
if (!have_delude)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"DELUDE\" target\n");
|
||||
|
||||
if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {
|
||||
printk(KERN_WARNING PFX "xt_register_target returned "
|
||||
"error %d\n", ret);
|
||||
goto out3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out3:
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
module_put(xt_reject->me);
|
||||
out2:
|
||||
module_put(xm_tcp->me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit chaos_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&chaos_tg_reg);
|
||||
module_put(xm_tcp->me);
|
||||
module_put(xt_reject->me);
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
}
|
||||
|
||||
module_init(chaos_tg_init);
|
||||
module_exit(chaos_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_CHAOS");
|
14
extensions/xt_CHAOS.h
Normal file
14
extensions/xt_CHAOS.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_CHAOS_H
|
||||
#define _LINUX_NETFILTER_XT_CHAOS_H 1
|
||||
|
||||
enum xt_chaos_target_variant {
|
||||
XTCHAOS_NORMAL,
|
||||
XTCHAOS_TARPIT,
|
||||
XTCHAOS_DELUDE,
|
||||
};
|
||||
|
||||
struct xt_chaos_tginfo {
|
||||
uint8_t variant;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_CHAOS_H */
|
176
extensions/xt_DELUDE.c
Normal file
176
extensions/xt_DELUDE.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* "DELUDE" target extension for Xtables
|
||||
* Copyright © Jan Engelhardt, 2007 - 2008
|
||||
*
|
||||
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||
* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
# include <linux/netfilter_bridge.h>
|
||||
#endif
|
||||
#include <net/tcp.h>
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
{
|
||||
struct tcphdr _otcph, *tcph;
|
||||
const struct tcphdr *oth;
|
||||
const struct iphdr *oiph;
|
||||
unsigned int addr_type;
|
||||
struct sk_buff *nskb;
|
||||
struct iphdr *niph;
|
||||
|
||||
oiph = ip_hdr(oldskb);
|
||||
|
||||
/* IP header checks: fragment. */
|
||||
if (oiph->frag_off & htons(IP_OFFSET))
|
||||
return;
|
||||
|
||||
oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
|
||||
sizeof(_otcph), &_otcph);
|
||||
if (oth == NULL)
|
||||
return;
|
||||
|
||||
/* No RST for RST. */
|
||||
if (oth->rst)
|
||||
return;
|
||||
|
||||
/* Check checksum */
|
||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
||||
return;
|
||||
|
||||
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
||||
LL_MAX_HEADER, GFP_ATOMIC);
|
||||
if (nskb == NULL)
|
||||
return;
|
||||
|
||||
skb_reserve(nskb, LL_MAX_HEADER);
|
||||
skb_reset_network_header(nskb);
|
||||
niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
|
||||
niph->version = 4;
|
||||
niph->ihl = sizeof(struct iphdr) / 4;
|
||||
niph->tos = 0;
|
||||
niph->id = 0;
|
||||
niph->frag_off = htons(IP_DF);
|
||||
niph->protocol = IPPROTO_TCP;
|
||||
niph->check = 0;
|
||||
niph->saddr = oiph->daddr;
|
||||
niph->daddr = oiph->saddr;
|
||||
|
||||
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
|
||||
memset(tcph, 0, sizeof(*tcph));
|
||||
tcph->source = oth->dest;
|
||||
tcph->dest = oth->source;
|
||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||
|
||||
/* DELUDE essential part */
|
||||
if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {
|
||||
tcph->syn = true;
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
|
||||
oldskb->len - ip_hdrlen(oldskb) -
|
||||
(oth->doff << 2));
|
||||
} else {
|
||||
tcph->rst = true;
|
||||
if (!oth->ack) {
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn +
|
||||
oth->fin + oldskb->len -
|
||||
ip_hdrlen(oldskb) - (oth->doff << 2));
|
||||
} else {
|
||||
tcph->seq = oth->ack_seq;
|
||||
tcph->ack = false;
|
||||
tcph->ack_seq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
|
||||
addr_type = RTN_UNSPEC;
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||
nskb->nf_bridge->mask & BRNF_BRIDGED))
|
||||
#else
|
||||
if (hook != NF_INET_FORWARD)
|
||||
#endif
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
/* ip_route_me_harder expects skb->dst to be set */
|
||||
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
||||
|
||||
if (ip_route_me_harder(&nskb, addr_type))
|
||||
goto free_nskb;
|
||||
else
|
||||
niph = ip_hdr(nskb);
|
||||
|
||||
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
/* "Never happens" */
|
||||
if (nskb->len > dst_mtu(skb_dst(nskb)))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(nskb, oldskb);
|
||||
|
||||
ip_local_out(nskb);
|
||||
return;
|
||||
|
||||
free_nskb:
|
||||
kfree_skb(nskb);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
delude_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
/* WARNING: This code causes reentry within iptables.
|
||||
This means that the iptables jump stack is now crap. We
|
||||
must return an absolute verdict. --RR */
|
||||
delude_send_reset(*pskb, par->hooknum);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static struct xt_target delude_tg_reg __read_mostly = {
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
|
||||
.proto = IPPROTO_TCP,
|
||||
.target = delude_tg,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init delude_tg_init(void)
|
||||
{
|
||||
return xt_register_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
static void __exit delude_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
module_init(delude_tg_init);
|
||||
module_exit(delude_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DELUDE");
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user