mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +01:00
Compare commits
936 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f46dee9f19 | ||
|
|
5b082a82b2 | ||
|
|
07012648fb | ||
|
|
ce409dbc7e | ||
|
|
16e77146ab | ||
|
|
a87c4a64f5 | ||
|
|
9e61286a59 | ||
|
|
8da102fb48 | ||
|
|
750c3556d9 | ||
|
|
28663b0e93 | ||
|
|
731e36e373 | ||
|
|
608b48f25c | ||
|
|
de247fcbc8 | ||
|
|
7bc4d38470 | ||
|
|
a926b75224 | ||
|
|
064439236c | ||
|
|
0c40a0714b | ||
|
|
d74520768b | ||
|
|
3385df9cc9 | ||
|
|
18c31b20f5 | ||
|
|
7387912ca1 | ||
|
|
0d52763a61 | ||
|
|
86b505f998 | ||
|
|
62a803c55c | ||
|
|
0573808aeb | ||
|
|
22b4435c81 | ||
|
|
b803959e11 | ||
|
|
2f16497bf8 | ||
|
|
78aa7d1787 | ||
|
|
ba2216e6e9 | ||
|
|
74e3d909e6 | ||
|
|
5e52091ecf | ||
|
|
dafb299ea3 | ||
|
|
659bec56d7 | ||
|
|
8c1bea6f84 | ||
|
|
d8d1dc003b | ||
|
|
c2bb52b82f | ||
|
|
1f5456b18b | ||
|
|
dc702f4fd6 | ||
|
|
2a8101eef3 | ||
|
|
20702ddaff | ||
|
|
f4e2701705 | ||
|
|
776ae4e83b | ||
|
|
2158c7a92e | ||
|
|
b53bad7b29 | ||
|
|
6c92bcdad1 | ||
|
|
b949e56d15 | ||
|
|
18ff3e7b6a | ||
|
|
559b1fb89a | ||
|
|
1e78ef0752 | ||
|
|
602ada7820 | ||
|
|
57ac099703 | ||
|
|
eb7628eca4 | ||
|
|
c26e4943c2 | ||
|
|
7e90c8be6a | ||
|
|
3659d89c25 | ||
|
|
db992d42e5 | ||
|
|
5571a270d4 | ||
|
|
b18c2cefec | ||
|
|
3f204321ce | ||
|
|
63603b8ac8 | ||
|
|
fa79582b89 | ||
|
|
342e2c77a7 | ||
|
|
7848e28b62 | ||
|
|
544aa1b339 | ||
|
|
de4791f0c7 | ||
|
|
915f506f3a | ||
|
|
f29566d6d9 | ||
|
|
e4f747164c | ||
|
|
683550b297 | ||
|
|
971fdf7d1c | ||
|
|
1038c6f7f3 | ||
|
|
8efc0271f5 | ||
|
|
9ac5e597e6 | ||
|
|
f7fc5fae1d | ||
|
|
f44b253a42 | ||
|
|
8f85a6e557 | ||
|
|
8fd25e23a6 | ||
|
|
a3dd057147 | ||
|
|
e16fe46d7a | ||
|
|
39f3b24058 | ||
|
|
8e50756afa | ||
|
|
c07cd40234 | ||
|
|
d2addea9cf | ||
|
|
f88c024b2f | ||
|
|
983325bfdf | ||
|
|
f4635a696e | ||
|
|
c439eccdf8 | ||
|
|
04e29858ee | ||
|
|
ab2850e22e | ||
|
|
6429dcd03f | ||
|
|
b43d2f74e4 | ||
|
|
2aab4cf126 | ||
|
|
f2766db829 | ||
|
|
db0fb7f20d | ||
|
|
a6817528bc | ||
|
|
a7dd867503 | ||
|
|
e48f64daac | ||
|
|
171067eb22 | ||
|
|
78b94fa350 | ||
|
|
c84652af40 | ||
|
|
19fd9a7c1d | ||
|
|
5df1c354f0 | ||
|
|
eb0d82ce89 | ||
|
|
f89e922d72 | ||
|
|
ecacd4aee5 | ||
|
|
a17ec89332 | ||
|
|
7003541284 | ||
|
|
87c0e3a337 | ||
|
|
cfb9b646cc | ||
|
|
eed8229a04 | ||
|
|
3e6e25d0aa | ||
|
|
77ca5c2701 | ||
|
|
ca3127ffbc | ||
|
|
77d965784e | ||
|
|
edd289c645 | ||
|
|
2f528876ad | ||
|
|
aa64e34880 | ||
|
|
5fcde41023 | ||
|
|
63e22fc349 | ||
|
|
7af1ec0984 | ||
|
|
4e95797710 | ||
|
|
a641589b09 | ||
|
|
b8e4c7248b | ||
|
|
d29296935e | ||
|
|
1da2c1dcdc | ||
|
|
76395370de | ||
|
|
7589a0a108 | ||
|
|
34072f733c | ||
|
|
9442233a8a | ||
|
|
993831709d | ||
|
|
4def995185 | ||
|
|
fa85aa3f8b | ||
|
|
8021112fea | ||
|
|
80f424b6b3 | ||
|
|
1ef5be352a | ||
|
|
1a83801722 | ||
|
|
3c2f40ec02 | ||
|
|
b47dc3f77c | ||
|
|
f1e726f503 | ||
|
|
afb6ad488c | ||
|
|
5d68211af2 | ||
|
|
887bccf0af | ||
|
|
7eb067338f | ||
|
|
6896cc6346 | ||
|
|
de2f29b797 | ||
|
|
1ec6006f33 | ||
|
|
d9f92c46c4 | ||
|
|
9677c06036 | ||
|
|
a07b3e8a3a | ||
|
|
58a4d336b9 | ||
|
|
86da3818ff | ||
|
|
815889bd22 | ||
|
|
be48947ead | ||
|
|
3e7188edf7 | ||
|
|
3d4f9285c9 | ||
|
|
e556f4147f | ||
|
|
4e4f7a2390 | ||
|
|
35e65d018c | ||
|
|
714b8d9810 | ||
|
|
d061fced7e | ||
|
|
36fedf4f65 | ||
|
|
89202c5dd5 | ||
|
|
110adc58dc | ||
|
|
6f32a1982a | ||
|
|
c50c4c105c | ||
|
|
ac69278676 | ||
|
|
af325f00d9 | ||
|
|
28fa1b2f7e | ||
|
|
ab51787323 | ||
|
|
92bda42ac1 | ||
|
|
730e69463c | ||
|
|
07f000f65a | ||
|
|
3e7d30e01c | ||
|
|
22c72955f5 | ||
|
|
6f681f6519 | ||
|
|
c7273ddd30 | ||
|
|
2c6ef2a5c0 | ||
|
|
4eb4dfe5fa | ||
|
|
8838ddf921 | ||
|
|
6b3875ae39 | ||
|
|
ab763f25a4 | ||
|
|
550eea98b1 | ||
|
|
ecfed8db44 | ||
|
|
fe6e575158 | ||
|
|
d0b4383a0d | ||
|
|
83e2c8dc47 | ||
|
|
57787649d7 | ||
|
|
c9e7237184 | ||
|
|
52be4b0e8a | ||
|
|
e1571e19a8 | ||
|
|
8c7bf7d779 | ||
|
|
406e458c3a | ||
|
|
3f26974563 | ||
|
|
988f2382c4 | ||
|
|
b983fe0bb3 | ||
|
|
5a3f3e43a6 | ||
|
|
49d6e42324 | ||
|
|
d7a7877bfe | ||
|
|
d8ead95070 | ||
|
|
5404e9f004 | ||
|
|
f0aaec98f3 | ||
|
|
348371e43c | ||
|
|
4763486523 | ||
|
|
7250c7a03d | ||
|
|
cedd127e8f | ||
|
|
fcad90b5e9 | ||
|
|
64778f5412 | ||
|
|
a5766a19c2 | ||
|
|
c6f4e816aa | ||
|
|
ce6ef3186b | ||
|
|
6a66008153 | ||
|
|
6c6b345ba0 | ||
|
|
734b874dab | ||
|
|
6d573d8327 | ||
|
|
11eca1816a | ||
|
|
b0d66a01d2 | ||
|
|
bd0db1354e | ||
|
|
01475679d1 | ||
|
|
b2173ffb86 | ||
|
|
3f2f6438fd | ||
|
|
60b5f3e6e4 | ||
|
|
82e97addb1 | ||
|
|
19ae1f366b | ||
|
|
a9747a349a | ||
|
|
fe38bba477 | ||
|
|
a20f9d3e81 | ||
|
|
39e9f0542d | ||
|
|
1c2c5d7dd4 | ||
|
|
1c2ac61bb0 | ||
|
|
f764f68e9c | ||
|
|
2453e57436 | ||
|
|
500ef1088b | ||
|
|
c83cff36d8 | ||
|
|
589adba798 | ||
|
|
6e1d1d3dc4 | ||
|
|
ec59194232 | ||
|
|
7de4474996 | ||
|
|
95626a867e | ||
|
|
c072ffe421 | ||
|
|
ac797a836e | ||
|
|
0cda2287a8 | ||
|
|
6bfc0c84f0 | ||
|
|
1bd0cd504e | ||
|
|
a3e863942b | ||
|
|
f88cf9b025 | ||
|
|
1ad245238f | ||
|
|
4c54a69e64 | ||
|
|
77a31ca6b5 | ||
|
|
c06787ca22 | ||
|
|
15a353c123 | ||
|
|
1b4d22314d | ||
|
|
35383ac359 | ||
|
|
d2b00990fe | ||
|
|
97a11073d4 | ||
|
|
95b6261324 | ||
|
|
37c92fcf5c | ||
|
|
18281e614d | ||
|
|
7f8644cb39 | ||
|
|
799ba2b4b6 | ||
|
|
ad0a1ca97d | ||
|
|
7607610cf9 | ||
|
|
a71a3d29ff | ||
|
|
9051197603 | ||
|
|
94e5ac2109 | ||
|
|
84cb686928 | ||
|
|
da07ad3b13 | ||
|
|
d5cba00ce0 | ||
|
|
ba9d0b34c6 | ||
|
|
f2850cc0b9 | ||
|
|
c69ea0c1fb | ||
|
|
a63387f85e | ||
|
|
df7e7b391d | ||
|
|
5d6431d2d9 | ||
|
|
a61a361eb1 | ||
|
|
9dbad2a26f | ||
|
|
aaba3dd46a | ||
|
|
2e013847d9 | ||
|
|
22e569d430 | ||
|
|
2847039ffe | ||
|
|
54ce11629c | ||
|
|
8dcfd6aae0 | ||
|
|
838a4a5cb9 | ||
|
|
e82b72e931 | ||
|
|
fdc6ccdf5c | ||
|
|
52b389afe8 | ||
|
|
552006c876 | ||
|
|
f0b32edaa9 | ||
|
|
5a901ca155 | ||
|
|
9593cf4cf6 | ||
|
|
64725e2ed9 | ||
|
|
9260f9374a | ||
|
|
2ccf50db3e | ||
|
|
e843ee7117 | ||
|
|
a192e814bf | ||
|
|
ccda631708 | ||
|
|
1552e33c67 | ||
|
|
8afc784956 | ||
|
|
5b00916f83 | ||
|
|
6b7bc76603 | ||
|
|
732c665af5 | ||
|
|
8cf367d68c | ||
|
|
d070978a54 | ||
|
|
7f30efab38 | ||
|
|
d7fed87ebb | ||
|
|
269ac164ed | ||
|
|
55edf31aa6 | ||
|
|
364782b8af | ||
|
|
d3c576f6de | ||
|
|
8d52d73968 | ||
|
|
48022d3a3f | ||
|
|
ec1634d6d8 | ||
|
|
688bb7094e | ||
|
|
928e66eb27 | ||
|
|
d80c27de29 | ||
|
|
6aac22fa74 | ||
|
|
7bc1ab41f7 | ||
|
|
068e304baa | ||
|
|
5dc7b20a43 | ||
|
|
a70ce10bed | ||
|
|
3773443fc8 | ||
|
|
1f4be63d08 | ||
|
|
6a69d1ff6c | ||
|
|
85102b4546 | ||
|
|
f188ea4d2a | ||
|
|
a75dd9e3f9 | ||
|
|
dda673cad4 | ||
|
|
8b125d31f2 | ||
|
|
67ee3e8a7d | ||
|
|
d70536f9ab | ||
|
|
bfe9f9f4a5 | ||
|
|
97e24131c6 | ||
|
|
42b6c40433 | ||
|
|
4dcef0f15d | ||
|
|
c082dfad67 | ||
|
|
331bc57b44 | ||
|
|
b7e20f550e | ||
|
|
e15ef0d837 | ||
|
|
08fd9e2d69 | ||
|
|
3a99213c0b | ||
|
|
ad71158268 | ||
|
|
186d23c920 | ||
|
|
cfbf88bb5f | ||
|
|
1681981fe8 | ||
|
|
3e84b07a01 | ||
|
|
b087c964d4 | ||
|
|
bf70a94921 | ||
|
|
e5282f8a3c | ||
|
|
5920185288 | ||
|
|
92f0249d2b | ||
|
|
016cfeecc6 | ||
|
|
8bf0c355f4 | ||
|
|
fa4178de09 | ||
|
|
04578b109f | ||
|
|
9dabb6f570 | ||
|
|
8812153491 | ||
|
|
17da10d76e | ||
|
|
dae25b3381 | ||
|
|
745071af65 | ||
|
|
f3448f1797 | ||
|
|
dad6091706 | ||
|
|
6d6eb9c5d7 | ||
|
|
64b84fa91d | ||
|
|
bac8388cec | ||
|
|
e69d0d7ce9 | ||
|
|
b326546229 | ||
|
|
5c22cc7985 | ||
|
|
bd31b3648f | ||
|
|
3c595e6225 | ||
|
|
ed40dd423d | ||
|
|
0e5d7d7ae0 | ||
|
|
9ef6f7a612 | ||
|
|
da923aa63c | ||
|
|
f88d94cbaa | ||
|
|
6403d1908d | ||
|
|
423dbf2404 | ||
|
|
af6b0fdbb2 | ||
|
|
8e7eb25558 | ||
|
|
91a724fe2d | ||
|
|
eb1c43d293 | ||
|
|
4123764a48 | ||
|
|
abe94ece52 | ||
|
|
2498ebf7d6 | ||
|
|
f8445c2e5c | ||
|
|
116eb9f1c1 | ||
|
|
48c068b84a | ||
|
|
20a3868e82 | ||
|
|
85d7401520 | ||
|
|
3b848060aa | ||
|
|
69fc5ff54b | ||
|
|
8db6032303 | ||
|
|
549c0e97d0 | ||
|
|
c3861cf54e | ||
|
|
7c1453662f | ||
|
|
5b60b79fd8 | ||
|
|
07b5d74179 | ||
|
|
76b0c919b9 | ||
|
|
785ee7b47b | ||
|
|
64b267c7ea | ||
|
|
0832184896 | ||
|
|
5d41316b9a | ||
|
|
602ead5de5 | ||
|
|
72e038b9bf | ||
|
|
4b0976571e | ||
|
|
8ab48106d6 | ||
|
|
3036f9ce91 | ||
|
|
88d8f99676 | ||
|
|
fb4e5086fd | ||
|
|
58e3a7a687 | ||
|
|
f54399c45c | ||
|
|
0cf3dd3342 | ||
|
|
d7df3a449e | ||
|
|
dc1a5a6982 | ||
|
|
3d21ad7bec | ||
|
|
757e54dc08 | ||
|
|
ced645fb02 | ||
|
|
c1e479f523 | ||
|
|
ca56cc10dd | ||
|
|
75add84741 | ||
|
|
3d3d7b8506 | ||
|
|
b21154a926 | ||
|
|
2169b1f71f | ||
|
|
d84f10cf08 | ||
|
|
f5a82b1a17 | ||
|
|
2c16aaaecd | ||
|
|
d7e0d17154 | ||
|
|
2b7714500c | ||
|
|
03ad7f3ae7 | ||
|
|
756dd97fc7 | ||
|
|
7bffa7801d | ||
|
|
4ba9085eeb | ||
|
|
c4a2fed112 | ||
|
|
df3bca099a | ||
|
|
53e2c58f0b | ||
|
|
d7a9816246 | ||
|
|
67d31fd62c | ||
|
|
afe778d03c | ||
|
|
7a2ae6b7d5 | ||
|
|
481c51b4c7 | ||
|
|
38239be472 | ||
|
|
31ca9a6cc8 | ||
|
|
49af3714e8 | ||
|
|
36216107ec | ||
|
|
02e2b278de | ||
|
|
9750f46c6d | ||
|
|
13c05fbdb1 | ||
|
|
6d90b0ce32 | ||
|
|
6b82e50c03 | ||
|
|
530cc56922 | ||
|
|
0a16d8f462 | ||
|
|
e3c382efa0 | ||
|
|
fb43cb738b | ||
|
|
6e026fcb66 | ||
|
|
187e7b1ca3 | ||
|
|
8aff1b4afe | ||
|
|
45546eee39 | ||
|
|
a35b086d12 | ||
|
|
3e23bcc73c | ||
|
|
35d5045db4 | ||
|
|
65b7919ebf | ||
|
|
4b9f998784 | ||
|
|
b07deba105 | ||
|
|
534bdaf30b | ||
|
|
87c4963533 | ||
|
|
978041a9a2 | ||
|
|
30445f1e97 | ||
|
|
693cef04df | ||
|
|
9d0a2d4f3e | ||
|
|
2cf61403e1 | ||
|
|
69b26bd637 | ||
|
|
cec69ee261 | ||
|
|
891f4ac4d7 | ||
|
|
af71a4eca7 | ||
|
|
dd0b9ecde4 | ||
|
|
6dec68128d | ||
|
|
ab61907a06 | ||
|
|
9c9994f129 | ||
|
|
97e6a99c5e | ||
|
|
d09450980a | ||
|
|
79c0023f75 | ||
|
|
3b23d68a10 | ||
|
|
fe48586eef | ||
|
|
848d8348ae | ||
|
|
da3bf12671 | ||
|
|
d447009779 | ||
|
|
2c2c92325d | ||
|
|
b451a9eae0 | ||
|
|
c42c18f5df | ||
|
|
8bb837eda8 | ||
|
|
6b6636b0bb | ||
|
|
316bb12946 | ||
|
|
cab0ba8b9a | ||
|
|
0a2fdfcd42 | ||
|
|
43217549eb | ||
|
|
0f3441ccf6 | ||
|
|
9c25f635eb | ||
|
|
3ec8ab868e | ||
|
|
8d28bfe7a1 | ||
|
|
46f5d7a0cd | ||
|
|
8400079bce | ||
|
|
68c750810f | ||
|
|
0dee5618f2 | ||
|
|
76c6511e0c | ||
|
|
2f2a705127 | ||
|
|
b0faebd135 | ||
|
|
2bf2b222e0 | ||
|
|
c42cd0114f | ||
|
|
5cd0c8e41b | ||
|
|
8276dca22e | ||
|
|
d4e632f513 | ||
|
|
325de4abca | ||
|
|
e651770018 | ||
|
|
d1ffecb132 | ||
|
|
460e87cb43 | ||
|
|
a607ab380c | ||
|
|
a7a63483df | ||
|
|
9de57e1b23 | ||
|
|
f229f9a81e | ||
|
|
62260ab93b | ||
|
|
c108f6e4e6 | ||
|
|
5c8fdd2b6c | ||
|
|
34bf1f23f7 | ||
|
|
ae503523e4 | ||
|
|
e64e0ce27b | ||
|
|
93ed4f537e | ||
|
|
995abd4d00 | ||
|
|
0dcbe6ffbe | ||
|
|
745ebfb904 | ||
|
|
c5b9afaf83 | ||
|
|
f4ccba93e6 | ||
|
|
308cbcdc40 | ||
|
|
eb5598be7c | ||
|
|
830da2488b | ||
|
|
530ac79ba4 | ||
|
|
213b812520 | ||
|
|
8c2b56e286 | ||
|
|
147c1a4315 | ||
|
|
2fa4c2ade3 | ||
|
|
621af33a81 | ||
|
|
0d9fe13166 | ||
|
|
1a9cd63397 | ||
|
|
e2f96123a3 | ||
|
|
96fc1a3749 | ||
|
|
f2ed64293b | ||
|
|
bf807be7bd | ||
|
|
437911eacd | ||
|
|
2d89f1548d | ||
|
|
c8b3b8d2b8 | ||
|
|
7d7aae5929 | ||
|
|
fc950f643b | ||
|
|
4bfec7b358 | ||
|
|
3478c7b09a | ||
|
|
a326463160 | ||
|
|
ebad686987 | ||
|
|
3791fc0ee6 | ||
|
|
40a8354125 | ||
|
|
bb683c9f79 | ||
|
|
5edd5932ba | ||
|
|
021f596cf0 | ||
|
|
992d187b04 | ||
|
|
d6d2434482 | ||
|
|
811270760a | ||
|
|
38ee449921 | ||
|
|
9efd00956f | ||
|
|
b56be87315 | ||
|
|
c67f7ba2e8 | ||
|
|
aad0c511a8 | ||
|
|
8bdce8e7b8 | ||
|
|
64deb4fb39 | ||
|
|
8c74bada85 | ||
|
|
8a51050f0b | ||
|
|
4be9719195 | ||
|
|
fa4a074e2f | ||
|
|
be51d67575 | ||
|
|
695f191bb8 | ||
|
|
c304dc08c4 | ||
|
|
87207a8091 | ||
|
|
88c122ffcb | ||
|
|
c05f93a16f | ||
|
|
93a46366a0 | ||
|
|
179e0722f5 | ||
|
|
d640eebb99 | ||
|
|
184328ea95 | ||
|
|
eb0b7c9091 | ||
|
|
2587dd6cb0 | ||
|
|
fb97b2b8f0 | ||
|
|
7382cc65de | ||
|
|
1ca4f8166b | ||
|
|
65607b0eb5 | ||
|
|
a4c67e5acd | ||
|
|
ccbeca269a | ||
|
|
ab972565d6 | ||
|
|
c3a81f76d5 | ||
|
|
8bf3b1af45 | ||
|
|
ae135bb035 | ||
|
|
bcd8cc58f7 | ||
|
|
8415f41722 | ||
|
|
3d832cc48e | ||
|
|
3b126ca02b | ||
|
|
0ba05f9d1a | ||
|
|
3a38d36a60 | ||
|
|
d55a03ca0c | ||
|
|
c4609fedd6 | ||
|
|
23a5cfb0c4 | ||
|
|
69440fbc75 | ||
|
|
64fac4f255 | ||
|
|
9ee90755d1 | ||
|
|
a1636896aa | ||
|
|
e7435d3974 | ||
|
|
3ad96422b9 | ||
|
|
1bc9bd1504 | ||
|
|
8fcfd57125 | ||
|
|
ff74f3103c | ||
|
|
addf0b3d98 | ||
|
|
ad5e0614d4 | ||
|
|
1ba203d742 | ||
|
|
74cca6a483 | ||
|
|
977231cf46 | ||
|
|
b532753a16 | ||
|
|
e0b9e38587 | ||
|
|
9d4bdce7a9 | ||
|
|
e00d6aaa7e | ||
|
|
9bda470f9d | ||
|
|
8b2f6a7fb2 | ||
|
|
57be666de1 | ||
|
|
050214a5dc | ||
|
|
8bd3313010 | ||
|
|
4d8658ca54 | ||
|
|
b6fdba0077 | ||
|
|
83ced826d0 | ||
|
|
d820b0d19d | ||
|
|
7135473d19 | ||
|
|
a7a4105cf8 | ||
|
|
2b6a079980 | ||
|
|
07be8e244c | ||
|
|
9d2a60ef43 | ||
|
|
88fc1e7a87 | ||
|
|
b063687621 | ||
|
|
039b41cb76 | ||
|
|
49f451ecd1 | ||
|
|
10c5013305 | ||
|
|
5b2934e102 | ||
|
|
74c85085fb | ||
|
|
e7e66808a4 | ||
|
|
2beebd6df3 | ||
|
|
0e967b4d30 | ||
|
|
f5b0603799 | ||
|
|
443974335a | ||
|
|
2c2df752d0 | ||
|
|
3a02bd0a3f | ||
|
|
d0d4379b1b | ||
|
|
fb7dbed58a | ||
|
|
d2f0cd0686 | ||
|
|
2d6fcfb74a | ||
|
|
424e31bdd6 | ||
|
|
5d8f3e6741 | ||
|
|
5d0ba22ac4 | ||
|
|
8a44b29d92 | ||
|
|
1b47623484 | ||
|
|
282cd0913c | ||
|
|
aed5ccdfca | ||
|
|
8e6ddfd764 | ||
|
|
1c2bfd42ca | ||
|
|
b9db3ea1d3 | ||
|
|
52b0ee7ceb | ||
|
|
3ef85aae38 | ||
|
|
3bb310dd6b | ||
|
|
a918229d4b | ||
|
|
95a9d18b6b | ||
|
|
7371b95ebc | ||
|
|
416edc34f7 | ||
|
|
2dff95700f | ||
|
|
46b52ad26e | ||
|
|
22e7c1d7c4 | ||
|
|
dd2ed5daa4 | ||
|
|
c25d4738b4 | ||
|
|
3d4f509a62 | ||
|
|
c9e955903e | ||
|
|
201ea885a1 | ||
|
|
356ea2a68a | ||
|
|
559c963d63 | ||
|
|
4bf5876adf | ||
|
|
b2788fad63 | ||
|
|
c249ff608c | ||
|
|
bd55307b47 | ||
|
|
6b17dc78e5 | ||
|
|
5fe4ab0de8 | ||
|
|
4ee89662f2 | ||
|
|
86e3f138f8 | ||
|
|
cd2b9aab98 | ||
|
|
f05840b9e9 | ||
|
|
8c2abf9249 | ||
|
|
64d35b4903 | ||
|
|
10421fe945 | ||
|
|
7c8aefccfe | ||
|
|
60404296fb | ||
|
|
dbc3ab4c32 | ||
|
|
f83521f778 | ||
|
|
6fb8cbfc86 | ||
|
|
0acf388277 | ||
|
|
4c4a5f6c03 | ||
|
|
fbef2e765d | ||
|
|
ea927caa4b | ||
|
|
60f9116af1 | ||
|
|
75c6bb46dc | ||
|
|
0a2f3b477b | ||
|
|
e73ea43f7b | ||
|
|
17933765d3 | ||
|
|
ed175e0ad6 | ||
|
|
c5404a6111 | ||
|
|
6d7e06535a | ||
|
|
853e1ce647 | ||
|
|
dbcdda9d36 | ||
|
|
17ceba6064 | ||
|
|
52078cc567 | ||
|
|
e2656739f1 | ||
|
|
33091ccbae | ||
|
|
ca6b603478 | ||
|
|
069ae82b10 | ||
|
|
ea6638c163 | ||
|
|
112a357726 | ||
|
|
0e54579200 | ||
|
|
ccb8ffd1b5 | ||
|
|
b83c1a2a96 | ||
|
|
81a947e3b3 | ||
|
|
1cec0f106d | ||
|
|
0acb0fee3e | ||
|
|
9b57585b62 | ||
|
|
2ddec368c3 | ||
|
|
83dc8819b6 | ||
|
|
5e668e6e83 | ||
|
|
ca4912ded4 | ||
|
|
295ebb679c | ||
|
|
6355aff3cd | ||
|
|
a6655191d4 | ||
|
|
dc6c37777b | ||
|
|
23552ea105 | ||
|
|
9962381fc7 | ||
|
|
93ab8d3b91 | ||
|
|
5345b29f8c | ||
|
|
de06fee5ab | ||
|
|
6d329424f1 | ||
|
|
dfbbea33d5 | ||
|
|
0b02af616a | ||
|
|
a101ec9796 | ||
|
|
b0868b5d60 | ||
|
|
f57b8c189c | ||
|
|
a507355e27 | ||
|
|
87fdd62b57 | ||
|
|
3337335df2 | ||
|
|
08113b8f5f | ||
|
|
6dd949611d | ||
|
|
b6a55935b4 | ||
|
|
01b2a9c7b2 | ||
|
|
58e2c93e30 | ||
|
|
bcfe26175a | ||
|
|
c4e6a7c0d6 | ||
|
|
9cbac6b044 | ||
|
|
2414edd1e7 | ||
|
|
74ef177e25 | ||
|
|
54d012b92e | ||
|
|
1b4efc1520 | ||
|
|
96ecd054ab | ||
|
|
d7d2dec5cb | ||
|
|
20f3911e12 | ||
|
|
f8d71687e1 | ||
|
|
d393c1fbfc | ||
|
|
e21e34e194 | ||
|
|
a01fff411e | ||
|
|
7d4222fb17 | ||
|
|
de0ec914cc | ||
|
|
15f2896811 | ||
|
|
b26f353e46 | ||
|
|
5f2c923c48 | ||
|
|
4ca21bdad7 | ||
|
|
2cc0ceb1aa | ||
|
|
7063e60af9 | ||
|
|
21b80a7370 | ||
|
|
fb8fb92ee6 | ||
|
|
2a5b64526f | ||
|
|
02d3a14083 | ||
|
|
3b349471ea | ||
|
|
f385e4e975 | ||
|
|
acff8f1e1f | ||
|
|
59090e62d2 | ||
|
|
74594a3b20 | ||
|
|
681bdc727f | ||
|
|
996e0f139e | ||
|
|
c2353314fa | ||
|
|
5d315c5b6d | ||
|
|
87ac5acdd8 | ||
|
|
3b4dc10211 | ||
|
|
8c1d71c7b7 | ||
|
|
5db196a630 | ||
|
|
ec8374be60 | ||
|
|
eeb62add59 | ||
|
|
908fcb56e8 | ||
|
|
ddf47365c1 | ||
|
|
b052aa1d88 | ||
|
|
cacf75995d | ||
|
|
4960077495 | ||
|
|
8147a2bfb7 | ||
|
|
28c8d393d6 | ||
|
|
ec7e718e38 | ||
|
|
62740e8e64 | ||
|
|
2bb699dc97 | ||
|
|
14b1a4988b | ||
|
|
7f6e4446b4 | ||
|
|
cf19c8758d | ||
|
|
5197e7f5f1 | ||
|
|
eb87b82c17 | ||
|
|
5064a9255b | ||
|
|
bf604339f0 | ||
|
|
7e85058ef1 | ||
|
|
ec05a49cce | ||
|
|
b0eefe15f9 | ||
|
|
0f2bc45059 | ||
|
|
f8134be8b7 | ||
|
|
8afbe14c82 | ||
|
|
fdfb8b0dea | ||
|
|
9be4f0ca37 | ||
|
|
66ff604580 | ||
|
|
7e0e85db65 | ||
|
|
ed39eb36f5 | ||
|
|
7da8de6ea7 | ||
|
|
d1b64ec48e | ||
|
|
69968cbc5c | ||
|
|
9e20c0241f | ||
|
|
97f049580b | ||
|
|
6f04329fbe | ||
|
|
077b54bbed | ||
|
|
759e92706f | ||
|
|
2ea952d6ab | ||
|
|
91bdcca577 | ||
|
|
75bd445bd3 | ||
|
|
9812ad441f | ||
|
|
3fd1b3d37d | ||
|
|
923f51ae15 | ||
|
|
804ea411fc | ||
|
|
9bcfd07896 | ||
|
|
58c8eccc46 | ||
|
|
a674640ef2 | ||
|
|
dde890b24b | ||
|
|
38ccb4413b | ||
|
|
9631734805 | ||
|
|
7faf514496 | ||
|
|
08091fc7c2 | ||
|
|
1450c8cf26 | ||
|
|
b533775cb4 | ||
|
|
3f4c48ad9f | ||
|
|
30d6a4f2e0 | ||
|
|
f4522acd44 | ||
|
|
1fbef641da | ||
|
|
fee938b46d | ||
|
|
ae1e1c2ce2 | ||
|
|
20054e6c73 | ||
|
|
f7f5a9bc9a | ||
|
|
f2a5f73337 | ||
|
|
97049140af | ||
|
|
dfc0498b70 | ||
|
|
1cec099c0e | ||
|
|
3989566608 | ||
|
|
b32586e739 | ||
|
|
82ef41dd92 | ||
|
|
b0dc376494 | ||
|
|
8be0c4c23c | ||
|
|
d7dd1e131f | ||
|
|
584fe81f04 | ||
|
|
16a99ef35b | ||
|
|
247273e086 | ||
|
|
0f27b04a92 | ||
|
|
a8edc2af74 | ||
|
|
f5ecaa3faa | ||
|
|
b5f9f5095e | ||
|
|
02a53da361 | ||
|
|
f86f727810 | ||
|
|
836dbd8955 | ||
|
|
a24e0d5a4b | ||
|
|
c6dc18d215 | ||
|
|
931a86eff9 | ||
|
|
2a1a28c3fb | ||
|
|
3f060de381 | ||
|
|
0945e0b29e | ||
|
|
5ee0ebb264 | ||
|
|
0dc762f15d | ||
|
|
c7c56a610c | ||
|
|
a826d92666 | ||
|
|
5b2e117347 | ||
|
|
e712550cb8 | ||
|
|
044d0a5a31 | ||
|
|
9d0e84f1fa | ||
|
|
02265061cc | ||
|
|
a13d7d0cb1 | ||
|
|
7a86012292 | ||
|
|
c933faaf5e | ||
|
|
a7e0c094fb | ||
|
|
592a15ebe4 | ||
|
|
75b32c75bc | ||
|
|
765285c6ee | ||
|
|
356fe00aad | ||
|
|
647ba1f46e | ||
|
|
53fe80d8a7 | ||
|
|
742276c251 | ||
|
|
6d1e96866e | ||
|
|
dbe67c8cae | ||
|
|
dd9c0b3fd5 | ||
|
|
9bdee61e5b | ||
|
|
e2426b493e | ||
|
|
acff776d56 | ||
|
|
4036e7daa2 | ||
|
|
93b5b86c5d | ||
|
|
de82dc2322 | ||
|
|
6696c1b284 | ||
|
|
e6e3e8453b | ||
|
|
4576d8746c | ||
|
|
b42c868a66 | ||
|
|
a18cd3e0de | ||
|
|
88faee9b26 | ||
|
|
16a29fab3e | ||
|
|
cd6bc16d48 | ||
|
|
443803caf0 | ||
|
|
75a4bbfed6 | ||
|
|
b74a353c17 | ||
|
|
492fd611f9 | ||
|
|
a938d2ecfd | ||
|
|
8276e7d086 | ||
|
|
ffdfb160c4 | ||
|
|
bf6c086b3d | ||
|
|
08b4c92dac | ||
|
|
2a0b248518 | ||
|
|
60323ded9b | ||
|
|
f3ea99e0b0 | ||
|
|
7e080cf1ab | ||
|
|
688be1e1da | ||
|
|
28e5df3abc | ||
|
|
d0048e3aef |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build/**
|
||||
include/tins/config.h
|
||||
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "googletest"]
|
||||
path = googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
ignore = dirty
|
||||
27
.travis.yml
Normal file
27
.travis.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libpcap-dev
|
||||
- libssl-dev
|
||||
- libboost-all-dev
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DLIBTINS_ENABLE_CXX11=1
|
||||
- make tests
|
||||
|
||||
script:
|
||||
- ctest -V
|
||||
2
AUTHORS
2
AUTHORS
@@ -1,2 +0,0 @@
|
||||
Matias Fontanini - mfontanini@nasel.com.ar
|
||||
Santiago Alessandri - salessandri@nasel.com.ar
|
||||
763
CHANGES.md
Normal file
763
CHANGES.md
Normal file
@@ -0,0 +1,763 @@
|
||||
##### v4.3 - Fri Sep 18 03:08:33 UTC 2020
|
||||
|
||||
- Assign a PDUType to `Dot11ControlTA` (#420)
|
||||
|
||||
- Don't consider IPv6 ESP header a normal extension header (#374)
|
||||
|
||||
- Don't include non-existing headers when installed without libpcap (#382)
|
||||
|
||||
- Add `IPv6Address::is_local_unicast` (#369)
|
||||
|
||||
- Fix memory leak in `PacketWriter` (#343)
|
||||
|
||||
- Fix memory leaks in `OfflinePacketFilter` (#343)
|
||||
|
||||
- Fix detection of new TCP stream (#335)
|
||||
|
||||
- Introduce `TCP::has_flags` (#334)
|
||||
|
||||
- Fix padding calculations in RadioTapWriter (#333)
|
||||
|
||||
##### v4.2 - Fri Mar 8 04:15:13 UTC 2019
|
||||
|
||||
- Updated location of installed CMake files in unix systems (#331)
|
||||
|
||||
- Fix check to detect cross compilation (#330)
|
||||
|
||||
- Allow getting a PDU's advertised size and use it in `PacketWriter` (#324)
|
||||
|
||||
- Install DLLs in right directory (#326)
|
||||
|
||||
- Add missing Dot11 tagged option types (#305)
|
||||
|
||||
- Add support for DLT_RAW (#313)
|
||||
|
||||
- Fix potential invalid memory accesses when parsing RadioTap (#322)
|
||||
|
||||
##### v4.1 - Tue Dec 11 02:08:48 UTC 2018
|
||||
|
||||
- Fix serialization for QinQ (#316)
|
||||
|
||||
- Added base class access specifier for socket_close_error (#306)
|
||||
|
||||
- Rewrote hw_address_to_string to not require a stringstream (#299)
|
||||
|
||||
- Make RadioTapParser::skip_to_field check for end of buffer (#296)
|
||||
|
||||
- Ensure local include directory comes before system. (#293)
|
||||
|
||||
- Calculate IP option sizes properly (#288)
|
||||
|
||||
- Add parsing of well known IPv6 extension headers (#287)
|
||||
|
||||
- Add missing operators to address classes (#275)
|
||||
|
||||
- Add version macros in config.h
|
||||
|
||||
- Don't assume IPv6 uses ICMPv6 underneath
|
||||
|
||||
- Allow users to specify library install dir
|
||||
|
||||
- Use Sleep windows function passing milliseconds as parameter
|
||||
|
||||
- Implement IPv6::recv_response
|
||||
|
||||
- Don't use nullptr in non C++11 code
|
||||
|
||||
- Ignore (possibly malformed) options after EOL (#281)
|
||||
|
||||
- Don't include dot11.h in tins.h if it is not configured in the library (#277)
|
||||
|
||||
- Fix memory leak in PDU's move assignment operator
|
||||
|
||||
- Append padding to IPv6 options
|
||||
|
||||
##### v4.0 - Mon Dec 4 00:04:30 UTC 2017
|
||||
|
||||
- Add parent PDU to each PDU.
|
||||
|
||||
- Removed parent PDU parameter on `PDU::write_serialization`.
|
||||
|
||||
- Split `utils.h` into multiple files under the `utils` directory.
|
||||
|
||||
- Split `internals.h` into multiple files under the `detail` directory.
|
||||
|
||||
- Improve compilation times by removing useless include directives.
|
||||
|
||||
- Refactor `PDUOption` conversions so that heavy headers are not included in source file.
|
||||
|
||||
- Use `std::vector` instead of `std::list` in `TCP`, `IP`, `IPv6`, `DHCP`, `DHCPv6`, `DNS`, `LLC`, `Dot11` and `PPPoE`.
|
||||
|
||||
- Improve performance on `IP`, `IPv6` and `TCP` by compiting option sizes during serialization.
|
||||
|
||||
- Minor performance improvements in `DNS`.
|
||||
|
||||
- Fix `IPv6` next header handling. Now each one contains its own type and the next type is only set during serialization for ease of use.
|
||||
|
||||
- Refactor `RadioTap` parsing and serialization using a generic parser/writer.
|
||||
|
||||
- Add `BaseSniffer::set_pcap_sniffing_method` to specify whether `pcap_loop` or `pcap_dispatch` should be used when sniffing.
|
||||
|
||||
- Use `IFF_POINTOPOINT` on BSD when getting broadcast address for an interface.
|
||||
|
||||
- Added cipher and akm suites from 802.11-2016.
|
||||
|
||||
- Add IPv6 layer parsing on `Loopback` packets.
|
||||
|
||||
- Allow serializing `Loopback` on Windows.
|
||||
|
||||
- Use the right flag on `Loopback` for `IPv6`.
|
||||
|
||||
- Use the first fragment as a base when reassembling `IP` packets in `IPv4Reassembler`.
|
||||
|
||||
- Restructure CMake files removing useless `CMakeLists.txt` in `include` paths.
|
||||
|
||||
- Add getter/setter for "more data" field in `Dot11Base`.
|
||||
|
||||
- Implemented matching for ND protocol related ICMPv6 messages.
|
||||
|
||||
- Ensure TCP::OptionTypes has 8-bit range.
|
||||
|
||||
- Add header files into CMake sources so IDE can pick them up.
|
||||
|
||||
- Add MPLS "experimental" field.
|
||||
|
||||
- Fix dhcpv6::duid_type constructor from duid_ll.
|
||||
|
||||
##### v3.5 - Sat Apr 1 09:11:58 PDT 2017
|
||||
|
||||
- Added Utils::route6_entries
|
||||
|
||||
- Allow masking IPv4/6 and hardware addresses via `operator&`
|
||||
|
||||
- Add IPv4Address::from_prefix_length
|
||||
|
||||
- Move `stream_id` into a new file and rename it `StreamIdentifier`
|
||||
|
||||
- Allow disabling TCPIP classes
|
||||
|
||||
- Properly handle out of order SACKs on `AckTracker`
|
||||
|
||||
- Move TCP data tracking into a separate class
|
||||
|
||||
- Allow constructing `StreamIdentifier` from a `Stream`
|
||||
|
||||
- Allow configuring pcap timestamp precision
|
||||
|
||||
- Allow building libtins using MinGW
|
||||
|
||||
- Allow including libtins using `add_subdirectory` via CMake
|
||||
|
||||
- Allow setting customer user data to each TCP stream
|
||||
|
||||
- Allow skipping data forward in TCP streams
|
||||
|
||||
- Allow attaching to already existing TCP streams
|
||||
|
||||
- Fix: AddressRange masks first address as well
|
||||
|
||||
- Fix: Add TINS_API to `IPv4Address::operator<<`, `DataTracker` and `AckTracker`
|
||||
|
||||
- Fix: Don't always set `key_t` to 0 on `RSNEAPOL`
|
||||
|
||||
- Fix: Handle MLDv1 properly on ICMP
|
||||
|
||||
- Fix: Make Utils::resolve_hwaddress work on Windows
|
||||
|
||||
- Fix: Interface was sometimes considered down when it was up (BSD/Linux)
|
||||
|
||||
- Fix: Don't set `Dot1Q`'s payload type if next protocol type is unknown
|
||||
|
||||
- Fix: Use recvfrom on BSD/OSX when capturing layer 3 packets
|
||||
|
||||
- Fix: Make `Timestamp::current_time` work on Windows
|
||||
|
||||
- Fix: Forward `NetworkInterface` argument when calling `PacketSender::send_l2`
|
||||
|
||||
- Fix: `Timestamp` overflow issue
|
||||
|
||||
- Fix: boost's include directories variable incorrectly used on build system
|
||||
|
||||
- Fix: Configuring auto cleanup of `Stream`'s server data not working
|
||||
|
||||
- Fix: Set `EthernetII` payload type to `UNKNOWN` if there's no inner PDU
|
||||
|
||||
- Fix: Set payload type to 0 if there's no inner PDU in `IP`, `Dot1Q` and `IPv6`
|
||||
|
||||
- Fix: Buffer length check issues on `Dot11QosData`
|
||||
|
||||
- Fix: Use AF_INET6 flag when opening L3 IPv6 socket
|
||||
|
||||
- Fix: Check expecter size properly on `DNS::extract_metadata`
|
||||
|
||||
- Fix: several unused parameter warnings
|
||||
|
||||
- Fix: CCMP decryption issue when `Dot11QoSData` has a TID != 0
|
||||
|
||||
##### v3.4 - Wed Mar 9 20:24:54 PST 2016
|
||||
|
||||
- Check the secure bit on HandshakeCapturer to detect 2nd packet
|
||||
|
||||
- Add info members directly into NetworkInterface
|
||||
|
||||
- Add IPv6 addresses to NetworkInterface::Info
|
||||
|
||||
- Make *MemoryStream use size_t rather than uint32_t
|
||||
|
||||
- Add WPA2Decrypter callback interface
|
||||
|
||||
- Set MACOSX_RPATH to ON
|
||||
|
||||
- Don't fail configuration if openssl is missing
|
||||
|
||||
- Build layer 5 as RawPDU if IPv6 has fragment header
|
||||
|
||||
- Fix examples so they build on gcc 4.6
|
||||
|
||||
- Fix flag value for sniffer's immediate mode
|
||||
|
||||
- Fix IP fragment reassemble when packet has flags DF+MF
|
||||
|
||||
- Add extract_metadata to main PDU classes
|
||||
|
||||
- Fix examples to make them work on Windows
|
||||
|
||||
- Use timercmp/sub and std::chrono to subtract timevals on PacketSender
|
||||
|
||||
- Build examples against local libtins build
|
||||
|
||||
- Add uninstall target
|
||||
|
||||
- Prefix HAVE_ config.h macros with TINS_
|
||||
|
||||
- Use compiler intrinsics to swap bytes
|
||||
|
||||
- Use C++11 mode by default
|
||||
|
||||
- Add missing TINS_API to PDU classes.
|
||||
|
||||
- Extend/fix ICMPv6 enum values and unify naming
|
||||
|
||||
- Return an empty string for dot11 ssid, if ssid is present but empty
|
||||
|
||||
- Implement new TCP stream follower mechanism
|
||||
|
||||
- Use ExternalProject_Add rather than including the gtest directory
|
||||
|
||||
- Fix invalid endian on IP fragment offset on OSX
|
||||
|
||||
##### v3.3 - Sun Jan 31 21:06:04 PST 2016
|
||||
|
||||
- Add TCP connection close example
|
||||
|
||||
- Move implementations on utils.h to utils.cpp
|
||||
|
||||
- Add ICMPv6 Multicast Listener Query Messages support
|
||||
|
||||
- Add ICMPv6 Multicast Listener Report Message support
|
||||
|
||||
- Make DNS::Query and DNS::Resource lowercase and deprecate the old names
|
||||
|
||||
- Change DNS::query/resource::type to query_type and deprecate old name
|
||||
|
||||
- Add DNS Start Of Authority parsing and serialization
|
||||
|
||||
- Parse and serialize MX preference field correctly
|
||||
|
||||
- Add NetworkInterface::friendly_name to get Windows friendly names
|
||||
|
||||
- Mask 16 bits on random number generated on traceroute example
|
||||
|
||||
- Fix TCP sequence number addition/subtraction when wrapping around
|
||||
|
||||
- Use 802.1ad protocol flag when seralizing stacked Dot1Q
|
||||
|
||||
- Code cleanup and use same syntax on the entire project
|
||||
|
||||
- Correctly serialize PPPoE session packets
|
||||
|
||||
- Fix IPv6 extension headers parsing/serialization
|
||||
|
||||
- Include examples before src to avoid duplicate tins target issue
|
||||
|
||||
- Add MPLS PDU and hook it up with ICMP extensions
|
||||
|
||||
- Set UDP checksum to 0xffff if it's 0
|
||||
|
||||
- Don't define TINS_STATIC in config.h
|
||||
|
||||
- Fix invalid RSNEAPOL parsing issue
|
||||
|
||||
- Remove special clang on OSX case when building gtest
|
||||
|
||||
- Update pseudoheader_checksum signature
|
||||
|
||||
- Fix overall checksum calculation
|
||||
|
||||
- Set ICMP payload length without padding if no extensions are present
|
||||
|
||||
- Export classes on Windows shared lib builds
|
||||
|
||||
- Use google/googletest submodule and update to HEAD
|
||||
|
||||
- Remove unused cassert header inclusions
|
||||
|
||||
- Add input/output memory stream classes port PDU classes to use them
|
||||
|
||||
- Add extensions for ICMP/ICMPv6
|
||||
|
||||
- Fix RSNInformation issues on big endian architectures
|
||||
|
||||
- Add IP::fragment_offset and IP::flags
|
||||
|
||||
- Don't set Ethernet type if inner PDU type is unknown
|
||||
|
||||
- Don't run IP source address overwrite tests on OSX
|
||||
|
||||
- Always calculate IP/IPv6 checksum
|
||||
|
||||
- Fix invalid constant value on PPPoE
|
||||
|
||||
- Define default constructor for PKTAP
|
||||
|
||||
- Guard 802.11 parsing code on PPI around HAVE_DOT11
|
||||
|
||||
- Fix parsing of Dot11 packets encapsulated on PPI having FCS-at-end
|
||||
|
||||
- Fix DataLinkType typo on doxygen docs
|
||||
|
||||
- Update docs on sniff_loop handle persistency
|
||||
|
||||
- Use uint32_t for DNS resource TTL setter
|
||||
|
||||
- Erase streams when they're reassembed on IPv4Reassembler
|
||||
|
||||
- Make all exceptions derive from exception_base
|
||||
|
||||
- Add remove_option member to IP, TCP, Dot11, ICMPv6, DHCP and DHCPv6
|
||||
|
||||
- Allow HW addresses to be 00:00:00:00:00 on NetworkInterface::info
|
||||
|
||||
- Increment option size when adding a new DHCPv6 option
|
||||
|
||||
- Use NOMINMAX on examples
|
||||
|
||||
- Add metric field to RouteEntry
|
||||
|
||||
- Allow setting immediate mode on Sniffer
|
||||
|
||||
- Use one flags field for all flags on SnifferConfiguration
|
||||
|
||||
- Add ICMP responses example
|
||||
|
||||
- Add interfaces_info example
|
||||
|
||||
- Fix bug on SessionKeys::SessionKeys
|
||||
|
||||
- Fix compilation errors on android platform
|
||||
|
||||
- Fix example compilation on Windows
|
||||
|
||||
- Add PacketWriter::write overload that takes a Packet
|
||||
|
||||
- Use different IP addresses on IP tests depending on OS
|
||||
|
||||
- Allow retrieving keys on WPA2Decrypter
|
||||
|
||||
- Add NetworkInterface::is_up and NetworkInterface::info
|
||||
|
||||
- Add NetworkInterface::Info::is_up
|
||||
|
||||
- Fix compilation warnings on Windows x64
|
||||
|
||||
- Fix FindPCAP.cmake to find winpcap on x64
|
||||
|
||||
- Fix more tests warnings triggered on Windows
|
||||
|
||||
- Fix tests compilation warnings on Windows
|
||||
|
||||
- Fix error on VC triggered by pcap redefining the "inline" keyword
|
||||
|
||||
- Soften DNS parsing rules
|
||||
|
||||
- Replace WIN32 macro with _WIN32
|
||||
|
||||
- Fix IPv6Address::to_string on Windows
|
||||
|
||||
- Fix DNS issues triggered on VC
|
||||
|
||||
- Add google test as git submodule
|
||||
|
||||
- Perserve IP protocol when using RawPDU
|
||||
|
||||
- Use pcap_sendpacket by default to send packets on Windows
|
||||
|
||||
- Don't allow receiving l2 packets on windows
|
||||
|
||||
- Added RadioTap channel map type
|
||||
|
||||
- Made rsn_information() a const member function to make Dot11ManagementFrame
|
||||
immutable
|
||||
|
||||
- Ensure HAVE_CXX11 is checked when defining TINS_IS_CXX11
|
||||
|
||||
- Use one integer field for all flags on TCP
|
||||
|
||||
- Fix invalid DNS IPv4 address parsing on big endian arch
|
||||
|
||||
- Don't compile WPA2 test if LIBTINS_ENABLE_WPA2=0
|
||||
|
||||
- Add Dot11 radio measurement name corresponding to IEEE 802.11-2012
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.2 - Fri Mar 20 22:12:23 PST 2015
|
||||
|
||||
- Added include guard for config.h.
|
||||
|
||||
- The functor used on BaseSniffer::sniff_loop can now take a Packet.
|
||||
|
||||
- Added mcs, tx_flags, ext and data_retries options to RadioTap.
|
||||
|
||||
- Fixed big endian representation of RadioTap header.
|
||||
|
||||
- RadioTap's dbm_signal and dbm_noise are now signed.
|
||||
|
||||
- RadioTap now throws if an option is not present when getting
|
||||
its value.
|
||||
|
||||
- TKIP decryption now works correctly on packets from AP to STA.
|
||||
|
||||
- Added support for PKTAP header.
|
||||
|
||||
- Fixed endian issue on IPv4Address::ip_to_int on Windows.
|
||||
|
||||
- Fixed IP parsing when total length is 0 due to TCP segmentation offload.
|
||||
|
||||
- Re-added support for pkg-config.
|
||||
|
||||
- TCPStreamFollower now calls PDU::find_pdu instead of PDU::rfind_pdu.
|
||||
|
||||
- Fixed assertion throw caused by DNS parsing on Windows on debug mode.
|
||||
|
||||
- Added throw on BSD when trying to send_recv L3 packets.
|
||||
|
||||
- Added Loopback::matches_response.
|
||||
|
||||
- Removed obsolete autotools files.
|
||||
|
||||
- Fixed exception thrown when an interface didn't have an IP address
|
||||
on NetworkInterface.
|
||||
|
||||
- Added NetworkInterface::is_loopback.
|
||||
|
||||
- Moved all headers to the directory include/tins.
|
||||
|
||||
- Fixed compilation warning on TCPStramFollower due to signed to unsigned
|
||||
conversion on integral constant.
|
||||
|
||||
- BaseSniffer::get_pcap_handle is now public.
|
||||
|
||||
- PPPoE session packets are now parsed correctly.
|
||||
|
||||
- Fixed invalid Loopback protocol detection on FreeBSD/OSX.
|
||||
|
||||
- Fixed OSX IP packet sending issue.
|
||||
|
||||
- Added useful constructors to RawPDU.
|
||||
|
||||
- Fixed compilation errors on FreeBSD.
|
||||
|
||||
- Improved documentation on several classes.
|
||||
|
||||
- Fixed parsing bug when allocating IP over IP packets.
|
||||
|
||||
- Fixed Windows network interface naming.
|
||||
|
||||
- Utils::network_interface returns pcap compatible names on Windows.
|
||||
|
||||
- NetworkInterface::name now works on Windows.
|
||||
|
||||
- Added documentation generation through the build system.
|
||||
|
||||
- Added SnifferConfiguration class.
|
||||
|
||||
- Fixed bug on Dot3 serialization.
|
||||
|
||||
- Added OfflinePacketFilter class.
|
||||
|
||||
- Renamed NOEXCEPT macro to TINS_NOEXCEPT.
|
||||
|
||||
- Added DataLinkType class.
|
||||
|
||||
- IPv4Address now uses inet_pton when constructing from string.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.1 - Sun Aug 24 21:39:43 ART 2014
|
||||
|
||||
- Fixed ICMPv6 checksum error on serialization.
|
||||
|
||||
- Fixed empty domain name encoding on DNS.
|
||||
|
||||
- Changed the build system to CMake.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.0 - Thu Aug 7 21:39:09 ART 2014
|
||||
|
||||
- Timestamps can now be constructed from std::chrono::duration.
|
||||
|
||||
- Packets can now be constructed from a PDU pointer and take ownership
|
||||
of it.
|
||||
|
||||
- All protocols now set the next layer protocol flag, regardless if
|
||||
it was already set. This was not done in some protocols,
|
||||
like EthernetII, and as a consequence if the network layer protocol
|
||||
was replaced by other, the packet would be serialized incorrectly.
|
||||
|
||||
- Fixed invalid parsing of some unknown DNS records.
|
||||
|
||||
- Fixed unaligned memory accesses that were not supported under
|
||||
ARMv4 and ARMv5.
|
||||
|
||||
- Added BaseSniffer::set_extract_raw_pdus.
|
||||
|
||||
- Reduced minimum automake version to 1.11.
|
||||
|
||||
- Added Utils::to_string(PDU::PDUType).
|
||||
|
||||
- Fixed error compilations on Windows.
|
||||
|
||||
- Fixed ICMPv6 checksum calculation.
|
||||
|
||||
- Added method in IP and TCP to emplace an option (C++11 only).
|
||||
|
||||
- Added small option optimization to PDUOption.
|
||||
|
||||
- Fixed error compilation on RSNInformation.
|
||||
|
||||
- Renamed ICMP::check to ICMP::checksum.
|
||||
|
||||
- Added Sniffer support to set interface to promiscuous mode.
|
||||
|
||||
- TCPStreamFollower now handles overlapping fragments correctly.
|
||||
|
||||
- Fixed bugs in TCPStreamFollower which didn't allow it to follow
|
||||
stream correctly.
|
||||
|
||||
- TCPStreamFollower now doesn't clear its state after every call to
|
||||
TCPStreamFollower::follow_streams.
|
||||
|
||||
- Added IPv6 flag check to pdu_flag_to_ip_type.
|
||||
|
||||
- Added DHCP::hostname to extract the hostname options.
|
||||
|
||||
- Removed extra qualifier on SessionKeys::decrypt_unicast which
|
||||
produced compilation errors on some platforms.
|
||||
|
||||
- PacketSender::send now uses PDU::matches_flag to match specific
|
||||
PDU types.
|
||||
|
||||
- Removed 'no newline at end of file' warnings.
|
||||
|
||||
- Fixed bug when calling BIOCIMMEDIATE on *BSD.
|
||||
|
||||
- Fixed bug on PacketSender::send_recv which didn't work under *BSD.
|
||||
|
||||
- Fixed bug triggered by not including the string header.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v2.0 - Thu Jan 23 11:09:38 ART 2014
|
||||
|
||||
- DNSResourceRecord was removed. Now DNS records are added using
|
||||
DNS::Resource.
|
||||
|
||||
- tins.h now includes ppi.h.
|
||||
|
||||
- Done significant improvements in the speed of DNS parsing.
|
||||
|
||||
- Added PDUOption<>::to<> which converts a PDUOption to a specific type.
|
||||
|
||||
- Layer 3 packets sent using PacketSender::send_recv for which the
|
||||
answer is a different PDU type.
|
||||
|
||||
- ICMP::gateway now uses IPv4Address.
|
||||
|
||||
- Added support for ICMP address mask request/reply.
|
||||
|
||||
- Fixed bug in PacketSender when using send_recv and a layer 2 PDU. The
|
||||
interface in which the packet was sent was not the default_interface
|
||||
set when the sender was constructed.
|
||||
|
||||
- IP packets sent using PacketSender::send_recv now match ICMP
|
||||
responses.
|
||||
|
||||
- Added support for ICMP timestamp request/reply packets.
|
||||
ICMP::matches_response now works with these types of packets as well.
|
||||
|
||||
- Added support for reassembling of fragmented IP packets via the
|
||||
IPv4Reassembler class.
|
||||
|
||||
- Fragmented IP packet's inner_pdu PDUs are not decoded now.
|
||||
|
||||
- Added 1000ms as the default read timeout used when calling
|
||||
pcap_open_live. Added BaseSniffer::set_timeout to modify this parameter.
|
||||
|
||||
- Added the --disable-dot11 configure switch.
|
||||
|
||||
- Added support for IPSec.
|
||||
|
||||
- Fixed bug triggered when ifaddrs::ifa_addr was null in
|
||||
NetworkInterface::addresses.
|
||||
|
||||
- Added another overload of Utils::route_entries which returns the
|
||||
result either than storing it in a parameter.
|
||||
|
||||
- Added ARP monitor, WPS detector, DNS queries sniffer and DNS spoofer
|
||||
examples.
|
||||
|
||||
- Added another Sniffer constructor which doesn't expect the maximum
|
||||
capture size.
|
||||
|
||||
- Added tins_cast as a replacement for dynamic_cast on PDUs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v1.2 - Mon oct 7 23:33:49 ART 2013
|
||||
|
||||
- Added BaseSniffer::begin and BaseSniffer::end.
|
||||
|
||||
- BaseSniffer::next_packet uses pcap_loop instead of pcap_next, which
|
||||
doesn't work well on some linux distributions.
|
||||
|
||||
- Added PPI PDU class.
|
||||
|
||||
- Fixed a bug in EthernetII triggered when the size of the whole frame
|
||||
was lower than 60 bytes.
|
||||
|
||||
- Added AddressRange class and IPv4Address, IPv6Address and
|
||||
HWAddress<>::operator/.
|
||||
|
||||
- Added is_broadcast, is_multicast and is_unicast to IPv4, IPv6
|
||||
and HWAddress.
|
||||
|
||||
- Added is_private and is_loopback methods to IPv4 and IPv6 addresses.
|
||||
|
||||
- Done some optimizations on TCP's constructor from buffer.
|
||||
|
||||
- Added helper functions to Dot11Data to retrieve the source,
|
||||
destination and BSSID addresses.
|
||||
|
||||
- Fixed bugs in DNS triggered when parsing MX and unknown records.
|
||||
|
||||
- BaseSniffer::next_packet now iterates until a valid packet is found.
|
||||
|
||||
- TCP::get_flag is now const.
|
||||
|
||||
- The --disable-wpa2 now works as expected.
|
||||
|
||||
v1.1 - Wed Jun 5 09:03:37 ART 2013
|
||||
|
||||
- Implemented std::hash specialization for IPv4, IPv6 and HWAddress<>
|
||||
types.
|
||||
|
||||
- Added a RSNHandshakeCapturer class.
|
||||
|
||||
- Added WPA2Decrypter class.
|
||||
|
||||
- IEEE 802.11 frames are not parsed if the RadioTap FAILED_FCS flag
|
||||
is on.
|
||||
|
||||
- RadioTap now calculates its size everytime it's serialized.
|
||||
|
||||
- Splitted the dot11.h and dot11.cpp files into several files to
|
||||
speed up compilation times.
|
||||
|
||||
- Added HWAddress<>::is_broadcast and HWAddress::operator[].
|
||||
|
||||
- Fixed a bug triggered when parsing Dot11QoSData frames.
|
||||
|
||||
v1.0 - Tue Apr 23 20:40:57 ART 2013
|
||||
|
||||
- Link layer protocol PDUs now don't hold a NetworkInterface. This led
|
||||
to changes in their constructors.
|
||||
|
||||
- Removed the obsolete PDU* parameter taken by several classes'
|
||||
constructors.
|
||||
|
||||
- IP now sets the sender's address automatically when no link layer
|
||||
PDU is used.
|
||||
|
||||
- IP, TCP and UDP now calculate the checksum everytime they're
|
||||
serialized.
|
||||
|
||||
- Added PDU::rfind_pdu.
|
||||
|
||||
- Defined several exception types.
|
||||
|
||||
- Implemented matches_response on several protocols.
|
||||
|
||||
- PacketSender is now movable.
|
||||
|
||||
- Added an overload of add_option that takes an rvalue-reference in IP,
|
||||
TCP, DHCP, ICMPv6 and Dot11.
|
||||
|
||||
- Added support for GNU/kFreeBSD.
|
||||
|
||||
- Removed several deprecated methods, such as PDU::clone_packet.
|
||||
|
||||
- Added PacketSender::send(PDU&, NetworkInterface).
|
||||
|
||||
- Normalized the TLV options naming conventions in all of the classes
|
||||
that used them.
|
||||
|
||||
- Added support for Dot1Q, STP, PPPoE protocols.
|
||||
|
||||
- Made some important optimizations on PDUOption<>'s constructors.
|
||||
|
||||
- Added Utils::resolve_domain and Utils::resolve_domain6
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v0.3 - Thu Jan 31 16:47:27 ART 2013
|
||||
|
||||
- Added IPv6, ICMPv6 and DHCPv6 classes.
|
||||
|
||||
- Added support for Loopback interfaces and the Linux Crooked Capture
|
||||
pseudo protocol.
|
||||
|
||||
- Added support for IPv6 records in DNS.
|
||||
|
||||
- Added Packet/RefPacket class.
|
||||
|
||||
- Added support for FreeBSD, OSX and Windows.
|
||||
|
||||
- Added C++11 move semantics to several classes.
|
||||
|
||||
- Done a complete rewrite of the build system; it now uses libtool.
|
||||
|
||||
- Fixed several bugs in DNS.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v0.2 - Sat Oct 20 11:26:40 2012
|
||||
|
||||
- Added support for big endian architectures.
|
||||
|
||||
- Simplified several interfaces.
|
||||
|
||||
- Added IPv4Address and HWAddress class to simplify handling IP and hardware addresses.
|
||||
|
||||
- Added NetworkInterface class to abstract network interfaces.
|
||||
|
||||
- Added TCPStreamFollower class to follow TCP streams on the fly.
|
||||
|
||||
- Added WEPDecrypter class to decrypt WEP-encrypted 802.11 data frames on the fly.
|
||||
|
||||
- Added several new PDUs: Loopback, IEEE802_3, LLC, DNS.
|
||||
|
||||
- Added support for reading and writing pcap files.
|
||||
|
||||
- Moved to BSD-2 license.
|
||||
355
CMakeLists.txt
Normal file
355
CMakeLists.txt
Normal file
@@ -0,0 +1,355 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.1)
|
||||
PROJECT(libtins)
|
||||
|
||||
OPTION(LIBTINS_BUILD_EXAMPLES "Build examples" ON)
|
||||
OPTION(LIBTINS_BUILD_TESTS "Build tests" ON)
|
||||
|
||||
# Compile in release mode by default
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
MESSAGE(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
ELSE(NOT CMAKE_BUILD_TYPE)
|
||||
MESSAGE(STATUS "Using specified '${CMAKE_BUILD_TYPE}' build type.")
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Compilation flags.
|
||||
IF(MSVC)
|
||||
# Don't always use Wall, since VC's /Wall is ridiculously verbose.
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||
# Disable VC secure checks, since these are not really issues.
|
||||
ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS=1")
|
||||
ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS=1")
|
||||
ADD_DEFINITIONS("-DNOGDI=1")
|
||||
ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
ENDIF()
|
||||
|
||||
IF(APPLE)
|
||||
# This is set to ON as of policy CMP0042
|
||||
SET(CMAKE_MACOSX_RPATH ON)
|
||||
ENDIF()
|
||||
|
||||
# Build output checks
|
||||
OPTION(LIBTINS_BUILD_SHARED "Build libtins as a shared library." ON)
|
||||
IF(LIBTINS_BUILD_SHARED)
|
||||
MESSAGE(
|
||||
STATUS
|
||||
"Build will generate a shared library. "
|
||||
"Use LIBTINS_BUILD_SHARED=0 to perform a static build"
|
||||
)
|
||||
SET(LIBTINS_TYPE SHARED)
|
||||
ELSE(LIBTINS_BUILD_SHARED)
|
||||
MESSAGE(STATUS "Build will generate a static library.")
|
||||
SET(LIBTINS_TYPE STATIC)
|
||||
ADD_DEFINITIONS("-DTINS_STATIC=1")
|
||||
ENDIF(LIBTINS_BUILD_SHARED)
|
||||
|
||||
# The version number.
|
||||
SET(TINS_VERSION_MAJOR 4)
|
||||
SET(TINS_VERSION_MINOR 3)
|
||||
SET(TINS_VERSION_PATCH 0)
|
||||
SET(LIBTINS_VERSION "${TINS_VERSION_MAJOR}.${TINS_VERSION_MINOR}")
|
||||
|
||||
# Required Packages
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
# Allow disabling packet capture mechanism
|
||||
OPTION(LIBTINS_ENABLE_PCAP "Enable capturing packets via libpcap" ON)
|
||||
|
||||
# Look for libpcap
|
||||
IF(LIBTINS_ENABLE_PCAP)
|
||||
FIND_PACKAGE(PCAP REQUIRED)
|
||||
SET(TINS_HAVE_PCAP ON)
|
||||
ENDIF()
|
||||
|
||||
# Set some Windows specific flags
|
||||
IF(WIN32)
|
||||
# We need to link against these libs
|
||||
SET(LIBTINS_OS_LIBS Ws2_32.lib Iphlpapi.lib)
|
||||
|
||||
# Add the NOMINMAX macro to avoid Windows' min and max macros.
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
|
||||
# MinWG need some extra definitions to compile properly (WIN32 for PCAP and WIN32_WINNT version for ws2tcpip.h)
|
||||
IF(MINGW)
|
||||
ADD_DEFINITIONS(-DWIN32)
|
||||
MACRO(get_WIN32_WINNT version)
|
||||
IF (WIN32 AND CMAKE_SYSTEM_VERSION)
|
||||
SET(ver ${CMAKE_SYSTEM_VERSION})
|
||||
STRING(REPLACE "." "" ver ${ver})
|
||||
STRING(REGEX REPLACE "([0-9])" "0\\1" ver ${ver})
|
||||
SET(${version} "0x${ver}")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
get_WIN32_WINNT(ver)
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=${ver})
|
||||
ENDIF(MINGW)
|
||||
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
|
||||
# *******************
|
||||
# Compilation options
|
||||
# *******************
|
||||
|
||||
# Always check for C++ features
|
||||
INCLUDE(CheckCXXFeatures)
|
||||
|
||||
IF(HAS_GCC_BUILTIN_SWAP)
|
||||
SET(TINS_HAVE_GCC_BUILTIN_SWAP ON)
|
||||
ENDIF()
|
||||
|
||||
# C++11 support
|
||||
OPTION(LIBTINS_ENABLE_CXX11 "Compile libtins with c++11 features" ON)
|
||||
IF(LIBTINS_ENABLE_CXX11)
|
||||
# We only use declval and decltype on gcc/clang as VC fails to build that code,
|
||||
# at least on VC2013
|
||||
IF(HAS_CXX11_RVALUE_REFERENCES AND HAS_CXX11_FUNCTIONAL AND HAS_CXX11_CHRONO AND
|
||||
HAS_CXX11_NOEXCEPT AND ((HAS_CXX11_DECLVAL AND HAS_CXX11_DECLTYPE) OR MSVC))
|
||||
SET(TINS_HAVE_CXX11 ON)
|
||||
MESSAGE(STATUS "Enabling C++11 features")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "The compiler doesn't support the necessary C++11 features. "
|
||||
"Disabling C++11 on this build")
|
||||
ENDIF()
|
||||
ELSE(LIBTINS_ENABLE_CXX11)
|
||||
MESSAGE(
|
||||
WARNING
|
||||
"Disabling C++11 features. Use LIBTINS_ENABLE_CXX11=1 to enable them. "
|
||||
"Unless you are using an old compiler, you should enable this option, "
|
||||
"as it increases the library's performance")
|
||||
ENDIF(LIBTINS_ENABLE_CXX11)
|
||||
|
||||
# IEEE 802.11 and WPA2 decryption support
|
||||
OPTION(LIBTINS_ENABLE_DOT11 "Compile libtins with IEEE 802.11 support" ON)
|
||||
OPTION(LIBTINS_ENABLE_WPA2 "Compile libtins with WPA2 decryption features (requires OpenSSL)" ON)
|
||||
IF(LIBTINS_ENABLE_DOT11)
|
||||
SET(TINS_HAVE_DOT11 ON)
|
||||
MESSAGE(STATUS "Enabling IEEE 802.11 support.")
|
||||
IF(LIBTINS_ENABLE_WPA2)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
IF(OPENSSL_FOUND)
|
||||
SET(TINS_HAVE_WPA2_DECRYPTION ON)
|
||||
MESSAGE(STATUS "Enabling WPA2 decryption support.")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling WPA2 decryption support since OpenSSL was not found")
|
||||
# Default this to empty strings
|
||||
SET(OPENSSL_INCLUDE_DIR "")
|
||||
SET(OPENSSL_LIBRARIES "")
|
||||
ENDIF()
|
||||
ELSE(LIBTINS_ENABLE_WPA2)
|
||||
MESSAGE(STATUS "Disabling WPA2 decryption support.")
|
||||
ENDIF(LIBTINS_ENABLE_WPA2)
|
||||
ENDIF(LIBTINS_ENABLE_DOT11)
|
||||
|
||||
# Optionally enable TCPIP classes (on by default)
|
||||
OPTION(LIBTINS_ENABLE_TCPIP "Enable TCPIP classes" ON)
|
||||
IF(LIBTINS_ENABLE_TCPIP AND TINS_HAVE_CXX11)
|
||||
SET(TINS_HAVE_TCPIP ON)
|
||||
MESSAGE(STATUS "Enabling TCPIP classes")
|
||||
ELSE()
|
||||
SET(TINS_HAVE_TCPIP OFF)
|
||||
MESSAGE(STATUS "Disabling TCPIP classes")
|
||||
ENDIF()
|
||||
|
||||
# Search for libboost
|
||||
FIND_PACKAGE(Boost)
|
||||
|
||||
# Optionally enable the ACK tracker (on by default)
|
||||
OPTION(LIBTINS_ENABLE_ACK_TRACKER "Enable TCP ACK tracking support" ON)
|
||||
IF(LIBTINS_ENABLE_ACK_TRACKER AND TINS_HAVE_CXX11)
|
||||
IF (Boost_FOUND)
|
||||
MESSAGE(STATUS "Enabling TCP ACK tracking support.")
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
SET(TINS_HAVE_ACK_TRACKER ON)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling ACK tracking support as boost.icl was not found")
|
||||
SET(TINS_HAVE_ACK_TRACKER OFF)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(TINS_HAVE_ACK_TRACKER OFF)
|
||||
MESSAGE(STATUS "Disabling ACK tracking support")
|
||||
ENDIF()
|
||||
|
||||
# Optionally enable the TCP stream custom data (on by default)
|
||||
OPTION(LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA "Enable TCP stream custom data support" ON)
|
||||
IF(LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA AND TINS_HAVE_CXX11)
|
||||
IF (Boost_FOUND)
|
||||
MESSAGE(STATUS "Enabling TCP stream custom data support.")
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA ON)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling TCP stream custom data support as boost.any was not found")
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA OFF)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA OFF)
|
||||
MESSAGE(STATUS "Disabling TCP stream custom data support")
|
||||
ENDIF()
|
||||
|
||||
OPTION(LIBTINS_ENABLE_WPA2_CALLBACKS "Enable WPA2 callback interface" ON)
|
||||
IF(LIBTINS_ENABLE_WPA2_CALLBACKS AND TINS_HAVE_WPA2_DECRYPTION AND TINS_HAVE_CXX11)
|
||||
SET(STATUS "Enabling WPA2 callback interface")
|
||||
SET(TINS_HAVE_WPA2_CALLBACKS ON)
|
||||
ENDIF()
|
||||
|
||||
# Use pcap_sendpacket to send l2 packets rather than raw sockets
|
||||
IF(WIN32)
|
||||
SET(USE_PCAP_SENDPACKET_DEFAULT ON)
|
||||
ELSE(WIN32)
|
||||
SET(USE_PCAP_SENDPACKET_DEFAULT OFF)
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(LIBTINS_USE_PCAP_SENDPACKET "Use pcap_sendpacket to send l2 packets"
|
||||
${USE_PCAP_SENDPACKET_DEFAULT})
|
||||
IF(LIBTINS_ENABLE_PCAP AND LIBTINS_USE_PCAP_SENDPACKET)
|
||||
SET(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET ON)
|
||||
MESSAGE(STATUS "Using pcap_sendpacket to send l2 packets.")
|
||||
ENDIF()
|
||||
|
||||
# Add a target to generate API documentation using Doxygen
|
||||
FIND_PACKAGE(Doxygen QUIET)
|
||||
IF(DOXYGEN_FOUND)
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
ADD_CUSTOM_TARGET(
|
||||
docs
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
||||
)
|
||||
ENDIF(DOXYGEN_FOUND)
|
||||
|
||||
# Configuration file
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/include/tins/config.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/include/tins/config.h"
|
||||
)
|
||||
|
||||
IF (NOT CMAKE_INSTALL_LIBDIR)
|
||||
SET(CMAKE_INSTALL_LIBDIR lib)
|
||||
ENDIF()
|
||||
IF (NOT CMAKE_INSTALL_BINDIR)
|
||||
SET(CMAKE_INSTALL_BINDIR bin)
|
||||
ENDIF()
|
||||
# The library output directory
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
# Support for pkg-config
|
||||
SET(pkgconfig_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(pkgconfig_exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(pkgconfig_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(pkgconfig_version ${LIBTINS_VERSION})
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libtins.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libtins.pc @ONLY)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libtins.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
|
||||
# Confiugure the uninstall script
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY
|
||||
)
|
||||
|
||||
# Add uninstall target
|
||||
ADD_CUSTOM_TARGET(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
# ******************
|
||||
# Add subdirectories
|
||||
# ******************
|
||||
ADD_SUBDIRECTORY(src)
|
||||
|
||||
IF(LIBTINS_BUILD_EXAMPLES)
|
||||
IF(LIBTINS_ENABLE_PCAP)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Not building examples as pcap support is disabled")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LIBTINS_BUILD_TESTS)
|
||||
# Only include googletest if the git submodule has been fetched
|
||||
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/googletest/CMakeLists.txt")
|
||||
# Enable tests and add the test directory
|
||||
MESSAGE(STATUS "Tests have been enabled")
|
||||
SET(GOOGLETEST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||
SET(GOOGLETEST_INCLUDE ${GOOGLETEST_ROOT}/googletest/include)
|
||||
SET(GOOGLETEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/googletest)
|
||||
SET(GOOGLETEST_LIBRARY ${GOOGLETEST_BINARY_DIR}/googletest)
|
||||
|
||||
ExternalProject_Add(
|
||||
googletest
|
||||
DOWNLOAD_COMMAND ""
|
||||
SOURCE_DIR ${GOOGLETEST_ROOT}
|
||||
BINARY_DIR ${GOOGLETEST_BINARY_DIR}
|
||||
CMAKE_CACHE_ARGS "-DBUILD_GTEST:bool=ON" "-DBUILD_GMOCK:bool=OFF"
|
||||
"-Dgtest_force_shared_crt:bool=ON"
|
||||
"-DCMAKE_CXX_COMPILER:path=${CMAKE_CXX_COMPILER}"
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
# Make sure we build googletest before anything else
|
||||
ADD_DEPENDENCIES(tins googletest)
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "googletest git submodule is absent. Run `git submodule init && git submodule update` to get it")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# **********************************
|
||||
# CMake project configuration export
|
||||
# **********************************
|
||||
|
||||
if(UNIX)
|
||||
set(CONF_CMAKE_INSTALL_DIR lib/cmake/libtins)
|
||||
else()
|
||||
set(CONF_CMAKE_INSTALL_DIR CMake)
|
||||
endif()
|
||||
|
||||
# Add all targets to the build-tree export set
|
||||
EXPORT(
|
||||
TARGETS tins
|
||||
FILE "${PROJECT_BINARY_DIR}/libtinsTargets.cmake"
|
||||
)
|
||||
|
||||
# Export the package for use from the build-tree
|
||||
# (this registers the build-tree with a global CMake-registry)
|
||||
EXPORT(PACKAGE libtins)
|
||||
|
||||
# Create the libtinsConfig.cmake and libtinsConfigVersion.cmake files
|
||||
# for the build tree
|
||||
SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
|
||||
CONFIGURE_FILE(
|
||||
cmake/libtinsConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfig.cmake" @ONLY
|
||||
)
|
||||
CONFIGURE_FILE(
|
||||
cmake/libtinsConfigVersion.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake" @ONLY
|
||||
)
|
||||
# Install the libtinsConfig.cmake and libtinsConfigVersion.cmake
|
||||
INSTALL(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfig.cmake"
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake"
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
# Install the export set for use with the install-tree
|
||||
INSTALL(
|
||||
EXPORT libtinsTargets
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
||||
27
CONTRIBUTING.md
Normal file
27
CONTRIBUTING.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Contributing
|
||||
|
||||
Bug reports and enhancements to the library are really valued and appreciated!
|
||||
|
||||
# Bug reports
|
||||
|
||||
If you find a bug, please report it! Bugs on the library are taken seriously
|
||||
and a patch for them is usually pushed on the same day.
|
||||
|
||||
When reporting a bug, please make sure to indicate the platform (e.g. GNU/Linux, Windows, OSX)
|
||||
in which you came across the issue, as this is essential to finding the cause.
|
||||
|
||||
## Packet parsing bugs
|
||||
|
||||
If you find a bug related to packet parsing (e.g. a field on a packet contains an
|
||||
invalid value), please try to provide a pcap file that contains the packet that
|
||||
was incorrectly parsed. Doing this will make it very simple to find the issue, plus
|
||||
you will be asked to provide this file anyway, so this just makes things
|
||||
easier.
|
||||
|
||||
# Pull requests
|
||||
|
||||
Pull requests are very welcomed. When doing a pull request please:
|
||||
|
||||
* Notice that your code will be compiled and tests will be run automatically by the travis and
|
||||
appveyor CI tools. If your code has issues on any of the tested platforms (GNU/Linux, Windows
|
||||
and OSX), please fix it or otherwise the PR won't be merged.
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2012, Nasel
|
||||
Copyright (c) 2012-2017, Matias Fontanini
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
44
Makefile.in
44
Makefile.in
@@ -1,44 +0,0 @@
|
||||
CXX=@CXX@
|
||||
CFLAGS=-c -Wall -fPIC @CFLAGS@ -DTINS_VERSION=@PACKAGE_VERSION@
|
||||
LDFLAGS=-lpcap -shared -Wl,-soname,libtins.so -Wl,-z,defs
|
||||
SOURCES=$(wildcard src/*.cpp)
|
||||
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
INCLUDE=-Iinclude/
|
||||
EXECUTABLE=libtins.so
|
||||
DEPS = $(SOURCES:.cpp=.d)
|
||||
|
||||
all: $(SOURCES) $(EXECUTABLE)
|
||||
|
||||
compile: $(OBJECTS)
|
||||
|
||||
recompile: clean all
|
||||
|
||||
depends: $(SOURCES)
|
||||
rm -f ./depends.d
|
||||
make do_make_deps
|
||||
|
||||
do_make_deps: $(DEPS)
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS)
|
||||
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CFLAGS) $(INCLUDE) $< -o $@
|
||||
|
||||
%.d : %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDE) -MG -MM -MP -MT"$(<:.cpp=.o)" $< >> depends.d
|
||||
|
||||
clean:
|
||||
rm $(OBJECTS) $(EXECUTABLE)
|
||||
|
||||
install:
|
||||
install -d /usr/include/tins/
|
||||
install -t /usr/include/tins/ include/*
|
||||
install $(EXECUTABLE) /usr/lib/
|
||||
|
||||
uninstall:
|
||||
rm -r /usr/include/tins/
|
||||
rm /usr/lib/$(EXECUTABLE)
|
||||
|
||||
-include depends.d
|
||||
147
README.md
Normal file
147
README.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# libtins
|
||||
|
||||
[](https://travis-ci.org/mfontanini/libtins)
|
||||
[](https://ci.appveyor.com/project/mfontanini/libtins/branch/master)
|
||||
|
||||
libtins is a high-level, multiplatform C++ network packet sniffing and
|
||||
crafting library.
|
||||
|
||||
Its main purpose is to provide the C++ developer an easy, efficient,
|
||||
platform and endianess-independent way to create tools which need to
|
||||
send, receive and manipulate specially crafted packets.
|
||||
|
||||
In order to read tutorials, examples and checkout some benchmarks of the
|
||||
library, please visit:
|
||||
|
||||
http://libtins.github.io/
|
||||
|
||||
## Compiling ##
|
||||
|
||||
[libtins](http://libtins.github.io/) depends on
|
||||
[libpcap](http://www.tcpdump.org/) and
|
||||
[openssl](http://www.openssl.org/), although the latter is not necessary
|
||||
if some features of the library are disabled.
|
||||
|
||||
In order to compile, execute:
|
||||
|
||||
```Shell
|
||||
# Create the build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Configure the project. Add any relevant configuration flags
|
||||
cmake ../
|
||||
|
||||
# Compile!
|
||||
make
|
||||
```
|
||||
|
||||
### Static/shared build
|
||||
Note that by default, only the shared object is compiled. If you would
|
||||
like to generate a static library file, run:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_BUILD_SHARED=0
|
||||
```
|
||||
|
||||
The generated static/shared library files will be located in the
|
||||
_build/lib_ directory.
|
||||
|
||||
### C++11 support
|
||||
|
||||
libtins is noticeably faster if you enable _C++11_ support. Therefore,
|
||||
if your compiler supports this standard, then you should enable it.
|
||||
In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_CXX11=1
|
||||
```
|
||||
|
||||
### TCP ACK tracker
|
||||
|
||||
The TCP ACK tracker feature requires the boost.icl library (header only).
|
||||
This feature is enabled by default but will be disabled if the boost
|
||||
headers are not found. You can disable this feature by using:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_ACK_TRACKER=0
|
||||
```
|
||||
|
||||
If your boost installation is on some non-standard path, use
|
||||
the parameters shown on the
|
||||
[CMake FindBoost help](https://cmake.org/cmake/help/v3.0/module/FindBoost.html)
|
||||
|
||||
### WPA2 decryption
|
||||
|
||||
If you want to disable _WPA2_ decryption support, which will remove
|
||||
openssl as a dependency for compilation, use the
|
||||
_LIBTINS_ENABLE_WPA2_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_WPA2=0
|
||||
```
|
||||
|
||||
### IEEE 802.11 support
|
||||
|
||||
If you want to disable IEEE 802.11 support(this will also disable
|
||||
RadioTap and WPA2 decryption), which will reduce the size of the
|
||||
resulting library in around 20%, use the _LIBTINS_ENABLE_DOT11_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_DOT11=0
|
||||
```
|
||||
|
||||
## Installing ##
|
||||
|
||||
Once you're done, if you want to install the header files and the
|
||||
shared object, execute as root:
|
||||
|
||||
```Shell
|
||||
make install
|
||||
```
|
||||
|
||||
This will install the shared object typically in _/usr/local/lib_. Note
|
||||
that you might have to update ldconfig's cache before using it, so
|
||||
in order to invalidate it, you should run(as root):
|
||||
|
||||
```Shell
|
||||
ldconfig
|
||||
```
|
||||
|
||||
## Running tests ##
|
||||
|
||||
You may want to run the unit tests on your system so you make sure
|
||||
everything works. In order to do so, you need to follow these steps:
|
||||
|
||||
```Shell
|
||||
# This will fetch the googletest submodule, needed for tests
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Use any options you want
|
||||
cmake ..
|
||||
|
||||
# Compile tests
|
||||
make tests
|
||||
|
||||
# Run them
|
||||
make test
|
||||
```
|
||||
|
||||
If you find that any tests fail, please create an ticket in the
|
||||
issue tracker indicating the platform and architecture you're using.
|
||||
|
||||
## Examples ##
|
||||
|
||||
You might want to have a look at the examples located in the "examples"
|
||||
directory. The same samples can be found online at:
|
||||
|
||||
http://libtins.github.io/examples/
|
||||
|
||||
## Contributing ##
|
||||
|
||||
If you want to report a bug or make a pull request, please have a look at
|
||||
the [contributing](CONTRIBUTING.md) file before doing so.
|
||||
4
THANKS
Normal file
4
THANKS
Normal file
@@ -0,0 +1,4 @@
|
||||
We'd like to thank the following people, who have been of great help
|
||||
through the development of libtins:
|
||||
|
||||
- Raúl Benencia <rbenencia@gmail.com> - For creating the Debian package.
|
||||
135
cmake/Modules/CheckCXXFeatures.cmake
Normal file
135
cmake/Modules/CheckCXXFeatures.cmake
Normal file
@@ -0,0 +1,135 @@
|
||||
# - Check which parts of the C++11 standard the compiler supports
|
||||
#
|
||||
# When found it will set the following variables
|
||||
#
|
||||
# CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features
|
||||
#
|
||||
# HAS_CXX11_AUTO - auto keyword
|
||||
# HAS_CXX11_AUTO_RET_TYPE - function declaration with deduced return types
|
||||
# HAS_CXX11_CLASS_OVERRIDE - override and final keywords for classes and methods
|
||||
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
||||
# HAS_CXX11_CSTDINT_H - cstdint header
|
||||
# HAS_CXX11_DECLTYPE - decltype keyword
|
||||
# HAS_CXX11_DECLVAL - declval feature
|
||||
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
||||
# HAS_CXX11_INITIALIZER_LIST - initializer list
|
||||
# HAS_CXX11_LAMBDA - lambdas
|
||||
# HAS_CXX11_LIB_REGEX - regex library
|
||||
# HAS_CXX11_LONG_LONG - long long signed & unsigned types
|
||||
# HAS_CXX11_NULLPTR - nullptr
|
||||
# HAS_CXX11_RVALUE_REFERENCES - rvalue references
|
||||
# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members
|
||||
# HAS_CXX11_STATIC_ASSERT - static_assert()
|
||||
# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011,2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||
# Copyright 2012 Andreas Weis
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
#
|
||||
# Each feature may have up to 3 checks, every one of them in it's own file
|
||||
# FEATURE.cpp - example that must build and return 0 when run
|
||||
# FEATURE_fail.cpp - example that must build, but may not return 0 when run
|
||||
# FEATURE_fail_compile.cpp - example that must fail compilation
|
||||
#
|
||||
# The first one is mandatory, the latter 2 are optional and do not depend on
|
||||
# each other (i.e. only one may be present).
|
||||
#
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILER_LOADED)
|
||||
message(FATAL_ERROR "CheckCXX11Features modules only works if language CXX is enabled")
|
||||
endif ()
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
|
||||
#
|
||||
### Check for needed compiler flags
|
||||
#
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("-std=c++11" _HAS_CXX11_FLAG)
|
||||
if (NOT _HAS_CXX11_FLAG)
|
||||
check_cxx_compiler_flag("-std=c++0x" _HAS_CXX0X_FLAG)
|
||||
endif ()
|
||||
|
||||
if (_HAS_CXX11_FLAG)
|
||||
set(CXX11_COMPILER_FLAGS "-std=c++11")
|
||||
elseif (_HAS_CXX0X_FLAG)
|
||||
set(CXX11_COMPILER_FLAGS "-std=c++0x")
|
||||
endif ()
|
||||
|
||||
function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
||||
if (NOT DEFINED ${RESULT_VAR})
|
||||
set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${FEATURE_NAME}")
|
||||
|
||||
set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXXFeatures/cxx-test-${FEATURE_NAME})
|
||||
set(_LOG_NAME "\"${FEATURE_NAME}\"")
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}")
|
||||
|
||||
set(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
||||
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
||||
set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
else (CMAKE_CROSSCOMPILING)
|
||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
||||
"${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
else (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
endif (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
||||
"${_bindir}_fail" "${_SRCFILE_FAIL}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
else (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
endif (CMAKE_CROSSCOMPILING)
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_TMP_RESULT)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
else (_TMP_RESULT)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
endif (_TMP_RESULT)
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||
|
||||
if (${RESULT_VAR})
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}: works")
|
||||
else (${RESULT_VAR})
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}: not supported")
|
||||
endif (${RESULT_VAR})
|
||||
set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++ support for ${_LOG_NAME}")
|
||||
endif (NOT DEFINED ${RESULT_VAR})
|
||||
endfunction(cxx11_check_feature)
|
||||
|
||||
cxx11_check_feature("decltype" HAS_CXX11_DECLTYPE)
|
||||
cxx11_check_feature("declval" HAS_CXX11_DECLVAL)
|
||||
cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST)
|
||||
cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES)
|
||||
cxx11_check_feature("functional" HAS_CXX11_FUNCTIONAL)
|
||||
cxx11_check_feature("chrono" HAS_CXX11_CHRONO)
|
||||
cxx11_check_feature("noexcept" HAS_CXX11_NOEXCEPT)
|
||||
cxx11_check_feature("builtin-swap" HAS_GCC_BUILTIN_SWAP)
|
||||
8
cmake/Modules/CheckCXXFeatures/cxx-test-__func__.cpp
Normal file
8
cmake/Modules/CheckCXXFeatures/cxx-test-__func__.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
int main(void)
|
||||
{
|
||||
if (!__func__)
|
||||
return 1;
|
||||
if (!(*__func__))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
12
cmake/Modules/CheckCXXFeatures/cxx-test-auto.cpp
Normal file
12
cmake/Modules/CheckCXXFeatures/cxx-test-auto.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
auto i = 5;
|
||||
auto f = 3.14159f;
|
||||
auto d = 3.14159;
|
||||
bool ret = (
|
||||
(sizeof(f) < sizeof(d)) &&
|
||||
(sizeof(i) == sizeof(int))
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
int main(void)
|
||||
{
|
||||
// must fail because there is no initializer
|
||||
auto i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
auto foo(int i) -> int {
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo(1);
|
||||
}
|
||||
8
cmake/Modules/CheckCXXFeatures/cxx-test-builtin-swap.cpp
Normal file
8
cmake/Modules/CheckCXXFeatures/cxx-test-builtin-swap.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int main() {
|
||||
uint16_t u16 = __builtin_bswap16(0x9812U);
|
||||
uint32_t u32 = __builtin_bswap32(0x9812ad81U);
|
||||
uint64_t u64 = __builtin_bswap64(0x9812ad81f61a890dU);
|
||||
return (u16 > 0 && u32 > 0 && u64 > 0) ? 0 : 1;
|
||||
}
|
||||
9
cmake/Modules/CheckCXXFeatures/cxx-test-chrono.cpp
Normal file
9
cmake/Modules/CheckCXXFeatures/cxx-test-chrono.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
int main() {
|
||||
system_clock::time_point tp = system_clock::now();
|
||||
milliseconds ms = duration_cast<milliseconds>(tp.time_since_epoch());
|
||||
return (ms.count() > 0) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
class base {
|
||||
public:
|
||||
virtual int foo(int a)
|
||||
{ return 4 + a; }
|
||||
int bar(int a) final
|
||||
{ return a - 2; }
|
||||
};
|
||||
|
||||
class sub final : public base {
|
||||
public:
|
||||
virtual int foo(int a) override
|
||||
{ return 8 + 2 * a; };
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
base b;
|
||||
sub s;
|
||||
|
||||
return (b.foo(2) * 2 == s.foo(2)) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
class base {
|
||||
public:
|
||||
virtual int foo(int a)
|
||||
{ return 4 + a; }
|
||||
virtual int bar(int a) final
|
||||
{ return a - 2; }
|
||||
};
|
||||
|
||||
class sub final : public base {
|
||||
public:
|
||||
virtual int foo(int a) override
|
||||
{ return 8 + 2 * a; };
|
||||
virtual int bar(int a)
|
||||
{ return a; }
|
||||
};
|
||||
|
||||
class impossible : public sub { };
|
||||
|
||||
int main(void)
|
||||
{
|
||||
base b;
|
||||
sub s;
|
||||
|
||||
return 1;
|
||||
}
|
||||
19
cmake/Modules/CheckCXXFeatures/cxx-test-constexpr.cpp
Normal file
19
cmake/Modules/CheckCXXFeatures/cxx-test-constexpr.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
constexpr int square(int x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
constexpr int the_answer()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int test_arr[square(3)];
|
||||
bool ret = (
|
||||
(square(the_answer()) == 1764) &&
|
||||
(sizeof(test_arr)/sizeof(test_arr[0]) == 9)
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
11
cmake/Modules/CheckCXXFeatures/cxx-test-cstdint.cpp
Normal file
11
cmake/Modules/CheckCXXFeatures/cxx-test-cstdint.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <cstdint>
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test =
|
||||
(sizeof(int8_t) == 1) &&
|
||||
(sizeof(int16_t) == 2) &&
|
||||
(sizeof(int32_t) == 4) &&
|
||||
(sizeof(int64_t) == 8);
|
||||
return test ? 0 : 1;
|
||||
}
|
||||
10
cmake/Modules/CheckCXXFeatures/cxx-test-decltype.cpp
Normal file
10
cmake/Modules/CheckCXXFeatures/cxx-test-decltype.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
bool check_size(int i)
|
||||
{
|
||||
return sizeof(int) == sizeof(decltype(i));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool ret = check_size(42);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
19
cmake/Modules/CheckCXXFeatures/cxx-test-declval.cpp
Normal file
19
cmake/Modules/CheckCXXFeatures/cxx-test-declval.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Example code taken from http://en.cppreference.com/w/cpp/utility/declval
|
||||
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
struct Default { int foo() const { return 1; } };
|
||||
|
||||
struct NonDefault
|
||||
{
|
||||
NonDefault(const NonDefault&) { }
|
||||
int foo() const { return 1; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
decltype(Default().foo()) n1 = 1; // type of n1 is int
|
||||
decltype(std::declval<NonDefault>().foo()) n2 = n1; // type of n2 is int
|
||||
return (n1 == 1 && n2 == 1) ? 0 : 1;
|
||||
}
|
||||
11
cmake/Modules/CheckCXXFeatures/cxx-test-functional.cpp
Normal file
11
cmake/Modules/CheckCXXFeatures/cxx-test-functional.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <functional>
|
||||
|
||||
int add(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::function<int(int, int)> func;
|
||||
func = std::bind(&add, std::placeholders::_1, std::placeholders::_2);
|
||||
return (func(2, 2) == 4) ? 0 : 1;
|
||||
}
|
||||
27
cmake/Modules/CheckCXXFeatures/cxx-test-initializer_list.cpp
Normal file
27
cmake/Modules/CheckCXXFeatures/cxx-test-initializer_list.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <vector>
|
||||
|
||||
class seq {
|
||||
public:
|
||||
seq(std::initializer_list<int> list);
|
||||
|
||||
int length() const;
|
||||
private:
|
||||
std::vector<int> m_v;
|
||||
};
|
||||
|
||||
seq::seq(std::initializer_list<int> list)
|
||||
: m_v(list)
|
||||
{
|
||||
}
|
||||
|
||||
int seq::length() const
|
||||
{
|
||||
return m_v.size();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
seq a = {18, 20, 2, 0, 4, 7};
|
||||
|
||||
return (a.length() == 6) ? 0 : 1;
|
||||
}
|
||||
5
cmake/Modules/CheckCXXFeatures/cxx-test-lambda.cpp
Normal file
5
cmake/Modules/CheckCXXFeatures/cxx-test-lambda.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
int main()
|
||||
{
|
||||
int ret = 0;
|
||||
return ([&ret]() -> int { return ret; })();
|
||||
}
|
||||
7
cmake/Modules/CheckCXXFeatures/cxx-test-long_long.cpp
Normal file
7
cmake/Modules/CheckCXXFeatures/cxx-test-long_long.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
int main(void)
|
||||
{
|
||||
long long l;
|
||||
unsigned long long ul;
|
||||
|
||||
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
|
||||
}
|
||||
7
cmake/Modules/CheckCXXFeatures/cxx-test-noexcept.cpp
Normal file
7
cmake/Modules/CheckCXXFeatures/cxx-test-noexcept.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
int foo() noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return foo();
|
||||
}
|
||||
6
cmake/Modules/CheckCXXFeatures/cxx-test-nullptr.cpp
Normal file
6
cmake/Modules/CheckCXXFeatures/cxx-test-nullptr.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
int main(void)
|
||||
{
|
||||
void *v = nullptr;
|
||||
|
||||
return v ? 1 : 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
int main(void)
|
||||
{
|
||||
int i = nullptr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
26
cmake/Modules/CheckCXXFeatures/cxx-test-regex.cpp
Normal file
26
cmake/Modules/CheckCXXFeatures/cxx-test-regex.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
|
||||
int parse_line(std::string const& line)
|
||||
{
|
||||
std::string tmp;
|
||||
if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+//(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+//(-)?(\\d)+"), std::string("V"));
|
||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
||||
} else {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+"), std::string("V"));
|
||||
}
|
||||
return static_cast<int>(std::count(tmp.begin(), tmp.end(), 'V'));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test = (parse_line("f 7/7/7 -3/3/-3 2/-2/2") == 3) &&
|
||||
(parse_line("f 7//7 3//-3 -2//2") == 3) &&
|
||||
(parse_line("f 7/7 3/-3 -2/2") == 3) &&
|
||||
(parse_line("f 7 3 -2") == 3);
|
||||
return test ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <cassert>
|
||||
|
||||
class rvmove {
|
||||
public:
|
||||
void *ptr;
|
||||
char *array;
|
||||
|
||||
rvmove()
|
||||
: ptr(0),
|
||||
array(new char[10])
|
||||
{
|
||||
ptr = this;
|
||||
}
|
||||
|
||||
rvmove(rvmove &&other)
|
||||
: ptr(other.ptr),
|
||||
array(other.array)
|
||||
{
|
||||
other.array = 0;
|
||||
other.ptr = 0;
|
||||
}
|
||||
|
||||
~rvmove()
|
||||
{
|
||||
assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0)));
|
||||
delete[] array;
|
||||
}
|
||||
|
||||
rvmove &operator=(rvmove &&other)
|
||||
{
|
||||
delete[] array;
|
||||
ptr = other.ptr;
|
||||
array = other.array;
|
||||
other.array = 0;
|
||||
other.ptr = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static rvmove create()
|
||||
{
|
||||
return rvmove();
|
||||
}
|
||||
private:
|
||||
rvmove(const rvmove &);
|
||||
rvmove &operator=(const rvmove &);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
rvmove mine;
|
||||
if (mine.ptr != &mine)
|
||||
return 1;
|
||||
mine = rvmove::create();
|
||||
if (mine.ptr == &mine)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
14
cmake/Modules/CheckCXXFeatures/cxx-test-sizeof_member.cpp
Normal file
14
cmake/Modules/CheckCXXFeatures/cxx-test-sizeof_member.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
struct foo {
|
||||
char bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool ret = (
|
||||
(sizeof(foo::bar) == 1) &&
|
||||
(sizeof(foo::baz) >= sizeof(foo::bar)) &&
|
||||
(sizeof(foo) >= sizeof(foo::bar) + sizeof(foo::baz))
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
struct foo {
|
||||
int baz;
|
||||
double bar;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return (sizeof(foo::bar) == 4) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
int main(void)
|
||||
{
|
||||
static_assert(0 < 1, "your ordering of integers is screwed");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
int main(void)
|
||||
{
|
||||
static_assert(1 < 0, "your ordering of integers is screwed");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
int Accumulate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
int Accumulate(T v, Ts... vs)
|
||||
{
|
||||
return v + Accumulate(vs...);
|
||||
}
|
||||
|
||||
template<int... Is>
|
||||
int CountElements()
|
||||
{
|
||||
return sizeof...(Is);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int acc = Accumulate(1, 2, 3, 4, -5);
|
||||
int count = CountElements<1,2,3,4,5>();
|
||||
return ((acc == 5) && (count == 5)) ? 0 : 1;
|
||||
}
|
||||
85
cmake/Modules/FindPCAP.cmake
Normal file
85
cmake/Modules/FindPCAP.cmake
Normal file
@@ -0,0 +1,85 @@
|
||||
# - Try to find libpcap include dirs and libraries
|
||||
#
|
||||
# Usage of this module as follows:
|
||||
#
|
||||
# find_package(PCAP)
|
||||
#
|
||||
# Variables used by this module, they can change the default behaviour and need
|
||||
# to be set before calling find_package:
|
||||
#
|
||||
# PCAP_ROOT_DIR Set this variable to the root installation of
|
||||
# libpcap if the module has problems finding the
|
||||
# proper installation path.
|
||||
#
|
||||
# Variables defined by this module:
|
||||
#
|
||||
# PCAP_FOUND System has libpcap, include and library dirs found
|
||||
# PCAP_INCLUDE_DIR The libpcap include directories.
|
||||
# PCAP_LIBRARY The libpcap library (possibly includes a thread
|
||||
# library e.g. required by pf_ring's libpcap)
|
||||
# HAVE_PF_RING If a found version of libpcap supports PF_RING
|
||||
# HAVE_PCAP_IMMEDIATE_MODE If the version of libpcap found supports immediate mode
|
||||
|
||||
find_path(PCAP_ROOT_DIR
|
||||
NAMES include/pcap.h
|
||||
)
|
||||
|
||||
find_path(PCAP_INCLUDE_DIR
|
||||
NAMES pcap.h
|
||||
HINTS ${PCAP_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
set (HINT_DIR ${PCAP_ROOT_DIR}/lib)
|
||||
|
||||
# On x64 windows, we should look also for the .lib at /lib/x64/
|
||||
# as this is the default path for the WinPcap developer's pack
|
||||
if (${CMAKE_SIZEOF_VOID_P} EQUAL 8 AND WIN32)
|
||||
set (HINT_DIR ${PCAP_ROOT_DIR}/lib/x64/ ${HINT_DIR})
|
||||
endif ()
|
||||
|
||||
find_library(PCAP_LIBRARY
|
||||
NAMES pcap wpcap
|
||||
HINTS ${HINT_DIR}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCAP DEFAULT_MSG
|
||||
PCAP_LIBRARY
|
||||
PCAP_INCLUDE_DIR
|
||||
)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||
check_cxx_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
# check if linking against libpcap also needs to link against a thread library
|
||||
if (NOT PCAP_LINKS_SOLO)
|
||||
find_package(Threads)
|
||||
if (THREADS_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||
check_cxx_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif (THREADS_FOUND)
|
||||
if (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||
list(REMOVE_DUPLICATES _tmp)
|
||||
set(PCAP_LIBRARY ${_tmp}
|
||||
CACHE STRING "Libraries needed to link against libpcap" FORCE)
|
||||
else (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
message(FATAL_ERROR "Couldn't determine how to link against libpcap")
|
||||
endif (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
endif (NOT PCAP_LINKS_SOLO)
|
||||
|
||||
include(CheckFunctionExists)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||
check_function_exists(pcap_get_pfring_id HAVE_PF_RING)
|
||||
check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE)
|
||||
check_function_exists(pcap_set_tstamp_precision HAVE_PCAP_TIMESTAMP_PRECISION)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
mark_as_advanced(
|
||||
PCAP_ROOT_DIR
|
||||
PCAP_INCLUDE_DIR
|
||||
PCAP_LIBRARY
|
||||
)
|
||||
53
cmake/appveyor.yml
Normal file
53
cmake/appveyor.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
version: 1.0.{build}
|
||||
configuration:
|
||||
- debug
|
||||
- release
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
environment:
|
||||
matrix:
|
||||
- compiler: vs2013
|
||||
- compiler: vs2015
|
||||
BOOST_ROOT: C:/Libraries/boost
|
||||
clone_depth: 1
|
||||
install:
|
||||
- git clone https://github.com/mfontanini/winpcap-installer.git
|
||||
- cd winpcap-installer
|
||||
- winpcap-boundary-meter-4.1.3.exe /S
|
||||
- cd ..
|
||||
- appveyor DownloadFile http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip
|
||||
- 7z x .\WpdPack_4_1_2.zip -oc:\
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
before_build:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if "%compiler%"=="vs2013" (set VS_VERSION=12) else (set VS_VERSION=14)
|
||||
- set VS=Visual Studio %VS_VERSION%
|
||||
- if "%platform%"=="Win32" (set GENERATOR="%VS%" & set ARCH_BITS=32)
|
||||
- if "%platform%"=="x64" (set GENERATOR="%VS% Win64" & set ARCH_BITS=64)
|
||||
- set BOOST_LIBRARYDIR=C:\Libraries\boost\lib%ARCH_BITS%-msvc-%VS_VERSION%.0
|
||||
- cmake .. -G %GENERATOR% -DPCAP_ROOT_DIR=c:\WpdPack -DLIBTINS_BUILD_SHARED=0 -DLIBTINS_ENABLE_WPA2=0 -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DBoost_USE_STATIC_LIBS="ON"
|
||||
build:
|
||||
project: C:/projects/libtins/build/libtins.sln
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- mkdir install\libtins\include
|
||||
- mkdir install\libtins\lib
|
||||
- cd install\libtins
|
||||
- copy C:\projects\libtins\build\lib\%Configuration%\tins.lib lib
|
||||
- xcopy C:\projects\libtins\include include /s /e
|
||||
- del include\CMakeLists.txt
|
||||
- del include\tins\CMakeLists.txt
|
||||
- del include\tins\config.h.in
|
||||
- del include\tins\dot11\CMakeLists.txt
|
||||
- cd ..\
|
||||
- 7z a libtins-%compiler%-%platform%-%Configuration%.zip libtins
|
||||
test_script:
|
||||
- cd c:\projects\libtins\build
|
||||
- ctest -C %Configuration% -V
|
||||
deploy_script:
|
||||
- ps: Push-AppveyorArtifact "install\libtins-$env:Compiler-$env:Platform-$env:Configuration.zip"
|
||||
skip_commits:
|
||||
message: /Update documentation.*/
|
||||
23
cmake/cmake_uninstall.cmake.in
Normal file
23
cmake/cmake_uninstall.cmake.in
Normal file
@@ -0,0 +1,23 @@
|
||||
# Taken from https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
|
||||
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
16
cmake/libtinsConfig.cmake.in
Normal file
16
cmake/libtinsConfig.cmake.in
Normal file
@@ -0,0 +1,16 @@
|
||||
# - Config file for the libtins package
|
||||
# It defines the following variables
|
||||
# LIBTINS_INCLUDE_DIRS - include directories for libtins
|
||||
# LIBTINS_LIBRARIES - libraries to link against
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(LIBTINS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
set(LIBTINS_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
|
||||
|
||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||
if(NOT TARGET libtins AND NOT LIBTINS_BINARY_DIR)
|
||||
include("${LIBTINS_CMAKE_DIR}/libtinsTargets.cmake")
|
||||
endif()
|
||||
|
||||
# These are IMPORTED targets created by libtinsTargets.cmake
|
||||
set(LIBTINS_LIBRARIES tins)
|
||||
11
cmake/libtinsConfigVersion.cmake.in
Normal file
11
cmake/libtinsConfigVersion.cmake.in
Normal file
@@ -0,0 +1,11 @@
|
||||
set(PACKAGE_VERSION "@LIBTINS_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
16
configure.ac
16
configure.ac
@@ -1,16 +0,0 @@
|
||||
AC_INIT(myconfig, 0.2)
|
||||
|
||||
AC_PROG_CXX()
|
||||
AC_LANG(C++)
|
||||
|
||||
if test -n "$debug"
|
||||
then
|
||||
CFLAGS="-DDEBUG -g"
|
||||
else
|
||||
CFLAGS="-O3"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([pcap.h])
|
||||
AC_CHECK_LIB(pcap, pcap_loop, [], [AC_MSG_ERROR([pcap library is needed!])])
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_OUTPUT(Makefile)
|
||||
558
depends.d
558
depends.d
@@ -1,558 +0,0 @@
|
||||
src/arp.o: src/arp.cpp include/arp.h include/pdu.h include/endianness.h \
|
||||
include/hw_address.h include/ip_address.h include/ip.h \
|
||||
include/small_uint.h include/pdu_option.h include/ethernetII.h \
|
||||
include/network_interface.h include/rawpdu.h include/constants.h \
|
||||
include/network_interface.h
|
||||
|
||||
include/arp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/ethernetII.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/constants.h:
|
||||
|
||||
include/network_interface.h:
|
||||
src/bootp.o: src/bootp.cpp include/bootp.h include/pdu.h \
|
||||
include/endianness.h include/ip_address.h include/hw_address.h
|
||||
|
||||
include/bootp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/hw_address.h:
|
||||
src/crypto.o: src/crypto.cpp include/crypto.h include/dot11.h \
|
||||
include/pdu.h include/endianness.h include/hw_address.h \
|
||||
include/small_uint.h include/pdu_option.h include/network_interface.h \
|
||||
include/ip_address.h include/utils.h include/snap.h include/rawpdu.h
|
||||
|
||||
include/crypto.h:
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/snap.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
src/dhcp.o: src/dhcp.cpp include/endianness.h include/dhcp.h \
|
||||
include/bootp.h include/pdu.h include/endianness.h include/ip_address.h \
|
||||
include/hw_address.h include/pdu_option.h include/ethernetII.h \
|
||||
include/network_interface.h
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/dhcp.h:
|
||||
|
||||
include/bootp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/ethernetII.h:
|
||||
|
||||
include/network_interface.h:
|
||||
src/dns.o: src/dns.cpp include/dns.h include/pdu.h include/endianness.h \
|
||||
include/dns_record.h include/ip_address.h
|
||||
|
||||
include/dns.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/dns_record.h:
|
||||
|
||||
include/ip_address.h:
|
||||
src/dns_record.o: src/dns_record.cpp include/dns_record.h \
|
||||
include/endianness.h
|
||||
|
||||
include/dns_record.h:
|
||||
|
||||
include/endianness.h:
|
||||
src/dot11.o: src/dot11.cpp include/dot11.h include/pdu.h \
|
||||
include/endianness.h include/hw_address.h include/small_uint.h \
|
||||
include/pdu_option.h include/network_interface.h include/ip_address.h \
|
||||
include/rawpdu.h include/radiotap.h include/rsn_information.h \
|
||||
include/packet_sender.h include/snap.h
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/radiotap.h:
|
||||
|
||||
include/rsn_information.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
|
||||
include/snap.h:
|
||||
src/eapol.o: src/eapol.cpp include/eapol.h include/pdu.h \
|
||||
include/small_uint.h include/endianness.h include/dot11.h \
|
||||
include/hw_address.h include/pdu_option.h include/network_interface.h \
|
||||
include/ip_address.h include/rsn_information.h
|
||||
|
||||
include/eapol.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/rsn_information.h:
|
||||
src/ethernetII.o: src/ethernetII.cpp include/ethernetII.h include/pdu.h \
|
||||
include/endianness.h include/hw_address.h include/network_interface.h \
|
||||
include/ip_address.h include/packet_sender.h include/rawpdu.h \
|
||||
include/ip.h include/small_uint.h include/pdu_option.h include/arp.h \
|
||||
include/constants.h
|
||||
|
||||
include/ethernetII.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/arp.h:
|
||||
|
||||
include/constants.h:
|
||||
src/icmp.o: src/icmp.cpp include/icmp.h include/pdu.h \
|
||||
include/endianness.h include/rawpdu.h include/utils.h \
|
||||
include/ip_address.h include/hw_address.h
|
||||
|
||||
include/icmp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/hw_address.h:
|
||||
src/ieee802_3.o: src/ieee802_3.cpp include/ieee802_3.h include/pdu.h \
|
||||
include/endianness.h include/hw_address.h include/network_interface.h \
|
||||
include/ip_address.h include/packet_sender.h include/llc.h
|
||||
|
||||
include/ieee802_3.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
|
||||
include/llc.h:
|
||||
src/ip_address.o: src/ip_address.cpp include/ip_address.h \
|
||||
include/endianness.h
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/endianness.h:
|
||||
src/ip.o: src/ip.cpp include/ip.h include/pdu.h include/small_uint.h \
|
||||
include/endianness.h include/ip_address.h include/pdu_option.h \
|
||||
include/tcp.h include/udp.h include/icmp.h include/rawpdu.h \
|
||||
include/utils.h include/hw_address.h include/packet_sender.h \
|
||||
include/constants.h
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/tcp.h:
|
||||
|
||||
include/udp.h:
|
||||
|
||||
include/icmp.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
|
||||
include/constants.h:
|
||||
src/llc.o: src/llc.cpp include/pdu.h include/llc.h include/pdu.h \
|
||||
include/endianness.h include/rawpdu.h
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/llc.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
src/loopback.o: src/loopback.cpp include/loopback.h include/pdu.h \
|
||||
include/packet_sender.h include/ip.h include/small_uint.h \
|
||||
include/endianness.h include/ip_address.h include/pdu_option.h \
|
||||
include/llc.h include/rawpdu.h
|
||||
|
||||
include/loopback.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/llc.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
src/network_interface.o: src/network_interface.cpp \
|
||||
include/network_interface.h include/hw_address.h include/ip_address.h \
|
||||
include/utils.h include/endianness.h
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/endianness.h:
|
||||
src/packet_sender.o: src/packet_sender.cpp include/pdu.h \
|
||||
include/packet_sender.h
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
src/packet_writer.o: src/packet_writer.cpp include/packet_writer.h \
|
||||
include/pdu.h
|
||||
|
||||
include/packet_writer.h:
|
||||
|
||||
include/pdu.h:
|
||||
src/pdu.o: src/pdu.cpp include/pdu.h include/rawpdu.h include/pdu.h \
|
||||
include/packet_sender.h
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
src/radiotap.o: src/radiotap.cpp include/radiotap.h include/pdu.h \
|
||||
include/endianness.h include/network_interface.h include/hw_address.h \
|
||||
include/ip_address.h include/dot11.h include/small_uint.h \
|
||||
include/pdu_option.h include/utils.h include/packet_sender.h
|
||||
|
||||
include/radiotap.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
src/rawpdu.o: src/rawpdu.cpp include/rawpdu.h include/pdu.h
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/pdu.h:
|
||||
src/rsn_information.o: src/rsn_information.cpp include/rsn_information.h \
|
||||
include/endianness.h
|
||||
|
||||
include/rsn_information.h:
|
||||
|
||||
include/endianness.h:
|
||||
src/snap.o: src/snap.cpp include/snap.h include/pdu.h \
|
||||
include/endianness.h include/small_uint.h include/constants.h \
|
||||
include/arp.h include/hw_address.h include/ip_address.h include/ip.h \
|
||||
include/pdu_option.h include/eapol.h
|
||||
|
||||
include/snap.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/constants.h:
|
||||
|
||||
include/arp.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/eapol.h:
|
||||
src/sniffer.o: src/sniffer.cpp include/sniffer.h include/pdu.h \
|
||||
include/ethernetII.h include/endianness.h include/hw_address.h \
|
||||
include/network_interface.h include/ip_address.h include/radiotap.h \
|
||||
include/loopback.h include/dot11.h include/small_uint.h \
|
||||
include/pdu_option.h
|
||||
|
||||
include/sniffer.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/ethernetII.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/radiotap.h:
|
||||
|
||||
include/loopback.h:
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
src/tcp.o: src/tcp.cpp include/tcp.h include/pdu.h include/endianness.h \
|
||||
include/small_uint.h include/pdu_option.h include/ip.h \
|
||||
include/ip_address.h include/constants.h include/rawpdu.h \
|
||||
include/utils.h include/hw_address.h
|
||||
|
||||
include/tcp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/constants.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/hw_address.h:
|
||||
src/tcp_stream.o: src/tcp_stream.cpp include/rawpdu.h include/pdu.h \
|
||||
include/tcp_stream.h include/sniffer.h include/ethernetII.h \
|
||||
include/endianness.h include/hw_address.h include/network_interface.h \
|
||||
include/ip_address.h include/radiotap.h include/loopback.h \
|
||||
include/dot11.h include/small_uint.h include/pdu_option.h include/tcp.h \
|
||||
include/ip.h
|
||||
|
||||
include/rawpdu.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/tcp_stream.h:
|
||||
|
||||
include/sniffer.h:
|
||||
|
||||
include/ethernetII.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/radiotap.h:
|
||||
|
||||
include/loopback.h:
|
||||
|
||||
include/dot11.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/tcp.h:
|
||||
|
||||
include/ip.h:
|
||||
src/udp.o: src/udp.cpp include/udp.h include/pdu.h include/endianness.h \
|
||||
include/constants.h include/utils.h include/ip_address.h \
|
||||
include/hw_address.h include/ip.h include/small_uint.h \
|
||||
include/pdu_option.h include/rawpdu.h
|
||||
|
||||
include/udp.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/constants.h:
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/rawpdu.h:
|
||||
src/utils.o: src/utils.cpp include/utils.h include/ip_address.h \
|
||||
include/hw_address.h include/pdu.h include/ip.h include/pdu.h \
|
||||
include/small_uint.h include/endianness.h include/pdu_option.h \
|
||||
include/arp.h include/endianness.h include/network_interface.h \
|
||||
include/packet_sender.h
|
||||
|
||||
include/utils.h:
|
||||
|
||||
include/ip_address.h:
|
||||
|
||||
include/hw_address.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/ip.h:
|
||||
|
||||
include/pdu.h:
|
||||
|
||||
include/small_uint.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/pdu_option.h:
|
||||
|
||||
include/arp.h:
|
||||
|
||||
include/endianness.h:
|
||||
|
||||
include/network_interface.h:
|
||||
|
||||
include/packet_sender.h:
|
||||
@@ -31,14 +31,14 @@ PROJECT_NAME = libtins
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.1
|
||||
PROJECT_NUMBER = @LIBTINS_VERSION@
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = docs/
|
||||
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/docs/
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||
@@ -581,7 +581,7 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = include src
|
||||
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/include @CMAKE_CURRENT_SOURCE_DIR@/src @CMAKE_CURRENT_SOURCE_DIR@/docs/mainpage.dox
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
@@ -1085,7 +1085,7 @@ SERVER_BASED_SEARCH = NO
|
||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||
# generate Latex output.
|
||||
|
||||
GENERATE_LATEX = YES
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
@@ -1365,7 +1365,9 @@ INCLUDE_FILE_PATTERNS =
|
||||
# undefined via #undef or recursively expanded use the := operator
|
||||
# instead of the = operator.
|
||||
|
||||
PREDEFINED =
|
||||
PREDEFINED = "TINS_IS_CXX11=1" \
|
||||
"TINS_HAVE_WPA2_CALLBACKS=1" \
|
||||
"TINS_HAVE_DOT11=1"
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
29
docs/mainpage.dox
Normal file
29
docs/mainpage.dox
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* \mainpage Documentation
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* <i>libtins</i> is a high-level, multiplatform <i>C++</i> network packet
|
||||
* sniffing and crafting library.
|
||||
*
|
||||
* Its main purpose is to provide the <i>C++</i> developer an easy, efficient,
|
||||
* platform and endianess-independent way to create tools which need to
|
||||
* send, receive and manipulate network packets.
|
||||
*
|
||||
* \section install_sec Installation
|
||||
*
|
||||
* Please visit the <a href="http://libtins.github.io/download/">downloads
|
||||
* section</a> in order to see the installation instructions.
|
||||
*
|
||||
* \section tutorials_sec Tutorials
|
||||
*
|
||||
* If you want to learn about how the library works, please visit the
|
||||
* <a href="http://libtins.github.io/tutorial/">tutorials</a> section.
|
||||
*
|
||||
* \section examples_sec Examples
|
||||
*
|
||||
* Make sure to visit the <a href="http://libtins.github.io/examples/">
|
||||
* examples</a> section to see some short but illustrative examples on how
|
||||
* to send and sniff packets using <i>libtins</i>.
|
||||
*
|
||||
*/
|
||||
81
examples/CMakeLists.txt
Normal file
81
examples/CMakeLists.txt
Normal file
@@ -0,0 +1,81 @@
|
||||
FIND_PACKAGE(Threads QUIET)
|
||||
FIND_PACKAGE(Boost COMPONENTS regex)
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
${PCAP_INCLUDE_DIR}
|
||||
)
|
||||
LINK_LIBRARIES(tins)
|
||||
|
||||
IF(TINS_HAVE_CXX11)
|
||||
SET(LIBTINS_CXX11_EXAMPLES
|
||||
arpmonitor
|
||||
dns_queries
|
||||
dns_spoof
|
||||
dns_stats
|
||||
stream_dump
|
||||
icmp_responses
|
||||
interfaces_info
|
||||
tcp_connection_close
|
||||
traceroute
|
||||
wps_detect
|
||||
)
|
||||
IF(Boost_REGEX_FOUND)
|
||||
SET(LIBTINS_CXX11_EXAMPLES ${LIBTINS_CXX11_EXAMPLES} http_requests)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling HTTP requests example since boost.regex was not found")
|
||||
ENDIF()
|
||||
ELSE(TINS_HAVE_CXX11)
|
||||
MESSAGE(WARNING "Disabling some examples since C++11 support is disabled.")
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
|
||||
ADD_CUSTOM_TARGET(
|
||||
examples DEPENDS
|
||||
arpspoofing
|
||||
${LIBTINS_CXX11_EXAMPLES}
|
||||
beacon_display
|
||||
portscan
|
||||
route_table
|
||||
defragmenter
|
||||
)
|
||||
|
||||
# Make sure we first build libtins
|
||||
ADD_DEPENDENCIES(examples tins)
|
||||
|
||||
ADD_EXECUTABLE(arpspoofing EXCLUDE_FROM_ALL arpspoofing.cpp)
|
||||
ADD_EXECUTABLE(route_table EXCLUDE_FROM_ALL route_table.cpp)
|
||||
ADD_EXECUTABLE(defragmenter EXCLUDE_FROM_ALL defragmenter.cpp)
|
||||
IF(TINS_HAVE_CXX11)
|
||||
ADD_EXECUTABLE(arpmonitor EXCLUDE_FROM_ALL arpmonitor.cpp)
|
||||
ADD_EXECUTABLE(dns_queries EXCLUDE_FROM_ALL dns_queries.cpp)
|
||||
ADD_EXECUTABLE(dns_spoof EXCLUDE_FROM_ALL dns_spoof.cpp)
|
||||
ADD_EXECUTABLE(stream_dump EXCLUDE_FROM_ALL stream_dump.cpp)
|
||||
ADD_EXECUTABLE(icmp_responses EXCLUDE_FROM_ALL icmp_responses.cpp)
|
||||
ADD_EXECUTABLE(interfaces_info EXCLUDE_FROM_ALL interfaces_info.cpp)
|
||||
ADD_EXECUTABLE(tcp_connection_close EXCLUDE_FROM_ALL tcp_connection_close.cpp)
|
||||
ADD_EXECUTABLE(wps_detect EXCLUDE_FROM_ALL wps_detect.cpp)
|
||||
IF (Boost_REGEX_FOUND)
|
||||
ADD_EXECUTABLE(http_requests EXCLUDE_FROM_ALL http_requests.cpp)
|
||||
TARGET_LINK_LIBRARIES(http_requests ${Boost_LIBRARIES})
|
||||
ENDIF()
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
|
||||
ADD_EXECUTABLE(beacon_display EXCLUDE_FROM_ALL beacon_display.cpp)
|
||||
|
||||
if(THREADS_FOUND)
|
||||
IF(TINS_HAVE_CXX11)
|
||||
ADD_EXECUTABLE(traceroute EXCLUDE_FROM_ALL traceroute.cpp)
|
||||
ADD_EXECUTABLE(dns_stats EXCLUDE_FROM_ALL dns_stats.cpp)
|
||||
TARGET_LINK_LIBRARIES(traceroute ${CMAKE_THREAD_LIBS_INIT})
|
||||
TARGET_LINK_LIBRARIES(dns_stats ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
IF(WIN32)
|
||||
MESSAGE(WARNING "Disabling portscan example since it doesn't compile on Windows.")
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(portscan EXCLUDE_FROM_ALL portscan.cpp)
|
||||
TARGET_LINK_LIBRARIES(portscan ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling portscan and traceroute examples since pthreads library was not found.")
|
||||
ENDIF()
|
||||
@@ -1,28 +0,0 @@
|
||||
CXX=@CXX@
|
||||
CXXFLAGS=-Wall @CXXFLAGS@
|
||||
LDFLAGS=-ltins
|
||||
EXECUTABLES=arpspoof portscan traceroute beacon_display
|
||||
|
||||
all: $(EXECUTABLES)
|
||||
|
||||
compile: $(OBJECTS)
|
||||
|
||||
recompile: clean all
|
||||
|
||||
arpspoof:
|
||||
$(CXX) arpspoofing.cpp -o arpspoofing $(CXXFLAGS) $(LDFLAGS)
|
||||
|
||||
beacon_display:
|
||||
$(CXX) beacon_display.cpp -o beacon_display $(CXXFLAGS) $(LDFLAGS)
|
||||
|
||||
portscan:
|
||||
$(CXX) portscan.cpp -o portscan $(CXXFLAGS) $(LDFLAGS) -lpthread
|
||||
|
||||
traceroute:
|
||||
$(CXX) traceroute.cpp -o traceroute -std=c++0x $(CXXFLAGS) $(LDFLAGS) -lpthread
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDE) $< -o $@
|
||||
|
||||
clean:
|
||||
rm $(OBJECTS) $(EXECUTABLES)
|
||||
107
examples/arpmonitor.cpp
Normal file
107
examples/arpmonitor.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::map;
|
||||
using std::bind;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class arp_monitor {
|
||||
public:
|
||||
void run(Sniffer& sniffer);
|
||||
private:
|
||||
bool callback(const PDU& pdu);
|
||||
|
||||
map<IPv4Address, HWAddress<6>> addresses;
|
||||
};
|
||||
|
||||
void arp_monitor::run(Sniffer& sniffer) {
|
||||
sniffer.sniff_loop(
|
||||
bind(
|
||||
&arp_monitor::callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bool arp_monitor::callback(const PDU& pdu) {
|
||||
// Retrieve the ARP layer
|
||||
const ARP& arp = pdu.rfind_pdu<ARP>();
|
||||
// Is it an ARP reply?
|
||||
if (arp.opcode() == ARP::REPLY) {
|
||||
// Let's check if there's already an entry for this address
|
||||
auto iter = addresses.find(arp.sender_ip_addr());
|
||||
if (iter == addresses.end()) {
|
||||
// We haven't seen this address. Save it.
|
||||
addresses.insert({ arp.sender_ip_addr(), arp.sender_hw_addr()});
|
||||
cout << "[INFO] " << arp.sender_ip_addr() << " is at "
|
||||
<< arp.sender_hw_addr() << std::endl;
|
||||
}
|
||||
else {
|
||||
// We've seen this address. If it's not the same HW address, inform it
|
||||
if (arp.sender_hw_addr() != iter->second) {
|
||||
cout << "[WARNING] " << arp.sender_ip_addr() << " is at "
|
||||
<< iter->second << " but also at " << arp.sender_hw_addr()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
arp_monitor monitor;
|
||||
// Sniffer configuration
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("arp");
|
||||
|
||||
try {
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// Only capture arp packets
|
||||
monitor.run(sniffer);
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
std::cerr << "Error: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,33 +32,38 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif // _WIN32
|
||||
#include <tins/arp.h>
|
||||
#include <tins/network_interface.h>
|
||||
#include <tins/utils.h>
|
||||
#include <tins/ethernetII.h>
|
||||
#include <tins/packet_sender.h>
|
||||
|
||||
using namespace std;
|
||||
using std::cout;
|
||||
using std::runtime_error;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
|
||||
int do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address victim,
|
||||
const NetworkInterface::Info &info)
|
||||
{
|
||||
void do_arp_spoofing(NetworkInterface iface,
|
||||
IPv4Address gw,
|
||||
IPv4Address victim,
|
||||
const NetworkInterface::Info& info) {
|
||||
PacketSender sender;
|
||||
EthernetII::address_type gw_hw, victim_hw;
|
||||
|
||||
// Resolves gateway's hardware address.
|
||||
if(!Utils::resolve_hwaddr(iface, gw, &gw_hw, sender)) {
|
||||
cout << "Could not resolve gateway's ip address.\n";
|
||||
return 5;
|
||||
}
|
||||
gw_hw = Utils::resolve_hwaddr(iface, gw, sender);
|
||||
|
||||
// Resolves victim's hardware address.
|
||||
if(!Utils::resolve_hwaddr(iface, victim, &victim_hw, sender)) {
|
||||
cout << "Could not resolve victim's ip address.\n";
|
||||
return 6;
|
||||
}
|
||||
victim_hw = Utils::resolve_hwaddr(iface, victim, sender);
|
||||
|
||||
// Print out the hw addresses we're using.
|
||||
cout << " Using gateway hw address: " << gw_hw << "\n";
|
||||
cout << " Using victim hw address: " << victim_hw << "\n";
|
||||
@@ -66,29 +71,35 @@ int do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address victim,
|
||||
|
||||
/* We tell the gateway that the victim is at out hw address,
|
||||
* and tell the victim that the gateway is at out hw address */
|
||||
ARP *gw_arp = new ARP(gw, victim, gw_hw, info.hw_addr),
|
||||
*victim_arp = new ARP(victim, gw, victim_hw, info.hw_addr);
|
||||
ARP gw_arp(gw, victim, gw_hw, info.hw_addr),
|
||||
victim_arp(victim, gw, victim_hw, info.hw_addr);
|
||||
// We are "replying" ARP requests
|
||||
gw_arp->opcode(ARP::REPLY);
|
||||
victim_arp->opcode(ARP::REPLY);
|
||||
gw_arp.opcode(ARP::REPLY);
|
||||
victim_arp.opcode(ARP::REPLY);
|
||||
|
||||
/* The packet we'll send to the gateway and victim.
|
||||
* We include our hw address as the source address
|
||||
* in ethernet layer, to avoid possible packet dropping
|
||||
* performed by any routers. */
|
||||
EthernetII to_gw(iface, gw_hw, info.hw_addr, gw_arp);
|
||||
EthernetII to_victim(iface, victim_hw, info.hw_addr, victim_arp);
|
||||
while(true) {
|
||||
EthernetII to_gw = EthernetII(gw_hw, info.hw_addr) / gw_arp;
|
||||
EthernetII to_victim = EthernetII(victim_hw, info.hw_addr) / victim_arp;
|
||||
while (true) {
|
||||
// Just send them once every 5 seconds.
|
||||
sender.send(to_gw);
|
||||
sender.send(to_victim);
|
||||
sleep(5);
|
||||
sender.send(to_gw, iface);
|
||||
sender.send(to_victim, iface);
|
||||
#ifdef _WIN32
|
||||
Sleep(5000);
|
||||
#else
|
||||
sleep(5);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 3 && cout << "Usage: " << *argv << " <Gateway> <Victim>\n")
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " <<* argv << " <Gateway> <Victim>" << endl;
|
||||
return 1;
|
||||
}
|
||||
IPv4Address gw, victim;
|
||||
EthernetII::address_type own_hw;
|
||||
try {
|
||||
@@ -96,7 +107,7 @@ int main(int argc, char *argv[]) {
|
||||
gw = argv[1];
|
||||
victim = argv[2];
|
||||
}
|
||||
catch(...) {
|
||||
catch (...) {
|
||||
cout << "Invalid ip found...\n";
|
||||
return 2;
|
||||
}
|
||||
@@ -110,15 +121,15 @@ int main(int argc, char *argv[]) {
|
||||
// Find the interface hardware and ip address.
|
||||
info = iface.addresses();
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
catch (runtime_error& ex) {
|
||||
cout << ex.what() << endl;
|
||||
return 3;
|
||||
}
|
||||
try {
|
||||
return do_arp_spoofing(iface, gw, victim, info);
|
||||
do_arp_spoofing(iface, gw, victim, info);
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
std::cout << "Runtime error: " << ex.what() << std::endl;
|
||||
catch (runtime_error& ex) {
|
||||
cout << "Runtime error: " << ex.what() << endl;
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,47 +32,57 @@
|
||||
#include <string>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::set;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class BeaconSniffer {
|
||||
public:
|
||||
void run(const std::string &iface);
|
||||
void run(const string& iface);
|
||||
private:
|
||||
typedef Dot11::address_type address_type;
|
||||
typedef std::set<address_type> ssids_type;
|
||||
typedef set<address_type> ssids_type;
|
||||
|
||||
bool callback(PDU &pdu);
|
||||
bool callback(PDU& pdu);
|
||||
|
||||
ssids_type ssids;
|
||||
};
|
||||
|
||||
void BeaconSniffer::run(const std::string &iface) {
|
||||
Sniffer sniffer(iface, 1500, true, "type mgt subtype beacon");
|
||||
void BeaconSniffer::run(const std::string& iface) {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("type mgt subtype beacon");
|
||||
config.set_rfmon(true);
|
||||
Sniffer sniffer(iface, config);
|
||||
sniffer.sniff_loop(make_sniffer_handler(this, &BeaconSniffer::callback));
|
||||
}
|
||||
|
||||
bool BeaconSniffer::callback(PDU &pdu) {
|
||||
bool BeaconSniffer::callback(PDU& pdu) {
|
||||
// Get the Dot11 layer
|
||||
Dot11Beacon *beacon = pdu.find_pdu<Dot11Beacon>();
|
||||
const Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
|
||||
// All beacons must have from_ds == to_ds == 0
|
||||
if(beacon && !beacon->from_ds() && !beacon->to_ds()) {
|
||||
if (!beacon.from_ds() && !beacon.to_ds()) {
|
||||
// Get the AP address
|
||||
address_type addr = beacon->addr2();
|
||||
address_type addr = beacon.addr2();
|
||||
// Look it up in our set
|
||||
ssids_type::iterator it = ssids.find(addr);
|
||||
if(it == ssids.end()) {
|
||||
if (it == ssids.end()) {
|
||||
// First time we encounter this BSSID.
|
||||
try {
|
||||
/* If no ssid option is set, then Dot11::ssid will throw
|
||||
* a std::runtime_error.
|
||||
*/
|
||||
std::string ssid = beacon->ssid();
|
||||
string ssid = beacon.ssid();
|
||||
// Save it so we don't show it again.
|
||||
ssids.insert(addr);
|
||||
// Display the tuple "address - ssid".
|
||||
std::cout << addr << " - " << ssid << std::endl;
|
||||
cout << addr << " - " << ssid << endl;
|
||||
}
|
||||
catch(std::runtime_error&) {
|
||||
catch (runtime_error&) {
|
||||
// No ssid, just ignore it.
|
||||
}
|
||||
}
|
||||
@@ -81,10 +91,11 @@ bool BeaconSniffer::callback(PDU &pdu) {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// By default, sniff wlan0
|
||||
std::string interface = "wlan0";
|
||||
if(argc == 2)
|
||||
interface = argv[1];
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
string interface = argv[1];
|
||||
BeaconSniffer sniffer;
|
||||
sniffer.run(interface);
|
||||
}
|
||||
|
||||
4116
examples/configure
vendored
4116
examples/configure
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
AC_INIT(myconfig, 0.1)
|
||||
|
||||
AC_PROG_CXX()
|
||||
AC_LANG(C++)
|
||||
|
||||
if test -n "$debug"
|
||||
then
|
||||
CFLAGS="-DDEBUG -g"
|
||||
else
|
||||
CFLAGS="-O3"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([pcap.h])
|
||||
AC_CHECK_LIB(pcap, pcap_loop, [], [AC_MSG_ERROR([pcap library is needed!])])
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_OUTPUT(Makefile)
|
||||
118
examples/defragmenter.cpp
Normal file
118
examples/defragmenter.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "tins/ip.h"
|
||||
#include "tins/ip_reassembler.h"
|
||||
#include "tins/sniffer.h"
|
||||
#include "tins/packet_writer.h"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::exception;
|
||||
|
||||
using Tins::IPv4Reassembler;
|
||||
using Tins::IP;
|
||||
using Tins::Packet;
|
||||
using Tins::FileSniffer;
|
||||
using Tins::PacketWriter;
|
||||
using Tins::DataLinkType;
|
||||
|
||||
// This example reads packets from a pcap file and writes them to a new file.
|
||||
// If any IPv4 fragmented packets are found in the input file, then they will
|
||||
// be reassembled before writing them, so instead of the individual fragments
|
||||
// it will write the whole packet.
|
||||
|
||||
class Defragmenter {
|
||||
public:
|
||||
// Construct the sniffer and the packet writer using the sniffer's
|
||||
// data link type
|
||||
Defragmenter(const string& input_file, const string& output_file)
|
||||
: sniffer_(input_file),
|
||||
writer_(output_file, (PacketWriter::LinkType)sniffer_.link_type()),
|
||||
total_reassembled_(0) {
|
||||
|
||||
}
|
||||
|
||||
void run() {
|
||||
Packet packet;
|
||||
// Read packets and keep going until there's no more packets to read
|
||||
while (packet = sniffer_.next_packet()) {
|
||||
// Try to reassemble the packet
|
||||
IPv4Reassembler::PacketStatus status = reassembler_.process(*packet.pdu());
|
||||
|
||||
// If we did reassemble it, increase this counter
|
||||
if (status == IPv4Reassembler::REASSEMBLED) {
|
||||
total_reassembled_++;
|
||||
}
|
||||
|
||||
// Regardless, we'll write it into the output file unless it's fragmented
|
||||
// (and not yet reassembled)
|
||||
if (status != IPv4Reassembler::FRAGMENTED) {
|
||||
writer_.write(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t total_packets_reassembled() const {
|
||||
return total_reassembled_;
|
||||
}
|
||||
private:
|
||||
FileSniffer sniffer_;
|
||||
IPv4Reassembler reassembler_;
|
||||
PacketWriter writer_;
|
||||
uint64_t total_reassembled_;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " << argv[0] << " <input-file> <output-file>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
// Build the defragmented
|
||||
Defragmenter defragmenter(argv[1], argv[2]);
|
||||
cout << "Processing " << argv[1] << endl;
|
||||
cout << "Writing results to " << argv[2] << endl;
|
||||
|
||||
// Run!
|
||||
defragmenter.run();
|
||||
cout << "Done" << endl;
|
||||
cout << "Reassembled: " << defragmenter.total_packets_reassembled()
|
||||
<< " packet(s)" << endl;
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
68
examples/dns_queries.cpp
Normal file
68
examples/dns_queries.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
bool callback(const PDU& pdu) {
|
||||
// The packet probably looks like this:
|
||||
//
|
||||
// EthernetII / IP / UDP / RawPDU
|
||||
//
|
||||
// So we retrieve the RawPDU layer, and construct a
|
||||
// DNS PDU using its contents.
|
||||
DNS dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
|
||||
|
||||
// Retrieve the queries and print the domain name:
|
||||
for (const auto& query : dns.queries()) {
|
||||
cout << query.dname() << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
// Only capture udp packets sent to port 53
|
||||
config.set_filter("udp and dst port 53");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// Start the capture
|
||||
sniffer.sniff_loop(callback);
|
||||
}
|
||||
107
examples/dns_spoof.cpp
Normal file
107
examples/dns_spoof.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
PacketSender sender;
|
||||
|
||||
bool callback(const PDU& pdu) {
|
||||
// The packet probably looks like this:
|
||||
//
|
||||
// EthernetII / IP / UDP / RawPDU
|
||||
//
|
||||
// So we retrieve each layer, and construct a
|
||||
// DNS PDU from the RawPDU layer contents.
|
||||
EthernetII eth = pdu.rfind_pdu<EthernetII>();
|
||||
IP ip = eth.rfind_pdu<IP>();
|
||||
UDP udp = ip.rfind_pdu<UDP>();
|
||||
DNS dns = udp.rfind_pdu<RawPDU>().to<DNS>();
|
||||
|
||||
// Is it a DNS query?
|
||||
if (dns.type() == DNS::QUERY) {
|
||||
// Let's see if there's any query for an "A" record.
|
||||
for (const auto& query : dns.queries()) {
|
||||
if (query.query_type() == DNS::A) {
|
||||
// Here's one! Let's add an answer.
|
||||
dns.add_answer(
|
||||
DNS::resource(
|
||||
query.dname(),
|
||||
"127.0.0.1",
|
||||
DNS::A,
|
||||
query.query_class(),
|
||||
// 777 is just a random TTL
|
||||
777
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// Have we added some answers?
|
||||
if (dns.answers_count() > 0) {
|
||||
// It's a response now
|
||||
dns.type(DNS::RESPONSE);
|
||||
// Recursion is available(just in case)
|
||||
dns.recursion_available(1);
|
||||
// Build our packet
|
||||
auto pkt = EthernetII(eth.src_addr(), eth.dst_addr()) /
|
||||
IP(ip.src_addr(), ip.dst_addr()) /
|
||||
UDP(udp.sport(), udp.dport()) /
|
||||
dns;
|
||||
// Send it!
|
||||
sender.send(pkt);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
// Use immediate mode so we get the packets as fast as we can
|
||||
config.set_immediate_mode(true);
|
||||
// Only capture udp packets sent to port 53
|
||||
config.set_filter("udp and dst port 53");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// All packets will be sent through the provided interface
|
||||
sender.default_interface(argv[1]);
|
||||
|
||||
// Start the capture
|
||||
sniffer.sniff_loop(callback);
|
||||
}
|
||||
218
examples/dns_stats.cpp
Normal file
218
examples/dns_stats.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#endif // _WIN32
|
||||
|
||||
// Fix for gcc 4.6
|
||||
#define _GLIBCXX_USE_NANOSLEEP
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::thread;
|
||||
using std::string;
|
||||
using std::bind;
|
||||
using std::map;
|
||||
using std::mutex;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::exception;
|
||||
using std::lock_guard;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::chrono::seconds;
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::system_clock;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// Holds the DNS response time statistics. The response time is
|
||||
// represented using the Duration template parameter.
|
||||
template<typename Duration>
|
||||
class statistics {
|
||||
public:
|
||||
typedef Duration duration_type;
|
||||
typedef lock_guard<mutex> locker_type;
|
||||
|
||||
struct information {
|
||||
duration_type average, worst;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
statistics()
|
||||
: m_duration(), m_worst(duration_type::min()), m_count() {
|
||||
|
||||
}
|
||||
|
||||
void add_response_time(const duration_type& duration) {
|
||||
locker_type _(m_lock);
|
||||
m_duration += duration;
|
||||
m_count++;
|
||||
m_worst = max(m_worst, duration);
|
||||
}
|
||||
|
||||
information get_information() const {
|
||||
locker_type _(m_lock);
|
||||
if(m_count == 0) {
|
||||
return { };
|
||||
}
|
||||
else {
|
||||
return { m_duration / m_count, m_worst, m_count };
|
||||
}
|
||||
};
|
||||
private:
|
||||
duration_type m_duration, m_worst;
|
||||
size_t m_count;
|
||||
mutable mutex m_lock;
|
||||
};
|
||||
|
||||
// Sniffs and tracks DNS queries. When a matching DNS response is found,
|
||||
// the response time is added to a statistics object.
|
||||
//
|
||||
// This class performs* no cleanup* on data associated with queries that
|
||||
// weren't answered.
|
||||
class dns_monitor {
|
||||
public:
|
||||
// The response times are measured in milliseconds
|
||||
typedef milliseconds duration_type;
|
||||
// The statistics type used.
|
||||
typedef statistics<duration_type> statistics_type;
|
||||
|
||||
void run(BaseSniffer& sniffer);
|
||||
const statistics_type& stats() const {
|
||||
return m_stats;
|
||||
}
|
||||
private:
|
||||
typedef tuple<IPv4Address, IPv4Address, uint16_t> packet_info;
|
||||
typedef system_clock clock_type;
|
||||
typedef clock_type::time_point time_point_type;
|
||||
|
||||
bool callback(const PDU& pdu);
|
||||
static packet_info make_packet_info(const PDU& pdu, const DNS& dns);
|
||||
|
||||
statistics_type m_stats;
|
||||
map<packet_info, time_point_type> m_packet_info;
|
||||
};
|
||||
|
||||
void dns_monitor::run(BaseSniffer& sniffer) {
|
||||
sniffer.sniff_loop(
|
||||
bind(
|
||||
&dns_monitor::callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bool dns_monitor::callback(const PDU& pdu) {
|
||||
auto now = clock_type::now();
|
||||
auto dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
|
||||
auto info = make_packet_info(pdu, dns);
|
||||
// If it's a query, add the sniff time to our map.
|
||||
if (dns.type() == DNS::QUERY) {
|
||||
m_packet_info.insert(
|
||||
std::make_pair(info, now)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// It's a response, we need to find the query in our map.
|
||||
auto iter = m_packet_info.find(info);
|
||||
if (iter != m_packet_info.end()) {
|
||||
// We found the query, let's add the response time to the
|
||||
// statistics object.
|
||||
m_stats.add_response_time(
|
||||
duration_cast<duration_type>(now - iter->second)
|
||||
);
|
||||
// Forget about the query.
|
||||
m_packet_info.erase(iter);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// It is required that we can identify packets sent and received that
|
||||
// hold the same DNS id as belonging to the same query.
|
||||
//
|
||||
// This function retrieves a tuple (addr, addr, id) that will achieve it.
|
||||
auto dns_monitor::make_packet_info(const PDU& pdu, const DNS& dns) -> packet_info {
|
||||
const auto& ip = pdu.rfind_pdu<IP>();
|
||||
return make_tuple(
|
||||
// smallest address first
|
||||
min(ip.src_addr(), ip.dst_addr()),
|
||||
// largest address second
|
||||
max(ip.src_addr(), ip.dst_addr()),
|
||||
dns.id()
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
string iface;
|
||||
if (argc == 2) {
|
||||
// Use the provided interface
|
||||
iface = argv[1];
|
||||
}
|
||||
else {
|
||||
// Use the default interface
|
||||
iface = NetworkInterface::default_interface().name();
|
||||
}
|
||||
try {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("udp and port 53");
|
||||
Sniffer sniffer(iface, config);
|
||||
dns_monitor monitor;
|
||||
thread thread(
|
||||
[&]() {
|
||||
monitor.run(sniffer);
|
||||
}
|
||||
);
|
||||
while (true) {
|
||||
auto info = monitor.stats().get_information();
|
||||
cout << "\rAverage " << info.average.count()
|
||||
<< "ms. Worst: " << info.worst.count() << "ms. Count: "
|
||||
<< info.count << " ";
|
||||
cout.flush();
|
||||
sleep_for(seconds(1));
|
||||
}
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "[-] Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
147
examples/http_requests.cpp
Normal file
147
examples/http_requests.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <boost/regex.hpp>
|
||||
#include "tins/tcp_ip/stream_follower.h"
|
||||
#include "tins/sniffer.h"
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::exception;
|
||||
|
||||
using boost::regex;
|
||||
using boost::match_results;
|
||||
|
||||
using Tins::PDU;
|
||||
using Tins::Sniffer;
|
||||
using Tins::SnifferConfiguration;
|
||||
using Tins::TCPIP::Stream;
|
||||
using Tins::TCPIP::StreamFollower;
|
||||
|
||||
// This example captures and follows TCP streams seen on port 80. It will
|
||||
// wait until both the client and server send data and then apply a regex
|
||||
// to both payloads, extrating some information and printing it.
|
||||
|
||||
// Don't buffer more than 3kb of data in either request/response
|
||||
const size_t MAX_PAYLOAD = 3 * 1024;
|
||||
// The regex to be applied on the request. This will extract the HTTP
|
||||
// method being used, the request's path and the Host header value.
|
||||
regex request_regex("([\\w]+) ([^ ]+).+\r\nHost: ([\\d\\w\\.-]+)\r\n");
|
||||
// The regex to be applied on the response. This finds the response code.
|
||||
regex response_regex("HTTP/[^ ]+ ([\\d]+)");
|
||||
|
||||
void on_server_data(Stream& stream) {
|
||||
match_results<Stream::payload_type::const_iterator> client_match;
|
||||
match_results<Stream::payload_type::const_iterator> server_match;
|
||||
const Stream::payload_type& client_payload = stream.client_payload();
|
||||
const Stream::payload_type& server_payload = stream.server_payload();
|
||||
// Run the regexes on client/server payloads
|
||||
bool valid = regex_search(server_payload.begin(), server_payload.end(),
|
||||
server_match, response_regex) &&
|
||||
regex_search(client_payload.begin(), client_payload.end(),
|
||||
client_match, request_regex);
|
||||
// If we matched both the client and the server regexes
|
||||
if (valid) {
|
||||
// Extract all fields
|
||||
string method = string(client_match[1].first, client_match[1].second);
|
||||
string url = string(client_match[2].first, client_match[2].second);
|
||||
string host = string(client_match[3].first, client_match[3].second);
|
||||
string response_code = string(server_match[1].first, server_match[1].second);
|
||||
// Now print them
|
||||
cout << method << " http://" << host << url << " -> " << response_code << endl;
|
||||
|
||||
// Once we've seen the first request on this stream, ignore it
|
||||
stream.ignore_client_data();
|
||||
stream.ignore_server_data();
|
||||
}
|
||||
|
||||
// Just in case the server returns invalid data, stop at 3kb
|
||||
if (stream.server_payload().size() > MAX_PAYLOAD) {
|
||||
stream.ignore_server_data();
|
||||
}
|
||||
}
|
||||
|
||||
void on_client_data(Stream& stream) {
|
||||
// Don't hold more than 3kb of data from the client's flow
|
||||
if (stream.client_payload().size() > MAX_PAYLOAD) {
|
||||
stream.ignore_client_data();
|
||||
}
|
||||
}
|
||||
|
||||
void on_new_connection(Stream& stream) {
|
||||
stream.client_data_callback(&on_client_data);
|
||||
stream.server_data_callback(&on_server_data);
|
||||
// Don't automatically cleanup the stream's data, as we'll manage
|
||||
// the buffer ourselves and let it grow until we see a full request
|
||||
// and response
|
||||
stream.auto_cleanup_payloads(false);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " << argv[0] << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
// Construct the sniffer configuration object
|
||||
SnifferConfiguration config;
|
||||
// Get packets as quickly as possible
|
||||
config.set_immediate_mode(true);
|
||||
// Only capture TCP traffic sent from/to port 80
|
||||
config.set_filter("tcp port 80");
|
||||
// Construct the sniffer we'll use
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
cout << "Starting capture on interface " << argv[1] << endl;
|
||||
|
||||
// Now construct the stream follower
|
||||
StreamFollower follower;
|
||||
// We just need to specify the callback to be executed when a new
|
||||
// stream is captured. In this stream, you should define which callbacks
|
||||
// will be executed whenever new data is sent on that stream
|
||||
// (see on_new_connection)
|
||||
follower.new_stream_callback(&on_new_connection);
|
||||
// Now start capturing. Every time there's a new packet, call
|
||||
// follower.process_packet
|
||||
sniffer.sniff_loop([&](PDU& packet) {
|
||||
follower.process_packet(packet);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
140
examples/icmp_responses.cpp
Normal file
140
examples/icmp_responses.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::bind;
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
using std::exception;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// This class captured packets on an interface, using the specified filter
|
||||
// and will respond with ICMP error packets whenever a packet is captured.
|
||||
// The response mechanism is pretty naive as it generates a packet which
|
||||
// has swapped HW and IP addresses (dst as src, src as dst).
|
||||
class ICMPResponder {
|
||||
public:
|
||||
// Use the given interface and ICMP type/code on responses
|
||||
ICMPResponder(string iface, int type, int code)
|
||||
: m_iface(iface), m_sender(iface), m_type(type), m_code(code) {
|
||||
|
||||
}
|
||||
|
||||
// Run using the given filter
|
||||
void run(const string& filter) {
|
||||
// Initialize the configuration
|
||||
SnifferConfiguration config;
|
||||
// Use promiscuous mode
|
||||
config.set_promisc_mode(true);
|
||||
// Use this packet filter
|
||||
config.set_filter(filter);
|
||||
// Use immediate mode (we don't want to buffer packets, we want the mright away).
|
||||
config.set_immediate_mode(true);
|
||||
|
||||
// Now create the Sniffer
|
||||
Sniffer sniffer(m_iface, config);
|
||||
if (sniffer.link_type() != DLT_EN10MB) {
|
||||
throw runtime_error("Ethernet interfaces only supported");
|
||||
}
|
||||
// Start the sniffing! For each packet, ICMPReponder::callback will be called
|
||||
sniffer.sniff_loop(bind(&ICMPResponder::callback, this, std::placeholders::_1));
|
||||
}
|
||||
private:
|
||||
// Extracts the payload to be used over the ICMP layer in the response.
|
||||
// This will be the entire IP header + 8 bytes of the next header.
|
||||
RawPDU extract_icmp_payload(IP& pdu) {
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
// Use whole IP + 8 bytes of next header.
|
||||
size_t end_index = pdu.header_size() + 8;
|
||||
return RawPDU(buffer.begin(), buffer.begin() + end_index);
|
||||
}
|
||||
|
||||
// Generates an ICMP response given a packet.
|
||||
EthernetII generate_response(PDU& pdu) {
|
||||
// Find Ethernet and IP headers.
|
||||
EthernetII& received_eth = pdu.rfind_pdu<EthernetII>();
|
||||
IP& received_ip = pdu.rfind_pdu<IP>();
|
||||
|
||||
// Create an Ethernet response, flipping the addresses
|
||||
EthernetII output(received_eth.src_addr(), received_eth.dst_addr());
|
||||
// Append an IP PDU, again flipping addresses.
|
||||
//output /= IP(received_ip.src_addr(), received_ip.dst_addr());
|
||||
output /= IP(received_ip.src_addr(), "8.8.8.8");
|
||||
|
||||
// Now generate the ICMP layer using the type and code provided.
|
||||
ICMP icmp;
|
||||
icmp.type(static_cast<ICMP::Flags>(m_type));
|
||||
icmp.code(m_code);
|
||||
// Append the ICMP layer to our packet
|
||||
output /= icmp;
|
||||
// Extract the payload to be used over ICMP.
|
||||
output /= extract_icmp_payload(received_ip);
|
||||
return output;
|
||||
}
|
||||
|
||||
// Packet capture callback
|
||||
bool callback(PDU& pdu) {
|
||||
// Generate a response for this packet
|
||||
EthernetII response = generate_response(pdu);
|
||||
// Send this packet!
|
||||
m_sender.send(response);
|
||||
return true;
|
||||
}
|
||||
|
||||
string m_iface;
|
||||
PacketSender m_sender;
|
||||
int m_type;
|
||||
int m_code;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const int type = 3;
|
||||
const int code = 0;
|
||||
if (argc < 3) {
|
||||
cout << "Usage: " << argv[0] << " <interface> <pcap_filter>" << endl;
|
||||
return 1;
|
||||
}
|
||||
string iface = argv[1];
|
||||
string filter = argv[2];
|
||||
try {
|
||||
ICMPResponder responder(iface, type, code);
|
||||
responder.run(filter);
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
87
examples/interfaces_info.cpp
Normal file
87
examples/interfaces_info.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <tins/network_interface.h>
|
||||
|
||||
using std::cout;
|
||||
using std::wcout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
int main() {
|
||||
// Get all interfaces and iterate over them.
|
||||
for (const NetworkInterface& iface : NetworkInterface::all()) {
|
||||
// Get the name of this interface
|
||||
string name = iface.name();
|
||||
|
||||
// "stringify" the status of the interface
|
||||
string status = iface.is_up() ? "up" : "down";
|
||||
|
||||
// Get this interface's information (addresses).
|
||||
NetworkInterface::Info info = iface.info();
|
||||
|
||||
// Now print all of this info.
|
||||
cout << name;
|
||||
|
||||
#ifdef _WIN32
|
||||
// If this is running on Windows, also print the friendly name
|
||||
wcout << " (" << iface.friendly_name() << ")";
|
||||
#endif // _WIN32
|
||||
cout << ": " << endl;
|
||||
|
||||
string ipv6_string;
|
||||
if (info.ipv6_addrs.empty()) {
|
||||
ipv6_string = "(none)";
|
||||
}
|
||||
else {
|
||||
ostringstream oss;
|
||||
for (size_t i = 0; i < info.ipv6_addrs.size(); ++i) {
|
||||
const NetworkInterface::IPv6Prefix& prefix = info.ipv6_addrs[i];
|
||||
if (i > 0) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << prefix.address << "/" << prefix.prefix_length;
|
||||
}
|
||||
ipv6_string = oss.str();
|
||||
}
|
||||
cout << " HW address: " << info.hw_addr << endl
|
||||
<< " IP address: " << info.ip_addr << endl
|
||||
<< " IPv6 addresses: " << ipv6_string << endl
|
||||
<< " Netmask: " << info.netmask << endl
|
||||
<< " Broadcast: " << info.bcast_addr << endl
|
||||
<< " Iface index: " << iface.id() << endl
|
||||
<< " Status: " << "interface " << status << endl << endl;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,9 +30,11 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <tins/ip.h>
|
||||
#include <tins/tcp.h>
|
||||
#include <tins/ip_address.h>
|
||||
@@ -42,49 +44,114 @@
|
||||
#include <tins/utils.h>
|
||||
#include <tins/packet_sender.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
using std::setw;
|
||||
using std::string;
|
||||
using std::set;
|
||||
using std::runtime_error;
|
||||
|
||||
using namespace std;
|
||||
using namespace Tins;
|
||||
|
||||
typedef std::pair<Sniffer*, std::string> sniffer_data;
|
||||
typedef pair<Sniffer*, string> sniffer_data;
|
||||
|
||||
class Scanner {
|
||||
public:
|
||||
Scanner(const NetworkInterface& interface,
|
||||
const IPv4Address& address,
|
||||
const vector<string>& ports);
|
||||
|
||||
void run();
|
||||
private:
|
||||
void send_syns(const NetworkInterface& iface, IPv4Address dest_ip);
|
||||
bool callback(PDU& pdu);
|
||||
static void* thread_proc(void* param);
|
||||
void launch_sniffer();
|
||||
|
||||
NetworkInterface iface;
|
||||
IPv4Address host_to_scan;
|
||||
set<uint16_t> ports_to_scan;
|
||||
Sniffer sniffer;
|
||||
};
|
||||
|
||||
Scanner::Scanner(const NetworkInterface& interface,
|
||||
const IPv4Address& address,
|
||||
const vector<string>& ports)
|
||||
: iface(interface), host_to_scan(address), sniffer(interface.name()) {
|
||||
sniffer.set_filter(
|
||||
"tcp and ip src " + address.to_string() + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0"
|
||||
);
|
||||
for (size_t i = 0; i < ports.size(); ++i) {
|
||||
ports_to_scan.insert(atoi(ports[i].c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void* Scanner::thread_proc(void* param) {
|
||||
Scanner* data = (Scanner*)param;
|
||||
data->launch_sniffer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scanner::launch_sniffer() {
|
||||
sniffer.sniff_loop(make_sniffer_handler(this, &Scanner::callback));
|
||||
}
|
||||
|
||||
/* Our scan handler. This will receive SYNs and RSTs and inform us
|
||||
* the scanned port's status.
|
||||
*/
|
||||
bool handler(PDU &pdu) {
|
||||
TCP *tcp = pdu.find_pdu<TCP>();
|
||||
if(tcp) {
|
||||
bool Scanner::callback(PDU& pdu) {
|
||||
// Find the layers we want.
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
||||
// Check if the host that we're scanning sent this packet and
|
||||
// the source port is one of those that we scanned.
|
||||
if(ip.src_addr() == host_to_scan && ports_to_scan.count(tcp.sport()) == 1) {
|
||||
// Ok, it's a TCP PDU. Is RST flag on? Then port is closed.
|
||||
if(tcp->get_flag(TCP::RST)) {
|
||||
if(tcp.get_flag(TCP::RST)) {
|
||||
// This indicates we should stop sniffing.
|
||||
if(tcp->get_flag(TCP::SYN))
|
||||
if(tcp.get_flag(TCP::SYN))
|
||||
return false;
|
||||
cout << "Port: " << setw(5) << tcp->sport() << " closed\n";
|
||||
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
|
||||
}
|
||||
// Is SYN flag on? Then port is open!
|
||||
else if(tcp->get_flag(TCP::SYN) && tcp->get_flag(TCP::ACK))
|
||||
cout << "Port: " << setw(5) << tcp->sport() << " open\n";
|
||||
else if(tcp.has_flags(TCP::SYN | TCP::ACK)) {
|
||||
cout << "Port: " << setw(5) << tcp.sport() << " open\n";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scanner::run() {
|
||||
pthread_t thread;
|
||||
// Launch our sniff thread.
|
||||
pthread_create(&thread, 0, &Scanner::thread_proc, this);
|
||||
// Start sending SYNs to port.
|
||||
send_syns(iface, host_to_scan);
|
||||
|
||||
// Wait for our sniffer.
|
||||
void* dummy;
|
||||
pthread_join(thread, &dummy);
|
||||
}
|
||||
|
||||
// Send syns to the given ip address, using the destination ports provided.
|
||||
void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<string> &ips) {
|
||||
void Scanner::send_syns(const NetworkInterface& iface, IPv4Address dest_ip) {
|
||||
// Retrieve the addresses.
|
||||
NetworkInterface::Info info = iface.addresses();
|
||||
PacketSender sender;
|
||||
TCP *tcp = new TCP();
|
||||
// Allocate the IP PDU
|
||||
IP ip(dest_ip, info.ip_addr, tcp);
|
||||
IP ip = IP(dest_ip, info.ip_addr) / TCP();
|
||||
// Get the reference to the TCP PDU
|
||||
TCP& tcp = ip.rfind_pdu<TCP>();
|
||||
// Set the SYN flag on.
|
||||
tcp->set_flag(TCP::SYN, 1);
|
||||
// Just some arbitrary port.
|
||||
tcp->sport(1337);
|
||||
tcp.set_flag(TCP::SYN, 1);
|
||||
// Just some random port.
|
||||
tcp.sport(1337);
|
||||
cout << "Sending SYNs..." << endl;
|
||||
for(vector<string>::const_iterator it = ips.begin(); it != ips.end(); ++it) {
|
||||
for (set<uint16_t>::const_iterator it = ports_to_scan.begin(); it != ports_to_scan.end(); ++it) {
|
||||
// Set the new port and send the packet!
|
||||
tcp->dport(atoi(it->c_str()));
|
||||
tcp.dport(*it);
|
||||
sender.send(ip);
|
||||
}
|
||||
// Wait 1 second.
|
||||
@@ -92,55 +159,37 @@ void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<
|
||||
/* Special packet to indicate that we're done. This will be sniffed
|
||||
* by our function, which will in turn return false.
|
||||
*/
|
||||
tcp->set_flag(TCP::RST, 1);
|
||||
tcp.set_flag(TCP::RST, 1);
|
||||
tcp.sport(*ports_to_scan.begin());
|
||||
// Pretend we're the scanned host...
|
||||
ip.src_addr(dest_ip);
|
||||
// We use an ethernet pdu, otherwise the kernel will drop it.
|
||||
EthernetII eth(iface, info.hw_addr, info.hw_addr, ip.clone());
|
||||
sender.send(eth);
|
||||
EthernetII eth = EthernetII(info.hw_addr, info.hw_addr) / ip;
|
||||
sender.send(eth, iface);
|
||||
}
|
||||
|
||||
void *thread_proc(void *param) {
|
||||
// IP address is our parameter.
|
||||
sniffer_data *data = (sniffer_data*)param;
|
||||
Sniffer *sniffer = data->first;
|
||||
sniffer->set_filter("tcp and ip src " + data->second + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0");
|
||||
// Sniff loop. Only sniff TCP PDUs comming from the given IP and have either RST or SYN flag on.
|
||||
sniffer->sniff_loop(handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scan(int argc, char *argv[]) {
|
||||
void scan(int argc, char* argv[]) {
|
||||
IPv4Address ip(argv[1]);
|
||||
// Resolve the interface which will be our gateway
|
||||
NetworkInterface iface(ip);
|
||||
cout << "Sniffing on interface: " << iface.name() << endl;
|
||||
|
||||
// 300 bytes are enough to receive SYNs and RSTs.
|
||||
Sniffer sniffer(iface.name(), 300);
|
||||
sniffer_data data(&sniffer, argv[1]);
|
||||
pthread_t thread;
|
||||
// Launch our sniff thread.
|
||||
pthread_create(&thread, 0, thread_proc, &data);
|
||||
|
||||
// Consume arguments
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
// Start sending SYNs to port.
|
||||
send_syns(iface, ip, vector<string>(argv, argv + (argc)));
|
||||
|
||||
// Wait for our sniffer.
|
||||
void *dummy;
|
||||
pthread_join(thread, &dummy);
|
||||
Scanner scanner(iface, ip, vector<string>(argv, argv + (argc)));
|
||||
scanner.run();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc < 3 && cout << "Usage: " << *argv << " <IPADDR> <port1> [port2] [port3]\n")
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 3) {
|
||||
cout << "Usage: " <<* argv << " <IPADDR> <port1> [port2] [port3]" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
scan(argc, argv);
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
catch(runtime_error& ex) {
|
||||
cout << "Error - " << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
69
examples/route_table.cpp
Normal file
69
examples/route_table.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::vector;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
int main() {
|
||||
vector<Utils::RouteEntry> v4_entries = Utils::route_entries();
|
||||
cout << "IPv4 route table entries: " << endl
|
||||
<< "========================= " << endl;
|
||||
for (size_t i = 0; i < v4_entries.size(); ++i) {
|
||||
cout << "Entry " << setw(2) << i << ": " << endl
|
||||
<< "Interface: " << v4_entries[i].interface << endl
|
||||
<< "Destination: " << v4_entries[i].destination << endl
|
||||
<< "Gateway: " << v4_entries[i].gateway << endl
|
||||
<< "Genmask: " << v4_entries[i].mask << endl
|
||||
<< "Metric: " << v4_entries[i].metric << endl << endl;
|
||||
}
|
||||
|
||||
vector<Utils::Route6Entry> v6_entries = Utils::route6_entries();
|
||||
if (!v6_entries.empty()) {
|
||||
cout << endl
|
||||
<< "IPv6 route table entries: " << endl
|
||||
<< "========================= " << endl;
|
||||
for (size_t i = 0; i < v6_entries.size(); ++i) {
|
||||
cout << "Entry " << setw(2) << i << ": " << endl
|
||||
<< "Interface: " << v6_entries[i].interface << endl
|
||||
<< "Destination: " << v6_entries[i].destination << endl
|
||||
<< "Gateway: " << v6_entries[i].gateway << endl
|
||||
<< "Genmask: " << v6_entries[i].mask << endl
|
||||
<< "Metric: " << v6_entries[i].metric << endl << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
192
examples/stream_dump.cpp
Normal file
192
examples/stream_dump.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "tins/tcp_ip/stream_follower.h"
|
||||
#include "tins/sniffer.h"
|
||||
#include "tins/packet.h"
|
||||
#include "tins/ip_address.h"
|
||||
#include "tins/ipv6_address.h"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::bind;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::ostringstream;
|
||||
using std::exception;
|
||||
|
||||
using Tins::Sniffer;
|
||||
using Tins::SnifferConfiguration;
|
||||
using Tins::PDU;
|
||||
using Tins::TCPIP::StreamFollower;
|
||||
using Tins::TCPIP::Stream;
|
||||
|
||||
// This example takes an interface and a port as an argument and
|
||||
// it listens for TCP streams on the given interface and port.
|
||||
// It will reassemble TCP streams and show the traffic sent by
|
||||
// both the client and the server.
|
||||
|
||||
// Convert the client endpoint to a readable string
|
||||
string client_endpoint(const Stream& stream) {
|
||||
ostringstream output;
|
||||
// Use the IPv4 or IPv6 address depending on which protocol the
|
||||
// connection uses
|
||||
if (stream.is_v6()) {
|
||||
output << stream.client_addr_v6();
|
||||
}
|
||||
else {
|
||||
output << stream.client_addr_v4();
|
||||
}
|
||||
output << ":" << stream.client_port();
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Convert the server endpoint to a readable string
|
||||
string server_endpoint(const Stream& stream) {
|
||||
ostringstream output;
|
||||
if (stream.is_v6()) {
|
||||
output << stream.server_addr_v6();
|
||||
}
|
||||
else {
|
||||
output << stream.server_addr_v4();
|
||||
}
|
||||
output << ":" << stream.server_port();
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Concat both endpoints to get a readable stream identifier
|
||||
string stream_identifier(const Stream& stream) {
|
||||
ostringstream output;
|
||||
output << client_endpoint(stream) << " - " << server_endpoint(stream);
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Whenever there's new client data on the stream, this callback is executed.
|
||||
void on_client_data(Stream& stream) {
|
||||
// Construct a string out of the contents of the client's payload
|
||||
string data(stream.client_payload().begin(), stream.client_payload().end());
|
||||
|
||||
// Now print it, prepending some information about the stream
|
||||
cout << client_endpoint(stream) << " >> "
|
||||
<< server_endpoint(stream) << ": " << endl << data << endl;
|
||||
}
|
||||
|
||||
// Whenever there's new server data on the stream, this callback is executed.
|
||||
// This does the same thing as on_client_data
|
||||
void on_server_data(Stream& stream) {
|
||||
string data(stream.server_payload().begin(), stream.server_payload().end());
|
||||
cout << server_endpoint(stream) << " >> "
|
||||
<< client_endpoint(stream) << ": " << endl << data << endl;
|
||||
}
|
||||
|
||||
// When a connection is closed, this callback is executed.
|
||||
void on_connection_closed(Stream& stream) {
|
||||
cout << "[+] Connection closed: " << stream_identifier(stream) << endl;
|
||||
}
|
||||
|
||||
// When a new connection is captured, this callback will be executed.
|
||||
void on_new_connection(Stream& stream) {
|
||||
if (stream.is_partial_stream()) {
|
||||
// We found a partial stream. This means this connection/stream had
|
||||
// been established before we started capturing traffic.
|
||||
//
|
||||
// In this case, we need to allow for the stream to catch up, as we
|
||||
// may have just captured an out of order packet and if we keep waiting
|
||||
// for the holes to be filled, we may end up waiting forever.
|
||||
//
|
||||
// Calling enable_recovery_mode will skip out of order packets that
|
||||
// fall withing the range of the given window size.
|
||||
// See Stream::enable_recover_mode for more information
|
||||
cout << "[+] New connection " << stream_identifier(stream) << endl;
|
||||
|
||||
// Enable recovery mode using a window of 10kb
|
||||
stream.enable_recovery_mode(10 * 1024);
|
||||
}
|
||||
else {
|
||||
// Print some information about the new connection
|
||||
cout << "[+] New connection " << stream_identifier(stream) << endl;
|
||||
}
|
||||
|
||||
// Now configure the callbacks on it.
|
||||
// First, we want on_client_data to be called every time there's new client data
|
||||
stream.client_data_callback(&on_client_data);
|
||||
|
||||
// Same thing for server data, but calling on_server_data
|
||||
stream.server_data_callback(&on_server_data);
|
||||
|
||||
// When the connection is closed, call on_connection_closed
|
||||
stream.stream_closed_callback(&on_connection_closed);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " << argv[0] << " <interface> <port>" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
// Construct the sniffer configuration object
|
||||
SnifferConfiguration config;
|
||||
|
||||
// Only capture TCP traffic sent from/to the given port
|
||||
config.set_filter("tcp port " + to_string(stoi(string(argv[2]))));
|
||||
|
||||
// Construct the sniffer we'll use
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
cout << "Starting capture on interface " << argv[1] << endl;
|
||||
|
||||
// Now construct the stream follower
|
||||
StreamFollower follower;
|
||||
|
||||
// We just need to specify the callback to be executed when a new
|
||||
// stream is captured. In this stream, you should define which callbacks
|
||||
// will be executed whenever new data is sent on that stream
|
||||
// (see on_new_connection)
|
||||
follower.new_stream_callback(&on_new_connection);
|
||||
|
||||
// Allow following partial TCP streams (e.g. streams that were
|
||||
// open before the sniffer started running)
|
||||
follower.follow_partial_streams(true);
|
||||
|
||||
// Now start capturing. Every time there's a new packet, call
|
||||
// follower.process_packet
|
||||
sniffer.sniff_loop([&](PDU& packet) {
|
||||
follower.process_packet(packet);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
107
examples/tcp_connection_close.cpp
Normal file
107
examples/tcp_connection_close.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::string;
|
||||
using std::bind;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::exception;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// This example will capture TCP packets and send packet that will reset
|
||||
// the connection when it captures a packet with the SYN and ACK flags on.
|
||||
class tcp_connection_closer {
|
||||
public:
|
||||
tcp_connection_closer() {
|
||||
|
||||
}
|
||||
|
||||
void run(const string& interface) {
|
||||
using std::placeholders::_1;
|
||||
// Make the PacketSender use this interface by default
|
||||
sender_.default_interface(interface);
|
||||
|
||||
// Create the sniffer configuration
|
||||
SnifferConfiguration config;
|
||||
config.set_filter("tcp");
|
||||
// We want to get the packets as fast as possible
|
||||
config.set_immediate_mode(true);
|
||||
// Create the sniffer and start the capture
|
||||
Sniffer sniffer(interface, config);
|
||||
sniffer.sniff_loop(bind(&tcp_connection_closer::callback, this, _1));
|
||||
}
|
||||
private:
|
||||
bool callback(const PDU& pdu) {
|
||||
const EthernetII& eth = pdu.rfind_pdu<EthernetII>();
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
||||
// We'll only close a connection when seeing a SYN|ACK
|
||||
if (tcp.has_flags(TCP::SYN | TCP::ACK)) {
|
||||
// Create an ethernet header flipping the addresses
|
||||
EthernetII packet(eth.src_addr(), eth.dst_addr());
|
||||
// Do the same for IP
|
||||
packet /= IP(ip.src_addr(), ip.dst_addr());
|
||||
// Flip TCP ports
|
||||
TCP response_tcp(tcp.sport(), tcp.dport());
|
||||
// Set RST|ACK flags
|
||||
response_tcp.flags(TCP::RST | TCP::ACK);
|
||||
// Use the right sequence and ack numbers
|
||||
response_tcp.seq(tcp.ack_seq());
|
||||
response_tcp.ack_seq(tcp.seq());
|
||||
// Add this PDU to the packet we'll send
|
||||
packet /= response_tcp;
|
||||
// Send it!
|
||||
sender_.send(packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PacketSender sender_;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " << *argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
tcp_connection_closer closer;
|
||||
closer.run(argv[1]);
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "[-] Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,15 +27,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#endif // _WIN32
|
||||
|
||||
// Fix for gcc 4.6
|
||||
#define _GLIBCXX_USE_NANOSLEEP
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::move;
|
||||
using std::map;
|
||||
using std::min;
|
||||
using std::setw;
|
||||
using std::atomic;
|
||||
using std::runtime_error;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::thread;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::lock_guard;
|
||||
using std::mutex;
|
||||
using std::random_device;
|
||||
using std::numeric_limits;
|
||||
using std::bind;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class Traceroute {
|
||||
@@ -43,115 +73,139 @@ public:
|
||||
typedef std::map<uint16_t, IPv4Address> result_type;
|
||||
|
||||
Traceroute(NetworkInterface interface, IPv4Address address)
|
||||
: iface(interface), addr(address) { }
|
||||
: iface(interface), addr(address), lowest_dest_ttl(numeric_limits<int>::max()) {
|
||||
sequence = random_device()() & 0xffff;
|
||||
}
|
||||
|
||||
result_type trace() {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(false);
|
||||
// ICMPs that aren't sent from us.
|
||||
Sniffer sniffer(
|
||||
iface.name(), 500, false,
|
||||
"ip proto \\icmp and not src host " + iface.addresses().ip_addr.to_string()
|
||||
);
|
||||
config.set_filter(
|
||||
"ip proto \\icmp and not src host " + iface.addresses().ip_addr.to_string());
|
||||
Sniffer sniffer(iface.name(), config);
|
||||
|
||||
PacketSender sender;
|
||||
// Create our handler
|
||||
auto handler = make_sniffer_handler(this, &Traceroute::sniff_callback);
|
||||
auto handler = bind(
|
||||
&Traceroute::sniff_callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
);
|
||||
// We're running
|
||||
running = true;
|
||||
// Start the sniff thread
|
||||
std::thread sniff_thread(
|
||||
&Sniffer::sniff_loop<decltype(handler)>,
|
||||
&sniffer,
|
||||
handler,
|
||||
0
|
||||
thread sniff_thread(
|
||||
[&]() {
|
||||
sniffer.sniff_loop(handler);
|
||||
}
|
||||
);
|
||||
send_packets(sender);
|
||||
sniff_thread.join();
|
||||
// If the final hop responded, add its address at the appropriate ttl
|
||||
if (lowest_dest_ttl != numeric_limits<int>::max()) {
|
||||
results[lowest_dest_ttl] = addr;
|
||||
}
|
||||
// Clear our results and return what we've found
|
||||
return std::move(results);
|
||||
return move(results);
|
||||
}
|
||||
private:
|
||||
typedef std::map<uint16_t, size_t> ttl_map;
|
||||
typedef map<uint16_t, size_t> ttl_map;
|
||||
|
||||
void send_packets(PacketSender &sender) {
|
||||
void send_packets(PacketSender& sender) {
|
||||
// ICMPs are icmp-requests by default
|
||||
IP ip(addr, iface.addresses().ip_addr, new ICMP());
|
||||
// We'll find at most 10 hops.
|
||||
IP ip = IP(addr, iface.addresses().ip_addr) / ICMP();
|
||||
ICMP& icmp = ip.rfind_pdu<ICMP>();
|
||||
icmp.sequence(sequence);
|
||||
// We'll find at most 20 hops.
|
||||
|
||||
for(auto i = 1; i <= 10; ++i) {
|
||||
// Set this "unique" id
|
||||
ip.id(i);
|
||||
for (auto i = 1; i <= 20; ++i) {
|
||||
// Set this ICMP id
|
||||
icmp.id(i);
|
||||
// Set the time-to-live option
|
||||
ip.ttl(i);
|
||||
|
||||
// Critical section
|
||||
{
|
||||
std::lock_guard<std::mutex> _(lock);
|
||||
lock_guard<mutex> _(lock);
|
||||
ttls[i] = i;
|
||||
}
|
||||
|
||||
sender.send(ip);
|
||||
// Give him a little time
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
// Give it a little time
|
||||
sleep_for(milliseconds(100));
|
||||
}
|
||||
running = false;
|
||||
sender.send(ip);
|
||||
}
|
||||
|
||||
bool sniff_callback(PDU &pdu) {
|
||||
IP *ip = pdu.find_pdu<IP>();
|
||||
RawPDU *raw = pdu.find_pdu<RawPDU>();
|
||||
if(ip && raw) {
|
||||
ttl_map::const_iterator iter;
|
||||
IP inner_ip;
|
||||
// This will fail if its a corrupted packet
|
||||
try {
|
||||
// Fetch the IP PDU attached to the ICMP response
|
||||
inner_ip = IP(&raw->payload()[0], raw->payload_size());
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
return running;
|
||||
}
|
||||
// Critical section
|
||||
{
|
||||
std::lock_guard<std::mutex> _(lock);
|
||||
iter = ttls.find(inner_ip.id());
|
||||
}
|
||||
bool sniff_callback(PDU& pdu) {
|
||||
// Find IP and ICMP PDUs
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const ICMP& icmp = pdu.rfind_pdu<ICMP>();
|
||||
// Check if this is an ICMP TTL exceeded error response
|
||||
if (icmp.type() == ICMP::TIME_EXCEEDED) {
|
||||
// Fetch the IP PDU attached to the ICMP response
|
||||
const IP inner_ip = pdu.rfind_pdu<RawPDU>().to<IP>();
|
||||
// Now get the ICMP layer
|
||||
const ICMP& inner_icmp = inner_ip.rfind_pdu<ICMP>();
|
||||
// Make sure this is one of our packets.
|
||||
if (inner_icmp.sequence() == sequence) {
|
||||
ttl_map::const_iterator iter;
|
||||
|
||||
// It's an actual response
|
||||
if(iter != ttls.end()) {
|
||||
// Store it
|
||||
results[inner_ip.id()] = ip->src_addr();
|
||||
// Critical section
|
||||
{
|
||||
std::lock_guard<std::mutex> _(lock);
|
||||
iter = ttls.find(inner_icmp.id());
|
||||
}
|
||||
|
||||
// It's an actual response
|
||||
if(iter != ttls.end()) {
|
||||
// Store it
|
||||
results[inner_icmp.id()] = ip.src_addr();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise, this could be the final hop making an echo response
|
||||
else if (icmp.type() == ICMP::ECHO_REPLY && icmp.sequence() == sequence &&
|
||||
ip.src_addr() == addr) {
|
||||
// Keep the lowest ttl seen for the destination.
|
||||
lowest_dest_ttl = min(lowest_dest_ttl, static_cast<int>(icmp.id()));
|
||||
}
|
||||
return running;
|
||||
}
|
||||
|
||||
NetworkInterface iface;
|
||||
IPv4Address addr;
|
||||
std::atomic<bool> running;
|
||||
atomic<bool> running;
|
||||
ttl_map ttls;
|
||||
result_type results;
|
||||
std::mutex lock;
|
||||
mutex lock;
|
||||
uint16_t sequence;
|
||||
int lowest_dest_ttl;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc <= 1 && std::cout << "Usage: " << *argv << " <IP_ADDRESS>\n")
|
||||
if (argc <= 1) {
|
||||
cout << "Usage: " <<* argv << " <ip_address>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
IPv4Address addr((std::string(argv[1])));
|
||||
IPv4Address addr = string(argv[1]);
|
||||
Traceroute tracer(addr, addr);
|
||||
auto results = tracer.trace();
|
||||
if(results.empty())
|
||||
std::cout << "No hops found" << std::endl;
|
||||
if (results.empty()) {
|
||||
cout << "No hops found" << endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "Results: " << std::endl;
|
||||
for(const auto &entry : results) {
|
||||
std::cout << entry.first << " - " << entry.second << std::endl;
|
||||
cout << "Results: " << endl;
|
||||
for(const auto& entry : results) {
|
||||
cout << setw(2) << entry.first << " - " << entry.second << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::runtime_error &ex) {
|
||||
std::cout << "Error - " << ex.what() << std::endl;
|
||||
catch (runtime_error& ex) {
|
||||
cout << "Error - " << ex.what() << endl;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
78
examples/wps_detect.cpp
Normal file
78
examples/wps_detect.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// BSSIDs which we've already seen
|
||||
std::set<HWAddress<6>> addrs;
|
||||
// This will be the content of the OUI field in the vendor specific
|
||||
// tagged option if it's a WPS tag.
|
||||
const HWAddress<3> expected_oui("00:50:F2");
|
||||
|
||||
bool handler(const PDU& pdu) {
|
||||
const Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
|
||||
// Only process it once
|
||||
if(addrs.insert(beacon.addr3()).second) {
|
||||
// Iterate the tagged options
|
||||
for(const auto& opt : beacon.options()) {
|
||||
// Is this a vendor-specific tag?
|
||||
if(opt.option() == Dot11::VENDOR_SPECIFIC) {
|
||||
// Make sure there's enough size for the OUI + identifier
|
||||
if(opt.data_size() >= 4) {
|
||||
// Retrieve the OUI field
|
||||
HWAddress<3> addr = opt.data_ptr();
|
||||
// Are we interested in this OUI and is it a WPS tag?
|
||||
if(addr == expected_oui && opt.data_ptr()[3] == 0x04) {
|
||||
std::cout << "[+] Access point: " << beacon.ssid() << " uses WPS\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
std::cout << "Usage: " <<* argv << " <DEVICE>\n";
|
||||
return 1;
|
||||
}
|
||||
// Only sniff beacons
|
||||
SnifferConfiguration config;
|
||||
config.set_snap_len(2000);
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("wlan type mgt subtype beacon");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
sniffer.sniff_loop(handler);
|
||||
}
|
||||
1
googletest
Submodule
1
googletest
Submodule
Submodule googletest added at 13206d6f53
310
include/arp.h
310
include/arp.h
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TINS_ARP_H
|
||||
#define TINS_ARP_H
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "hw_address.h"
|
||||
#include "ip_address.h"
|
||||
|
||||
namespace Tins {
|
||||
class NetworkInterface;
|
||||
class EthernetII;
|
||||
|
||||
/**
|
||||
* \brief Class that represents an ARP PDU.
|
||||
*
|
||||
*/
|
||||
class ARP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the hardware address.
|
||||
*/
|
||||
typedef HWAddress<6> hwaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the IP address.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::ARP;
|
||||
|
||||
/**
|
||||
* \brief Enum which indicates the type of ARP packet.
|
||||
*/
|
||||
enum Flags {
|
||||
REQUEST = 0x0001,
|
||||
REPLY = 0x0002
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Default constructor for ARP PDU objects.
|
||||
*
|
||||
* ARP requests and replies can be constructed easily using
|
||||
* ARP::make_arp_request/reply static functions.
|
||||
*/
|
||||
ARP(ipaddress_type target_ip = ipaddress_type(),
|
||||
ipaddress_type sender_ip = ipaddress_type(),
|
||||
const hwaddress_type &target_hw = hwaddress_type(),
|
||||
const hwaddress_type &sender_hw = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an ARP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
ARP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the sender's hardware address.
|
||||
*
|
||||
* \return The sender hardware address.
|
||||
*/
|
||||
hwaddress_type sender_hw_addr() const { return _arp.ar_sha; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sender's IP address.
|
||||
*
|
||||
* \return The sender IP address.
|
||||
*/
|
||||
ipaddress_type sender_ip_addr() const { return ipaddress_type(_arp.ar_sip); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's hardware address.
|
||||
*
|
||||
* \return The target hardware address.
|
||||
*/
|
||||
hwaddress_type target_hw_addr() const { return _arp.ar_tha; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's IP address.
|
||||
*
|
||||
* \return The target IP address.
|
||||
*/
|
||||
ipaddress_type target_ip_addr() const { return ipaddress_type(_arp.ar_tip); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address format.
|
||||
*
|
||||
* \return The hardware address format.
|
||||
*/
|
||||
uint16_t hw_addr_format() const { return Endian::be_to_host(_arp.ar_hrd); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address format.
|
||||
*
|
||||
* \return The protocol address format.
|
||||
*/
|
||||
uint16_t prot_addr_format() const { return Endian::be_to_host(_arp.ar_pro); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address length.
|
||||
*
|
||||
* \return The hardware address length.
|
||||
*/
|
||||
uint8_t hw_addr_length() const { return _arp.ar_hln; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address length.
|
||||
*
|
||||
* \return The protocol address length.
|
||||
*/
|
||||
uint8_t prot_addr_length() const { return _arp.ar_pln; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ARP opcode.
|
||||
*
|
||||
* \return The ARP opcode.
|
||||
*/
|
||||
uint16_t opcode() const { return Endian::be_to_host(_arp.ar_op); }
|
||||
|
||||
/** \brief Getter for the header size.
|
||||
* \return Returns the ARP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's hardware address.
|
||||
*
|
||||
* \param new_snd_hw_addr The new sender hardware address.
|
||||
*/
|
||||
void sender_hw_addr(const hwaddress_type &new_snd_hw_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's IP address.
|
||||
*
|
||||
* \param new_snd_ip_addr The new sender IP address.
|
||||
*/
|
||||
void sender_ip_addr(ipaddress_type new_snd_ip_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's hardware address.
|
||||
*
|
||||
* \param new_tgt_hw_addr The new target hardware address.
|
||||
*/
|
||||
void target_hw_addr(const hwaddress_type &new_tgt_hw_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's IP address.
|
||||
*
|
||||
* \param new_tgt_ip_addr The new target IP address.
|
||||
*/
|
||||
void target_ip_addr(ipaddress_type new_tgt_ip_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address format.
|
||||
*
|
||||
* \param new_hw_addr_fmt The new hardware address format.
|
||||
*/
|
||||
void hw_addr_format(uint16_t new_hw_addr_fmt);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address format.
|
||||
*
|
||||
* \param new_prot_addr_fmt The new protocol address format.
|
||||
*/
|
||||
void prot_addr_format(uint16_t new_prot_addr_fmt);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address length.
|
||||
*
|
||||
* \param new_hw_addr_len The new hardware address length.
|
||||
*/
|
||||
void hw_addr_length(uint8_t new_hw_addr_len);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address length.
|
||||
*
|
||||
* \param new_prot_addr_len The new protocol address length.
|
||||
*/
|
||||
void prot_addr_length(uint8_t new_prot_addr_len);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ARP opcode.
|
||||
*
|
||||
* \param new_opcode Flag enum value of the ARP opcode to set.
|
||||
*/
|
||||
void opcode(Flags new_opcode);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::ARP; }
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Request within a Layer 2 PDU using uint32_t for target and sender.
|
||||
*
|
||||
* Creates an ARP Request PDU and embeds it within a Layer 2 PDU ready to be
|
||||
* sent. The target and sender's protocol address are given using uint32_t.
|
||||
*
|
||||
* \param iface string with the interface from where to send the ARP.
|
||||
* \param target IPv4Address with the target's IP.
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns a EthernetII containing the ARP Request.
|
||||
*/
|
||||
static EthernetII make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Reply within a Layer 2 PDU using uint32_t for target and sender.
|
||||
*
|
||||
* Creates an ARP Reply PDU and embeds it within a Layer 2 PDU ready to be
|
||||
* sent. The target and sender's protocol address are given using uint32_t.
|
||||
*
|
||||
* \param iface string with the interface from where to send the ARP.
|
||||
* \param target IPv4Address with the target's IP.
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_tgt uint8_t array of 6 bytes containing the target's hardware address.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns an EthetnetII containing the ARP Replay.
|
||||
*/
|
||||
static EthernetII make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
ipaddress_type sender, const hwaddress_type &hw_tgt = hwaddress_type(),
|
||||
const hwaddress_type &hw_snd = hwaddress_type());
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/** \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
* \sa PDU::clone_packet
|
||||
*/
|
||||
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
ARP *clone() const {
|
||||
return new ARP(*this);
|
||||
}
|
||||
private:
|
||||
struct arphdr {
|
||||
uint16_t ar_hrd; /* format of hardware address */
|
||||
uint16_t ar_pro; /* format of protocol address */
|
||||
uint8_t ar_hln; /* length of hardware address */
|
||||
uint8_t ar_pln; /* length of protocol address */
|
||||
uint16_t ar_op; /* ARP opcode (command) */
|
||||
|
||||
/* sender hardware address */
|
||||
uint8_t ar_sha[hwaddress_type::address_size];
|
||||
/* sender IP address */
|
||||
uint32_t ar_sip;
|
||||
/* target hardware address */
|
||||
uint8_t ar_tha[hwaddress_type::address_size];
|
||||
/* target IP address */
|
||||
uint32_t ar_tip;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
arphdr _arp;
|
||||
};
|
||||
};
|
||||
#endif //TINS_ARP_H
|
||||
345
include/bootp.h
345
include/bootp.h
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_BOOTP_H
|
||||
#define TINS_BOOTP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "ip_address.h"
|
||||
#include "hw_address.h"
|
||||
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing a BootP packet.
|
||||
*/
|
||||
class BootP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the IP addresses.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the chaddr field.
|
||||
*/
|
||||
typedef HWAddress<16> chaddr_type;
|
||||
|
||||
/**
|
||||
* The type of the vend field.
|
||||
*/
|
||||
typedef std::vector<uint8_t> vend_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::BOOTP;
|
||||
|
||||
/**
|
||||
* \brief Enum which contains the different opcodes BootP messages.
|
||||
*/
|
||||
enum OpCodes {
|
||||
BOOTREQUEST = 1,
|
||||
BOOTREPLY = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of BootP.
|
||||
*
|
||||
* This sets the size of the vend field to 64, as the BootP RFC
|
||||
* states.
|
||||
*/
|
||||
BootP();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a BootP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \param vend_field_size The vend field size to allocate.
|
||||
* Subclasses might use 0 to provide their own interpretation of this field.
|
||||
*/
|
||||
BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size = 64);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the opcode field.
|
||||
* \return The opcode field for this BootP PDU.
|
||||
*/
|
||||
uint8_t opcode() const { return _bootp.opcode; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the htype field.
|
||||
* \return The htype field for this BootP PDU.
|
||||
*/
|
||||
uint8_t htype() const { return _bootp.htype; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hlen field.
|
||||
* \return The hlen field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hlen() const { return _bootp.hlen; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hops field.
|
||||
* \return The hops field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hops() const { return _bootp.hops; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the xid field.
|
||||
* \return The xid field for this BootP PDU.
|
||||
*/
|
||||
uint32_t xid() const { return Endian::be_to_host(_bootp.xid); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the secs field.
|
||||
* \return The secs field for this BootP PDU.
|
||||
*/
|
||||
uint16_t secs() const { return Endian::be_to_host(_bootp.secs); }
|
||||
|
||||
/** \brief Getter for the padding field.
|
||||
* \return The padding field for this BootP PDU.
|
||||
*/
|
||||
uint16_t padding() const { return Endian::be_to_host(_bootp.padding); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ciaddr field.
|
||||
* \return The ciaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type ciaddr() const { return ipaddress_type(_bootp.ciaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the yiaddr field.
|
||||
* \return The yiaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type yiaddr() const { return ipaddress_type(_bootp.yiaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the siaddr field.
|
||||
* \return The siaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type siaddr() const { return ipaddress_type(_bootp.siaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the giaddr field.
|
||||
* \return The giaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type giaddr() const { return ipaddress_type(_bootp.giaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the chaddr field.
|
||||
* \return The chddr field for this BootP PDU.
|
||||
*/
|
||||
chaddr_type chaddr() const { return _bootp.chaddr; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sname field.
|
||||
* \return The sname field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t *sname() const { return _bootp.sname; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the file field.
|
||||
* \return The file field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t *file() const { return _bootp.file; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
const vend_type &vend() const { return _vend; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
* \param new_opcode The opcode to be set.
|
||||
*/
|
||||
void opcode(uint8_t new_opcode);
|
||||
|
||||
/**
|
||||
* \brief Setter for the htype field.
|
||||
* \param new_htype The htype to be set.
|
||||
*/
|
||||
void htype(uint8_t new_htype);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hlen field.
|
||||
* \param new_hlen The hlen to be set.
|
||||
*/
|
||||
void hlen(uint8_t new_hlen);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hops field.
|
||||
* \param new_hops The hops to be set.
|
||||
*/
|
||||
void hops(uint8_t new_hops);
|
||||
|
||||
/**
|
||||
* \brief Setter for the xid field.
|
||||
* \param new_xid The xid to be set.
|
||||
*/
|
||||
void xid(uint32_t new_xid);
|
||||
|
||||
/**
|
||||
* \brief Setter for the secs field.
|
||||
* \param new_secs The secs to be set.
|
||||
*/
|
||||
void secs(uint16_t new_secs);
|
||||
|
||||
/**
|
||||
* \brief Setter for the padding field.
|
||||
* \param new_padding The padding to be set.
|
||||
*/
|
||||
void padding(uint16_t new_padding);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ciaddr field.
|
||||
* \param new_ciaddr The ciaddr to be set.
|
||||
*/
|
||||
void ciaddr(ipaddress_type new_ciaddr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the yiaddr field.
|
||||
* \param new_yiaddr The yiaddr to be set.
|
||||
*/
|
||||
void yiaddr(ipaddress_type new_yiaddr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the siaddr field.
|
||||
* \param new_siaddr The siaddr to be set.
|
||||
*/
|
||||
void siaddr(ipaddress_type new_siaddr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the giaddr field.
|
||||
* \param new_giaddr The giaddr to be set.
|
||||
*/
|
||||
void giaddr(ipaddress_type new_giaddr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the chaddr field.
|
||||
* The new_chaddr pointer must be at least BOOTP::hlen() bytes long.
|
||||
* \param new_chaddr The chaddr to be set.
|
||||
*/
|
||||
template<size_t n>
|
||||
void chaddr(const HWAddress<n> &new_chaddr) {
|
||||
// Copy the new addr
|
||||
uint8_t *end = std::copy(
|
||||
new_chaddr.begin(),
|
||||
new_chaddr.begin() + std::min(n, sizeof(_bootp.chaddr)),
|
||||
_bootp.chaddr
|
||||
);
|
||||
// Fill what's left with zeros
|
||||
std::fill(end, _bootp.chaddr + chaddr_type::address_size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the sname field.
|
||||
* \param new_sname The sname to be set.
|
||||
*/
|
||||
void sname(const uint8_t *new_sname);
|
||||
|
||||
/**
|
||||
* \brief Setter for the file field.
|
||||
* \param new_file The file to be set.
|
||||
*/
|
||||
void file(const uint8_t *new_file);
|
||||
|
||||
/**
|
||||
* \brief Setter for the vend field.
|
||||
* \param new_vend The vend to be set.
|
||||
*/
|
||||
void vend(const vend_type &new_vend);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::BOOTP; }
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
BootP *clone() const {
|
||||
return new BootP(*this);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
*
|
||||
* This getter can be used by subclasses to avoid copying the
|
||||
* vend field around.
|
||||
*
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
vend_type &vend() { return _vend; }
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the Bootp datagram.
|
||||
*/
|
||||
struct bootphdr {
|
||||
uint8_t opcode;
|
||||
uint8_t htype;
|
||||
uint8_t hlen;
|
||||
uint8_t hops;
|
||||
uint32_t xid;
|
||||
uint16_t secs;
|
||||
uint16_t padding;
|
||||
uint32_t ciaddr;
|
||||
uint32_t yiaddr;
|
||||
uint32_t siaddr;
|
||||
uint32_t giaddr;
|
||||
uint8_t chaddr[16];
|
||||
uint8_t sname[64];
|
||||
uint8_t file[128];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
bootphdr _bootp;
|
||||
vend_type _vend;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_BOOTP_H
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_CONSTANTS_H
|
||||
#define TINS_CONSTANTS_H
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Constants used in protocols.
|
||||
*/
|
||||
namespace Constants {
|
||||
/** \cond */
|
||||
struct IP {
|
||||
/** \endcond */
|
||||
enum e {
|
||||
PROTO_IP = 0, /* Dummy protocol for TCP. */
|
||||
PROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
|
||||
PROTO_ICMP = 1, /* Internet Control Message Protocol. */
|
||||
PROTO_IGMP = 2, /* Internet Group Management Protocol. */
|
||||
PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94). */
|
||||
PROTO_TCP = 6, /* Transmission Control Protocol. */
|
||||
PROTO_EGP = 8, /* Exterior Gateway Protocol. */
|
||||
PROTO_PUP = 12, /* PUP protocol. */
|
||||
PROTO_UDP = 17, /* User Datagram Protocol. */
|
||||
PROTO_IDP = 22, /* XNS IDP protocol. */
|
||||
PROTO_TP = 29, /* SO Transport Protocol Class 4. */
|
||||
PROTO_DCCP = 33, /* Datagram Congestion Control Protocol. */
|
||||
PROTO_IPV6 = 41, /* IPv6 header. */
|
||||
PROTO_ROUTING = 43, /* IPv6 routing header. */
|
||||
PROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
|
||||
PROTO_RSVP = 46, /* Reservation Protocol. */
|
||||
PROTO_GRE = 47, /* General Routing Encapsulation. */
|
||||
PROTO_ESP = 50, /* encapsulating security payload. */
|
||||
PROTO_AH = 51, /* authentication header. */
|
||||
PROTO_ICMPV6 = 58, /* ICMPv6. */
|
||||
PROTO_NONE = 59, /* IPv6 no next header. */
|
||||
PROTO_DSTOPTS = 60, /* IPv6 destination options. */
|
||||
PROTO_MTP = 92, /* Multicast Transport Protocol. */
|
||||
PROTO_ENCAP = 98, /* Encapsulation Header. */
|
||||
PROTO_PIM = 103, /* Protocol Independent Multicast. */
|
||||
PROTO_COMP = 108, /* Compression Header Protocol. */
|
||||
PROTO_SCTP = 132, /* Stream Control Transmission Protocol. */
|
||||
PROTO_UDPLITE = 136, /* UDP-Lite protocol. */
|
||||
PROTO_RAW = 255 /* Raw IP packets. */
|
||||
};
|
||||
};
|
||||
|
||||
struct Ethernet {
|
||||
enum e {
|
||||
PUP = 0x0200, /* Xerox PUP */
|
||||
SPRITE = 0x0500, /* Sprite */
|
||||
IP = 0x0800, /* IP */
|
||||
ARP = 0x0806, /* Address resolution */
|
||||
REVARP = 0x8035, /* Reverse ARP */
|
||||
AT = 0x809B, /* AppleTalk protocol */
|
||||
AARP = 0x80F3, /* AppleTalk ARP */
|
||||
VLAN = 0x8100, /* IEEE 802.1Q VLAN tagging */
|
||||
IPX = 0x8137, /* IPX */
|
||||
IPV6 = 0x86dd, /* IP protocol version 6 */
|
||||
EAPOL = 0x888e, /* EAPOL */
|
||||
LOOPBACK = 0x9000 /* used to test interfaces */
|
||||
};
|
||||
};
|
||||
|
||||
struct ARP {
|
||||
enum e {
|
||||
NETROM = 0, /* From KA9Q: NET/ROM pseudo. */
|
||||
ETHER = 1, /* Ethernet 10/100Mbps. */
|
||||
EETHER = 2, /* Experimental Ethernet. */
|
||||
AX25 = 3, /* AX.25 Level 2. */
|
||||
PRONET = 4, /* PROnet token ring. */
|
||||
CHAOS = 5, /* Chaosnet. */
|
||||
IEEE802 = 6, /* IEEE 802.2 Ethernet/TR/TB. */
|
||||
ARCNET = 7, /* ARCnet. */
|
||||
APPLETLK = 8, /* APPLEtalk. */
|
||||
DLCI = 15, /* Frame Relay DLCI. */
|
||||
ATM = 19, /* ATM. */
|
||||
METRICOM = 23, /* Metricom STRIP (new IANA id). */
|
||||
IEEE1394 = 24, /* IEEE 1394 IPv4 - RFC 2734. */
|
||||
EUI64 = 27, /* EUI-64. */
|
||||
INFINIBAND = 32, /* InfiniBand. */
|
||||
SLIP = 256,
|
||||
CSLIP = 257,
|
||||
SLIP6 = 258,
|
||||
CSLIP6 = 259,
|
||||
RSRVD = 260, /* Notional KISS type. */
|
||||
ADAPT = 264,
|
||||
ROSE = 270,
|
||||
X25 = 271, /* CCITT X.25. */
|
||||
HWX25 = 272, /* Boards with X.25 in firmware. */
|
||||
PPP = 512,
|
||||
CISCO = 513, /* Cisco HDLC. */
|
||||
HDLC = CISCO,
|
||||
LAPB = 516, /* LAPB. */
|
||||
DDCMP = 517, /* Digital's DDCMP. */
|
||||
RAWHDLC = 518, /* Raw HDLC. */
|
||||
TUNNEL = 768, /* IPIP tunnel. */
|
||||
TUNNEL6 = 769, /* IPIP6 tunnel. */
|
||||
FRAD = 770, /* Frame Relay Access Device. */
|
||||
SKIP = 771, /* SKIP vif. */
|
||||
LOOPBACK = 772, /* Loopback device. */
|
||||
LOCALTLK = 773, /* Localtalk device. */
|
||||
FDDI = 774, /* Fiber Distributed Data Interface. */
|
||||
BIF = 775, /* AP1000 BIF. */
|
||||
SIT = 776, /* sit0 device - IPv6-in-IPv4. */
|
||||
IPDDP = 777, /* IP-in-DDP tunnel. */
|
||||
IPGRE = 778, /* GRE over IP. */
|
||||
PIMREG = 779, /* PIMSM register interface. */
|
||||
HIPPI = 780, /* High Performance Parallel I'face. */
|
||||
ASH = 781, /* (Nexus Electronics) Ash. */
|
||||
ECONET = 782, /* Acorn Econet. */
|
||||
IRDA = 783, /* Linux-IrDA. */
|
||||
FCPP = 784, /* Point to point fibrechanel. */
|
||||
FCAL = 785, /* Fibrechanel arbitrated loop. */
|
||||
FCPL = 786, /* Fibrechanel public loop. */
|
||||
FCFABRIC = 787, /* Fibrechanel fabric. */
|
||||
IEEE802_TR = 800, /* Magic type ident for TR. */
|
||||
IEEE80211 = 801, /* IEEE 802.11. */
|
||||
IEEE80211_PRISM = 802, /* IEEE 802.11 + Prism2 header. */
|
||||
IEEE80211_RADIOTAP = 803, /* IEEE 802.11 + radiotap header. */
|
||||
IEEE802154 = 804, /* IEEE 802.15.4 header. */
|
||||
IEEE802154_PHY = 805, /* IEEE 802.15.4 PHY header. */
|
||||
VOID_TYPE = 0xFFFF, /* Void type, nothing is known. */
|
||||
NONE = 0xFFFE, /* Zero header length. */
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // TINS_CONSTANTS_H
|
||||
262
include/crypto.h
262
include/crypto.h
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_CRYPTO_H
|
||||
#define TINS_CRYPTO_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "dot11.h"
|
||||
#include "utils.h"
|
||||
#include "snap.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
namespace Tins {
|
||||
class PDU;
|
||||
|
||||
namespace Crypto {
|
||||
/**
|
||||
* \brief RC4 Key abstraction.
|
||||
*/
|
||||
struct RC4Key {
|
||||
static const size_t data_size = 256;
|
||||
|
||||
/**
|
||||
* \brief Initializes the key using the provided iterator range.
|
||||
*
|
||||
* \param start The start of the range.
|
||||
* \param end The end of the range.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
RC4Key(ForwardIterator start, ForwardIterator end);
|
||||
|
||||
/**
|
||||
* The actual key data.
|
||||
*/
|
||||
uint8_t data[data_size];
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class WEPDecrypter {
|
||||
public:
|
||||
typedef Dot11::address_type address_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs a WEPDecrypter object.
|
||||
*/
|
||||
WEPDecrypter();
|
||||
|
||||
/**
|
||||
* \brief Adds a decryption password.
|
||||
*
|
||||
* \param addr The access point's BSSID.
|
||||
* \param password The password which will be used to decrypt
|
||||
* packets sent from and to the AP identifier by the BSSID addr.
|
||||
*/
|
||||
void add_password(const address_type &addr, const std::string &password);
|
||||
|
||||
/**
|
||||
* \brief Removes a decryption password
|
||||
*
|
||||
* \param addr The BSSID of the access point.
|
||||
*/
|
||||
void remove_password(const address_type &addr);
|
||||
|
||||
/**
|
||||
* \brief Decrypts the provided PDU and forwards the decrypted
|
||||
* PDU to the functor held by this object.
|
||||
*
|
||||
* A Dot11Data PDU is looked up inside the provided PDU chain.
|
||||
* If no such PDU exists or there is no password associated
|
||||
* with the Dot11 packet's BSSID, then the PDU is left intact.
|
||||
*
|
||||
* Otherwise, the packet is decrypted using the given password.
|
||||
* If the CRC found after decrypting it is invalid,
|
||||
* then false is returned.
|
||||
*
|
||||
* \return false if decryption failed due to invalid CRC, true
|
||||
* otherwise.
|
||||
*/
|
||||
bool decrypt(PDU &pdu);
|
||||
private:
|
||||
typedef std::map<address_type, std::string> passwords_type;
|
||||
|
||||
PDU *decrypt(RawPDU &raw, const std::string &password);
|
||||
|
||||
passwords_type passwords;
|
||||
std::vector<uint8_t> key_buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Pluggable decrypter object which can be used to decrypt
|
||||
* data on sniffing sessions.
|
||||
*
|
||||
* This class holds a decrypter object and a functor, and implements
|
||||
* a suitable operator() to be used on BaseSniffer::sniff_loop, which
|
||||
* decrypts packets and forwards them to the given functor.
|
||||
*/
|
||||
template<typename Functor, typename Decrypter>
|
||||
class DecrypterProxy {
|
||||
public:
|
||||
/**
|
||||
* The type of the functor object.
|
||||
*/
|
||||
typedef Functor functor_type;
|
||||
|
||||
/**
|
||||
* The type of the decrypter object.
|
||||
*/
|
||||
typedef Decrypter decrypter_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs an object from a functor and a decrypter.
|
||||
* \param func The functor to be used to forward decrypted
|
||||
* packets.
|
||||
* \param decrypter The decrypter which will be used to decrypt
|
||||
* packets
|
||||
*/
|
||||
DecrypterProxy(const functor_type &func,
|
||||
const decrypter_type &decr = decrypter_type());
|
||||
|
||||
/**
|
||||
* \brief Retrieves a reference to the decrypter object.
|
||||
*/
|
||||
decrypter_type &decrypter();
|
||||
|
||||
/**
|
||||
* \brief Retrieves a const reference to the decrypter object.
|
||||
*/
|
||||
const decrypter_type &decrypter() const;
|
||||
|
||||
/**
|
||||
* \brief The operator() which decrypts packets and forwards
|
||||
* them to the functor.
|
||||
*/
|
||||
bool operator() (PDU &pdu);
|
||||
private:
|
||||
Functor functor_;
|
||||
decrypter_type decrypter_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Performs RC4 encription/decryption of the given byte range,
|
||||
* using the provided key.
|
||||
*
|
||||
* The decrypted range will be copied to the OutputIterator provided.
|
||||
*
|
||||
* \param start The beginning of the range.
|
||||
* \param start The end of the range.
|
||||
* \param key The key to be used.
|
||||
* \param output The iterator in which to write the output.
|
||||
*/
|
||||
template<typename ForwardIterator, typename OutputIterator>
|
||||
void rc4(ForwardIterator start, ForwardIterator end, RC4Key &key, OutputIterator output);
|
||||
|
||||
/**
|
||||
* \brief Wrapper function to create DecrypterProxyes using a
|
||||
* WEPDecrypter as the Decrypter template parameter.
|
||||
*
|
||||
* \param functor The functor to be forwarded to the DecrypterProxy
|
||||
* constructor.
|
||||
*/
|
||||
template<typename Functor>
|
||||
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor &functor);
|
||||
|
||||
// Implementation section
|
||||
|
||||
// DecrypterProxy
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
DecrypterProxy<Functor, Decrypter>::DecrypterProxy(
|
||||
const functor_type &func, const decrypter_type& decr)
|
||||
: functor_(func), decrypter_(decr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
|
||||
DecrypterProxy<Functor, Decrypter>::decrypter()
|
||||
{
|
||||
return decrypter_;
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
const typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
|
||||
DecrypterProxy<Functor, Decrypter>::decrypter() const
|
||||
{
|
||||
return decrypter_;
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
bool DecrypterProxy<Functor, Decrypter>::operator() (PDU &pdu)
|
||||
{
|
||||
return decrypter_.decrypt(pdu) ? functor_(pdu) : true;
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor &functor)
|
||||
{
|
||||
return DecrypterProxy<Functor, WEPDecrypter>(functor);
|
||||
}
|
||||
|
||||
// RC4 stuff
|
||||
|
||||
template<typename ForwardIterator>
|
||||
RC4Key::RC4Key(ForwardIterator start, ForwardIterator end) {
|
||||
for(size_t i = 0; i < data_size; ++i)
|
||||
data[i] = i;
|
||||
size_t j = 0;
|
||||
ForwardIterator iter = start;
|
||||
for(size_t i = 0; i < data_size; ++i) {
|
||||
j = (j + data[i] + *iter++) % 256;
|
||||
if(iter == end)
|
||||
iter = start;
|
||||
std::swap(data[i], data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ForwardIterator, typename OutputIterator>
|
||||
void rc4(ForwardIterator start, ForwardIterator end, RC4Key &key, OutputIterator output) {
|
||||
size_t i = 0, j = 0;
|
||||
while(start != end) {
|
||||
i = (i + 1) % RC4Key::data_size;
|
||||
j = (j + key.data[i]) % RC4Key::data_size;
|
||||
std::swap(key.data[i], key.data[j]);
|
||||
*output++ = *start++ ^ key.data[(key.data[i] + key.data[j]) % RC4Key::data_size];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TINS_CRYPTO_H
|
||||
423
include/dhcp.h
423
include/dhcp.h
@@ -1,423 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DHCP_H
|
||||
#define TINS_DHCP_H
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "bootp.h"
|
||||
#include "pdu_option.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Class that represents the DHCP PDU.
|
||||
*
|
||||
* The end option is added automatically at the end of the option list.
|
||||
*/
|
||||
class DHCP : public BootP {
|
||||
public:
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DHCP;
|
||||
|
||||
/**
|
||||
* DHCP flags.
|
||||
*/
|
||||
enum Flags {
|
||||
DISCOVER = 1,
|
||||
OFFER = 2,
|
||||
REQUEST = 3,
|
||||
DECLINE = 4,
|
||||
ACK = 5,
|
||||
NAK = 6,
|
||||
RELEASE = 7,
|
||||
INFORM = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DHCP options enum.
|
||||
*/
|
||||
enum Options {
|
||||
PAD,
|
||||
SUBNET_MASK,
|
||||
TIME_OFFSET,
|
||||
ROUTERS,
|
||||
TIME_SERVERS,
|
||||
NAME_SERVERS,
|
||||
DOMAIN_NAME_SERVERS,
|
||||
LOG_SERVERS,
|
||||
COOKIE_SERVERS,
|
||||
LPR_SERVERS,
|
||||
IMPRESS_SERVERS,
|
||||
RESOURCE_LOCATION_SERVERS,
|
||||
HOST_NAME,
|
||||
BOOT_SIZE,
|
||||
MERIT_DUMP,
|
||||
DOMAIN_NAME,
|
||||
SWAP_SERVER,
|
||||
ROOT_PATH,
|
||||
EXTENSIONS_PATH,
|
||||
IP_FORWARDING,
|
||||
NON_LOCAL_SOURCE_ROUTING,
|
||||
POLICY_FILTER,
|
||||
MAX_DGRAM_REASSEMBLY,
|
||||
DEFAULT_IP_TTL,
|
||||
PATH_MTU_AGING_TIMEOUT,
|
||||
PATH_MTU_PLATEAU_TABLE,
|
||||
INTERFACE_MTU,
|
||||
ALL_SUBNETS_LOCAL,
|
||||
BROADCAST_ADDRESS,
|
||||
PERFORM_MASK_DISCOVERY,
|
||||
MASK_SUPPLIER,
|
||||
ROUTER_DISCOVERY,
|
||||
ROUTER_SOLICITATION_ADDRESS,
|
||||
STATIC_ROUTES,
|
||||
TRAILER_ENCAPSULATION,
|
||||
ARP_CACHE_TIMEOUT,
|
||||
IEEE802_3_ENCAPSULATION,
|
||||
DEFAULT_TCP_TTL,
|
||||
TCP_KEEPALIVE_INTERVAL,
|
||||
TCP_KEEPALIVE_GARBAGE,
|
||||
NIS_DOMAIN,
|
||||
NIS_SERVERS,
|
||||
NTP_SERVERS,
|
||||
VENDOR_ENCAPSULATED_OPTIONS,
|
||||
NETBIOS_NAME_SERVERS,
|
||||
NETBIOS_DD_SERVER,
|
||||
NETBIOS_NODE_TYPE,
|
||||
NETBIOS_SCOPE,
|
||||
FONT_SERVERS,
|
||||
X_DISPLAY_MANAGER,
|
||||
DHCP_REQUESTED_ADDRESS,
|
||||
DHCP_LEASE_TIME,
|
||||
DHCP_OPTION_OVERLOAD,
|
||||
DHCP_MESSAGE_TYPE,
|
||||
DHCP_SERVER_IDENTIFIER,
|
||||
DHCP_PARAMETER_REQUEST_LIST,
|
||||
DHCP_MESSAGE,
|
||||
DHCP_MAX_MESSAGE_SIZE,
|
||||
DHCP_RENEWAL_TIME,
|
||||
DHCP_REBINDING_TIME,
|
||||
VENDOR_CLASS_IDENTIFIER,
|
||||
DHCP_CLIENT_IDENTIFIER,
|
||||
NWIP_DOMAIN_NAME,
|
||||
NWIP_SUBOPTIONS,
|
||||
USER_CLASS = 77,
|
||||
FQDN = 81,
|
||||
DHCP_AGENT_OPTIONS = 82,
|
||||
SUBNET_SELECTION = 118,
|
||||
AUTHENTICATE = 210,
|
||||
END = 255
|
||||
};
|
||||
|
||||
/**
|
||||
* The DHCP option type.
|
||||
*/
|
||||
typedef PDUOption<uint8_t> dhcp_option;
|
||||
|
||||
/**
|
||||
* The type used to store the DHCP options.
|
||||
*/
|
||||
typedef std::list<dhcp_option> options_type;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of DHCP.
|
||||
*
|
||||
* This sets the hwtype and hlen fields to match the ethernet
|
||||
* type and length.
|
||||
*/
|
||||
DHCP();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a DHCP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* Subclasses might use 0 to provide their own interpretation of this field.
|
||||
*/
|
||||
DHCP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Adds a new option to this DHCP PDU.
|
||||
* \param option The option to be added.
|
||||
*/
|
||||
void add_option(const dhcp_option &option);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
* \param opt_flag The flag to be searched.
|
||||
* \return A pointer to the option, or 0 if it was not found.
|
||||
*/
|
||||
const dhcp_option *search_option(Options opt) const;
|
||||
|
||||
/**
|
||||
* \brief Adds a type option the the option list.
|
||||
* \param type The type of this DHCP PDU.
|
||||
*/
|
||||
void type(Flags type);
|
||||
|
||||
/**
|
||||
* \brief Adds an end option the the option list.
|
||||
*
|
||||
* The END option is not added automatically. You should explicitly
|
||||
* add it at the end of the DHCP options for the PDU to be
|
||||
* standard-compliant.
|
||||
*/
|
||||
void end();
|
||||
|
||||
/**
|
||||
* \brief Adds a server identifier option.
|
||||
* \param ip The ip of the server.
|
||||
*/
|
||||
void server_identifier(ipaddress_type ip);
|
||||
|
||||
/**
|
||||
* \brief Adds an IP address lease time option.
|
||||
* \param time The lease time.
|
||||
*/
|
||||
void lease_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a lease renewal time option.
|
||||
* \param time The lease renew time.
|
||||
*/
|
||||
void renewal_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a rebind time option.
|
||||
* \param time The lease rebind time.
|
||||
*/
|
||||
void rebind_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a subnet mask option.
|
||||
* \param mask The subnet mask.
|
||||
*/
|
||||
void subnet_mask(ipaddress_type mask);
|
||||
|
||||
/**
|
||||
* \brief Adds a routers option.
|
||||
* \param routers A list of ip addresses.
|
||||
*/
|
||||
void routers(const std::list<ipaddress_type> &routers);
|
||||
|
||||
/**
|
||||
* \brief Adds a domain name servers option.
|
||||
* \param dns A list of ip addresses.
|
||||
*/
|
||||
void domain_name_servers(const std::list<ipaddress_type> &dns);
|
||||
|
||||
/**
|
||||
* \brief Adds a broadcast address option.
|
||||
* \param addr The broadcast address.
|
||||
*/
|
||||
void broadcast(ipaddress_type addr);
|
||||
|
||||
/**
|
||||
* \brief Adds a requested address option.
|
||||
* \param addr The requested address.
|
||||
*/
|
||||
void requested_ip(ipaddress_type addr);
|
||||
|
||||
/**
|
||||
* \brief Adds a domain name option.
|
||||
* \param name The domain name.
|
||||
*/
|
||||
void domain_name(const std::string &name);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Searchs for a type option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint8_t containing the type option.
|
||||
*/
|
||||
uint8_t type() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a server identifier option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the server identifier.
|
||||
*/
|
||||
ipaddress_type server_identifier() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a lease time option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the lease time.
|
||||
*/
|
||||
uint32_t lease_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a lease renewal time option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the renewal time.
|
||||
*/
|
||||
uint32_t renewal_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a rebind time option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the rebind time.
|
||||
*/
|
||||
uint32_t rebind_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a subnet mask option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the subnet mask.
|
||||
*/
|
||||
ipaddress_type subnet_mask() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a routers option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::list<ipaddress_type> Containing the routers
|
||||
* option data.
|
||||
*/
|
||||
std::list<ipaddress_type> routers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a dns option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::list<ipaddress_type> Contanining the DNS servers
|
||||
* provided.
|
||||
*/
|
||||
std::list<ipaddress_type> domain_name_servers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a broadcast option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the broadcast address.
|
||||
*/
|
||||
ipaddress_type broadcast() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a requested option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the requested IP address.
|
||||
*/
|
||||
ipaddress_type requested_ip() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a domain name option.
|
||||
*
|
||||
* If the option is not found, a option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::string Containing the domain name.
|
||||
*/
|
||||
std::string domain_name() const;
|
||||
|
||||
/** \brief Getter for the options list.
|
||||
* \return The option list.
|
||||
*/
|
||||
const options_type options() const { return _options; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DHCP; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
DHCP *clone() const {
|
||||
return new DHCP(*this);
|
||||
}
|
||||
private:
|
||||
static const uint32_t MAX_DHCP_SIZE;
|
||||
|
||||
template<typename T>
|
||||
struct type2type {};
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
template<class T>
|
||||
T generic_search(Options opt, type2type<T>) const {
|
||||
const dhcp_option *option = search_option(opt);
|
||||
if(option && option->data_size() == sizeof(T))
|
||||
return *(const T*)option->data_ptr();
|
||||
else
|
||||
throw option_not_found();
|
||||
}
|
||||
|
||||
std::list<ipaddress_type> generic_search(Options opt, type2type<std::list<ipaddress_type> >) const;
|
||||
std::string generic_search(Options opt, type2type<std::string>) const;
|
||||
ipaddress_type generic_search(Options opt, type2type<ipaddress_type>) const;
|
||||
|
||||
serialization_type serialize_list(const std::list<ipaddress_type> &ip_list);
|
||||
|
||||
options_type _options;
|
||||
uint32_t _size;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_DHCP_H
|
||||
636
include/dns.h
636
include/dns.h
@@ -1,636 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DNS_H
|
||||
#define TINS_DNS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "dns_record.h"
|
||||
|
||||
namespace Tins {
|
||||
class IPv4Address;
|
||||
|
||||
/**
|
||||
* \class DNS
|
||||
* \brief Represents a DNS PDU.
|
||||
*/
|
||||
class DNS : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DNS;
|
||||
|
||||
/**
|
||||
* The DNS type.
|
||||
*/
|
||||
enum QRType {
|
||||
QUERY = 0,
|
||||
RESPONSE = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Query types enum.
|
||||
*/
|
||||
enum QueryType {
|
||||
A = 1,
|
||||
NS,
|
||||
MD,
|
||||
MF,
|
||||
CNAME,
|
||||
SOA,
|
||||
MB,
|
||||
MG,
|
||||
MR,
|
||||
NULL_R,
|
||||
WKS,
|
||||
PTR,
|
||||
HINFO,
|
||||
MINFO,
|
||||
MX,
|
||||
TXT,
|
||||
RP,
|
||||
AFSDB,
|
||||
X25,
|
||||
ISDN,
|
||||
RT,
|
||||
NSAP,
|
||||
NSAP_PTR,
|
||||
SIG,
|
||||
KEY,
|
||||
PX,
|
||||
GPOS,
|
||||
AAAA,
|
||||
LOC,
|
||||
NXT,
|
||||
EID,
|
||||
NIMLOC,
|
||||
SRV,
|
||||
ATMA,
|
||||
NAPTR,
|
||||
KX,
|
||||
CERT,
|
||||
A6,
|
||||
DNAM,
|
||||
SINK,
|
||||
OPT,
|
||||
APL,
|
||||
DS,
|
||||
SSHFP,
|
||||
IPSECKEY,
|
||||
RRSIG,
|
||||
NSEC,
|
||||
DNSKEY,
|
||||
DHCID,
|
||||
NSEC3,
|
||||
NSEC3PARAM
|
||||
};
|
||||
|
||||
enum QueryClass {
|
||||
IN = 1,
|
||||
CH = 3,
|
||||
HS = 4,
|
||||
ANY = 255
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Struct that represent DNS queries.
|
||||
*/
|
||||
class Query {
|
||||
public:
|
||||
/**
|
||||
* \brief Constructs a DNS query.
|
||||
*
|
||||
* \param nm The name of the domain being resolved.
|
||||
* \param tp The query type.
|
||||
* \param cl The query class.
|
||||
*/
|
||||
Query(const std::string &nm, QueryType tp, QueryClass cl)
|
||||
: name_(nm), type_(tp), qclass_(cl) {}
|
||||
|
||||
/**
|
||||
* \brief Default constructs this Query.
|
||||
*/
|
||||
Query() : type_(), qclass_() {}
|
||||
|
||||
/**
|
||||
* \brief Setter for the name field.
|
||||
*
|
||||
* \param nm The name to be set.
|
||||
*/
|
||||
void dname(const std::string &nm) {
|
||||
name_ = nm;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the query type field.
|
||||
*
|
||||
* \param tp The query type to be set.
|
||||
*/
|
||||
void type(QueryType tp) {
|
||||
type_ = tp;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the query class field.
|
||||
*
|
||||
* \param cl The query class to be set.
|
||||
*/
|
||||
void query_class(QueryClass cl) {
|
||||
qclass_ = cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the name field.
|
||||
*/
|
||||
const std::string &dname() const { return name_; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the query type field.
|
||||
*/
|
||||
QueryType type() const { return type_; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the query class field.
|
||||
*/
|
||||
QueryClass query_class() const { return qclass_; }
|
||||
private:
|
||||
std::string name_;
|
||||
QueryType type_;
|
||||
QueryClass qclass_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Struct that represent DNS resource records.
|
||||
*/
|
||||
class Resource {
|
||||
public:
|
||||
Resource(const std::string &nm, const std::string &ad,
|
||||
uint16_t t, uint16_t c, uint32_t tt)
|
||||
: dname_(nm), addr_(ad), type_(t), qclass_(c), ttl_(tt) {}
|
||||
|
||||
Resource() : type_(), qclass_(), ttl_() {}
|
||||
|
||||
/**
|
||||
* \brief Getter for the dname field.
|
||||
*
|
||||
* This returns the domain name for which this record
|
||||
* provides an answer.
|
||||
*/
|
||||
const std::string &dname() const { return dname_; }
|
||||
|
||||
/**
|
||||
* Getter for the type field.
|
||||
*/
|
||||
const std::string &data() const { return addr_; }
|
||||
|
||||
/**
|
||||
* Getter for the query type field.
|
||||
*/
|
||||
uint16_t type() const { return type_; }
|
||||
|
||||
/**
|
||||
* Getter for the query class field.
|
||||
*/
|
||||
uint16_t query_class() const { return qclass_; }
|
||||
|
||||
/**
|
||||
* Getter for the type field.
|
||||
*/
|
||||
uint32_t ttl() const { return ttl_; }
|
||||
private:
|
||||
std::string dname_, addr_;
|
||||
uint16_t type_, qclass_;
|
||||
uint32_t ttl_;
|
||||
};
|
||||
|
||||
typedef std::list<Query> queries_type;
|
||||
typedef std::list<Resource> resources_type;
|
||||
typedef IPv4Address address_type;
|
||||
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*
|
||||
* This constructor initializes every field to 0.
|
||||
*/
|
||||
DNS();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a DNS object from a buffer.
|
||||
* \param buffer The buffer from which this PDU will be
|
||||
* constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
DNS(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
// Getters
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
* \return uint16_t containing the value of the id field.
|
||||
*/
|
||||
uint16_t id() const { return Endian::be_to_host(dns.id); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the query response field.
|
||||
*
|
||||
* \return QRType containing the value of the query response
|
||||
* field.
|
||||
*/
|
||||
QRType type() const { return static_cast<QRType>(dns.qr); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
*
|
||||
* \return uint8_t containing the value of the opcode field.
|
||||
*/
|
||||
uint8_t opcode() const { return dns.opcode; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authoritative answer field.
|
||||
*
|
||||
* \return uint8_t containing the value of the authoritative
|
||||
* answer field.
|
||||
*/
|
||||
uint8_t authoritative_answer() const { return dns.aa; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the truncated field.
|
||||
*
|
||||
* \return uint8_t containing the value of the truncated field.
|
||||
*/
|
||||
uint8_t truncated() const { return dns.tc; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion desired field.
|
||||
*
|
||||
* \return uint8_t containing the value of the recursion
|
||||
* desired field.
|
||||
*/
|
||||
uint8_t recursion_desired() const { return dns.rd; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion available field.
|
||||
*
|
||||
* \return uint8_t containing the value of the recursion
|
||||
* available field.
|
||||
*/
|
||||
uint8_t recursion_available() const { return dns.ra; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the z desired field.
|
||||
*
|
||||
* \return uint8_t containing the value of the z field.
|
||||
*/
|
||||
uint8_t z() const { return dns.z; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authenticated data field.
|
||||
*
|
||||
* \return uint8_t containing the value of the authenticated
|
||||
* data field.
|
||||
*/
|
||||
uint8_t authenticated_data() const { return dns.ad; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the checking disabled field.
|
||||
*
|
||||
* \return uint8_t containing the value of the checking
|
||||
* disabled field.
|
||||
*/
|
||||
uint8_t checking_disabled() const { return dns.cd; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the rcode field.
|
||||
*
|
||||
* \return uint8_t containing the value of the rcode field.
|
||||
*/
|
||||
uint8_t rcode() const { return dns.rcode; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the questions field.
|
||||
*
|
||||
* \return uint16_t containing the value of the questions field.
|
||||
*/
|
||||
uint16_t questions_count() const { return Endian::be_to_host(dns.questions); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the answers field.
|
||||
*
|
||||
* \return uint16_t containing the value of the answers field.
|
||||
*/
|
||||
uint16_t answers_count() const { return Endian::be_to_host(dns.answers); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authority field.
|
||||
*
|
||||
* \return uint16_t containing the value of the authority field.
|
||||
*/
|
||||
uint16_t authority_count() const { return Endian::be_to_host(dns.authority); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the additional field.
|
||||
*
|
||||
* \return uint16_t containing the value of the additional field.
|
||||
*/
|
||||
uint16_t additional_count() const { return Endian::be_to_host(dns.additional); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DNS; }
|
||||
|
||||
/**
|
||||
* \brief The header's size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
// Setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
* \param new_id The new id to be set.
|
||||
*/
|
||||
void id(uint16_t new_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the query response field.
|
||||
*
|
||||
* \param new_qr The new qr to be set.
|
||||
*/
|
||||
void type(QRType new_qr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
*
|
||||
* \param new_opcode The new opcode to be set.
|
||||
*/
|
||||
void opcode(uint8_t new_opcode);
|
||||
|
||||
/**
|
||||
* \brief Setter for the authoritative answer field.
|
||||
*
|
||||
* \param new_aa The new authoritative answer field value to
|
||||
* be set.
|
||||
*/
|
||||
void authoritative_answer(uint8_t new_aa);
|
||||
|
||||
/**
|
||||
* \brief Setter for the truncated field.
|
||||
*
|
||||
* \param new_tc The new truncated field value to
|
||||
* be set.
|
||||
*/
|
||||
void truncated(uint8_t new_tc);
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion desired field.
|
||||
*
|
||||
* \param new_rd The new recursion desired value to
|
||||
* be set.
|
||||
*/
|
||||
void recursion_desired(uint8_t new_rd);
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion available field.
|
||||
*
|
||||
* \param new_ra The new recursion available value to
|
||||
* be set.
|
||||
*/
|
||||
void recursion_available(uint8_t new_ra);
|
||||
|
||||
/**
|
||||
* \brief Setter for the z(reserved) field.
|
||||
*
|
||||
* \param new_z The new z value to be set.
|
||||
*/
|
||||
void z(uint8_t new_z);
|
||||
|
||||
/**
|
||||
* \brief Setter for the authenticated data field.
|
||||
*
|
||||
* \param new_ad The new authenticated data value to
|
||||
* be set.
|
||||
*/
|
||||
void authenticated_data(uint8_t new_ad);
|
||||
|
||||
/**
|
||||
* \brief Setter for the checking disabled field.
|
||||
*
|
||||
* \param new_z The new checking disabled value to be set.
|
||||
*/
|
||||
void checking_disabled(uint8_t new_cd);
|
||||
|
||||
/**
|
||||
* \brief Setter for the rcode field.
|
||||
*
|
||||
* \param new_rcode The new rcode value to be set.
|
||||
*/
|
||||
void rcode(uint8_t new_rcode);
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* \brief Add a query to perform.
|
||||
*
|
||||
* \param query The query to be added.
|
||||
*/
|
||||
void add_query(const Query &query);
|
||||
|
||||
/**
|
||||
* \brief Add a query response.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this answer.
|
||||
* \param qclass The class of this answer.
|
||||
* \param ttl The time-to-live of this answer.
|
||||
* \param ip The ip address of the resolved name.
|
||||
*/
|
||||
void add_answer(const std::string &name,
|
||||
const DNSResourceRecord::info &info, address_type ip);
|
||||
|
||||
/**
|
||||
* \brief Add a query response.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this answer.
|
||||
* \param qclass The class of this answer.
|
||||
* \param ttl The time-to-live of this answer.
|
||||
* \param dname The domain of the resolved name.
|
||||
*/
|
||||
void add_answer(const std::string &name,
|
||||
const DNSResourceRecord::info &info, const std::string &dname);
|
||||
|
||||
/**
|
||||
* \brief Add a query response.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this answer.
|
||||
* \param qclass The class of this answer.
|
||||
* \param ttl The time-to-live of this answer.
|
||||
* \param data The data of this option.
|
||||
* \param sz The size of the data.
|
||||
*/
|
||||
void add_answer(const std::string &name,
|
||||
const DNSResourceRecord::info &info, const uint8_t *data, uint32_t sz);
|
||||
|
||||
/**
|
||||
* \brief Add an authority record.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this record.
|
||||
* \param qclass The class of this record.
|
||||
* \param ttl The time-to-live of this record.
|
||||
* \param data The data of this option.
|
||||
* \param sz The size of the data.
|
||||
*/
|
||||
void add_authority(const std::string &name,
|
||||
const DNSResourceRecord::info &info, const uint8_t *data, uint32_t sz);
|
||||
|
||||
/**
|
||||
* \brief Add an additional record.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this record.
|
||||
* \param qclass The class of this record.
|
||||
* \param ttl The time-to-live of this record.
|
||||
* \param ip The ip address of the resolved name.
|
||||
*/
|
||||
void add_additional(const std::string &name,
|
||||
const DNSResourceRecord::info &info, uint32_t ip);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Getter for this PDU's DNS queries.
|
||||
* \return std::list<Query> containing the queries in this
|
||||
* record.
|
||||
*/
|
||||
queries_type queries() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for this PDU's DNS answers
|
||||
* \return std::list<Resource> containing the answers in this
|
||||
* record.
|
||||
*/
|
||||
resources_type answers() const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
DNS *clone() const {
|
||||
return new DNS(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create a resource record information
|
||||
*
|
||||
* \param type The type of the query.
|
||||
* \param qclass The class of the query.
|
||||
* \param ttl The time-to-live of the query.
|
||||
*/
|
||||
static DNSResourceRecord::info make_info(QueryType type, QueryClass qclass, uint32_t ttl) {
|
||||
return DNSResourceRecord::info((uint16_t)type, (uint16_t)qclass, ttl);
|
||||
}
|
||||
private:
|
||||
struct dnshdr {
|
||||
uint16_t id;
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t
|
||||
rd:1,
|
||||
tc:1,
|
||||
aa:1,
|
||||
opcode:4,
|
||||
qr:1,
|
||||
rcode:4,
|
||||
cd:1,
|
||||
ad:1,
|
||||
z:1,
|
||||
ra:1;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
uint16_t
|
||||
qr:1,
|
||||
opcode:4,
|
||||
aa:1,
|
||||
tc:1,
|
||||
rd:1,
|
||||
ra:1,
|
||||
z:1,
|
||||
ad:1,
|
||||
cd:1,
|
||||
rcode:4;
|
||||
#endif
|
||||
uint16_t questions, answers,
|
||||
authority, additional;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef std::map<uint16_t, std::string> SuffixMap;
|
||||
typedef std::map<uint16_t, uint16_t> SuffixIndices;
|
||||
typedef std::list<DNSResourceRecord> ResourcesType;
|
||||
typedef std::list<Query> QueriesType;
|
||||
|
||||
const uint8_t *build_resource_list(ResourcesType &lst, const uint8_t *ptr, uint32_t &sz, uint16_t nrecs);
|
||||
uint32_t find_domain_name(const std::string &dname);
|
||||
bool find_domain_name(const std::string &dname, const ResourcesType &lst, uint16_t &out);
|
||||
void parse_domain_name(const std::string &dn, std::string &out) const;
|
||||
void unparse_domain_name(const std::string &dn, std::string &out) const;
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
uint8_t *serialize_list(const ResourcesType &lst, uint8_t *buffer) const;
|
||||
void compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) const;
|
||||
void convert_resources(const ResourcesType &lst, std::list<Resource> &res) const;
|
||||
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, uint32_t ip);
|
||||
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, const std::string &dname);
|
||||
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, const uint8_t *ptr, uint32_t len);
|
||||
void add_suffix(uint32_t index, const uint8_t *data, uint32_t sz) const;
|
||||
uint32_t build_suffix_map(uint32_t index, const ResourcesType &lst) const;
|
||||
uint32_t build_suffix_map(uint32_t index, const QueriesType &lst) const;
|
||||
void build_suffix_map() const ;
|
||||
static bool contains_dname(uint16_t type);
|
||||
|
||||
dnshdr dns;
|
||||
uint32_t extra_size;
|
||||
std::list<Query> queries_;
|
||||
ResourcesType ans, arity, addit;
|
||||
mutable SuffixMap suffixes;
|
||||
mutable SuffixIndices suffix_indices;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_DNS_H
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DNS_RECORD_H
|
||||
#define TINS_DNS_RECORD_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Tins {
|
||||
class DNSRRImpl;
|
||||
|
||||
/**
|
||||
* \brief Abstracts a DNS resource record.
|
||||
*/
|
||||
class DNSResourceRecord {
|
||||
public:
|
||||
/**
|
||||
* \brief The type used to store resource records' information.
|
||||
*/
|
||||
struct info {
|
||||
uint16_t type, qclass;
|
||||
uint32_t ttl;
|
||||
|
||||
info(uint16_t tp, uint16_t qc, uint32_t tm)
|
||||
: type(tp), qclass(qc), ttl(tm) { }
|
||||
|
||||
info() : type(), qclass(), ttl() {}
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* \brief Constructs a record.
|
||||
* \param impl A pointer to the impl object.
|
||||
* \param data A pointer to the start of the data buffer.
|
||||
* \param len The length of the data.
|
||||
*/
|
||||
DNSResourceRecord(DNSRRImpl *impl = 0, const uint8_t *data = 0, uint16_t len = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructs a record.
|
||||
* \param buffer A pointer to the start of the data buffer.
|
||||
* \param len The length of the data.
|
||||
*/
|
||||
DNSResourceRecord(const uint8_t *buffer, uint32_t size);
|
||||
|
||||
/**
|
||||
* \brief Constructs a record from an input range.
|
||||
* \param impl A pointer to the impl object.
|
||||
* \param start The begining of the range.
|
||||
* \param end The end of the range.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
DNSResourceRecord(DNSRRImpl *impl, ForwardIterator start, ForwardIterator end)
|
||||
: impl(impl), data(start, end)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
*
|
||||
* This handles cloning the impl object.
|
||||
* \param rhs The record which will be copied.
|
||||
*/
|
||||
DNSResourceRecord(const DNSResourceRecord &rhs);
|
||||
|
||||
/**
|
||||
* \brief Copy assignment operator.
|
||||
*
|
||||
* This handles cloning the impl object.
|
||||
* \param rhs The record which will be copied.
|
||||
*/
|
||||
DNSResourceRecord& operator=(const DNSResourceRecord &rhs);
|
||||
|
||||
/**
|
||||
* \brief Destructor.
|
||||
*
|
||||
* This frees the impl object.
|
||||
*/
|
||||
~DNSResourceRecord();
|
||||
|
||||
/**
|
||||
* \brief Writes this record to a buffer.
|
||||
*
|
||||
* \param buffer The buffer in which to store the serialization.
|
||||
* \return uint32_t containing the number of bytes written.
|
||||
*/
|
||||
uint32_t write(uint8_t *buffer) const;
|
||||
|
||||
/**
|
||||
* \brief Returns the size of the data in this record.
|
||||
*/
|
||||
uint32_t data_size() const {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the pointer to the start of the data buffer.
|
||||
*/
|
||||
const uint8_t *data_ptr() const {
|
||||
return &data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a bool indicating whether this record contains
|
||||
* a domain name as the name being resolved.
|
||||
*/
|
||||
bool has_domain_name() const;
|
||||
|
||||
/**
|
||||
* \brief Returns a pointer to the domain name stored in this record.
|
||||
*
|
||||
* This will throw a std::bad_cast exception if the impl object is
|
||||
* not of the type NamedDNSRRImpl.
|
||||
*/
|
||||
const std::string *dname() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the offset stored in this record.
|
||||
*
|
||||
* This will throw a std::bad_cast exception if the impl object is
|
||||
* not of the type OffsetedDNSRRImpl.
|
||||
*/
|
||||
uint16_t offset() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the size of this record.
|
||||
*/
|
||||
uint32_t size() const;
|
||||
|
||||
/**
|
||||
* \brief Returns a reference to the info field.
|
||||
*/
|
||||
info &information() {
|
||||
return info_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a const reference to the info field.
|
||||
*/
|
||||
const info &information() const {
|
||||
return info_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if the domain name stored in this record matches
|
||||
* the given one.
|
||||
*
|
||||
* This is a shortcut
|
||||
*/
|
||||
bool matches(const std::string &dname) const;
|
||||
private:
|
||||
DNSRRImpl *clone_impl() const;
|
||||
size_t impl_size() const;
|
||||
|
||||
info info_;
|
||||
std::vector<uint8_t> data;
|
||||
DNSRRImpl *impl;
|
||||
};
|
||||
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
class DNSRRImpl {
|
||||
public:
|
||||
virtual ~DNSRRImpl() {}
|
||||
virtual uint32_t size() const = 0;
|
||||
virtual uint32_t do_write(uint8_t *buffer) const = 0;
|
||||
virtual bool matches(const std::string &dname) const { return false; }
|
||||
virtual DNSRRImpl *clone() const = 0;
|
||||
};
|
||||
|
||||
class OffsetedDNSRRImpl : public DNSRRImpl {
|
||||
public:
|
||||
OffsetedDNSRRImpl(uint16_t off);
|
||||
|
||||
uint32_t do_write(uint8_t *buffer) const;
|
||||
uint32_t size() const;
|
||||
OffsetedDNSRRImpl *clone() const;
|
||||
uint16_t offset() const;
|
||||
private:
|
||||
uint16_t offset_;
|
||||
};
|
||||
|
||||
class NamedDNSRRImpl : public DNSRRImpl {
|
||||
public:
|
||||
NamedDNSRRImpl(const std::string &nm);
|
||||
|
||||
template<typename ForwardIterator>
|
||||
NamedDNSRRImpl(ForwardIterator start, ForwardIterator end)
|
||||
: name(start, end)
|
||||
{ }
|
||||
|
||||
uint32_t do_write(uint8_t *buffer) const;
|
||||
|
||||
uint32_t size() const;
|
||||
|
||||
bool matches(const std::string &dname) const;
|
||||
|
||||
const std::string *dname_pointer() const;
|
||||
NamedDNSRRImpl *clone() const;
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
inline DNSResourceRecord make_offseted_record(uint16_t offset, const uint8_t *data = 0, uint32_t size = 0) {
|
||||
return DNSResourceRecord(new OffsetedDNSRRImpl(offset), data, size);
|
||||
}
|
||||
|
||||
inline DNSResourceRecord make_named_record(const std::string &name, const uint8_t *data = 0, uint32_t size = 0) {
|
||||
return DNSResourceRecord(new NamedDNSRRImpl(name), data, size);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TINS_DNS_RECORD_H
|
||||
3396
include/dot11.h
3396
include/dot11.h
File diff suppressed because it is too large
Load Diff
729
include/eapol.h
729
include/eapol.h
@@ -1,729 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_EAPOL_H
|
||||
#define TINS_EAPOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pdu.h"
|
||||
#include "small_uint.h"
|
||||
#include "endianness.h"
|
||||
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \cond
|
||||
* Forward declaration. Avoid header inclusion.
|
||||
*/
|
||||
class RSNInformation;
|
||||
/** \endcond */
|
||||
|
||||
/**
|
||||
* \brief Class that represents the EAP encapsulation over LAN.
|
||||
*/
|
||||
class EAPOL : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::EAPOL;
|
||||
|
||||
/**
|
||||
* The EAPOL type enum.
|
||||
*/
|
||||
enum EAPOLTYPE {
|
||||
RC4 = 1,
|
||||
RSN,
|
||||
EAPOL_WPA = 254
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Static method to instantiate the correct EAPOL subclass
|
||||
* based on a raw buffer.
|
||||
* \param buffer The buffer from which the data will be taken.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
static EAPOL *from_bytes(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the version field.
|
||||
* \return The version field.
|
||||
*/
|
||||
uint8_t version() const { return _header.version; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the packet type field.
|
||||
* \return The packet type field.
|
||||
*/
|
||||
uint8_t packet_type() const { return _header.packet_type; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the length field.
|
||||
* \return The length field.
|
||||
*/
|
||||
uint16_t length() const { return Endian::be_to_host(_header.length); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the type field.
|
||||
* \return The type field.
|
||||
*/
|
||||
uint8_t type() const { return _header.type; }
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Sets the version field.
|
||||
* \param new_version The new version to be set.
|
||||
*/
|
||||
void version(uint8_t new_version);
|
||||
|
||||
/**
|
||||
* \brief Sets the packet type field.
|
||||
* \param new_ptype The new packet type to be set.
|
||||
*/
|
||||
void packet_type(uint8_t new_ptype);
|
||||
|
||||
/**
|
||||
* \brief Sets the length field.
|
||||
* \param new_length The new length to be set.
|
||||
*/
|
||||
void length(uint16_t new_length);
|
||||
|
||||
/**
|
||||
* \brief Sets the type field.
|
||||
* \param new_type The new type to be set.
|
||||
*/
|
||||
void type(uint8_t new_type);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::EAPOL; }
|
||||
protected:
|
||||
/**
|
||||
* \brief Protected constructor that sets the packet_type and type fields.
|
||||
*/
|
||||
EAPOL(uint8_t packet_type, EAPOLTYPE type);
|
||||
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
*/
|
||||
EAPOL(const EAPOL &other);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an EAPOL object from a buffer.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
EAPOL(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
void copy_eapol_fields(const EAPOL *other);
|
||||
|
||||
struct eapolhdr {
|
||||
uint8_t version, packet_type;
|
||||
uint16_t length;
|
||||
uint8_t type;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* \brief Virtual method which should serialize the subclass specific
|
||||
* body and save it in a byte array.
|
||||
*
|
||||
* \param buffer The pointer in which to save the serialization.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
virtual void write_body(uint8_t *buffer, uint32_t total_sz) = 0;
|
||||
private:
|
||||
/**
|
||||
* \brief Serialices this EAPOL PDU.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
* \param total_sz The size available in the buffer.
|
||||
* \param parent The PDU that's one level below this one on the stack.
|
||||
*/
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
eapolhdr _header;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Class that represents the RC4 EAPOL PDU.
|
||||
*/
|
||||
class RC4EAPOL : public EAPOL {
|
||||
public:
|
||||
/**
|
||||
* The type used to store the key.
|
||||
*/
|
||||
typedef std::vector<uint8_t> key_type;
|
||||
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::RC4EAPOL;
|
||||
|
||||
/**
|
||||
* The length of the key IV field
|
||||
*/
|
||||
static const size_t key_iv_size = 16;
|
||||
|
||||
/**
|
||||
* The length of the key sign field
|
||||
*/
|
||||
static const size_t key_sign_size = 16;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RC4EAPOL
|
||||
*/
|
||||
RC4EAPOL();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an RC4EAPOL object from a buffer.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
RC4EAPOL(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the key length field.
|
||||
* \return The key length field.
|
||||
*/
|
||||
uint16_t key_length() const { return Endian::be_to_host(_header.key_length); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the replay counter field.
|
||||
* \return The replay counter field.
|
||||
*/
|
||||
uint64_t replay_counter() const { return Endian::be_to_host(_header.replay_counter); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key IV field.
|
||||
* \return The key IV field.
|
||||
*/
|
||||
const uint8_t *key_iv() const { return _header.key_iv; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key flag field.
|
||||
* \return The key flag field.
|
||||
*/
|
||||
small_uint<1> key_flag() const { return _header.key_flag; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key index field.
|
||||
* \return The key index field.
|
||||
*/
|
||||
small_uint<7> key_index() const { return _header.key_index; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key signature field.
|
||||
* \return The key signature field.
|
||||
*/
|
||||
const uint8_t *key_sign() const { return _header.key_sign; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key field.
|
||||
* \return The key field.
|
||||
*/
|
||||
const key_type &key() const { return _key; }
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Sets the key length field.
|
||||
* \param new_key_length The new key length to be set.
|
||||
*/
|
||||
void key_length(uint16_t new_key_length);
|
||||
|
||||
/**
|
||||
* \brief Sets the replay counter field.
|
||||
* \param new_replay_counter The new replay counter to be set.
|
||||
*/
|
||||
void replay_counter(uint64_t new_replay_counter);
|
||||
|
||||
/**
|
||||
* \brief Sets the key IV field.
|
||||
* \param new_key_iv The new key IV to be set.
|
||||
*/
|
||||
void key_iv(const uint8_t *new_key_iv);
|
||||
|
||||
/**
|
||||
* \brief Sets the key flag field.
|
||||
* \param new_key_flag The new key flag to be set.
|
||||
*/
|
||||
void key_flag(small_uint<1> new_key_flag);
|
||||
|
||||
/**
|
||||
* \brief Sets the key index field.
|
||||
* \param new_key_index The new key index to be set.
|
||||
*/
|
||||
void key_index(small_uint<7> new_key_index);
|
||||
|
||||
/**
|
||||
* \brief Sets the key signature field.
|
||||
* \param new_key_sign The new key signature to be set.
|
||||
*/
|
||||
void key_sign(const uint8_t *new_key_sign);
|
||||
|
||||
/**
|
||||
* \brief Sets the key field.
|
||||
* \param new_key The new key to be set.
|
||||
*/
|
||||
void key(const key_type &new_key);
|
||||
|
||||
/* Virtual method override. */
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size.
|
||||
*
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::RC4EAPOL; }
|
||||
|
||||
/**
|
||||
* \brief Check wether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) {
|
||||
return flag == PDU::RC4EAPOL || EAPOL::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
RC4EAPOL *clone() const {
|
||||
return new RC4EAPOL(*this);
|
||||
}
|
||||
private:
|
||||
struct rc4hdr {
|
||||
uint16_t key_length;
|
||||
uint64_t replay_counter;
|
||||
uint8_t key_iv[key_iv_size];
|
||||
uint8_t key_index:7,
|
||||
key_flag:1;
|
||||
uint8_t key_sign[16];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_body(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
|
||||
key_type _key;
|
||||
rc4hdr _header;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Class that represents the RSN EAPOL PDU.
|
||||
*/
|
||||
class RSNEAPOL : public EAPOL {
|
||||
public:
|
||||
/**
|
||||
* The type used to store the key.
|
||||
*/
|
||||
typedef std::vector<uint8_t> key_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::RSNEAPOL;
|
||||
|
||||
/**
|
||||
* The length of the key IV field
|
||||
*/
|
||||
static const size_t key_iv_size = 16;
|
||||
|
||||
/**
|
||||
* The length of the nonce field
|
||||
*/
|
||||
static const size_t nonce_size = 32;
|
||||
|
||||
/**
|
||||
* The length of the mic field
|
||||
*/
|
||||
static const size_t mic_size = 16;
|
||||
|
||||
/**
|
||||
* The length of the rsc field
|
||||
*/
|
||||
static const size_t rsc_size = 8;
|
||||
|
||||
/**
|
||||
* The length of the id field
|
||||
*/
|
||||
static const size_t id_size = 8;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNEAPOL.
|
||||
*/
|
||||
RSNEAPOL();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an RSNEAPOL object from a buffer.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
RSNEAPOL(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the key length field.
|
||||
* \return The key length field.
|
||||
*/
|
||||
uint16_t key_length() const { return Endian::be_to_host(_header.key_length); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the replay counter field.
|
||||
* \return The replay counter field.
|
||||
*/
|
||||
uint64_t replay_counter() const { return Endian::be_to_host(_header.replay_counter); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key IV field.
|
||||
* \return The key IV field.
|
||||
*/
|
||||
const uint8_t *key_iv() const { return _header.key_iv; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the nonce field.
|
||||
* \return The nonce field.
|
||||
*/
|
||||
const uint8_t *nonce() const { return _header.nonce; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the rsc field.
|
||||
* \return The rsc field.
|
||||
*/
|
||||
const uint8_t *rsc() const { return _header.rsc; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the id field.
|
||||
* \return The id field.
|
||||
*/
|
||||
const uint8_t *id() const { return _header.id; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the mic field.
|
||||
* \return The mic field.
|
||||
*/
|
||||
const uint8_t *mic() const { return _header.mic; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the wpa length field.
|
||||
* \return The wpa length field.
|
||||
*/
|
||||
uint16_t wpa_length() const { return Endian::be_to_host(_header.wpa_length); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key field.
|
||||
* \return The key field.
|
||||
*/
|
||||
const key_type &key() const { return _key; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_mic field.
|
||||
* \return The key_mic field.
|
||||
*/
|
||||
small_uint<1> key_mic() const { return _header.key_mic; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the secure field.
|
||||
* \return The secure field.
|
||||
*/
|
||||
small_uint<1> secure() const { return _header.secure; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the error field.
|
||||
* \return The error field.
|
||||
*/
|
||||
small_uint<1> error() const { return _header.error; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the request field.
|
||||
* \return The request field.
|
||||
*/
|
||||
small_uint<1> request() const { return _header.request; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the encrypted field.
|
||||
* \return The encrypted field.
|
||||
*/
|
||||
small_uint<1 > encrypted() const { return _header.encrypted; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_descriptor field.
|
||||
* \return The key_descriptor field.
|
||||
*/
|
||||
small_uint<3> key_descriptor() const { return _header.key_descriptor; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_t field.
|
||||
* \return The key_t field.
|
||||
*/
|
||||
small_uint<1> key_t() const { return _header.key_t; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_index field.
|
||||
* \return The key_index field.
|
||||
*/
|
||||
small_uint<2> key_index() const { return _header.key_index; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the install field.
|
||||
* \return The install field.
|
||||
*/
|
||||
small_uint<1> install() const { return _header.install; };
|
||||
|
||||
/**
|
||||
* \brief Getter for the key_ack field.
|
||||
* \return The key_ack field.
|
||||
*/
|
||||
small_uint<1> key_ack() const { return _header.key_ack; };
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size.
|
||||
*
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Sets the key length field.
|
||||
* \param new_key_length The new key length to be set.
|
||||
*/
|
||||
void key_length(uint16_t new_key_length);
|
||||
|
||||
/**
|
||||
* \brief Sets the replay counter field.
|
||||
* \param new_replay_counter The new replay counter to be set.
|
||||
*/
|
||||
void replay_counter(uint64_t new_replay_counter);
|
||||
|
||||
/**
|
||||
* \brief Sets the key IV field.
|
||||
* \param new_key_iv The new key IV to be set.
|
||||
*/
|
||||
void key_iv(const uint8_t *new_key_iv);
|
||||
|
||||
/**
|
||||
* \brief Sets the nonce field.
|
||||
*
|
||||
* This method sets the nonce field. This field is 32 bytes long,
|
||||
* therefore the input buffer should be at least that length.
|
||||
* \param new_nonce The new nonce to be set.
|
||||
*/
|
||||
void nonce(const uint8_t *new_nonce);
|
||||
|
||||
/**
|
||||
* \brief Sets the rsc field.
|
||||
* \param new_rsc The new rsc to be set.
|
||||
*/
|
||||
void rsc(const uint8_t *new_rsc);
|
||||
|
||||
/**
|
||||
* \brief Sets the id field.
|
||||
* \param new_id The new id to be set.
|
||||
*/
|
||||
void id(const uint8_t *new_id);
|
||||
|
||||
/**
|
||||
* \brief Sets the mic field.
|
||||
*
|
||||
* This method sets the mic field. This field is 16 bytes long,
|
||||
* therefore the input buffer should be at least that length.
|
||||
* \param new_mic The new mic to be set.
|
||||
*/
|
||||
void mic(const uint8_t *new_mic);
|
||||
|
||||
/**
|
||||
* \brief Sets the wpa length field.
|
||||
* \param new_wpa_length The new wpa length to be set.
|
||||
*/
|
||||
void wpa_length(uint16_t new_wpa_length);
|
||||
|
||||
/**
|
||||
* \brief Sets the key field.
|
||||
* \param new_key The new key to be set.
|
||||
*/
|
||||
void key(const key_type &new_key);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_mic field.
|
||||
* \param new_key_mic The new to be set.
|
||||
*/
|
||||
void key_mic(small_uint<1> new_key_mic);
|
||||
|
||||
/**
|
||||
* \brief Setter for the secure field.
|
||||
* \param new_secure The new to be set.
|
||||
*/
|
||||
void secure(small_uint<1> new_secure);
|
||||
|
||||
/**
|
||||
* \brief Setter for the error field.
|
||||
* \param new_error The new to be set.
|
||||
*/
|
||||
void error(small_uint<1> new_error);
|
||||
|
||||
/**
|
||||
* \brief Setter for the request field.
|
||||
* \param new_request The new to be set.
|
||||
*/
|
||||
void request(small_uint<1> new_request);
|
||||
|
||||
/**
|
||||
* \brief Setter for the encrypted field.
|
||||
* \param new_encrypted The new to be set.
|
||||
*/
|
||||
void encrypted(small_uint<1 > new_encrypted);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_descriptor field.
|
||||
* \param new_key_descriptor The new to be set.
|
||||
*/
|
||||
void key_descriptor(small_uint<3> new_key_descriptor);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_t field.
|
||||
* \param new_key_t The new to be set.
|
||||
*/
|
||||
void key_t(small_uint<1> new_key_t);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_index field.
|
||||
* \param new_key_index The new to be set.
|
||||
*/
|
||||
void key_index(small_uint<2> new_key_index);
|
||||
|
||||
/**
|
||||
* \brief Setter for the install field.
|
||||
* \param new_install The new to be set.
|
||||
*/
|
||||
void install(small_uint<1> new_install);
|
||||
|
||||
/**
|
||||
* \brief Setter for the key_ack field.
|
||||
* \param new_key_ack The new to be set.
|
||||
*/
|
||||
void key_ack(small_uint<1> new_key_ack);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::RSNEAPOL; }
|
||||
|
||||
/**
|
||||
* \brief Check wether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) {
|
||||
return flag == PDU::RSNEAPOL || EAPOL::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
RSNEAPOL *clone() const {
|
||||
return new RSNEAPOL(*this);
|
||||
}
|
||||
private:
|
||||
struct rsnhdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t key_mic:1,
|
||||
secure:1,
|
||||
error:1,
|
||||
request:1,
|
||||
encrypted:1,
|
||||
reserved:3,
|
||||
key_descriptor:3,
|
||||
key_t:1,
|
||||
key_index:2,
|
||||
install:1,
|
||||
key_ack:1;
|
||||
uint16_t key_length;
|
||||
uint64_t replay_counter;
|
||||
uint8_t nonce[nonce_size], key_iv[key_iv_size];
|
||||
uint8_t rsc[rsc_size], id[id_size];
|
||||
uint8_t mic[mic_size];
|
||||
uint16_t wpa_length;
|
||||
#else
|
||||
uint16_t reserved:3,
|
||||
encrypted:1,
|
||||
request:1,
|
||||
error:1,
|
||||
secure:1,
|
||||
key_mic:1,
|
||||
key_ack:1,
|
||||
install:1,
|
||||
key_index:2,
|
||||
key_t:1,
|
||||
key_descriptor:3;
|
||||
uint16_t key_length;
|
||||
uint64_t replay_counter;
|
||||
uint8_t nonce[nonce_size], key_iv[key_iv_size];
|
||||
uint8_t rsc[rsc_size], id[id_size];
|
||||
uint8_t mic[mic_size];
|
||||
uint16_t wpa_length;
|
||||
#endif
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_body(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
|
||||
rsnhdr _header;
|
||||
key_type _key;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_EAPOL_H
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ENDIANNESS_H
|
||||
#define TINS_ENDIANNESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#ifndef WIN32
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#define TINS_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
#define TINS_IS_BIG_ENDIAN (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
|
||||
namespace Tins {
|
||||
namespace Endian {
|
||||
/**
|
||||
* \brief Changes a 16-bit integral value's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
inline uint16_t change_endian(uint16_t data) {
|
||||
return ((data & 0xff00) >> 8) | ((data & 0x00ff) << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Changes a 32-bit integral value's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
inline uint32_t change_endian(uint32_t data) {
|
||||
return (((data & 0xff000000) >> 24) | ((data & 0x00ff0000) >> 8) |
|
||||
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Changes a 64-bit integral value's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
inline uint64_t change_endian(uint64_t data) {
|
||||
return (((uint64_t)(change_endian((uint32_t)((data << 32) >> 32))) << 32) |
|
||||
(change_endian(((uint32_t)(data >> 32)))));
|
||||
}
|
||||
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
/**
|
||||
* \brief Convert any integral type to big endian.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T host_to_be(T data) {
|
||||
return change_endian(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any integral type to little endian.
|
||||
*
|
||||
* On little endian platforms, the parameter is simply returned.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T host_to_le(T data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any big endian value to the host's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T be_to_host(T data) {
|
||||
return change_endian(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any little endian value to the host's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T le_to_host(T data) {
|
||||
return data;
|
||||
}
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
/**
|
||||
* \brief Convert any integral type to big endian.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T host_to_be(T data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any integral type to little endian.
|
||||
*
|
||||
* On little endian platforms, the parameter is simply returned.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T host_to_le(T data) {
|
||||
return change_endian(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any big endian value to the host's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T be_to_host(T data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert any little endian value to the host's endianess.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T le_to_host(T data) {
|
||||
return change_endian(data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TINS_ENDIANNESS_H
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ETHERNET_II_H
|
||||
#define TINS_ETHERNET_II_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "hw_address.h"
|
||||
#include "network_interface.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing an Ethernet II PDU.
|
||||
*/
|
||||
class EthernetII : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief The hardware address type.
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::ETHERNET_II;
|
||||
|
||||
/**
|
||||
* \brief Represents the ethernetII broadcast address.
|
||||
*/
|
||||
static const address_type BROADCAST;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating an ethernet PDU
|
||||
*
|
||||
* Constructor that builds an ethernet PDU taking the interface name,
|
||||
* destination's and source's MAC.
|
||||
*
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param dst_hw_addr address_type containing the destination's MAC(optional).
|
||||
* \param src_hw_addr address_type containing the source's MAC(optional).
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
*/
|
||||
EthernetII(const NetworkInterface& iface = NetworkInterface(),
|
||||
const address_type &dst_hw_addr = address_type(),
|
||||
const address_type &src_hw_addr = address_type(),
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
EthernetII(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the destination's hardware address.
|
||||
*
|
||||
* \return address_type containing the destination hardware
|
||||
* address.
|
||||
*/
|
||||
address_type dst_addr() const { return _eth.dst_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source's hardware address.
|
||||
*
|
||||
* \return address_type containing the source hardware address.
|
||||
*/
|
||||
address_type src_addr() const { return _eth.src_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the interface.
|
||||
*
|
||||
* \return Returns the interface in which this PDU will be sent.
|
||||
*/
|
||||
const NetworkInterface &iface() const { return _iface; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the payload_type
|
||||
* \return The payload type.
|
||||
*/
|
||||
uint16_t payload_type() const { return Endian::be_to_host(_eth.payload_type); };
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the destination hardware address.
|
||||
*
|
||||
* \param new_dst_addr the destination hardware address to be set.
|
||||
*/
|
||||
void dst_addr(const address_type &new_dst_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source hardware address.
|
||||
*
|
||||
* \param new_src_addr the source hardware address to be set.
|
||||
*/
|
||||
void src_addr(const address_type &new_src_addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the interface.
|
||||
*
|
||||
* \param new_iface the interface to be set.
|
||||
*/
|
||||
void iface(const NetworkInterface& new_iface);
|
||||
|
||||
/**
|
||||
* \brief Setter for the payload type.
|
||||
*
|
||||
* \param new_payload_type the new value of the payload type field.
|
||||
*/
|
||||
void payload_type(uint16_t new_payload_type);
|
||||
|
||||
/* Virtual methods */
|
||||
/**
|
||||
* \brief Returns the ethernet frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
// Windows does not support sending L2 PDUs.
|
||||
#ifndef WIN32
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
#ifndef WIN32
|
||||
/** \brief Receives a matching response for this packet.
|
||||
*
|
||||
* \sa PDU::recv_response
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
*/
|
||||
PDU *recv_response(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::ETHERNET_II; }
|
||||
|
||||
/** \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
* \sa PDU::clone_packet
|
||||
*/
|
||||
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
EthernetII *clone() const {
|
||||
return new EthernetII(*this);
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the Ethernet II header
|
||||
*/
|
||||
struct ethhdr {
|
||||
uint8_t dst_mac[address_type::address_size];
|
||||
uint8_t src_mac[address_type::address_size];
|
||||
uint16_t payload_type;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
ethhdr _eth;
|
||||
NetworkInterface _iface;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // TINS_ETHERNET_II_H
|
||||
@@ -1,323 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_HWADDRESS_H
|
||||
#define TINS_HWADDRESS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \class HWAddress
|
||||
* \brief Represents a hardware address.
|
||||
*/
|
||||
template<size_t n, typename Storage = uint8_t>
|
||||
class HWAddress {
|
||||
public:
|
||||
/**
|
||||
* \brief The type of the elements stored in the hardware address.
|
||||
*
|
||||
* This is the same as the template parameter Storage.
|
||||
*/
|
||||
typedef Storage storage_type;
|
||||
|
||||
/**
|
||||
* \brief The random access iterator type.
|
||||
*/
|
||||
typedef storage_type* iterator;
|
||||
|
||||
/**
|
||||
* \brief Const iterator type.
|
||||
*/
|
||||
typedef const storage_type* const_iterator;
|
||||
|
||||
/**
|
||||
* \brief Non-member constant indicating the amount of storage_type
|
||||
* elements in this address.
|
||||
*/
|
||||
static const size_t address_size = n;
|
||||
|
||||
/**
|
||||
* \brief Constructor from a const storage_type*.
|
||||
*
|
||||
* If no pointer or a null pointer is provided, the address is
|
||||
* initialized to 00:00:.....
|
||||
* This constructor is very usefull when passing zero initialized
|
||||
* addresses as arguments to other functions. You can use a
|
||||
* literal 0, which will be implicitly converted to the empty address.
|
||||
*
|
||||
* If a pointer is provided, address_size storage_type elements
|
||||
* are copied from the pointer, into the internal address representation.
|
||||
*
|
||||
* \param ptr The pointer from which to construct this address.
|
||||
*/
|
||||
HWAddress(const storage_type* ptr = 0) {
|
||||
if(ptr)
|
||||
std::copy(ptr, ptr + address_size, buffer);
|
||||
else
|
||||
std::fill(begin(), end(), storage_type());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constructs an address from a hex-notation address.
|
||||
*
|
||||
* This constructor will parse strings in the form:
|
||||
*
|
||||
* "00:01:da:fa:..."
|
||||
*
|
||||
* And initialize the internal representation accordingly.
|
||||
*
|
||||
* \param address The hex-notation address to be parsed.
|
||||
*/
|
||||
HWAddress(const std::string &address) {
|
||||
convert(address, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Overload provided basically for string literals.
|
||||
*
|
||||
* This constructor takes a const char array of i elements in
|
||||
* hex-notation. \sa HWAddress::HWAddress(const std::string &address)
|
||||
*
|
||||
* This is mostly used when providing string literals. If this where
|
||||
* a const char*, then there would be an ambiguity when providing
|
||||
* a null pointer.
|
||||
*
|
||||
* \param address The array of chars containing the hex-notation
|
||||
* cstring to be parsed.
|
||||
*/
|
||||
template<size_t i>
|
||||
HWAddress(const char (&address)[i]) {
|
||||
convert(address, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Copy construct from a HWAddress of length i.
|
||||
*
|
||||
* If i is lower or equal than address_size, then i storage_type
|
||||
* elements are copied, and the last (n - i) are initialized to
|
||||
* the default storage_type value(0 most of the times).
|
||||
*
|
||||
* If i is larger than address_size, then only the first address_size
|
||||
* elements are copied.
|
||||
*
|
||||
* \param rhs The HWAddress to be constructed from.
|
||||
*/
|
||||
template<size_t i>
|
||||
HWAddress(const HWAddress<i> &rhs) {
|
||||
std::copy(
|
||||
rhs.begin(),
|
||||
rhs.begin() + std::min(i, n),
|
||||
begin()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an iterator pointing to the begining of the
|
||||
* address.
|
||||
*
|
||||
* \return iterator.
|
||||
*/
|
||||
iterator begin() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves a const iterator pointing to the begining of
|
||||
* the address.
|
||||
*
|
||||
* \return const_iterator.
|
||||
*/
|
||||
const_iterator begin() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an iterator pointing one-past-the-end of the
|
||||
* address.
|
||||
*
|
||||
* \return iterator.
|
||||
*/
|
||||
iterator end() {
|
||||
return buffer + address_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves a const iterator pointing one-past-the-end of
|
||||
* the address.
|
||||
*
|
||||
* \return const_iterator.
|
||||
*/
|
||||
const_iterator end() const {
|
||||
return buffer + address_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compares this HWAddress for equality.
|
||||
*
|
||||
* \param rhs The HWAddress to be compared to.
|
||||
*
|
||||
* \return bool indicating whether addresses are equal.
|
||||
*/
|
||||
bool operator==(const HWAddress &rhs) const {
|
||||
return std::equal(begin(), end(), rhs.begin());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compares this HWAddress for in-equality.
|
||||
*
|
||||
* \param rhs The HWAddress to be compared to.
|
||||
*
|
||||
* \return bool indicating whether addresses are distinct.
|
||||
*/
|
||||
bool operator!=(const HWAddress &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compares this HWAddress for less-than inequality.
|
||||
*
|
||||
* \param rhs The HWAddress to be compared to.
|
||||
*
|
||||
* \return bool indicating whether this address is less-than rhs.
|
||||
*/
|
||||
bool operator<(const HWAddress &rhs) const {
|
||||
return std::lexicographical_compare(begin(), end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves the size of this address.
|
||||
*
|
||||
* This effectively returns the address_size constant.
|
||||
*/
|
||||
const size_t size() const {
|
||||
return address_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert this address to a hex-notation std::string address.
|
||||
*
|
||||
* \return std::string containing the hex-notation address.
|
||||
*/
|
||||
std::string to_string() const {
|
||||
std::ostringstream oss;
|
||||
oss << *this;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes this HWAddress in hex-notation to a std::ostream.
|
||||
*
|
||||
* \param os The stream in which to write the address.
|
||||
* \param addr The parameter to be written.
|
||||
* \return std::ostream& pointing to the os parameter.
|
||||
*/
|
||||
friend std::ostream &operator<<(std::ostream &os, const HWAddress &addr) {
|
||||
std::transform(
|
||||
addr.begin(),
|
||||
addr.end() - 1,
|
||||
std::ostream_iterator<std::string>(os, ":"),
|
||||
&HWAddress::storage_to_string
|
||||
);
|
||||
return os << storage_to_string(addr.buffer[HWAddress::address_size-1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function which copies the address into an output
|
||||
* iterator.
|
||||
*
|
||||
* This is the same as:
|
||||
*
|
||||
* std::copy(begin(), end(), iter);
|
||||
*
|
||||
* But since some PDUs return a HWAddress<> by value, this function
|
||||
* can be used to avoid temporaries.
|
||||
*
|
||||
* \param iter The output iterator in which to store this address.
|
||||
* \return OutputIterator pointing to one-past the last position
|
||||
* written.
|
||||
*/
|
||||
template<typename OutputIterator>
|
||||
OutputIterator copy(OutputIterator iter) const {
|
||||
return std::copy(begin(), end(), iter);
|
||||
}
|
||||
private:
|
||||
template<typename OutputIterator>
|
||||
static void convert(const std::string &hw_addr, OutputIterator output);
|
||||
|
||||
static std::string storage_to_string(storage_type element) {
|
||||
std::ostringstream oss;
|
||||
oss << std::hex;
|
||||
if(element < 0x10)
|
||||
oss << '0';
|
||||
oss << (unsigned)element;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
storage_type buffer[n];
|
||||
};
|
||||
|
||||
template<size_t n, typename Storage>
|
||||
template<typename OutputIterator>
|
||||
void HWAddress<n, Storage>::convert(const std::string &hw_addr,
|
||||
OutputIterator output)
|
||||
{
|
||||
unsigned i(0);
|
||||
storage_type tmp;
|
||||
while(i < hw_addr.size()) {
|
||||
const unsigned end = i+2;
|
||||
tmp = storage_type();
|
||||
while(i < end) {
|
||||
if(hw_addr[i] >= 'a' && hw_addr[i] <= 'f')
|
||||
tmp = (tmp << 4) | (hw_addr[i] - 'a' + 10);
|
||||
else if(hw_addr[i] >= '0' && hw_addr[i] <= '9')
|
||||
tmp = (tmp << 4) | (hw_addr[i] - '0');
|
||||
else if(hw_addr[i] == ':')
|
||||
break;
|
||||
else
|
||||
throw std::runtime_error("Invalid byte found");
|
||||
i++;
|
||||
}
|
||||
*(output++) = tmp;
|
||||
if(i < hw_addr.size()) {
|
||||
if(hw_addr[i] == ':')
|
||||
i++;
|
||||
else
|
||||
throw std::runtime_error("Invalid separator");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // TINS_HWADDRESS_H
|
||||
351
include/icmp.h
351
include/icmp.h
@@ -1,351 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ICMP_H
|
||||
#define TINS_ICMP_H
|
||||
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \brief Class that represents an ICMP PDU.
|
||||
*
|
||||
* ICMP is the representation of the ICMP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
*/
|
||||
class ICMP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::ICMP;
|
||||
|
||||
/** \brief ICMP flags
|
||||
*/
|
||||
enum Flags {
|
||||
ECHO_REPLY = 0,
|
||||
DEST_UNREACHABLE = 3,
|
||||
SOURCE_QUENCH = 4,
|
||||
REDIRECT = 5,
|
||||
ECHO_REQUEST = 8,
|
||||
TIME_EXCEEDED = 11,
|
||||
PARAM_PROBLEM = 12,
|
||||
INFO_REQUEST = 15,
|
||||
INFO_REPLY = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of ICMP.
|
||||
*
|
||||
* If no flag is specified, then ECHO_REQUEST will be used.
|
||||
* \param flag The type flag which will be set.
|
||||
*/
|
||||
ICMP(Flags flag = ECHO_REQUEST);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an ICMP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
ICMP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Sets the code field.
|
||||
*
|
||||
* \param new_code The code which will be stored in the ICMP struct.
|
||||
*/
|
||||
void code(uint8_t new_code);
|
||||
|
||||
/** \brief Sets the type field.
|
||||
*
|
||||
* \param type The type which will be stored in the ICMP struct.
|
||||
*/
|
||||
void type(Flags type);
|
||||
|
||||
/**
|
||||
* \brief Setter for checksum field.
|
||||
*
|
||||
* \param new_check uint16_t with the new checksum.
|
||||
*/
|
||||
void check(uint16_t new_check);
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
* \param new_id uint16_t with the new id.
|
||||
*/
|
||||
void id(uint16_t new_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sequence field.
|
||||
*
|
||||
* \param new_seq uint16_t with the new sequence.
|
||||
*/
|
||||
void sequence(uint16_t new_seq);
|
||||
|
||||
/**
|
||||
* \brief Setter for the gateway field.
|
||||
*
|
||||
* \param new_gw uint32_t with the new gateway.
|
||||
*/
|
||||
void gateway(uint32_t new_gw);
|
||||
|
||||
/**
|
||||
* \brief Setter for the mtu field.
|
||||
*
|
||||
* \param new_mtu uint16_t with the new sequence.
|
||||
*/
|
||||
void mtu(uint16_t new_mtu);
|
||||
|
||||
/**
|
||||
* \brief Setter for the pointer field.
|
||||
*
|
||||
* \param new_pointer uint8_t with the new pointer.
|
||||
*/
|
||||
void pointer(uint8_t new_pointer);
|
||||
|
||||
/**
|
||||
* \brief Sets echo request flag for this PDU.
|
||||
*
|
||||
* \param id The identifier for this request.
|
||||
* \param seq The sequence number for this request.
|
||||
*/
|
||||
void set_echo_request(uint16_t id, uint16_t seq);
|
||||
|
||||
/**
|
||||
* \brief Sets echo request flag for this PDU.
|
||||
*
|
||||
* This uses a global id and sequence number to fill the request's
|
||||
* fields.
|
||||
*/
|
||||
void set_echo_request();
|
||||
|
||||
/**
|
||||
* \brief Sets echo reply flag for this PDU.
|
||||
*
|
||||
* \param id The identifier for this request.
|
||||
* \param seq The sequence number for this request.
|
||||
*/
|
||||
void set_echo_reply(uint16_t id, uint16_t seq);
|
||||
|
||||
/**
|
||||
* \brief Sets echo reply flag for this PDU.
|
||||
*
|
||||
* This uses a global id and sequence number to fill the request's
|
||||
* fields.
|
||||
*/
|
||||
void set_echo_reply();
|
||||
|
||||
/**
|
||||
* \brief Sets information request flag for this PDU.
|
||||
*
|
||||
* \param id The identifier for this request.
|
||||
* \param seq The sequence number for this request.
|
||||
*/
|
||||
void set_info_request(uint16_t id, uint16_t seq);
|
||||
|
||||
/**
|
||||
* \brief Sets information reply flag for this PDU.
|
||||
*
|
||||
* \param id The identifier for this request.
|
||||
* \param seq The sequence number for this request.
|
||||
*/
|
||||
void set_info_reply(uint16_t id, uint16_t seq);
|
||||
|
||||
/**
|
||||
* \brief Sets destination unreachable for this PDU.
|
||||
*/
|
||||
void set_dest_unreachable();
|
||||
|
||||
/**
|
||||
* \brief Sets time exceeded flag for this PDU.
|
||||
*
|
||||
* \param ttl_exceeded If true this PDU will represent a ICMP ttl
|
||||
* exceeded, otherwise it will represent a fragment reassembly
|
||||
* time exceeded.
|
||||
*/
|
||||
void set_time_exceeded(bool ttl_exceeded = true);
|
||||
|
||||
/**
|
||||
* \brief Sets parameter problem flag for this PDU.
|
||||
*
|
||||
* \param set_pointer Indicates wether a pointer to the bad octet
|
||||
* is provided.
|
||||
* \param bad_octet Identifies the octet in which the error was
|
||||
* detected. If set_pointer == false, it is ignored.
|
||||
*/
|
||||
void set_param_problem(bool set_pointer = false, uint8_t bad_octet = 0);
|
||||
|
||||
/**
|
||||
* \brief Sets source quench flag for this PDU.
|
||||
*/
|
||||
void set_source_quench();
|
||||
|
||||
/**
|
||||
* \brief Sets redirect flag for this PDU.
|
||||
*
|
||||
* \param icode The code to be set.
|
||||
* \param address Address of the gateway to which traffic should
|
||||
* be sent.
|
||||
*/
|
||||
void set_redirect(uint8_t icode, uint32_t address);
|
||||
|
||||
/**
|
||||
* \brief Getter for the ICMP type flag.
|
||||
*
|
||||
* \return The type flag for this ICMP PDU.
|
||||
*/
|
||||
Flags type() const { return (Flags)_icmp.type; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ICMP code flag.
|
||||
*
|
||||
* \return The code flag for this ICMP PDU.
|
||||
*/
|
||||
uint8_t code() const { return _icmp.code; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the checksum field.
|
||||
*
|
||||
* \return Returns the checksum as an unit16_t.
|
||||
*/
|
||||
uint16_t check() const { return Endian::be_to_host(this->_icmp.check); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the echo id.
|
||||
*
|
||||
* \return Returns the echo id.
|
||||
*/
|
||||
uint16_t id() const { return Endian::be_to_host(_icmp.un.echo.id); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the echo sequence number.
|
||||
*
|
||||
* \return Returns the echo sequence number.
|
||||
*/
|
||||
uint16_t sequence() const { return Endian::be_to_host(_icmp.un.echo.sequence); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the gateway field.
|
||||
*
|
||||
* \return Returns the gateways in an unit32_t.
|
||||
*/
|
||||
uint32_t gateway() const { return Endian::be_to_host(this->_icmp.un.gateway); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the pointer field.
|
||||
*
|
||||
* \return Returns the pointer value.
|
||||
*/
|
||||
uint8_t pointer() const { return this->_icmp.un.pointer; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the mtu field.
|
||||
*
|
||||
* \return Returns the mtu value in an uint16_t.
|
||||
*/
|
||||
uint16_t mtu() const { return Endian::be_to_host(this->_icmp.un.frag.mtu); }
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::ICMP; }
|
||||
|
||||
/**
|
||||
* \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
* \sa PDU::clone_packet
|
||||
*/
|
||||
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
ICMP *clone() const {
|
||||
return new ICMP(*this);
|
||||
}
|
||||
private:
|
||||
static uint16_t global_id, global_seq;
|
||||
|
||||
struct icmphdr {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t check;
|
||||
union {
|
||||
struct {
|
||||
uint16_t id;
|
||||
uint16_t sequence;
|
||||
} echo;
|
||||
uint32_t gateway;
|
||||
struct {
|
||||
uint16_t __unused;
|
||||
uint16_t mtu;
|
||||
} frag;
|
||||
uint8_t pointer;
|
||||
} un;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/** \brief Serialices this ICMP PDU.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
* \param total_sz The size available in the buffer.
|
||||
* \param parent The PDU that's one level below this one on the stack.
|
||||
*/
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
icmphdr _icmp;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_ICMP_H
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_IEEE802_3_H
|
||||
#define TINS_IEEE802_3_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "hw_address.h"
|
||||
#include "network_interface.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing an Ethernet II PDU.
|
||||
*/
|
||||
class IEEE802_3 : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief The address type.
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::IEEE802_3;
|
||||
|
||||
/**
|
||||
* \brief Represents the IEEE802_3 broadcast address.
|
||||
*/
|
||||
static const address_type BROADCAST;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating an IEEE802_3 PDU
|
||||
*
|
||||
* Constructor that builds an IEEE802_3 PDU taking the interface name,
|
||||
* destination's and source's MAC.
|
||||
*
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
* \param child The PDU which will be set as the inner PDU.
|
||||
*/
|
||||
IEEE802_3(const NetworkInterface& iface = NetworkInterface(),
|
||||
const address_type &dst_hw_addr = address_type(),
|
||||
const address_type &src_hw_addr = address_type(),
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an IEEE802_3 object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
IEEE802_3(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the destination hardware address.
|
||||
*
|
||||
* \return The destination hardware address.
|
||||
*/
|
||||
address_type dst_addr() const { return _eth.dst_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source hardware address.
|
||||
*
|
||||
* \return The source hardware address.
|
||||
*/
|
||||
address_type src_addr() const { return _eth.src_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the interface.
|
||||
*
|
||||
* \return The network interface.
|
||||
*/
|
||||
const NetworkInterface &iface() const { return this->_iface; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the length field.
|
||||
* \return The length field value.
|
||||
*/
|
||||
uint16_t length() const { return Endian::be_to_host(_eth.length); };
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the destination hardware address.
|
||||
*
|
||||
* \param new_dst_mac The new destination hardware address.
|
||||
*/
|
||||
void dst_addr(const address_type &new_dst_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source hardware address.
|
||||
*
|
||||
* \param new_src_mac The new source hardware address.
|
||||
*/
|
||||
void src_addr(const address_type &new_src_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the interface.
|
||||
*
|
||||
* \param new_iface The interface in which to send this PDU.
|
||||
*/
|
||||
void iface(const NetworkInterface &new_iface);
|
||||
|
||||
/**
|
||||
* \brief Setter for the length field.
|
||||
*
|
||||
* \param new_length uint16_t with the new value of the length field.
|
||||
*/
|
||||
void length(uint16_t new_length);
|
||||
|
||||
/* Virtual methods */
|
||||
/**
|
||||
* \brief Returns the IEEE802_3 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
#ifndef WIN32
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
#ifndef WIN32
|
||||
/** \brief Receives a matching response for this packet.
|
||||
*
|
||||
* \sa PDU::recv_response
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
*/
|
||||
PDU *recv_response(PacketSender &sender);
|
||||
#endif // WIN32
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::IEEE802_3; }
|
||||
|
||||
/**
|
||||
* \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
* \sa PDU::clone_packet
|
||||
*/
|
||||
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
IEEE802_3 *clone() const {
|
||||
return new IEEE802_3(*this);
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the Ethernet II header
|
||||
*/
|
||||
struct ethhdr {
|
||||
uint8_t dst_mac[address_type::address_size];
|
||||
uint8_t src_mac[address_type::address_size];
|
||||
uint16_t length;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
ethhdr _eth;
|
||||
NetworkInterface _iface;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // TINS_IEEE802_3_H
|
||||
615
include/ip.h
615
include/ip.h
@@ -1,615 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_IP_H
|
||||
#define TINS_IP_H
|
||||
|
||||
#include <list>
|
||||
#include "pdu.h"
|
||||
#include "small_uint.h"
|
||||
#include "endianness.h"
|
||||
#include "ip_address.h"
|
||||
#include "pdu_option.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class that represents an IP PDU.
|
||||
*
|
||||
* By default, IP PDUs are initialized, setting TTL to IP::DEFAULT_TTL,
|
||||
* id field to 1 and version to 4. Taking this into account, users
|
||||
* should set destination and source port and would be enough to send one.
|
||||
*/
|
||||
class IP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* his PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::IP;
|
||||
|
||||
/**
|
||||
* The type used to store addresses.
|
||||
*/
|
||||
typedef IPv4Address address_type;
|
||||
|
||||
/**
|
||||
* \brief Enum indicating the option's class.
|
||||
*
|
||||
* Enum OptionClass represents the different classes of
|
||||
* IP Options.
|
||||
*/
|
||||
enum OptionClass {
|
||||
CONTROL = 0,
|
||||
MEASUREMENT = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum indicating the option's id number.
|
||||
*
|
||||
* Enum Option indicates the possible IP Options.
|
||||
*/
|
||||
enum OptionNumber {
|
||||
END = 0,
|
||||
NOOP = 1,
|
||||
SEC = 2,
|
||||
LSSR = 3,
|
||||
TIMESTAMP = 4,
|
||||
EXTSEC = 5,
|
||||
RR = 7,
|
||||
SID = 8,
|
||||
SSRR = 9,
|
||||
MTUPROBE = 11,
|
||||
MTUREPLY = 12,
|
||||
EIP = 17,
|
||||
TR = 18,
|
||||
ADDEXT = 19,
|
||||
RTRALT = 20,
|
||||
SDB = 21,
|
||||
DPS = 23,
|
||||
UMP = 24,
|
||||
QS = 25
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The type used to represent an option's type.
|
||||
*/
|
||||
struct option_identifier {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint8_t number:5,
|
||||
op_class:2,
|
||||
copied:1;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
uint8_t copied:1,
|
||||
op_class:2,
|
||||
number:5;
|
||||
#endif
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*
|
||||
* Initializes every field to 0.
|
||||
*/
|
||||
option_identifier()
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
: number(0), op_class(0), copied(0) {}
|
||||
#else
|
||||
: copied(0), op_class(0), number(0) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Constructs this option from a single uint8_t value.
|
||||
*
|
||||
* This parses the value and initializes each field with the
|
||||
* appropriate value.
|
||||
*
|
||||
* \param value The value to be parsed and used for
|
||||
* initialization
|
||||
*/
|
||||
option_identifier(uint8_t value)
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
: number(value & 0x1f),
|
||||
op_class((value >> 5) & 0x03),
|
||||
copied((value >> 7) & 0x01) {}
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
: copied((value >> 7) & 0x01),
|
||||
op_class((value >> 5) & 0x03),
|
||||
number(value & 0x1f) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Constructor using user provided values for each field.
|
||||
* \param number The number field value.
|
||||
* \param op_class The option class field value.
|
||||
* \param copied The copied field value.
|
||||
*/
|
||||
option_identifier(OptionNumber number, OptionClass op_class,
|
||||
small_uint<1> copied)
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
: number(number), op_class(op_class), copied(copied) {}
|
||||
#else
|
||||
: copied(copied), op_class(op_class), number(number) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Equality operator.
|
||||
*/
|
||||
bool operator==(const option_identifier &rhs) const {
|
||||
return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
|
||||
}
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* The IP options type.
|
||||
*/
|
||||
typedef PDUOption<option_identifier> ip_option;
|
||||
|
||||
/**
|
||||
* The type of the security option.
|
||||
*/
|
||||
struct security_type {
|
||||
uint16_t security, compartments;
|
||||
uint16_t handling_restrictions;
|
||||
small_uint<24> transmission_control;
|
||||
|
||||
security_type(uint16_t sec = 0, uint16_t comp = 0,
|
||||
uint16_t hand_res = 0, small_uint<24> tcc = 0)
|
||||
: security(sec), compartments(comp),
|
||||
handling_restrictions(hand_res), transmission_control(tcc)
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the Loose Source and Record Route
|
||||
*/
|
||||
struct generic_route_option_type {
|
||||
typedef std::vector<address_type> routes_type;
|
||||
|
||||
uint8_t pointer;
|
||||
routes_type routes;
|
||||
|
||||
generic_route_option_type(uint8_t ptr = 0,
|
||||
routes_type rts = routes_type())
|
||||
: pointer(ptr), routes(rts) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the Loose Source and Record Route
|
||||
*/
|
||||
typedef generic_route_option_type lsrr_type;
|
||||
|
||||
/**
|
||||
* The type of the Strict Source and Record Route
|
||||
*/
|
||||
typedef generic_route_option_type ssrr_type;
|
||||
|
||||
/**
|
||||
* The type of the Record Route
|
||||
*/
|
||||
typedef generic_route_option_type record_route_type;
|
||||
|
||||
/**
|
||||
* \brief Constructor for building the IP PDU.
|
||||
*
|
||||
* Both the destination and source IP address can be supplied.
|
||||
* By default, those fields are initialized using the IP
|
||||
* address 0.0.0.0.
|
||||
*
|
||||
* \param ip_dst The destination ip address(optional).
|
||||
* \param ip_src The source ip address(optional).
|
||||
* \param child pointer to a PDU which will be set as the inner_pdu
|
||||
* for the packet being constructed(optional).
|
||||
*/
|
||||
IP(address_type ip_dst = address_type(),
|
||||
address_type ip_src = address_type(),
|
||||
PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an IP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
IP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the header length field.
|
||||
*
|
||||
* \return The number of dwords the header occupies in an uin8_t.
|
||||
*/
|
||||
small_uint<4> head_len() const { return this->_ip.ihl; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the type of service field.
|
||||
*
|
||||
* \return The this IP PDU's type of service.
|
||||
*/
|
||||
uint8_t tos() const { return _ip.tos; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the total length field.
|
||||
*
|
||||
* \return The total length of this IP PDU.
|
||||
*/
|
||||
uint16_t tot_len() const { return Endian::be_to_host(_ip.tot_len); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the id field.
|
||||
*
|
||||
* \return The id for this IP PDU.
|
||||
*/
|
||||
uint16_t id() const { return Endian::be_to_host(_ip.id); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment offset field.
|
||||
*
|
||||
* \return The fragment offset for this IP PDU.
|
||||
*/
|
||||
uint16_t frag_off() const { return Endian::be_to_host(_ip.frag_off); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the time to live field.
|
||||
*
|
||||
* \return The time to live for this IP PDU.
|
||||
*/
|
||||
uint8_t ttl() const { return _ip.ttl; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol field.
|
||||
*
|
||||
* \return The protocol for this IP PDU.
|
||||
*/
|
||||
uint8_t protocol() const { return _ip.protocol; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the checksum field.
|
||||
*
|
||||
* \return The checksum for this IP PDU.
|
||||
*/
|
||||
uint16_t check() const { return Endian::be_to_host(_ip.check); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source address field.
|
||||
*
|
||||
* \return The source address for this IP PDU.
|
||||
*/
|
||||
address_type src_addr() const { return address_type(_ip.saddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the destination address field.
|
||||
* \return The destination address for this IP PDU.
|
||||
*/
|
||||
address_type dst_addr() const { return address_type(_ip.daddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the version field.
|
||||
* \return The version for this IP PDU.
|
||||
*/
|
||||
small_uint<4> version() const { return _ip.version; }
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the header length field.
|
||||
*
|
||||
* \param new_head_len The new header length.
|
||||
*/
|
||||
void head_len(small_uint<4> new_head_len);
|
||||
|
||||
/**
|
||||
* \brief Setter for the type of service field.
|
||||
*
|
||||
* \param new_tos The new type of service.
|
||||
*/
|
||||
void tos(uint8_t new_tos);
|
||||
|
||||
/**
|
||||
* \brief Setter for the total length field.
|
||||
*
|
||||
* \param new_tot_len The new total length.
|
||||
*/
|
||||
void tot_len(uint16_t new_tot_len);
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
* \param new_id The new id.
|
||||
*/
|
||||
void id(uint16_t new_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment offset field.
|
||||
*
|
||||
* \param new_frag_off The new fragment offset.
|
||||
*/
|
||||
void frag_off(uint16_t new_frag_off);
|
||||
|
||||
/**
|
||||
* \brief Setter for the time to live field.
|
||||
*
|
||||
* \param new_ttl The new time to live.
|
||||
*/
|
||||
void ttl(uint8_t new_ttl);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol field.
|
||||
*
|
||||
* \param new_protocol The new protocol.
|
||||
*/
|
||||
void protocol(uint8_t new_protocol);
|
||||
|
||||
/**
|
||||
* \brief Setter for the checksum field.
|
||||
*
|
||||
* \param new_check The new checksum.
|
||||
*/
|
||||
void check(uint16_t new_check);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source address field.
|
||||
*
|
||||
* \param ip The source address to be set.
|
||||
*/
|
||||
void src_addr(address_type ip);
|
||||
|
||||
/**
|
||||
* \brief Setter for the destination address field.
|
||||
*
|
||||
* \param ip The destination address to be set.
|
||||
*/
|
||||
void dst_addr(address_type ip);
|
||||
|
||||
/**
|
||||
* \brief Setter for the version field.
|
||||
*
|
||||
* \param ver The version field to be set.
|
||||
*/
|
||||
void version(small_uint<4> ver);
|
||||
|
||||
/**
|
||||
* \brief Adds an IP option.
|
||||
*
|
||||
* The option is added after the last option in the option
|
||||
* fields.
|
||||
*
|
||||
* \param option The option to be added
|
||||
*/
|
||||
void add_option(const ip_option &option);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
* \param id The option identifier to be searched.
|
||||
*/
|
||||
const ip_option *search_option(option_identifier id) const;
|
||||
|
||||
// Option setters
|
||||
|
||||
/**
|
||||
* \brief Adds an End Of List option.
|
||||
*/
|
||||
void eol();
|
||||
|
||||
/**
|
||||
* \brief Adds a NOP option.
|
||||
*/
|
||||
void noop();
|
||||
|
||||
/**
|
||||
* \brief Adds a security option.
|
||||
*
|
||||
* \param data The data to be stored in this option.
|
||||
*/
|
||||
void security(const security_type &data);
|
||||
|
||||
/**
|
||||
* \brief Adds a Loose Source and Record Route option.
|
||||
*
|
||||
* \param data The data to be stored in this option.
|
||||
*/
|
||||
void lsrr(const lsrr_type &data) {
|
||||
add_route_option(131, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Strict Source and Record Route option.
|
||||
*
|
||||
* \param data The data to be stored in this option.
|
||||
*/
|
||||
void ssrr(const ssrr_type &data) {
|
||||
add_route_option(137, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Record Route option.
|
||||
*
|
||||
* \param data The data to be stored in this option.
|
||||
*/
|
||||
void record_route(const record_route_type &data) {
|
||||
add_route_option(7, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Stream Identifier option.
|
||||
*
|
||||
* \param stream_id The stream id to be stored in this option.
|
||||
*/
|
||||
void stream_identifier(uint16_t stream_id);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Searchs and returns a security option.
|
||||
*
|
||||
* If no such option exists, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return security_type containing the option found.
|
||||
*/
|
||||
security_type security() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs and returns a Loose Source and Record Route
|
||||
* option.
|
||||
*
|
||||
* If no such option exists, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return lsrr_type containing the option found.
|
||||
*/
|
||||
lsrr_type lsrr() const {
|
||||
return search_route_option(131);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Searchs and returns a Strict Source and Record Route
|
||||
* option.
|
||||
*
|
||||
* If no such option exists, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ssrr_type containing the option found.
|
||||
*/
|
||||
ssrr_type ssrr() const {
|
||||
return search_route_option(137);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Searchs and returns a Record Route option.
|
||||
*
|
||||
* If no such option exists, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return record_route_type containing the option found.
|
||||
*/
|
||||
record_route_type record_route() const {
|
||||
return search_route_option(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Searchs and returns a Stream Identifier option.
|
||||
*
|
||||
* If no such option exists, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint16_t containing the option found.
|
||||
*/
|
||||
uint16_t stream_identifier() const;
|
||||
|
||||
/* Virtual methods */
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
|
||||
/**
|
||||
* \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Receives a matching response for this packet.
|
||||
*
|
||||
* \sa PDU::recv_response
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
*/
|
||||
PDU *recv_response(PacketSender &sender);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::IP; }
|
||||
|
||||
/**
|
||||
* \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
* \sa PDU::clone_packet
|
||||
*/
|
||||
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
IP *clone() const {
|
||||
return new IP(*this);
|
||||
}
|
||||
private:
|
||||
static const uint8_t DEFAULT_TTL;
|
||||
|
||||
struct iphdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
unsigned int ihl:4;
|
||||
unsigned int version:4;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
unsigned int version:4;
|
||||
unsigned int ihl:4;
|
||||
#else
|
||||
# error "Endian is not LE nor BE..."
|
||||
#endif
|
||||
uint8_t tos;
|
||||
uint16_t tot_len;
|
||||
uint16_t id;
|
||||
uint16_t frag_off;
|
||||
uint8_t ttl;
|
||||
uint8_t protocol;
|
||||
uint16_t check;
|
||||
uint32_t saddr;
|
||||
uint32_t daddr;
|
||||
/*The options start here. */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void init_ip_fields();
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
uint8_t* write_option(const ip_option &opt, uint8_t* buffer);
|
||||
void add_route_option(option_identifier id, const generic_route_option_type &data);
|
||||
generic_route_option_type search_route_option(option_identifier id) const;
|
||||
|
||||
iphdr _ip;
|
||||
std::list<ip_option> _ip_options;
|
||||
uint32_t _options_size, _padded_options_size;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_IP_H
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_IPADDRESS_H
|
||||
#define TINS_IPADDRESS_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \class IPv4Address
|
||||
* \brief Abstraction of an IPv4 address.
|
||||
*/
|
||||
class IPv4Address {
|
||||
public:
|
||||
/**
|
||||
* The address size.
|
||||
*/
|
||||
static const size_t address_size = sizeof(uint32_t);
|
||||
|
||||
/**
|
||||
* \brief Constructor taking a const char*.
|
||||
*
|
||||
* Constructs an IPv4Address from a dotted-notation address
|
||||
* cstring. If the pointer provided is null, then a default
|
||||
* IPv4Address object is constructed, which corresponds to
|
||||
* the 0.0.0.0 address.
|
||||
*
|
||||
* \param ip const char* containing the dotted-notation address.
|
||||
*/
|
||||
IPv4Address(const char *ip = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor taking a std::string.
|
||||
*
|
||||
* Constructs an IPv4Address from a dotted-notation std::strings
|
||||
*
|
||||
* \param ip std::string containing the dotted-notation address.
|
||||
*/
|
||||
IPv4Address(const std::string &ip);
|
||||
|
||||
/**
|
||||
* \brief Constructor taking a IP address represented as a
|
||||
* big endian integer.
|
||||
*
|
||||
* This constructor should be used internally by PDUs that
|
||||
* handle IP addresses. The provided integer <b>must</b> be
|
||||
* be in big endian.
|
||||
*/
|
||||
explicit IPv4Address(uint32_t ip);
|
||||
|
||||
/**
|
||||
* \brief User defined conversion to big endian integral value.
|
||||
*/
|
||||
operator uint32_t() const;
|
||||
|
||||
/**
|
||||
* \brief Retrieve the string representation of this address.
|
||||
*
|
||||
* \return std::string containing the representation of this address.
|
||||
*/
|
||||
std::string to_string() const;
|
||||
|
||||
/**
|
||||
* \brief Compare this IPv4Address for equality.
|
||||
*
|
||||
* \param rhs The address to be compared.
|
||||
* \return bool indicating whether this address equals rhs.
|
||||
*/
|
||||
bool operator==(const IPv4Address &rhs) const {
|
||||
return ip_addr == rhs.ip_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compare this IPv4Address for inequality.
|
||||
*
|
||||
* \param rhs The address to be compared.
|
||||
* \return bool indicating whether this address is distinct
|
||||
* from rhs.
|
||||
*/
|
||||
bool operator!=(const IPv4Address &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compare this IPv4Address for less-than inequality.
|
||||
*
|
||||
* \param rhs The address to be compared.
|
||||
* \return bool indicating whether this address is less-than rhs.
|
||||
*/
|
||||
bool operator< (const IPv4Address &rhs) const {
|
||||
return ip_addr < rhs.ip_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes this address to a std::ostream.
|
||||
*
|
||||
* This method writes addr in a dotted-string notation address
|
||||
* to the std::ostream argument.
|
||||
*
|
||||
* \param output The std::ostream in which to write the address.
|
||||
* \param addr The IPv4Address to be written.
|
||||
* \return std::stream& pointing to output.
|
||||
*/
|
||||
friend std::ostream &operator<<(std::ostream &output, const IPv4Address &addr);
|
||||
private:
|
||||
uint32_t ip_to_int(const std::string &ip);
|
||||
|
||||
uint32_t ip_addr;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // TINS_IPADDRESS_H
|
||||
389
include/llc.h
389
include/llc.h
@@ -1,389 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_IEEE8022_H
|
||||
#define TINS_IEEE8022_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing a LLC frame.
|
||||
*
|
||||
* This PDU follows the standard LLC frame described in the IEEE 802.2 specs.
|
||||
*/
|
||||
class LLC : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::LLC;
|
||||
|
||||
/**
|
||||
* \brief Represents the LLC global DSAP address.
|
||||
*/
|
||||
static const uint8_t GLOBAL_DSAP_ADDR;
|
||||
static const uint8_t NULL_ADDR;
|
||||
|
||||
/**
|
||||
* \brief LLC Format flags.
|
||||
*/
|
||||
enum Format {
|
||||
INFORMATION = 0,
|
||||
SUPERVISORY = 1,
|
||||
UNNUMBERED = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief LLC Modifier functions.
|
||||
*/
|
||||
enum ModifierFunctions {
|
||||
UI = 0x00,
|
||||
XID = 0x1D,
|
||||
TEST = 0x07,
|
||||
SABME = 0x1E,
|
||||
DISC = 0x02,
|
||||
UA = 0x06,
|
||||
DM = 0x18,
|
||||
FRMR = 0x11
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief LLC Supervisory functions
|
||||
*/
|
||||
enum SupervisoryFunctions {
|
||||
RECEIVE_READY = 0,
|
||||
REJECT = 2,
|
||||
RECEIVE_NOT_READY = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of LLC
|
||||
* \param child The child PDU.(optional)
|
||||
*/
|
||||
LLC(PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of LLC, setting the dsap and ssap.
|
||||
* The control field is set all to 0.
|
||||
* @param dsap The dsap value to be set.
|
||||
* @param ssap The ssap value to be set.
|
||||
*/
|
||||
LLC(uint8_t dsap, uint8_t ssap, PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a LLC object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
LLC(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the group destination bit.
|
||||
* \param value The value to be set.
|
||||
*/
|
||||
void group(bool value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the dsap field.
|
||||
* \param new_dsap The new dsap field.
|
||||
*/
|
||||
void dsap(uint8_t new_dsap);
|
||||
|
||||
/**
|
||||
* \brief Setter for the response bit.
|
||||
* \param value The value to be set.
|
||||
*/
|
||||
void response(bool value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ssap field.
|
||||
* \param new_ssap The new ssap field.
|
||||
*/
|
||||
void ssap(uint8_t new_ssap);
|
||||
|
||||
/**
|
||||
* \brief Setter for the LLC frame format type.
|
||||
* \param type The LLC frame format to set.
|
||||
*/
|
||||
void type(Format type);
|
||||
|
||||
/**
|
||||
* \brief Setter for sender send sequence number.
|
||||
* Only applied if format is INFORMATION.
|
||||
* \param seq_number New sender send sequence number to be set.
|
||||
*/
|
||||
void send_seq_number(uint8_t seq_number);
|
||||
|
||||
/**
|
||||
* \brief Setter for sender receive sequence number.
|
||||
* Only applied if format is INFORMATION or SUPERVISORY.
|
||||
* \param seq_number New sender receive sequence number to be set.
|
||||
*/
|
||||
void receive_seq_number(uint8_t seq_number);
|
||||
|
||||
/**
|
||||
* \brief Setter for the poll/final flag.
|
||||
* \param value Bool indicating the value of the flag.
|
||||
*/
|
||||
void poll_final(bool value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the supervisory function.
|
||||
* Only applied if format is SUPERVISORY.
|
||||
* \param new_func Value to set on the supervisory function field.
|
||||
*/
|
||||
void supervisory_function(SupervisoryFunctions new_func);
|
||||
|
||||
/**
|
||||
* \brief Setter for the modifier function field.
|
||||
* Only applied if format is UNNUMBERED.
|
||||
* \param modifier_func Value to set on the modifier function field.
|
||||
*/
|
||||
void modifier_function(ModifierFunctions mod_func);
|
||||
|
||||
/**
|
||||
* \brief Add a xid information field.
|
||||
* Only applied if format is UNNUMBERED and function is XID.
|
||||
* \param xid_id XID information of the MAC sublayer.
|
||||
* \param llc_type_class Value to set the llc_type_class field.
|
||||
* \param receive_window XID sender's receive window size.
|
||||
*/
|
||||
void add_xid_information(uint8_t xid_id, uint8_t llc_type_class, uint8_t receive_window);
|
||||
|
||||
//TODO: Add Acknowledged connectionless information
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the group destination bit.
|
||||
* \return Whether the group bit is set or not.
|
||||
*/
|
||||
bool group() {return _header.dsap & 0x01; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the dsap field.
|
||||
* \return The dsap field value
|
||||
*/
|
||||
uint8_t dsap() {return _header.dsap; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the response bit.
|
||||
* \return Whether the response bit is set or not.
|
||||
*/
|
||||
bool response() {return (_header.ssap & 0x01); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ssap field.
|
||||
* \return The ssap field.
|
||||
*/
|
||||
uint8_t ssap() {return _header.ssap; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the LLC frame format type.
|
||||
* \return The LLC frame format.
|
||||
*/
|
||||
uint8_t type() {return _type; }
|
||||
|
||||
/**
|
||||
* \brief Getter for sender send sequence number.
|
||||
*
|
||||
* \return The sender send sequence number if format is INFORMATION else 0.
|
||||
*/
|
||||
uint8_t send_seq_number() {
|
||||
return (type() == INFORMATION) ? (control_field.info.send_seq_num) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for sender receive sequence number.
|
||||
*
|
||||
* \return The sender receive sequence number if format is
|
||||
* INFORMATION or SUPERVISORY else 0.
|
||||
*/
|
||||
uint8_t receive_seq_number() {
|
||||
switch (type()) {
|
||||
case INFORMATION:
|
||||
return control_field.info.recv_seq_num;
|
||||
case SUPERVISORY:
|
||||
return control_field.super.recv_seq_num;
|
||||
case UNNUMBERED:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the poll/final flag.
|
||||
* \return Whether the poll/final flag is set.
|
||||
*/
|
||||
bool poll_final() {
|
||||
switch (type()) {
|
||||
case UNNUMBERED:
|
||||
return control_field.unnumbered.poll_final_bit;
|
||||
case INFORMATION:
|
||||
return control_field.info.poll_final_bit;
|
||||
case SUPERVISORY:
|
||||
return control_field.super.poll_final_bit;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the supervisory function.
|
||||
*
|
||||
* \return The supervisory function if format is SUPERVISORY else 0.
|
||||
*/
|
||||
uint8_t supervisory_function() {
|
||||
if (type() == SUPERVISORY)
|
||||
return control_field.super.supervisory_func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the modifier function field.
|
||||
*
|
||||
* \return The modifier function if format is UNNUMBERED else 0.
|
||||
*/
|
||||
uint8_t modifier_function() {
|
||||
if (type() == UNNUMBERED)
|
||||
return (control_field.unnumbered.mod_func1 << 3) + control_field.unnumbered.mod_func2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the LLC frame's header length.
|
||||
*
|
||||
* \return The header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::LLC; }
|
||||
|
||||
/**
|
||||
* \brief Delete all the information fields added.
|
||||
*/
|
||||
void clear_information_fields();
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
LLC *clone() const {
|
||||
return new LLC(*this);
|
||||
}
|
||||
private:
|
||||
struct llchdr {
|
||||
uint8_t dsap;
|
||||
uint8_t ssap;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
struct info_control_field {
|
||||
uint16_t
|
||||
type_bit:1,
|
||||
send_seq_num:7,
|
||||
poll_final_bit:1,
|
||||
recv_seq_num:7;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct super_control_field {
|
||||
uint16_t type_bit:2,
|
||||
supervisory_func:2,
|
||||
unused:4,
|
||||
poll_final_bit:1,
|
||||
recv_seq_num:7;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct un_control_field {
|
||||
uint8_t type_bits:2,
|
||||
mod_func1:2,
|
||||
poll_final_bit:1,
|
||||
mod_func2:3;
|
||||
} __attribute__((__packed__));
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
struct info_control_field {
|
||||
uint16_t send_seq_num:7,
|
||||
type_bit:1,
|
||||
recv_seq_num:7,
|
||||
poll_final_bit:1;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct super_control_field {
|
||||
uint16_t unused:4,
|
||||
supervisory_func:2,
|
||||
type_bit:2,
|
||||
recv_seq_num:7,
|
||||
poll_final_bit:1;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct un_control_field {
|
||||
uint8_t mod_func2:3,
|
||||
poll_final_bit:1,
|
||||
mod_func1:2,
|
||||
type_bits:2;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#endif
|
||||
|
||||
typedef std::vector<uint8_t> field_type;
|
||||
|
||||
void copy_fields(const LLC *other);
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
llchdr _header;
|
||||
uint8_t control_field_length;
|
||||
union {
|
||||
info_control_field info;
|
||||
super_control_field super;
|
||||
un_control_field unnumbered;
|
||||
} control_field;
|
||||
Format _type;
|
||||
uint8_t information_field_length;
|
||||
std::list<field_type> information_fields;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // TINS_IEEE8022_H
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PACKET_SENDER_H
|
||||
#define TINS_PACKET_SENDER_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
|
||||
struct timeval;
|
||||
|
||||
namespace Tins {
|
||||
class PDU;
|
||||
|
||||
/**
|
||||
* \brief Class that enables sending the created PDUs
|
||||
*
|
||||
* PacketSender class is responsible for sending the packets using the
|
||||
* correct PDU layer. It is responsible for opening the raw sockets.
|
||||
*/
|
||||
class PacketSender {
|
||||
public:
|
||||
/**
|
||||
* The default timeout for receive actions.
|
||||
*/
|
||||
static const uint32_t DEFAULT_TIMEOUT;
|
||||
|
||||
/**
|
||||
* Flags to indicate the socket type.
|
||||
*/
|
||||
enum SocketType {
|
||||
ETHER_SOCKET,
|
||||
IP_SOCKET,
|
||||
ARP_SOCKET,
|
||||
ICMP_SOCKET,
|
||||
SOCKETS_END
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructor for PacketSender objects.
|
||||
*
|
||||
* \param recv_timeout The timeout which will be used when receiving responses.
|
||||
*/
|
||||
PacketSender(uint32_t recv_timeout = DEFAULT_TIMEOUT, uint32_t usec = 0);
|
||||
|
||||
/**
|
||||
* \brief PacketSender destructor.
|
||||
*
|
||||
* This gracefully closes all open sockets.
|
||||
*/
|
||||
~PacketSender();
|
||||
|
||||
#ifndef WIN32
|
||||
/**
|
||||
* \brief Opens a layer 2 socket.
|
||||
*
|
||||
* If this operation fails, then a SocketOpenError will be thrown.
|
||||
*/
|
||||
void open_l2_socket();
|
||||
#endif // WIN32
|
||||
|
||||
/**
|
||||
* \brief Opens a layer 3 socket, using the corresponding protocol
|
||||
* for the given flag.
|
||||
*
|
||||
* If this operation fails, then a SocketOpenError will be thrown.
|
||||
* If the provided socket type is not valid, a InvalidSocketTypeError
|
||||
* will be throw.
|
||||
*
|
||||
* \param type The type of socket which will be used to pick the protocol flag
|
||||
* for this socket.
|
||||
*/
|
||||
void open_l3_socket(SocketType type);
|
||||
|
||||
/**
|
||||
* \brief Closes the socket associated with the given flag.
|
||||
*
|
||||
* If the provided type is invalid, meaning no such open socket
|
||||
* exists, a InvalidSocketTypeError is thrown.
|
||||
*
|
||||
* If any socket close errors are encountered, a SocketCloseError
|
||||
* is thrown.
|
||||
*
|
||||
* \param type The type of the socket to be closed.
|
||||
*/
|
||||
void close_socket(SocketType type);
|
||||
|
||||
/**
|
||||
* \brief Sends a PDU.
|
||||
*
|
||||
* This method opens the appropriate socket, if it's not open yet,
|
||||
* and sends the PDU on the open socket.
|
||||
*
|
||||
* If any send error occurs, then a SocketWriteError is thrown.
|
||||
*
|
||||
* \param pdu The PDU to be sent.
|
||||
*/
|
||||
void send(PDU &pdu);
|
||||
|
||||
/**
|
||||
* \brief Sends a PDU and waits for its response.
|
||||
*
|
||||
* This method is used to send PDUs and receive their response.
|
||||
* It opens the required socket(if it's not open yet). This can be used
|
||||
* to expect responses for ICMP, ARP, and such packets that are normally
|
||||
* answered by the host that receives the packet.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \return Returns the response PDU, 0 if not response was received.
|
||||
*/
|
||||
PDU *send_recv(PDU &pdu);
|
||||
|
||||
#ifndef WIN32
|
||||
/**
|
||||
* \brief Receives a layer 2 PDU response to a previously sent PDU.
|
||||
*
|
||||
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol, until a match for the given PDU is received.
|
||||
*
|
||||
* \param pdu The PDU which will try to match the responses.
|
||||
* \param link_addr The sockaddr struct which will be used to receive the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
* \return Returns the response PDU. If no response is received, then 0 is returned.
|
||||
*/
|
||||
PDU *recv_l2(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr);
|
||||
|
||||
/**
|
||||
* \brief Sends a level 2 PDU.
|
||||
*
|
||||
* This method sends a layer 2 PDU, using a raw socket, open
|
||||
* using the corresponding flag, according to the given type of
|
||||
* protocol.
|
||||
*
|
||||
* If any socket write error occurs, a SocketWriteError is thrown.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
*/
|
||||
void send_l2(PDU &pdu, struct sockaddr* link_addr, uint32_t len_addr);
|
||||
#endif // WIN32
|
||||
|
||||
/**
|
||||
* \brief Receives a layer 3 PDU response to a previously sent PDU.
|
||||
*
|
||||
* This PacketSender will receive data from a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol, until a match for the given PDU is received.
|
||||
*
|
||||
* \param pdu The PDU which will try to match the responses.
|
||||
* \param link_addr The sockaddr struct which will be used to receive the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
* \param type The socket protocol type.
|
||||
* \return Returns the response PDU. If no response is received, then 0 is returned.
|
||||
*/
|
||||
PDU *recv_l3(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr, SocketType type);
|
||||
|
||||
/**
|
||||
* \brief Sends a level 3 PDU.
|
||||
*
|
||||
* This method sends a layer 3 PDU, using a raw socket, open using the corresponding flag,
|
||||
* according to the given type of protocol.
|
||||
*
|
||||
* If any socket write error occurs, a SocketWriteError is thrown.
|
||||
*
|
||||
* \param pdu The PDU to send.
|
||||
* \param link_addr The sockaddr struct which will be used to send the PDU.
|
||||
* \param len_addr The sockaddr struct length.
|
||||
* \param type The socket protocol type.
|
||||
*/
|
||||
void send_l3(PDU &pdu, struct sockaddr *link_addr, uint32_t len_addr, SocketType type);
|
||||
private:
|
||||
static const int INVALID_RAW_SOCKET;
|
||||
|
||||
typedef std::map<SocketType, int> SocketTypeMap;
|
||||
|
||||
int find_type(SocketType type);
|
||||
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
|
||||
|
||||
PDU *recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen);
|
||||
|
||||
std::vector<int> _sockets;
|
||||
SocketTypeMap _types;
|
||||
uint32_t _timeout, _timeout_usec;
|
||||
};
|
||||
|
||||
|
||||
class SocketOpenError : public std::runtime_error {
|
||||
public:
|
||||
SocketOpenError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class SocketCloseError : public std::runtime_error {
|
||||
public:
|
||||
SocketCloseError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class SocketWriteError : public std::runtime_error {
|
||||
public:
|
||||
SocketWriteError(const std::string &msg)
|
||||
: std::runtime_error(msg) { }
|
||||
};
|
||||
|
||||
class InvalidSocketTypeError : public std::exception {
|
||||
public:
|
||||
const char *what() const throw() {
|
||||
return "The provided socket type is invalid";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_PACKET_SENDER_H
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PACKET_WRITER_H
|
||||
#define TINS_PACKET_WRITER_H
|
||||
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <pcap.h>
|
||||
#include "utils.h"
|
||||
|
||||
namespace Tins {
|
||||
class PDU;
|
||||
|
||||
/**
|
||||
* \class PacketWriter
|
||||
* \brief Writes PDUs to a pcap format file.
|
||||
*/
|
||||
class PacketWriter {
|
||||
public:
|
||||
/**
|
||||
* \brief The type of PDUs that will be written to this file.
|
||||
*
|
||||
* This flag should match the type of the lowest layer PDU to be
|
||||
* written.
|
||||
*/
|
||||
enum LinkType {
|
||||
RADIOTAP = DLT_IEEE802_11_RADIO,
|
||||
DOT11 = DLT_IEEE802_11,
|
||||
ETH2 = DLT_EN10MB
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructs a PacketWriter.
|
||||
* \param file_name The file in which to store the written PDUs.
|
||||
* \param lt The link type which will be written to this file.
|
||||
* \sa LinkType.
|
||||
*/
|
||||
PacketWriter(const std::string &file_name, LinkType lt);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~PacketWriter();
|
||||
|
||||
/**
|
||||
* \brief Writes a PDU to this file.
|
||||
*/
|
||||
void write(PDU &pdu);
|
||||
|
||||
/**
|
||||
* \brief Writes all the PDUs in the range [start, end)
|
||||
* \param start A forward iterator pointing to the first PDU
|
||||
* to be written.
|
||||
* \param end A forward iterator pointing to one past the last
|
||||
* PDU in the range.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
void write(ForwardIterator start, ForwardIterator end) {
|
||||
while(start != end)
|
||||
write(Utils::dereference_until_pdu(*start++));
|
||||
}
|
||||
private:
|
||||
// You shall not copy
|
||||
PacketWriter(const PacketWriter&);
|
||||
PacketWriter& operator=(const PacketWriter&);
|
||||
|
||||
pcap_t *handle;
|
||||
pcap_dumper_t *dumper;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_PACKET_WRITER_H
|
||||
355
include/pdu.h
355
include/pdu.h
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PDU_H
|
||||
#define TINS_PDU_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
/** \brief The Tins namespace.
|
||||
*/
|
||||
namespace Tins {
|
||||
|
||||
class PacketSender;
|
||||
|
||||
/** \brief Base class for protocol data units.
|
||||
*
|
||||
* Every PDU implementation must inherit this one. PDUs can be serialized,
|
||||
* therefore allowing a PacketSender to send them through the corresponding
|
||||
* sockets. PDUs are created upwards: upper layers will be children of the
|
||||
* lower ones. Each PDU must provide its flag identifier. This will be most
|
||||
* likely added to its parent's data, hence it should be a valid identifier.
|
||||
* For example, IP should provide IPPROTO_IP.
|
||||
*/
|
||||
class PDU {
|
||||
public:
|
||||
/**
|
||||
* The type that will be returned when serializing PDUs.
|
||||
*/
|
||||
typedef std::vector<uint8_t> serialization_type;
|
||||
|
||||
/**
|
||||
* \brief Enum which identifies each type of PDU.
|
||||
*
|
||||
* This enum is used to identify the PDU type.
|
||||
*/
|
||||
enum PDUType {
|
||||
RAW,
|
||||
ETHERNET_II,
|
||||
IEEE802_3,
|
||||
RADIOTAP,
|
||||
DOT11,
|
||||
DOT11_ACK,
|
||||
DOT11_ASSOC_REQ,
|
||||
DOT11_ASSOC_RESP,
|
||||
DOT11_AUTH,
|
||||
DOT11_BEACON,
|
||||
DOT11_BLOCK_ACK,
|
||||
DOT11_BLOCK_ACK_REQ,
|
||||
DOT11_CF_END,
|
||||
DOT11_DATA,
|
||||
DOT11_CONTROL,
|
||||
DOT11_DEAUTH,
|
||||
DOT11_DIASSOC,
|
||||
DOT11_END_CF_ACK,
|
||||
DOT11_MANAGEMENT,
|
||||
DOT11_PROBE_REQ,
|
||||
DOT11_PROBE_RESP,
|
||||
DOT11_PS_POLL,
|
||||
DOT11_REASSOC_REQ,
|
||||
DOT11_REASSOC_RESP,
|
||||
DOT11_RTS,
|
||||
DOT11_QOS_DATA,
|
||||
LLC,
|
||||
SNAP,
|
||||
IP,
|
||||
ARP,
|
||||
TCP,
|
||||
UDP,
|
||||
ICMP,
|
||||
BOOTP,
|
||||
DHCP,
|
||||
EAPOL,
|
||||
RC4EAPOL,
|
||||
RSNEAPOL,
|
||||
DNS,
|
||||
LOOPBACK
|
||||
};
|
||||
|
||||
/** \brief PDU constructor
|
||||
*
|
||||
* Must be called by subclasses in their constructors.
|
||||
* \param flag The flag identifier for the subclass' PDU.
|
||||
* \param next_pdu The child PDU. Can be obviated.
|
||||
*/
|
||||
PDU(PDU *next_pdu = 0);
|
||||
|
||||
/** \brief PDU destructor.
|
||||
*
|
||||
* Deletes the inner pdu, as a consequence every child pdu is
|
||||
* deleted.
|
||||
*/
|
||||
virtual ~PDU();
|
||||
|
||||
/** \brief The header's size
|
||||
*/
|
||||
virtual uint32_t header_size() const = 0;
|
||||
|
||||
/** \brief Trailer's size.
|
||||
*
|
||||
* Some protocols require a trailer(like Ethernet). This defaults to 0.
|
||||
*/
|
||||
virtual uint32_t trailer_size() const { return 0; }
|
||||
|
||||
/** \brief The whole chain of PDU's size, including this one.
|
||||
*
|
||||
* Returns the sum of this and all children PDUs' size.
|
||||
*/
|
||||
uint32_t size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the inner PDU.
|
||||
* \return The current inner PDU. Might be 0.
|
||||
*/
|
||||
PDU *inner_pdu() const { return _inner_pdu; }
|
||||
|
||||
/**
|
||||
* \brief Releases the inner PDU.
|
||||
*
|
||||
* This method makes this PDU to <b>no longer own</b> the inner
|
||||
* PDU. The current inner PDU is returned, and is <b>not</b>
|
||||
* destroyed. That means after calling this function, you are
|
||||
* responsible for using operator delete on the returned pointer.
|
||||
*
|
||||
* Use this method if you want to somehow re-use a PDU that
|
||||
* is already owned by another PDU.
|
||||
*
|
||||
* \return The current inner PDU. Might be 0.
|
||||
*/
|
||||
PDU *release_inner_pdu();
|
||||
|
||||
/**
|
||||
* \brief Sets the child PDU.
|
||||
*
|
||||
* \param next_pdu The new child PDU.
|
||||
* When setting a new inner_pdu, the instance takesownership of
|
||||
* the object, therefore deleting it when it's no longer required.
|
||||
*/
|
||||
void inner_pdu(PDU *next_pdu);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Serializes the whole chain of PDU's, including this one.
|
||||
*
|
||||
* This allocates a std::vector of size size(), and fills it
|
||||
* with the serialization this PDU, and all of the inner ones'.
|
||||
*
|
||||
* \return serialization_type containing the serialization
|
||||
* of the whole stack of PDUs.
|
||||
*/
|
||||
serialization_type serialize();
|
||||
|
||||
/**
|
||||
* \brief Find and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* This method searches for the first PDU which has the same type flag as
|
||||
* the given one. If the first PDU matches that flag, it is returned.
|
||||
* If no PDU matches, 0 is returned.
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<class T>
|
||||
T *find_pdu(PDUType type = T::pdu_flag) {
|
||||
PDU *pdu = this;
|
||||
while(pdu) {
|
||||
if(pdu->matches_flag(type))
|
||||
return static_cast<T*>(pdu);
|
||||
pdu = pdu->inner_pdu();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this packet.
|
||||
*
|
||||
* This method clones this PDU and clones every inner PDU,
|
||||
* therefore obtaining a clone of the whole inner PDU chain.
|
||||
* The pointer returned must be deleted by the user.
|
||||
* \return A pointer to a clone of this packet.
|
||||
*/
|
||||
virtual PDU *clone() const = 0;
|
||||
|
||||
/** \brief Send the stack of PDUs through a PacketSender.
|
||||
*
|
||||
* This method will be called only for the PDU on the bottom of the stack,
|
||||
* therefore it should only implement this method if it can be sent.
|
||||
* PacketSender implements specific methods to send packets which start
|
||||
* on every valid TCP/IP stack layer; this should only be a proxy for
|
||||
* those methods.
|
||||
* \param sender The PacketSender which will send the packet.
|
||||
*/
|
||||
virtual void send(PacketSender &sender);
|
||||
|
||||
/** \brief Receives a matching response for this packet.
|
||||
*
|
||||
* This method should act as a proxy for PacketSender::recv_lX methods.
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
*/
|
||||
virtual PDU *recv_response(PacketSender &sender);
|
||||
|
||||
/** \brief Check wether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* This method must check wether the buffer pointed by ptr is a valid
|
||||
* response for this PDU. If it is valid, then it might want to propagate
|
||||
* the call to the next PDU. Note that in some cases, such as ICMP
|
||||
* Host Unreachable, there is no need to ask the next layer for matching.
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
virtual bool matches_response(uint8_t *ptr, uint32_t total_sz) { return false; }
|
||||
|
||||
/**
|
||||
* \brief Check wether this PDU matches the specified flag.
|
||||
*
|
||||
* This method should be reimplemented in PDU classes which have
|
||||
* subclasses, and try to match the given PDU to each of its parent
|
||||
* classes' flag.
|
||||
* \param flag The flag to match.
|
||||
*/
|
||||
virtual bool matches_flag(PDUType flag) {
|
||||
return flag == pdu_type();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
virtual PDUType pdu_type() const = 0;
|
||||
|
||||
/** \brief Clones this pdu, filling the corresponding header with data
|
||||
* extracted from a buffer.
|
||||
*
|
||||
* \param ptr The pointer to the from from which the data will be extracted.
|
||||
* \param total_sz The size of the buffer.
|
||||
* \return The cloned PDU.
|
||||
*/
|
||||
virtual PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz) { return 0; }
|
||||
protected:
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
*/
|
||||
PDU(const PDU &other);
|
||||
|
||||
/**
|
||||
* \brief Copy assignment operator.
|
||||
*/
|
||||
PDU &operator=(const PDU &other);
|
||||
|
||||
/**
|
||||
* \brief Copy other PDU's inner PDU(if any).
|
||||
* \param pdu The PDU from which to copy the inner PDU.
|
||||
*/
|
||||
void copy_inner_pdu(const PDU &pdu);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Serializes this PDU and propagates this action to child PDUs.
|
||||
*
|
||||
* \param buffer The buffer in which to store this PDU's serialization.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \param parent The parent PDU. Will be 0 if there's the parent does not exist.
|
||||
*/
|
||||
void serialize(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
/**
|
||||
* \brief Clones the inner pdu(if any).
|
||||
*
|
||||
* This method clones the inner pdu using data from a buffer.
|
||||
* \param ptr The pointer from which the child PDU must be cloned.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \return Returns the cloned PDU. Will be 0 if cloning failed.
|
||||
*/
|
||||
PDU *clone_inner_pdu(const uint8_t *ptr, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Serializes this TCP PDU.
|
||||
*
|
||||
* Each PDU must override this method and implement it's own
|
||||
* serialization.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
* \param total_sz The size available in the buffer.
|
||||
* \param parent The PDU that's one level below this one on the stack. Might be 0.
|
||||
*/
|
||||
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0;
|
||||
private:
|
||||
PDU *_inner_pdu;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator.
|
||||
*
|
||||
* This operator concatenates several PDUs. A copy of the right
|
||||
* operand is set at the end of the left one's inner PDU chain.
|
||||
* This means that:
|
||||
*
|
||||
* IP some_ip = IP("127.0.0.1") / TCP(12, 13) / RawPDU("bleh");
|
||||
*
|
||||
* Works as expected, meaning the output PDU will look like the
|
||||
* following:
|
||||
*
|
||||
* IP - TCP - RawPDU
|
||||
*
|
||||
* \param lop The left operand, which will be the one modified.
|
||||
* \param rop The right operand, the one which will be appended
|
||||
* to lop.
|
||||
*/
|
||||
template<typename T>
|
||||
T &operator/= (T &lop, const PDU &rop) {
|
||||
PDU *last = &lop;
|
||||
while(last->inner_pdu())
|
||||
last = last->inner_pdu();
|
||||
last->inner_pdu(rop.clone());
|
||||
return lop;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator.
|
||||
*
|
||||
* \sa operator/=
|
||||
*/
|
||||
template<typename T>
|
||||
T operator/ (T lop, const PDU &rop) {
|
||||
lop /= rop;
|
||||
return lop;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TINS_PDU_H
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PDU_OPTION_H
|
||||
#define TINS_PDU_OPTION_H
|
||||
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Exception thrown when an option is not found.
|
||||
*/
|
||||
class option_not_found : public std::exception {
|
||||
public:
|
||||
const char* what() const throw() {
|
||||
return "Option not found";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \class PDUOption
|
||||
* \brief Represents a PDU option field.
|
||||
*
|
||||
* Several PDUs, such as TCP, IP, Dot11 or DHCP contain options. All
|
||||
* of them behave exactly the same way. This class represents those
|
||||
* options.
|
||||
*
|
||||
* The OptionType template parameter indicates the type that will be
|
||||
* used to store this option's identifier.
|
||||
*
|
||||
* The Container template parameter indicates the container which will
|
||||
* be used to store this option's data. The container <b>must</b>
|
||||
* store data sequentially. std::vector<uint8_t> is the default
|
||||
* container.
|
||||
*/
|
||||
template<typename OptionType, class Container = std::vector<uint8_t> >
|
||||
class PDUOption {
|
||||
public:
|
||||
typedef Container container_type;
|
||||
typedef typename container_type::value_type data_type;
|
||||
typedef OptionType option_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs a PDUOption.
|
||||
* \param opt The option type.
|
||||
* \param length The option's data length.
|
||||
* \param data The option's data(if any).
|
||||
*/
|
||||
PDUOption(option_type opt = option_type(), size_t length = 0, const data_type *data = 0)
|
||||
: option_(opt) {
|
||||
value_.push_back(length);
|
||||
if(data)
|
||||
value_.insert(value_.end(), data, data + length);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constructs a PDUOption from iterators, which
|
||||
* indicate the data to be stored in it.
|
||||
*
|
||||
* \param opt The option type.
|
||||
* \param start The beginning of the option data.
|
||||
* \param end The end of the option data.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
PDUOption(option_type opt, ForwardIterator start, ForwardIterator end)
|
||||
: option_(opt) {
|
||||
value_.push_back(std::distance(start, end));
|
||||
value_.insert(value_.end(), start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this option's type.
|
||||
* \return uint8_t containing this option's size.
|
||||
*/
|
||||
option_type option() const {
|
||||
return option_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this option's data.
|
||||
*
|
||||
* If this method is called when data_size() == 0,
|
||||
* dereferencing the returned pointer will result in undefined
|
||||
* behaviour.
|
||||
*
|
||||
* \return const value_type& containing this option's value.
|
||||
*/
|
||||
const data_type *data_ptr() const {
|
||||
return &*(++value_.begin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the length of this option's data.
|
||||
*/
|
||||
size_t data_size() const {
|
||||
return value_.empty() ? 0 : (value_.size() - 1);
|
||||
}
|
||||
private:
|
||||
option_type option_;
|
||||
container_type value_;
|
||||
};
|
||||
} // namespace Tins
|
||||
#endif // TINS_PDU_OPTION_H
|
||||
@@ -1,385 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_RADIOTAP_H
|
||||
#define TINS_RADIOTAP_H
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "network_interface.h"
|
||||
|
||||
namespace Tins {
|
||||
class PacketSender;
|
||||
|
||||
/**
|
||||
* \brief Class that represents the IEEE 802.11 radio tap header.
|
||||
*
|
||||
* By default, RadioTap PDUs set the necesary fields to send an 802.11
|
||||
* PDU as its inner pdu, avoiding packet drops. As a consequence,
|
||||
* the FCS-at-end flag is on, the channel is set to 1, TSFT is set to 0,
|
||||
* dbm_signal is set to 0xce, and the rx_flag and antenna fields to 0.
|
||||
*/
|
||||
class RadioTap : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::RADIOTAP;
|
||||
|
||||
/**
|
||||
* \brief Enumeration of the different channel type flags.
|
||||
*
|
||||
* These channel type flags can be OR'd and set using the
|
||||
* RadioTap::channel() method.
|
||||
*/
|
||||
enum ChannelType {
|
||||
TURBO = 0x10,
|
||||
CCK = 0x20,
|
||||
OFDM = 0x40,
|
||||
TWO_GZ = 0x80,
|
||||
FIVE_GZ = 0x100,
|
||||
PASSIVE = 0x200,
|
||||
DYN_CCK_OFDM = 0x400,
|
||||
GFSK = 0x800
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Flags used in the present field.
|
||||
*
|
||||
* \sa RadioTap::present()
|
||||
*/
|
||||
enum PresentFlags {
|
||||
TSTF = 1,
|
||||
FLAGS = 2,
|
||||
RATE = 4,
|
||||
CHANNEL = 8,
|
||||
FHSS = 16,
|
||||
DBM_SIGNAL = 32,
|
||||
DBM_NOISE = 64,
|
||||
LOCK_QUALITY = 128,
|
||||
TX_ATTENUATION = 256,
|
||||
DB_TX_ATTENUATION = 512,
|
||||
DBM_TX_ATTENUATION = 1024,
|
||||
ANTENNA = 2048,
|
||||
DB_SIGNAL = 4096,
|
||||
DB_NOISE = 8192,
|
||||
RX_FLAGS = 16382
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Flags used in the RadioTap::flags() method.
|
||||
*/
|
||||
enum FrameFlags {
|
||||
CFP = 1,
|
||||
PREAMBLE = 2,
|
||||
WEP = 4,
|
||||
FRAGMENTATION = 8,
|
||||
FCS = 16,
|
||||
PADDING = 32,
|
||||
FAILED_FCS = 64,
|
||||
SHORT_GI = 128
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RadioTap.
|
||||
* \param iface The interface in which to send this PDU.
|
||||
* \param child The child PDU.(optional)
|
||||
*/
|
||||
RadioTap(const NetworkInterface &iface = NetworkInterface(),
|
||||
PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a RadioTap object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
RadioTap(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
|
||||
/**
|
||||
* \brief Setter for the version field.
|
||||
* \param new_version The new version.
|
||||
*/
|
||||
void version(uint8_t new_version);
|
||||
|
||||
/**
|
||||
* \brief Setter for the padding field.
|
||||
* \param new_padding The new padding.
|
||||
*/
|
||||
void padding(uint8_t new_padding);
|
||||
|
||||
/**
|
||||
* \brief Setter for the length field.
|
||||
* \param new_length The new length.
|
||||
*/
|
||||
void length(uint16_t new_length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the TSFT field.
|
||||
* \param new_tsft The new TSFT
|
||||
*/
|
||||
void tsft(uint64_t new_tsft);
|
||||
|
||||
/**
|
||||
* \brief Setter for the flags field.
|
||||
* \param new_flags The new flags.
|
||||
*/
|
||||
void flags(FrameFlags new_flags);
|
||||
|
||||
/**
|
||||
* \brief Setter for the rate field.
|
||||
* \param new_rate The new rate.
|
||||
*/
|
||||
void rate(uint8_t new_rate);
|
||||
|
||||
/**
|
||||
* \brief Setter for the channel frequency and type field.
|
||||
* \param new_freq The new channel frequency.
|
||||
* \param new_type The new channel type.
|
||||
*/
|
||||
void channel(uint16_t new_freq, uint16_t new_type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the dbm signal field.
|
||||
* \param new_dbm_signal The new dbm signal.
|
||||
*/
|
||||
void dbm_signal(uint8_t new_dbm_signal);
|
||||
|
||||
/**
|
||||
* \brief Setter for the dbm noise field.
|
||||
* \param new_dbm_noise The new dbm noise.
|
||||
*/
|
||||
void dbm_noise(uint8_t new_dbm_noise);
|
||||
|
||||
/**
|
||||
* \brief Setter for the antenna field.
|
||||
* \param new_antenna The antenna signal.
|
||||
*/
|
||||
void antenna(uint8_t new_antenna);
|
||||
|
||||
/**
|
||||
* \brief Setter for the rx flag field.
|
||||
* \param new_rx_flag The antenna signal.
|
||||
*/
|
||||
void rx_flags(uint16_t new_rx_flag);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the version field.
|
||||
* \return The version field.
|
||||
*/
|
||||
uint8_t version() const { return _radio.it_version; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the padding field.
|
||||
* \return The padding field.
|
||||
*/
|
||||
uint8_t padding() const { return _radio.it_pad; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the length field.
|
||||
* \return The length field.
|
||||
*/
|
||||
uint16_t length() const { return Endian::le_to_host(_radio.it_len); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the tsft field.
|
||||
* \return The tsft field.
|
||||
*/
|
||||
uint64_t tsft() const { return Endian::le_to_host(_tsft); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the flags field.
|
||||
* \return The flags field.
|
||||
*/
|
||||
FrameFlags flags() const { return (FrameFlags)_flags; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the rate field.
|
||||
* \return The rate field.
|
||||
*/
|
||||
uint8_t rate() const { return _rate; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the channel frequency field.
|
||||
* \return The channel frequency field.
|
||||
*/
|
||||
uint16_t channel_freq() const { return Endian::le_to_host(_channel_freq); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the channel type field.
|
||||
* \return The channel type field.
|
||||
*/
|
||||
uint16_t channel_type() const { return Endian::le_to_host(_channel_type); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the dbm signal field.
|
||||
* \return The dbm signal field.
|
||||
*/
|
||||
uint8_t dbm_signal() const { return _dbm_signal; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the dbm noise field.
|
||||
* \return The dbm noise field.
|
||||
*/
|
||||
uint8_t dbm_noise() const { return _dbm_noise; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the antenna field.
|
||||
* \return The antenna field.
|
||||
*/
|
||||
uint8_t antenna() const { return _antenna; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the channel+ field.
|
||||
* \return The channel+ field.
|
||||
*/
|
||||
uint32_t channel_plus() const { return Endian::le_to_host(_channel_type); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the rx flags field.
|
||||
* \return The rx flags field.
|
||||
*/
|
||||
uint16_t rx_flags() const { return Endian::le_to_host(_rx_flags); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the present bit fields.
|
||||
*
|
||||
* Use this method and masks created from the values taken from
|
||||
* the PresentFlags enum to find out which fields are set.
|
||||
* Accessing non-initialized fields, the behaviour is undefined
|
||||
* will be undefined. It is only safe to use the getter of a field
|
||||
* if its corresponding bit flag is set in the present field.
|
||||
*/
|
||||
PresentFlags present() const {
|
||||
return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the RadioTap frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's trailer size.
|
||||
* \return The trailer's size.
|
||||
*/
|
||||
uint32_t trailer_size() const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
RadioTap *clone() const {
|
||||
return new RadioTap(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::RADIOTAP; }
|
||||
private:
|
||||
struct radiotap_hdr {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint8_t it_version;
|
||||
uint8_t it_pad;
|
||||
uint16_t it_len;
|
||||
uint32_t tsft:1,
|
||||
flags:1,
|
||||
rate:1,
|
||||
channel:1,
|
||||
fhss:1,
|
||||
dbm_signal:1,
|
||||
dbm_noise:1,
|
||||
lock_quality:1,
|
||||
tx_attenuation:1,
|
||||
db_tx_attenuation:1,
|
||||
dbm_tx_attenuation:1,
|
||||
antenna:1,
|
||||
db_signal:1,
|
||||
db_noise:1,
|
||||
rx_flags:1,
|
||||
reserved1:3,
|
||||
channel_plus:1,
|
||||
reserved2:12,
|
||||
ext:1;
|
||||
#else
|
||||
uint8_t it_pad;
|
||||
uint8_t it_version;
|
||||
uint16_t it_len;
|
||||
uint32_t lock_quality:1,
|
||||
dbm_noise:1,
|
||||
dbm_signal:1,
|
||||
fhss:1,
|
||||
channel:1,
|
||||
rate:1,
|
||||
flags:1,
|
||||
tsft:1,
|
||||
reserved3:1,
|
||||
tx_attenuation:1,
|
||||
db_tx_attenuation:1,
|
||||
dbm_tx_attenuation:1,
|
||||
antenna:1,
|
||||
db_signal:1,
|
||||
db_noise:1,
|
||||
rx_flags:1,
|
||||
reserved2:5,
|
||||
channel_plus:1,
|
||||
reserved1:2,
|
||||
reserved4:7,
|
||||
ext:1;
|
||||
#endif
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void init();
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
radiotap_hdr _radio;
|
||||
NetworkInterface _iface;
|
||||
// present fields...
|
||||
uint64_t _tsft;
|
||||
uint32_t _channel_type;
|
||||
uint16_t _channel_freq, _rx_flags;
|
||||
uint8_t _antenna, _flags, _rate, _dbm_signal, _dbm_noise, _channel, _max_power;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_RADIOTAP_H
|
||||
139
include/rawpdu.h
139
include/rawpdu.h
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_RAWPDU_H
|
||||
#define TINS_RAWPDU_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \brief Represents a PDU which holds raw data.
|
||||
*
|
||||
* In order to send payloads over TCP, UDP, or other transport layer or
|
||||
* higher level protocols, RawPDU can be used as a wrapper for raw byte arrays.
|
||||
*/
|
||||
class RawPDU : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type used to store the payload.
|
||||
*/
|
||||
typedef std::vector<uint8_t> payload_type;
|
||||
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::RAW;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RawPDU.
|
||||
*
|
||||
* The payload is copied, therefore the original payload's memory
|
||||
* must be freed by the user.
|
||||
* \param pload The payload which the RawPDU will contain.
|
||||
* \param size The size of the payload.
|
||||
*/
|
||||
RawPDU(const uint8_t *pload, uint32_t size);
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RawPDU from an input string.
|
||||
*
|
||||
* \param data The content of the payload.
|
||||
*/
|
||||
RawPDU(const std::string &data);
|
||||
|
||||
/**
|
||||
* \brief Setter for the payload field
|
||||
* \param pload The payload to be set.
|
||||
*/
|
||||
void payload(const payload_type &pload);
|
||||
|
||||
/**
|
||||
* \brief Setter for the payload field
|
||||
* \param start The start of the new payload.
|
||||
* \param end The end of the new payload.
|
||||
*/
|
||||
template<typename ForwardIterator>
|
||||
void payload(ForwardIterator start, ForwardIterator end) {
|
||||
_payload.assign(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Const getter for the payload.
|
||||
* \return The RawPDU's payload.
|
||||
*/
|
||||
const payload_type &payload() const { return _payload; }
|
||||
|
||||
/**
|
||||
* \brief Non-const getter for the payload.
|
||||
* \return The RawPDU's payload.
|
||||
*/
|
||||
payload_type &payload() { return _payload; }
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This returns the same as RawPDU::payload_size().
|
||||
*
|
||||
* This metod overrides PDU::header_size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the payload size.
|
||||
*
|
||||
* \return uint32_t containing the payload size.
|
||||
*/
|
||||
uint32_t payload_size() const {
|
||||
return _payload.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::RAW; }
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
RawPDU *clone() const {
|
||||
return new RawPDU(*this);
|
||||
}
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
payload_type _payload;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // TINS_RAWPDU_H
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_RSN_INFORMATION
|
||||
#define TINS_RSN_INFORMATION
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "endianness.h"
|
||||
|
||||
namespace Tins{
|
||||
/**
|
||||
* \brief Class that models the RSN information structure.
|
||||
*/
|
||||
class RSNInformation {
|
||||
public:
|
||||
/**
|
||||
* \brief Enum that represents the different cypher suites.
|
||||
*/
|
||||
enum CypherSuites {
|
||||
WEP_40 = 0x01ac0f00,
|
||||
TKIP = 0x02ac0f00,
|
||||
CCMP = 0x04ac0f00,
|
||||
WEP_104 = 0x05ac0f00
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum that represents the different akm suites.
|
||||
*/
|
||||
enum AKMSuites {
|
||||
PMKSA = 0x01ac0f00,
|
||||
PSK = 0x02ac0f00
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the cypher suites.
|
||||
*/
|
||||
typedef std::vector<CypherSuites> cyphers_type;
|
||||
|
||||
/**
|
||||
* The type used to store the AKM suites.
|
||||
*/
|
||||
typedef std::vector<AKMSuites> akm_type;
|
||||
|
||||
/**
|
||||
* The type returned on serialization.
|
||||
*/
|
||||
typedef std::vector<uint8_t> serialization_type;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation.
|
||||
*
|
||||
* By default, the version is set to 1.
|
||||
*/
|
||||
RSNInformation();
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation from a
|
||||
* serialization_type object.
|
||||
*
|
||||
* \param buffer The buffer from which to construct this object.
|
||||
*/
|
||||
RSNInformation(const serialization_type &buffer);
|
||||
|
||||
/**
|
||||
* \brief Constructor from buffer.
|
||||
*
|
||||
* \param buffer The buffer from which this object will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
RSNInformation(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Helper function to create a WPA2-PSK RSNInformation
|
||||
* \return An instance RSNInformation which contains information
|
||||
* for a WPA2-PSK AP.
|
||||
*/
|
||||
static RSNInformation wpa2_psk();
|
||||
|
||||
/**
|
||||
* \brief Adds a pairwise cypher suite.
|
||||
* \param cypher The pairwise cypher suite to be added.
|
||||
*/
|
||||
void add_pairwise_cypher(CypherSuites cypher);
|
||||
|
||||
/**
|
||||
* \brief Adds a akm suite.
|
||||
* \param akm The akm suite to be added.
|
||||
*/
|
||||
void add_akm_cypher(AKMSuites akm);
|
||||
|
||||
/**
|
||||
* \brief Sets the group suite cypher.
|
||||
* \param group The group suite cypher to be set.
|
||||
*/
|
||||
void group_suite(CypherSuites group);
|
||||
|
||||
/**
|
||||
* \brief Sets the version.
|
||||
* \param ver The version to be set.
|
||||
*/
|
||||
void version(uint16_t ver);
|
||||
|
||||
/**
|
||||
* \brief Sets the capabilities field.
|
||||
* \param cap The capabilities to be set.
|
||||
*/
|
||||
void capabilities(uint16_t cap);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the group suite field.
|
||||
* \return The group suite field.
|
||||
*/
|
||||
CypherSuites group_suite() const { return _group_suite; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the version field.
|
||||
* \return The version field.
|
||||
*/
|
||||
uint16_t version() const { return Endian::le_to_host(_version); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the capabilities field.
|
||||
* \return The version field.
|
||||
*/
|
||||
uint16_t capabilities() const { return Endian::le_to_host(_capabilities); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the pairwise cypher suite list.
|
||||
* \return A list of pairwise cypher suites.
|
||||
*/
|
||||
const cyphers_type &pairwise_cyphers() const { return _pairwise_cyphers; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the akm suite list.
|
||||
* \return A list of akm suites.
|
||||
*/
|
||||
const akm_type &akm_cyphers() const { return _akm_cyphers; }
|
||||
|
||||
/**
|
||||
* \brief Serializes this object.
|
||||
* \return The result of the serialization.
|
||||
*/
|
||||
serialization_type serialize() const;
|
||||
private:
|
||||
void init(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
uint16_t _version, _capabilities;
|
||||
CypherSuites _group_suite;
|
||||
akm_type _akm_cyphers;
|
||||
cyphers_type _pairwise_cyphers;
|
||||
};
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_RSN_INFORMATION
|
||||
178
include/snap.h
178
include/snap.h
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_SNAP_H
|
||||
#define TINS_SNAP_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "small_uint.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing a SNAP frame.
|
||||
*
|
||||
* Note that this PDU contains the 802.3 LLC structure + SNAP frame.
|
||||
* So far only unnumbered information structure is supported.
|
||||
*/
|
||||
class SNAP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::SNAP;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of SNAP
|
||||
* This constructor sets the dsap and ssap fields to 0xaa, and
|
||||
* the id field to 3.
|
||||
* \param child The child PDU.(optional)
|
||||
*/
|
||||
SNAP(PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a SNAP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
SNAP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the control field.
|
||||
* \param new_id The new control to be set.
|
||||
*/
|
||||
void control(uint8_t new_control);
|
||||
|
||||
/**
|
||||
* \brief Setter for the org code field.
|
||||
* \param new_org The new org code to be set.
|
||||
*/
|
||||
void org_code(small_uint<24> new_org);
|
||||
|
||||
/**
|
||||
* \brief Setter for the eth type field.
|
||||
* \param new_eth The new eth type to be set.
|
||||
*/
|
||||
void eth_type(uint16_t new_eth);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the dsap field.
|
||||
* \return The dsap field.
|
||||
*/
|
||||
uint8_t dsap() const { return _snap.dsap; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ssap field.
|
||||
* \return The ssap field.
|
||||
*/
|
||||
uint8_t ssap() const { return _snap.ssap; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the control field.
|
||||
* \return The control field.
|
||||
*/
|
||||
uint8_t control() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return (_snap.control_org) & 0xff;
|
||||
#else
|
||||
return (_snap.control_org >> 24) & 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the org code field.
|
||||
* \return The org code field.
|
||||
*/
|
||||
small_uint<24> org_code() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return Endian::be_to_host<uint32_t>(_snap.control_org & 0xffffff00);
|
||||
#else
|
||||
return _snap.control_org & 0xffffff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the eth type field.
|
||||
* \return The eth field.
|
||||
*/
|
||||
uint16_t eth_type() const { return Endian::be_to_host(_snap.eth_type); }
|
||||
|
||||
/**
|
||||
* \brief Returns the SNAP frame's header length.
|
||||
*
|
||||
* \return The header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::SNAP; }
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
SNAP *clone() const {
|
||||
return new SNAP(*this);
|
||||
}
|
||||
private:
|
||||
struct snaphdr {
|
||||
uint8_t dsap;
|
||||
uint8_t ssap;
|
||||
/*#if TINS_IS_LITTLE_ENDIAN
|
||||
uint32_t control:8,
|
||||
org_code:24;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
uint32_t org_code:24,
|
||||
control:8;
|
||||
#endif*/
|
||||
uint32_t control_org;
|
||||
uint16_t eth_type;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
snaphdr _snap;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // TINS_SNAP_H
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TINS_SNIFFER_H
|
||||
#define TINS_SNIFFER_H
|
||||
|
||||
|
||||
#include <pcap.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include "pdu.h"
|
||||
#include "ethernetII.h"
|
||||
#include "radiotap.h"
|
||||
#include "loopback.h"
|
||||
#include "dot11.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \class BaseSniffer
|
||||
* \brief Base class for sniffers.
|
||||
*
|
||||
* This class implements the basic sniffing operations. Subclasses
|
||||
* should only initialize this object using a pcap_t pointer, which
|
||||
* will be used to extract packets.
|
||||
*
|
||||
* Initialization must be done using the BaseSniffer::init method.
|
||||
*/
|
||||
class BaseSniffer {
|
||||
public:
|
||||
/**
|
||||
* \brief Sniffer destructor.
|
||||
* This frees all memory used by the pcap handle.
|
||||
*/
|
||||
virtual ~BaseSniffer();
|
||||
|
||||
/**
|
||||
* \brief Compiles a filter and uses it to capture one packet.
|
||||
*
|
||||
* This method returns the first sniffed packet that matches the
|
||||
* sniffer's filter, or the first sniffed packet if no filter has
|
||||
* been set.
|
||||
* \return The captured packet, matching the given filter, 0 if an
|
||||
* error occured(probably compiling the filter).
|
||||
*/
|
||||
PDU *next_packet();
|
||||
|
||||
/**
|
||||
* \brief Starts a sniffing loop, using a callback object for every
|
||||
* sniffed packet.
|
||||
*
|
||||
* The callback object must implement an operator with the
|
||||
* following(or compatible) signature:
|
||||
*
|
||||
* bool operator()(PDU&);
|
||||
*
|
||||
* This operator will be called using the sniffed packets
|
||||
* as arguments. You can modify the PDU argument as you wish.
|
||||
* Calling PDU methods like PDU::release_inner_pdu is perfectly
|
||||
* valid.
|
||||
*
|
||||
* Note that the Functor object will be copied using its copy
|
||||
* constructor, so that object should be some kind of proxy to
|
||||
* another object which will process the packets(e.g. std::bind).
|
||||
*
|
||||
* \param cback_handler The callback handler object which should process packets.
|
||||
* \param max_packets The maximum amount of packets to sniff. 0 == infinite.
|
||||
*/
|
||||
template<class Functor>
|
||||
void sniff_loop(Functor function, uint32_t max_packets = 0);
|
||||
|
||||
/**
|
||||
* \brief Sets a filter on this sniffer.
|
||||
* \param filter The filter to be set.
|
||||
* \return True iif it was possible to apply the filter.
|
||||
*/
|
||||
bool set_filter(const std::string &filter);
|
||||
|
||||
/**
|
||||
* \brief Stops sniffing loops.
|
||||
*/
|
||||
void stop_sniff();
|
||||
protected:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
BaseSniffer();
|
||||
|
||||
/**
|
||||
* \brief Initialices this BaseSniffer.
|
||||
*
|
||||
* \param phandle The pcap handle to be used for sniffing.
|
||||
* \param filter The pcap filter which will be applied to the
|
||||
* stream.
|
||||
* \param if_mask The interface's subnet mask. If 0 is provided,
|
||||
* then some IP broadcast tests won't work correctly.
|
||||
*/
|
||||
void init(pcap_t *phandle, const std::string &filter, bpf_u_int32 if_mask);
|
||||
private:
|
||||
template<class Functor>
|
||||
struct LoopData {
|
||||
pcap_t *handle;
|
||||
Functor c_handler;
|
||||
int iface_type;
|
||||
|
||||
LoopData(pcap_t *_handle, const Functor _handler,
|
||||
int if_type)
|
||||
: handle(_handle), c_handler(_handler), iface_type(if_type) { }
|
||||
};
|
||||
|
||||
BaseSniffer(const BaseSniffer&);
|
||||
BaseSniffer &operator=(const BaseSniffer&);
|
||||
|
||||
template<class ConcretePDU, class Functor>
|
||||
static bool call_functor(LoopData<Functor> *data, const u_char *packet, size_t len);
|
||||
|
||||
bool compile_set_filter(const std::string &filter, bpf_program &prog);
|
||||
|
||||
template<class Functor>
|
||||
static void callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
|
||||
|
||||
pcap_t *handle;
|
||||
bpf_u_int32 mask;
|
||||
bpf_program actual_filter;
|
||||
int iface_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class Sniffer
|
||||
* \brief Sniffs packets using pcap filters.
|
||||
*
|
||||
* This class uses a given filter to sniff packets and allow the user
|
||||
* to handle them. Each time a filter is set, it's used until a new one
|
||||
* is set. Both Sniffer::next_packet and Sniffer::sniff_loop have an
|
||||
* optional filter parameter. If a filter is set using those parameter,
|
||||
* the previously set filter is freed and the new one is used.
|
||||
*/
|
||||
class Sniffer : public BaseSniffer {
|
||||
public:
|
||||
/**
|
||||
* \brief Constructs an instance of Sniffer.
|
||||
* \param device The device which will be sniffed.
|
||||
* \param max_packet_size The maximum packet size to be read.
|
||||
* \param promisc bool indicating wether to put the interface in promiscuous mode.(optional)
|
||||
* \param filter A capture filter to be used on the sniffing session.(optional);
|
||||
*/
|
||||
Sniffer(const std::string &device, unsigned max_packet_size,
|
||||
bool promisc = false, const std::string &filter = "");
|
||||
};
|
||||
|
||||
/**
|
||||
* \class FileSniffer
|
||||
* \brief Parses pcap files and interprets the packets in it.
|
||||
*
|
||||
* This class acts exactly in the same way that Sniffer, but reads
|
||||
* packets from a pcap file instead of an interface.
|
||||
*/
|
||||
class FileSniffer : public BaseSniffer {
|
||||
public:
|
||||
/**
|
||||
* \brief Constructs an instance of FileSniffer.
|
||||
* \param file_name The pcap file which will be parsed.
|
||||
* \param filter A capture filter to be used on the file.(optional);
|
||||
*/
|
||||
FileSniffer(const std::string &file_name, const std::string &filter = "");
|
||||
};
|
||||
|
||||
template<class Functor>
|
||||
void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) {
|
||||
LoopData<Functor> data(handle, function, iface_type);
|
||||
pcap_loop(handle, max_packets, &BaseSniffer::callback_handler<Functor>, (u_char*)&data);
|
||||
}
|
||||
|
||||
template<class ConcretePDU, class Functor>
|
||||
bool Tins::BaseSniffer::call_functor(LoopData<Functor> *data, const u_char *packet, size_t len) {
|
||||
ConcretePDU some_pdu((const uint8_t*)packet, len);
|
||||
return data->c_handler(some_pdu);
|
||||
}
|
||||
|
||||
template<class Functor>
|
||||
void Tins::BaseSniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
|
||||
try {
|
||||
std::auto_ptr<PDU> pdu;
|
||||
LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args);
|
||||
bool ret_val(false);
|
||||
if(data->iface_type == DLT_EN10MB)
|
||||
ret_val = call_functor<Tins::EthernetII>(data, packet, header->caplen);
|
||||
else if(data->iface_type == DLT_IEEE802_11_RADIO)
|
||||
ret_val = call_functor<Tins::RadioTap>(data, packet, header->caplen);
|
||||
else if(data->iface_type == DLT_IEEE802_11) {
|
||||
std::auto_ptr<PDU> pdu(Tins::Dot11::from_bytes((const uint8_t*)packet, header->caplen));
|
||||
if(pdu.get())
|
||||
ret_val = data->c_handler(*pdu);
|
||||
}
|
||||
else if(data->iface_type == DLT_NULL)
|
||||
ret_val = call_functor<Tins::Loopback>(data, packet, header->caplen);
|
||||
|
||||
if(!ret_val)
|
||||
pcap_breakloop(data->handle);
|
||||
}
|
||||
catch(...) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class HandlerProxy {
|
||||
public:
|
||||
typedef T* ptr_type;
|
||||
typedef bool (T::*fun_type)(PDU&) ;
|
||||
|
||||
HandlerProxy(ptr_type ptr, fun_type function)
|
||||
: object(ptr), fun(function) {}
|
||||
|
||||
bool operator()(PDU &pdu) {
|
||||
return (object->*fun)(pdu);
|
||||
}
|
||||
private:
|
||||
ptr_type object;
|
||||
fun_type fun;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
HandlerProxy<T> make_sniffer_handler(T *ptr, typename HandlerProxy<T>::fun_type function)
|
||||
{
|
||||
return HandlerProxy<T>(ptr, function);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TINS_SNIFFER_H
|
||||
449
include/tcp.h
449
include/tcp.h
@@ -1,449 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_TCP_H
|
||||
#define TINS_TCP_H
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "small_uint.h"
|
||||
#include "pdu_option.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Class that represents an TCP PDU.
|
||||
*
|
||||
* TCP is the representation of the TCP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
*/
|
||||
|
||||
class TCP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::TCP;
|
||||
|
||||
/**
|
||||
* \brief TCP flags enum.
|
||||
*
|
||||
* These flags identify those supported by the TCP PDU.
|
||||
*/
|
||||
enum Flags {
|
||||
FIN,
|
||||
SYN,
|
||||
RST,
|
||||
PSH,
|
||||
ACK,
|
||||
URG,
|
||||
ECE,
|
||||
CWR
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief TCP options enum.
|
||||
*
|
||||
* This enum identifies valid options supported by TCP PDU.
|
||||
*/
|
||||
|
||||
enum Option {
|
||||
EOL = 0,
|
||||
NOP = 1,
|
||||
MSS = 2,
|
||||
WSCALE = 3,
|
||||
SACK_OK = 4,
|
||||
SACK = 5,
|
||||
TSOPT = 8,
|
||||
ALTCHK = 14
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Alternate checksum enum.
|
||||
*/
|
||||
enum AltChecksums {
|
||||
CHK_TCP,
|
||||
CHK_8FLETCHER,
|
||||
CHK_16FLETCHER
|
||||
};
|
||||
|
||||
typedef PDUOption<uint8_t> tcp_option;
|
||||
|
||||
/**
|
||||
* The type used to store the options.
|
||||
*/
|
||||
typedef std::list<tcp_option> options_type;
|
||||
|
||||
/**
|
||||
* The type used to store the sack option.
|
||||
*/
|
||||
typedef std::vector<uint32_t> sack_type;
|
||||
|
||||
/**
|
||||
* \brief TCP constructor.
|
||||
*
|
||||
* Creates an instance of TCP. Destination and source port can
|
||||
* be provided, otherwise both will be 0.
|
||||
* \param dport Destination port.
|
||||
* \param sport Source port.
|
||||
* */
|
||||
TCP(uint16_t dport = 0, uint16_t sport = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an TCP object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
TCP(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the destination port field.
|
||||
*
|
||||
* \return The destination port in an uint16_t.
|
||||
*/
|
||||
uint16_t dport() const { return Endian::be_to_host(_tcp.dport); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source port field.
|
||||
*
|
||||
* \return The source port in an uint16_t.
|
||||
*/
|
||||
uint16_t sport() const { return Endian::be_to_host(_tcp.sport); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sequence number field.
|
||||
*
|
||||
* \return The sequence number in an uint32_t.
|
||||
*/
|
||||
uint32_t seq() const { return Endian::be_to_host(_tcp.seq); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the acknowledge number field.
|
||||
*
|
||||
* \return The acknowledge number in an uint32_t.
|
||||
*/
|
||||
uint32_t ack_seq() const { return Endian::be_to_host(_tcp.ack_seq); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the window size field.
|
||||
*
|
||||
* \return The window size in an uint32_t.
|
||||
*/
|
||||
uint16_t window() const { return Endian::be_to_host(_tcp.window); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the checksum field.
|
||||
*
|
||||
* \return The checksum field in an uint16_t.
|
||||
*/
|
||||
uint16_t check() const { return Endian::be_to_host(_tcp.check); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the urgent pointer field.
|
||||
*
|
||||
* \return The urgent pointer in an uint16_t.
|
||||
*/
|
||||
uint16_t urg_ptr() const { return Endian::be_to_host(_tcp.urg_ptr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the data offset field.
|
||||
*
|
||||
* \return Data offset in an uint8_t.
|
||||
*/
|
||||
small_uint<4> data_offset() const { return this->_tcp.doff; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the option list.
|
||||
*
|
||||
* \return The options list.
|
||||
*/
|
||||
const options_type &options() const { return _options; }
|
||||
|
||||
/**
|
||||
* \brief Gets the value of a flag.
|
||||
*
|
||||
* \param tcp_flag The polled flag.
|
||||
* \return The value of the flag.
|
||||
*/
|
||||
small_uint<1> get_flag(Flags tcp_flag);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the destination port field.
|
||||
*
|
||||
* \param new_dport The new destination port.
|
||||
*/
|
||||
void dport(uint16_t new_dport);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source port field.
|
||||
*
|
||||
* \param new_sport The new source port.
|
||||
*/
|
||||
void sport(uint16_t new_sport);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sequence number.
|
||||
*
|
||||
* \param new_seq The new sequence number.
|
||||
*/
|
||||
void seq(uint32_t new_seq);
|
||||
|
||||
/**
|
||||
* \brief Setter for the acknowledge number.
|
||||
*
|
||||
* \param new_ack_seq The new acknowledge number.
|
||||
*/
|
||||
void ack_seq(uint32_t new_ack_seq);
|
||||
|
||||
/**
|
||||
* \brief Setter for the window size.
|
||||
*
|
||||
* \param new_window The new window size.
|
||||
*/
|
||||
void window(uint16_t new_window);
|
||||
|
||||
/**
|
||||
* \brief Setter for the checksum field.
|
||||
*
|
||||
* \param new_check The new checksum.
|
||||
*/
|
||||
void check(uint16_t new_check);
|
||||
|
||||
/**
|
||||
* \brief Setter for the urgent pointer field.
|
||||
*
|
||||
* \param new_urg_ptr The new urgent pointer.
|
||||
*/
|
||||
void urg_ptr(uint16_t new_urg_ptr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the data offset pointer field.
|
||||
*
|
||||
* \param new_doff The new data offset pointer.
|
||||
*/
|
||||
void data_offset(small_uint<4> new_doff);
|
||||
|
||||
// Options
|
||||
|
||||
/**
|
||||
* \brief Add a maximum segment size option.
|
||||
*
|
||||
* \param value The new maximum segment size.
|
||||
*/
|
||||
void mss(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Searchs for a maximum segment size option.
|
||||
* \param value A pointer in which the option's value will be stored.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
uint16_t mss() const;
|
||||
|
||||
/**
|
||||
* \brief Add a window scale option.
|
||||
*
|
||||
* \param value The new window scale.
|
||||
*/
|
||||
void winscale(uint8_t value);
|
||||
|
||||
/**
|
||||
* \brief Searchs for a window scale option.
|
||||
* \param value A pointer in which the option's value will be stored.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
uint8_t winscale() const;
|
||||
|
||||
/**
|
||||
* \brief Add a sack permitted option.
|
||||
*/
|
||||
void sack_permitted();
|
||||
|
||||
/**
|
||||
* \brief Searchs for a sack permitted option.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
bool has_sack_permitted() const;
|
||||
|
||||
/**
|
||||
* \brief Add a sack option.
|
||||
*
|
||||
* \param value The new window scale.
|
||||
*/
|
||||
void sack(const sack_type &edges);
|
||||
|
||||
/**
|
||||
* \brief Searchs for a sack option.
|
||||
* \param value A pointer in which the option's value will be stored.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
sack_type sack() const;
|
||||
|
||||
/**
|
||||
* \brief Add a timestamp option.
|
||||
*
|
||||
* \param value The current value of the timestamp clock.
|
||||
* \param reply The echo reply field.
|
||||
*/
|
||||
void timestamp(uint32_t value, uint32_t reply);
|
||||
|
||||
/**
|
||||
* \brief Searchs for a timestamp option.
|
||||
* \param value A pointer in which the option's value will be stored.
|
||||
* \param reply A pointer in which the option's reply value will be stored.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
std::pair<uint32_t, uint32_t> timestamp() const;
|
||||
|
||||
/**
|
||||
* \brief Add a alternate checksum option.
|
||||
*
|
||||
* \param value The new alternate checksum scale.
|
||||
*/
|
||||
void altchecksum(AltChecksums value);
|
||||
|
||||
/**
|
||||
* \brief Searchs for a alternate checksum option.
|
||||
* \param value A pointer in which the option's value will be stored.
|
||||
* \return True if the option was found, false otherwise.
|
||||
*/
|
||||
AltChecksums altchecksum() const;
|
||||
|
||||
/**
|
||||
* \brief Set a TCP flag value.
|
||||
*
|
||||
* \param tcp_flag The flag to be set.
|
||||
* \param value The new value for this flag. Must be 0 or 1.
|
||||
*/
|
||||
void set_flag(Flags tcp_flag, small_uint<1> value);
|
||||
|
||||
/**
|
||||
* \brief Adds a TCP option.
|
||||
*
|
||||
* \param option The option type flag to be set.
|
||||
* \param length The length of this option(optional).
|
||||
* \param data Pointer to this option's data(optional).
|
||||
*/
|
||||
void add_option(Option option, uint8_t length = 0, const uint8_t *data = 0);
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This metod overrides PDU::header_size. This size includes the
|
||||
* payload and options size.
|
||||
*
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::TCP; }
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
* \param opt_flag The flag to be searched.
|
||||
* \return A pointer to the option, or 0 if it was not found.
|
||||
*/
|
||||
const tcp_option *search_option(Option opt) const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
TCP *clone() const {
|
||||
return new TCP(*this);
|
||||
}
|
||||
private:
|
||||
struct tcphdr {
|
||||
uint16_t sport;
|
||||
uint16_t dport;
|
||||
uint32_t seq;
|
||||
uint32_t ack_seq;
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t res1:4,
|
||||
doff:4,
|
||||
fin:1,
|
||||
syn:1,
|
||||
rst:1,
|
||||
psh:1,
|
||||
ack:1,
|
||||
urg:1,
|
||||
ece:1,
|
||||
cwr:1;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
uint16_t doff:4,
|
||||
res1:4,
|
||||
cwr:1,
|
||||
ece:1,
|
||||
urg:1,
|
||||
ack:1,
|
||||
psh:1,
|
||||
rst:1,
|
||||
syn:1,
|
||||
fin:1;
|
||||
#else
|
||||
#error "Endian is not LE nor BE..."
|
||||
#endif
|
||||
uint16_t window;
|
||||
uint16_t check;
|
||||
uint16_t urg_ptr;
|
||||
} __attribute__((packed));
|
||||
|
||||
static const uint16_t DEFAULT_WINDOW;
|
||||
|
||||
template<class T>
|
||||
T generic_search(Option opt) const {
|
||||
const tcp_option *option = search_option(opt);
|
||||
if(option && option->data_size() == sizeof(T))
|
||||
return *(const T*)(&option->data_ptr()[0]);
|
||||
throw option_not_found();
|
||||
}
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
uint8_t *write_option(const tcp_option &opt, uint8_t *buffer);
|
||||
|
||||
tcphdr _tcp;
|
||||
options_type _options;
|
||||
uint32_t _options_size, _total_options_size;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // TINS_TCP_H
|
||||
334
include/tins/address_range.h
Normal file
334
include/tins/address_range.h
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ADDRESS_RANGE
|
||||
#define TINS_ADDRESS_RANGE
|
||||
|
||||
#include <iterator>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/exceptions.h>
|
||||
#include <tins/detail/address_helpers.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief AddressRange iterator class.
|
||||
*/
|
||||
template<typename Address>
|
||||
class AddressRangeIterator : public std::iterator<std::forward_iterator_tag, const Address> {
|
||||
public:
|
||||
typedef typename std::iterator<std::forward_iterator_tag, const Address>::value_type value_type;
|
||||
|
||||
struct end_iterator {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs an iterator.
|
||||
*
|
||||
* \param first The address held by this iterator.
|
||||
*/
|
||||
AddressRangeIterator(const value_type& address)
|
||||
: address_(address), reached_end_(false) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an iterator.
|
||||
*
|
||||
* \param first The address held by this iterator.
|
||||
*/
|
||||
AddressRangeIterator(const value_type& address, end_iterator)
|
||||
: address_(address) {
|
||||
reached_end_ = Internals::increment(address_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current address pointed by this iterator.
|
||||
*/
|
||||
const value_type& operator*() const {
|
||||
return address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the current address pointed by this iterator.
|
||||
*/
|
||||
const value_type* operator->() const {
|
||||
return& address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two iterators for equality.
|
||||
*
|
||||
* \param rhs The iterator with which to compare.
|
||||
*/
|
||||
bool operator==(const AddressRangeIterator& rhs) const {
|
||||
return reached_end_ == rhs.reached_end_ && address_ == rhs.address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two iterators for inequality.
|
||||
*
|
||||
* \param rhs The iterator with which to compare.
|
||||
*/
|
||||
bool operator!=(const AddressRangeIterator& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments this iterator.
|
||||
*/
|
||||
AddressRangeIterator& operator++() {
|
||||
reached_end_ = Internals::increment(address_);
|
||||
return* this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments this iterator.
|
||||
*/
|
||||
AddressRangeIterator operator++(int) {
|
||||
AddressRangeIterator copy(*this);
|
||||
(*this)++;
|
||||
return copy;
|
||||
}
|
||||
private:
|
||||
Address address_;
|
||||
bool reached_end_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents a range of addresses.
|
||||
*
|
||||
* This class provides a begin()/end() interface which allows
|
||||
* iterating through every address stored in it.
|
||||
*
|
||||
* Note that when iterating a range that was created using
|
||||
* operator/(IPv4Address, int) and the analog for IPv6, the
|
||||
* network and broadcast addresses are discarded:
|
||||
*
|
||||
* \code
|
||||
* auto range = IPv4Address("192.168.5.0") / 24;
|
||||
* for(const auto& addr : range) {
|
||||
* // process 192.168.5.1-254, .0 and .255 are discarded
|
||||
* process(addr);
|
||||
* }
|
||||
*
|
||||
* // That's only valid for iteration, not for AddressRange<>::contains
|
||||
*
|
||||
* assert(range.contains("192.168.5.0")); // works
|
||||
* assert(range.contains("192.168.5.255")); // works
|
||||
* \endcode
|
||||
*
|
||||
* Ranges created using AddressRange(address_type, address_type)
|
||||
* will allow the iteration over the entire range:
|
||||
*
|
||||
* \code
|
||||
* AddressRange<IPv4Address> range("192.168.5.0", "192.168.5.255");
|
||||
* for(const auto& addr : range) {
|
||||
* // process 192.168.5.0-255, no addresses are discarded
|
||||
* process(addr);
|
||||
* }
|
||||
*
|
||||
* assert(range.contains("192.168.5.0")); // still valid
|
||||
* assert(range.contains("192.168.5.255")); // still valid
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
template<typename Address>
|
||||
class AddressRange {
|
||||
public:
|
||||
/**
|
||||
* The type of addresses stored in the range.
|
||||
*/
|
||||
typedef Address address_type;
|
||||
|
||||
/**
|
||||
* The iterator type.
|
||||
*/
|
||||
typedef AddressRangeIterator<address_type> const_iterator;
|
||||
|
||||
/**
|
||||
* \brief The iterator type.
|
||||
*
|
||||
* This is the same type as const_iterator, since the
|
||||
* addresses stored in this range are read only.
|
||||
*/
|
||||
typedef const_iterator iterator;
|
||||
|
||||
/**
|
||||
* \brief Constructs an address range from two addresses.
|
||||
*
|
||||
* The range will consist of the addresses [first, last].
|
||||
*
|
||||
* If only_hosts is true, then the network and broadcast addresses
|
||||
* will not be available when iterating the range.
|
||||
*
|
||||
* If last < first, an std::runtime_error exception is thrown.
|
||||
*
|
||||
* \param first The first address in the range.
|
||||
* \param last The last address(inclusive) in the range.
|
||||
* \param only_hosts Indicates whether only host addresses
|
||||
* should be accessed when using iterators.
|
||||
*/
|
||||
AddressRange(const address_type& first, const address_type& last, bool only_hosts = false)
|
||||
: first_(first), last_(last), only_hosts_(only_hosts){
|
||||
if (last_ < first_) {
|
||||
throw exception_base("Invalid address range");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates an address range from a base address
|
||||
* and a network mask.
|
||||
*
|
||||
* \param first The base address.
|
||||
* \param mask The network mask to be used.
|
||||
*/
|
||||
static AddressRange from_mask(const address_type& first, const address_type& mask) {
|
||||
return AddressRange<address_type>(
|
||||
first & mask,
|
||||
Internals::last_address_from_mask(first, mask),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicates whether an address is included in this range.
|
||||
* \param addr The address to test.
|
||||
* \return a bool indicating whether the address is in the range.
|
||||
*/
|
||||
bool contains(const address_type& addr) const {
|
||||
return (first_ < addr && addr < last_) || addr == first_ || addr == last_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns an interator to the beginning of this range.
|
||||
* \brief const_iterator pointing to the beginning of this range.
|
||||
*/
|
||||
const_iterator begin() const {
|
||||
address_type addr = first_;
|
||||
if (only_hosts_) {
|
||||
Internals::increment(addr);
|
||||
}
|
||||
return const_iterator(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns an interator to the end of this range.
|
||||
* \brief const_iterator pointing to the end of this range.
|
||||
*/
|
||||
const_iterator end() const {
|
||||
address_type addr = last_;
|
||||
if (only_hosts_) {
|
||||
Internals::decrement(addr);
|
||||
}
|
||||
return const_iterator(addr, typename const_iterator::end_iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicates whether this range is iterable.
|
||||
*
|
||||
* Iterable ranges are those for which there is at least one
|
||||
* address that could represent a host. For IPv4 ranges, a /31 or
|
||||
* /32 ranges does not contain any, therefore it's not iterable.
|
||||
* The same is true for /127 and /128 IPv6 ranges.
|
||||
*
|
||||
* If is_iterable returns false for a range, then iterating it
|
||||
* through the iterators returned by begin() and end() is
|
||||
* undefined.
|
||||
*
|
||||
* \return bool indicating whether this range is iterable.
|
||||
*/
|
||||
bool is_iterable() const {
|
||||
// Since first < last, it's iterable
|
||||
if (!only_hosts_) {
|
||||
return true;
|
||||
}
|
||||
// We need that distance(first, last) >= 4
|
||||
address_type addr(first_);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
// If there's overflow before the last iteration, we're done
|
||||
if (Internals::increment(addr) && i != 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If addr <= last, it's OK.
|
||||
return addr < last_ || addr == last_;
|
||||
}
|
||||
private:
|
||||
address_type first_, last_;
|
||||
bool only_hosts_;
|
||||
};
|
||||
|
||||
/**
|
||||
* An IPv4 address range.
|
||||
*/
|
||||
typedef AddressRange<IPv4Address> IPv4Range;
|
||||
|
||||
/**
|
||||
* An IPv6 address range.
|
||||
*/
|
||||
typedef AddressRange<IPv6Address> IPv6Range;
|
||||
|
||||
/**
|
||||
* \brief Constructs an AddressRange from a base address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
template<size_t n>
|
||||
AddressRange<HWAddress<n> > operator/(const HWAddress<n>& addr, int mask) {
|
||||
if (mask > 48) {
|
||||
throw std::logic_error("Prefix length cannot exceed 48");
|
||||
}
|
||||
HWAddress<n> last_addr;
|
||||
typename HWAddress<n>::iterator it = last_addr.begin();
|
||||
while (mask > 8) {
|
||||
*it = 0xff;
|
||||
++it;
|
||||
mask -= 8;
|
||||
}
|
||||
*it = 0xff << (8 - mask);
|
||||
return AddressRange<HWAddress<6> >::from_mask(addr, last_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constructs an IPv6Range from a base IPv6Address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
IPv6Range operator/(const IPv6Address& addr, int mask);
|
||||
|
||||
/**
|
||||
* \brief Constructs an IPv4Range from a base IPv4Address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
IPv4Range operator/(const IPv4Address& addr, int mask);
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_ADDRESS_RANGE
|
||||
344
include/tins/arp.h
Normal file
344
include/tins/arp.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TINS_ARP_H
|
||||
#define TINS_ARP_H
|
||||
|
||||
#include <tins/macros.h>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/hw_address.h>
|
||||
#include <tins/ip_address.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
class NetworkInterface;
|
||||
class EthernetII;
|
||||
|
||||
/**
|
||||
* \class ARP
|
||||
* \brief Represents an ARP PDU.
|
||||
*
|
||||
*/
|
||||
class TINS_API ARP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the hardware address.
|
||||
*/
|
||||
typedef HWAddress<6> hwaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the IP address.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::ARP;
|
||||
|
||||
/**
|
||||
* \brief Enum which indicates the type of ARP packet.
|
||||
*/
|
||||
enum Flags {
|
||||
REQUEST = 0x0001,
|
||||
REPLY = 0x0002
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Extracts metadata for this protocol based on the buffer provided
|
||||
*
|
||||
* \param buffer Pointer to a buffer
|
||||
* \param total_sz Size of the buffer pointed by buffer
|
||||
*/
|
||||
static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Constructs an ARP object using the provided addresses.
|
||||
*
|
||||
* ARP requests and replies can be constructed easily using
|
||||
* ARP::make_arp_request/reply static member functions.
|
||||
*
|
||||
* \sa ARP::make_arp_request
|
||||
* \sa ARP::make_arp_reply
|
||||
*
|
||||
* \param target_ip The target IP address.
|
||||
* \param sender_ip The sender IP address.
|
||||
* \param target_hw The target hardware address.
|
||||
* \param sender_hw The sender hardware address.
|
||||
*/
|
||||
ARP(ipaddress_type target_ip = ipaddress_type(),
|
||||
ipaddress_type sender_ip = ipaddress_type(),
|
||||
const hwaddress_type& target_hw = hwaddress_type(),
|
||||
const hwaddress_type& sender_hw = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs an ARP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for an ARP header in the buffer,
|
||||
* a malformed_packet exception is thrown.
|
||||
*
|
||||
* If the buffer is bigger than the size of the ARP header,
|
||||
* then the extra data is stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
ARP(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the sender's hardware address.
|
||||
*
|
||||
* \return The sender hardware address.
|
||||
*/
|
||||
hwaddress_type sender_hw_addr() const {
|
||||
return header_.sender_hw_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the sender's IP address.
|
||||
*
|
||||
* \return The sender IP address.
|
||||
*/
|
||||
ipaddress_type sender_ip_addr() const {
|
||||
return ipaddress_type(header_.sender_ip_address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's hardware address.
|
||||
*
|
||||
* \return The target hardware address.
|
||||
*/
|
||||
hwaddress_type target_hw_addr() const {
|
||||
return header_.target_hw_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's IP address.
|
||||
*
|
||||
* \return The target IP address.
|
||||
*/
|
||||
ipaddress_type target_ip_addr() const {
|
||||
return ipaddress_type(header_.target_ip_address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address format field.
|
||||
*
|
||||
* \return The hardware address format.
|
||||
*/
|
||||
uint16_t hw_addr_format() const {
|
||||
return Endian::be_to_host(header_.hw_address_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address format field.
|
||||
*
|
||||
* \return The protocol address format.
|
||||
*/
|
||||
uint16_t prot_addr_format() const {
|
||||
return Endian::be_to_host(header_.proto_address_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address length field.
|
||||
*
|
||||
* \return The hardware address length.
|
||||
*/
|
||||
uint8_t hw_addr_length() const {
|
||||
return header_.hw_address_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address length field.
|
||||
*
|
||||
* \return The protocol address length.
|
||||
*/
|
||||
uint8_t prot_addr_length() const {
|
||||
return header_.proto_address_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the ARP opcode field.
|
||||
*
|
||||
* \return The ARP opcode.
|
||||
*/
|
||||
uint16_t opcode() const {
|
||||
return Endian::be_to_host(header_.opcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the ARP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's hardware address.
|
||||
*
|
||||
* \param address The new sender hardware address.
|
||||
*/
|
||||
void sender_hw_addr(const hwaddress_type& address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's IP address.
|
||||
*
|
||||
* \param address The new sender IP address.
|
||||
*/
|
||||
void sender_ip_addr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's hardware address.
|
||||
*
|
||||
* \param address The new target hardware address.
|
||||
*/
|
||||
void target_hw_addr(const hwaddress_type& address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's IP address.
|
||||
*
|
||||
* \param address The new target IP address.
|
||||
*/
|
||||
void target_ip_addr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address format field.
|
||||
*
|
||||
* \param format The new hardware address format.
|
||||
*/
|
||||
void hw_addr_format(uint16_t format);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address format field.
|
||||
*
|
||||
* \param format The new protocol address format.
|
||||
*/
|
||||
void prot_addr_format(uint16_t format);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address length field.
|
||||
*
|
||||
* \param length The new hardware address length.
|
||||
*/
|
||||
void hw_addr_length(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address length field.
|
||||
*
|
||||
* \param length The new protocol address length.
|
||||
*/
|
||||
void prot_addr_length(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ARP opcode field.
|
||||
*
|
||||
* \param code Flag enum value of the ARP opcode to set.
|
||||
*/
|
||||
void opcode(Flags code);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Request within an EthernetII PDU.
|
||||
*
|
||||
* Creates an ARP Request PDU and embeds it inside an EthernetII
|
||||
* PDU.
|
||||
*
|
||||
* \param target The target's IP address.
|
||||
* \param sender The sender's IP address.
|
||||
* \param hw_snd The sender's hardware address.
|
||||
* \return EthernetII object containing the ARP Request.
|
||||
*/
|
||||
static EthernetII make_arp_request(ipaddress_type target,
|
||||
ipaddress_type sender,
|
||||
const hwaddress_type& hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Reply within an EthernetII PDU.
|
||||
*
|
||||
* Creates an ARP Reply PDU and embeds it inside an EthernetII
|
||||
* PDU.
|
||||
*
|
||||
* \param target The target's IP address.
|
||||
* \param sender The sender's IP address.
|
||||
* \param hw_tgt The target's hardware address.
|
||||
* \param hw_snd The sender's hardware address.
|
||||
* \return EthernetII object containing the ARP Reply.
|
||||
*/
|
||||
static EthernetII make_arp_reply(ipaddress_type target,
|
||||
ipaddress_type sender,
|
||||
const hwaddress_type& hw_tgt = hwaddress_type(),
|
||||
const hwaddress_type& hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
ARP* clone() const {
|
||||
return new ARP(*this);
|
||||
}
|
||||
private:
|
||||
TINS_BEGIN_PACK
|
||||
struct arp_header {
|
||||
uint16_t hw_address_format;
|
||||
uint16_t proto_address_format;
|
||||
uint8_t hw_address_length;
|
||||
uint8_t proto_address_length;
|
||||
uint16_t opcode;
|
||||
uint8_t sender_hw_address[hwaddress_type::address_size];
|
||||
uint32_t sender_ip_address;
|
||||
uint8_t target_hw_address[hwaddress_type::address_size];
|
||||
uint32_t target_ip_address;
|
||||
} TINS_END_PACK;
|
||||
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
arp_header header_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_ARP_H
|
||||
363
include/tins/bootp.h
Normal file
363
include/tins/bootp.h
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_BOOTP_H
|
||||
#define TINS_BOOTP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/macros.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/ip_address.h>
|
||||
#include <tins/hw_address.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \class BootP
|
||||
* \brief Represents a BootP PDU
|
||||
*/
|
||||
class TINS_API BootP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the IP addresses.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the chaddr field.
|
||||
*/
|
||||
typedef HWAddress<16> chaddr_type;
|
||||
|
||||
/**
|
||||
* The type of the vend field.
|
||||
*/
|
||||
typedef std::vector<uint8_t> vend_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::BOOTP;
|
||||
|
||||
/**
|
||||
* \brief Enum which contains the different opcodes BootP messages.
|
||||
*/
|
||||
enum OpCodes {
|
||||
BOOTREQUEST = 1,
|
||||
BOOTREPLY = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of BootP.
|
||||
*
|
||||
* This sets the size of the vend field to 64, as the BootP RFC
|
||||
* states.
|
||||
*/
|
||||
BootP();
|
||||
|
||||
/**
|
||||
* \brief Constructs a BootP object from a buffer .
|
||||
*
|
||||
* If there's not enough size for a BootP header, then a
|
||||
* malformed_packet exception is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \param vend_field_size The vend field size to allocate.
|
||||
* Subclasses might use 0 to provide their own interpretation of this field.
|
||||
*/
|
||||
BootP(const uint8_t* buffer, uint32_t total_sz, uint32_t vend_field_size = 64);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the opcode field.
|
||||
* \return The opcode field for this BootP PDU.
|
||||
*/
|
||||
uint8_t opcode() const { return bootp_.opcode; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the htype field.
|
||||
* \return The htype field for this BootP PDU.
|
||||
*/
|
||||
uint8_t htype() const { return bootp_.htype; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hlen field.
|
||||
* \return The hlen field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hlen() const { return bootp_.hlen; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hops field.
|
||||
* \return The hops field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hops() const { return bootp_.hops; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the xid field.
|
||||
* \return The xid field for this BootP PDU.
|
||||
*/
|
||||
uint32_t xid() const { return Endian::be_to_host(bootp_.xid); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the secs field.
|
||||
* \return The secs field for this BootP PDU.
|
||||
*/
|
||||
uint16_t secs() const { return Endian::be_to_host(bootp_.secs); }
|
||||
|
||||
/** \brief Getter for the padding field.
|
||||
* \return The padding field for this BootP PDU.
|
||||
*/
|
||||
uint16_t padding() const { return Endian::be_to_host(bootp_.padding); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ciaddr field.
|
||||
* \return The ciaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type ciaddr() const { return ipaddress_type(bootp_.ciaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the yiaddr field.
|
||||
* \return The yiaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type yiaddr() const { return ipaddress_type(bootp_.yiaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the siaddr field.
|
||||
* \return The siaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type siaddr() const { return ipaddress_type(bootp_.siaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the giaddr field.
|
||||
* \return The giaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type giaddr() const { return ipaddress_type(bootp_.giaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the chaddr field.
|
||||
* \return The chddr field for this BootP PDU.
|
||||
*/
|
||||
chaddr_type chaddr() const { return bootp_.chaddr; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sname field.
|
||||
* \return The sname field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t* sname() const { return bootp_.sname; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the file field.
|
||||
* \return The file field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t* file() const { return bootp_.file; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
const vend_type& vend() const { return vend_; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
* \param code The opcode to be set.
|
||||
*/
|
||||
void opcode(uint8_t code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware type field.
|
||||
* \param type The hardware type field value to be set.
|
||||
*/
|
||||
void htype(uint8_t type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hlen field.
|
||||
* \param length The hlen field value to be set.
|
||||
*/
|
||||
void hlen(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hops field.
|
||||
* \param count The hops field value to be set.
|
||||
*/
|
||||
void hops(uint8_t count);
|
||||
|
||||
/**
|
||||
* \brief Setter for the xid field.
|
||||
* \param identifier The xid to be set.
|
||||
*/
|
||||
void xid(uint32_t identifier);
|
||||
|
||||
/**
|
||||
* \brief Setter for the secs field.
|
||||
* \param value The secs to be set.
|
||||
*/
|
||||
void secs(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the padding field.
|
||||
* \param value The padding to be set.
|
||||
*/
|
||||
void padding(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ciaddr field.
|
||||
* \param address The ciaddr to be set.
|
||||
*/
|
||||
void ciaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the yiaddr field.
|
||||
* \param address The yiaddr to be set.
|
||||
*/
|
||||
void yiaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the siaddr field.
|
||||
* \param address The siaddr to be set.
|
||||
*/
|
||||
void siaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the giaddr field.
|
||||
* \param address The giaddr to be set.
|
||||
*/
|
||||
void giaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the chaddr field.
|
||||
* The new_chaddr pointer must be at least BOOTP::hlen() bytes long.
|
||||
* \param new_chaddr The chaddr to be set.
|
||||
*/
|
||||
template<size_t n>
|
||||
void chaddr(const HWAddress<n>& new_chaddr) {
|
||||
size_t copy_threshold = std::min(n, sizeof(bootp_.chaddr));
|
||||
for (size_t i = 0; i < copy_threshold; ++i) {
|
||||
if (i < copy_threshold) {
|
||||
bootp_.chaddr[i] = new_chaddr[i];
|
||||
}
|
||||
else {
|
||||
bootp_.chaddr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the sname field.
|
||||
* \param new_sname The sname to be set.
|
||||
*/
|
||||
void sname(const uint8_t* new_sname);
|
||||
|
||||
/**
|
||||
* \brief Setter for the file field.
|
||||
* \param new_file The file to be set.
|
||||
*/
|
||||
void file(const uint8_t* new_file);
|
||||
|
||||
/**
|
||||
* \brief Setter for the vend field.
|
||||
* \param newvend_ The vend to be set.
|
||||
*/
|
||||
void vend(const vend_type& newvend_);
|
||||
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* This returns true if the xid field is equal.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
BootP* clone() const {
|
||||
return new BootP(*this);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
*
|
||||
* This getter can be used by subclasses to avoid copying the
|
||||
* vend field around.
|
||||
*
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
vend_type& vend() { return vend_; }
|
||||
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* Struct that represents the Bootp datagram.
|
||||
*/
|
||||
TINS_BEGIN_PACK
|
||||
struct bootp_header {
|
||||
uint8_t opcode;
|
||||
uint8_t htype;
|
||||
uint8_t hlen;
|
||||
uint8_t hops;
|
||||
uint32_t xid;
|
||||
uint16_t secs;
|
||||
uint16_t padding;
|
||||
uint32_t ciaddr;
|
||||
uint32_t yiaddr;
|
||||
uint32_t siaddr;
|
||||
uint32_t giaddr;
|
||||
uint8_t chaddr[16];
|
||||
uint8_t sname[64];
|
||||
uint8_t file[128];
|
||||
} TINS_END_PACK;
|
||||
|
||||
private:
|
||||
bootp_header bootp_;
|
||||
vend_type vend_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_BOOTP_H
|
||||
39
include/tins/config.h.in
Normal file
39
include/tins/config.h.in
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef TINS_CONFIG_H
|
||||
#define TINS_CONFIG_H
|
||||
|
||||
/* Define if the compiler supports basic C++11 syntax */
|
||||
#cmakedefine TINS_HAVE_CXX11
|
||||
|
||||
/* Have IEEE 802.11 support */
|
||||
#cmakedefine TINS_HAVE_DOT11
|
||||
|
||||
/* Have WPA2 decryption library */
|
||||
#cmakedefine TINS_HAVE_WPA2_DECRYPTION
|
||||
|
||||
/* Use pcap_sendpacket to send l2 packets */
|
||||
#cmakedefine TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||
|
||||
/* Have TCPIP classes */
|
||||
#cmakedefine TINS_HAVE_TCPIP
|
||||
|
||||
/* Have TCP ACK tracking */
|
||||
#cmakedefine TINS_HAVE_ACK_TRACKER
|
||||
|
||||
/* Have TCP stream custom data */
|
||||
#cmakedefine TINS_HAVE_TCP_STREAM_CUSTOM_DATA
|
||||
|
||||
/* Have GCC builtin swap */
|
||||
#cmakedefine TINS_HAVE_GCC_BUILTIN_SWAP
|
||||
|
||||
/* Have WPA2Decrypter callbacks */
|
||||
#cmakedefine TINS_HAVE_WPA2_CALLBACKS
|
||||
|
||||
/* Have libpcap */
|
||||
#cmakedefine TINS_HAVE_PCAP
|
||||
|
||||
/* Version macros */
|
||||
#define TINS_VERSION_MAJOR ${TINS_VERSION_MAJOR}
|
||||
#define TINS_VERSION_MINOR ${TINS_VERSION_MINOR}
|
||||
#define TINS_VERSION_PATCH ${TINS_VERSION_PATCH}
|
||||
|
||||
#endif // TINS_CONFIG_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user