1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 18:55:58 +01:00

222 Commits
v0.3 ... v3.0

Author SHA1 Message Date
Matias Fontanini
5d8f3e6741 Updated README and CHANGES files. 2014-08-07 21:39:54 -03:00
Matias Fontanini
5d0ba22ac4 Fixed invalid parsing of unknown DNS records. 2014-08-07 21:22:31 -03:00
Matias Fontanini
8a44b29d92 Protocols now always set the next layer protocol flag. 2014-08-07 20:42:17 -03:00
Matias Fontanini
1b47623484 Timestamps can now be constructed from std::chrono::duration. 2014-08-07 20:12:19 -03:00
Matias Fontanini
282cd0913c Added Packet constructor. 2014-08-07 19:58:41 -03:00
Matias Fontanini
aed5ccdfca Updated configure files. 2014-08-07 19:56:29 -03:00
Matias Fontanini
8e6ddfd764 Fixed bug in EthernetII when changing its inner PDU. 2014-08-07 19:38:05 -03:00
Matias Fontanini
1c2bfd42ca Fixed invalid address passed to memcpy. 2014-08-07 19:37:06 -03:00
Matias Fontanini
b9db3ea1d3 Merge pull request #22 from mantiz/fix-armv5-alignment-issues
fix armv5 alignment issues
2014-07-31 13:47:17 -03:00
Christian Hammerl
52b0ee7ceb fix armv5 alignment issues 2014-07-31 15:49:52 +00:00
Matias Fontanini
3ef85aae38 Added BaseSniffer::set_extract_raw_pdus. 2014-07-30 23:01:03 -03:00
Matias Fontanini
3bb310dd6b Updated autotools files. 2014-07-30 22:59:14 -03:00
Matias Fontanini
a918229d4b Merge pull request #21 from jedahan/master
minimum automake version from 1.13 -> 1.11
2014-07-30 22:52:08 -03:00
Jonathan Dahan
95a9d18b6b minimum automake version from 1.13 -> 1.11 2014-07-30 11:44:24 -04:00
Matias Fontanini
7371b95ebc Merge pull request #19 from kylemcdonald/master
added Utils::to_string(PDU::PDUType). closes #12.
2014-07-29 08:57:44 -03:00
Kyle McDonald
416edc34f7 added Utils::to_string(PDU::PDUType). closes #12. 2014-07-27 00:24:16 -04:00
Matias Fontanini
2dff95700f Updated copyright notice. 2014-07-13 11:04:29 -03:00
Matias Fontanini
46b52ad26e Updated example. 2014-07-13 10:59:00 -03:00
Matias Fontanini
22e7c1d7c4 Fixed error compilations on windows. 2014-07-02 19:02:48 -03:00
Matias Fontanini
dd2ed5daa4 Added undef directive to avoid compilation error on windows. 2014-07-01 17:06:39 -03:00
Matias Fontanini
c25d4738b4 Added check for HAVE_DOT11 macro in RSNInformation header/source files. 2014-06-09 22:50:49 -03:00
Matias Fontanini
3d4f509a62 Added call to pcap_can_set_rfmon before calling pcap_set_rfmon. 2014-06-09 10:24:09 -03:00
Matias Fontanini
c9e955903e Fixed ICMPv6 checksum calculation. 2014-06-09 10:09:20 -03:00
Matias Fontanini
201ea885a1 Added method in TCP and IP that emplaces an option. 2014-06-01 12:55:36 -03:00
Matias Fontanini
356ea2a68a Added small option optimization to PDUOption. 2014-05-29 23:15:44 -03:00
Matias Fontanini
559c963d63 Fixed compilation errors on Windows. 2014-05-06 00:13:05 -03:00
Matias Fontanini
4bf5876adf Fixed compilation error in RSNInformation. 2014-05-05 08:34:16 -03:00
Matias Fontanini
b2788fad63 Simplified error string generation on Sniffer::pcap_open_live_extended. 2014-05-05 08:32:45 -03:00
Matias Fontanini
c249ff608c Merge pull request #11 from kylemcdonald/master
changed ICMP::check to ICMP::checksum
2014-05-03 18:52:29 -03:00
Kyle McDonald
bd55307b47 changed ICMP::check to ICMP::checksum for both the public getter and private setter. closes #10 2014-05-03 17:43:35 -04:00
Matias Fontanini
6b17dc78e5 Merge pull request #9 from kylemcdonald/master
Allow Sniffer to enable monitor mode on interface
2014-05-03 14:32:27 -03:00
Kyle McDonald
5fe4ab0de8 added pcap_open_live_extended() shim to sniffer.cpp and set rfmon to true in beacon capture example 2014-05-03 12:48:35 -04:00
Matias Fontanini
4ee89662f2 Fix bug on TCPStreamFollower. 2014-04-12 11:53:00 -03:00
Matias Fontanini
86e3f138f8 Added correct handling of the PDU::IPv6 flag in Internals::pdu_flag_to_ip_type. 2014-04-07 13:29:14 -03:00
Matias Fontanini
cd2b9aab98 TCPStreamFollower now doesn't clear its state each time follow_streams is called. 2014-04-07 11:29:09 -03:00
Matias Fontanini
f05840b9e9 Merge pull request #5 from lodagro/patch-1
Fix typo in test name
2014-04-03 13:38:43 -03:00
Wouter Overmeire
8c2abf9249 Fix typo in test name 2014-04-03 15:39:26 +02:00
Matias Fontanini
64d35b4903 TCPStreamFollower now handles overlapping fragments. 2014-04-02 11:10:44 -03:00
Matias Fontanini
10421fe945 Added DHCP::hostname. 2014-04-01 10:22:05 -03:00
Matias Fontanini
7c8aefccfe Merge pull request #4 from jacob-baines/patch-1
Remove Extra Qualification
2014-03-12 14:40:46 -02:00
Jacob Baines
60404296fb Remove Extra Qualification
The extra "SessionKeys::" prevents compilation on Windows.
2014-03-12 12:19:29 -04:00
Matias Fontanini
dbc3ab4c32 Updated the LICENSE file. 2014-03-05 18:23:16 -03:00
Matias Fontanini
f83521f778 Merge pull request #3 from JeanJoskin/master
PacketSender::send does not work properly
2014-02-27 11:25:54 -02:00
Jean Joskin
6fb8cbfc86 PacketSender::send matched PDU against most specific type, hence the PDU::DOT11 case would never be chosen. 2014-02-27 13:34:14 +01:00
Matias Fontanini
0acf388277 Removed 'no newline at end of file' warnings. 2014-02-10 18:21:46 -03:00
Matias F
4c4a5f6c03 Fixed bug when calling BIOCIMMEDIATE on *BSD. 2014-02-10 12:33:48 -03:00
Matias Fontanini
fbef2e765d Fixed bug on PacketSender::send_recv which didn't work under OSX and FreeBSD. 2014-02-06 15:10:23 -03:00
Matias F
ea927caa4b Added BSD notice to DNS stats example. 2014-02-03 10:57:30 -03:00
Matias F
60f9116af1 Added DNS stats example. 2014-02-03 10:55:37 -03:00
Matias Fontanini
75c6bb46dc Fixed compilation error in OSX caused by including pcap/bpf.h instead of pcap.h in src/ppi.cpp. 2014-01-25 18:45:55 -03:00
Matias Fontanini
0a2f3b477b Merge pull request #2 from itay-grudev/master
Fixed bug - not included std::string
2014-01-25 13:00:07 -08:00
Itay Grudev
e73ea43f7b Fixed bug - not included std::string
Error details:
implicit instantiation of undefined template std::basic_string
2014-01-25 22:55:59 +02:00
Matias F
17933765d3 dns_spoof example now uses DNS::Resource. 2014-01-24 09:54:03 -03:00
Matias F
ed175e0ad6 Updated CHANGES, README and configure.ac files. 2014-01-23 11:30:05 -03:00
Matias Fontanini
c5404a6111 Removed DNSResourceRecord. Records in DNS are now managed completely by DNS::Resource. 2014-01-21 22:56:53 -03:00
Matias Fontanini
6d7e06535a Fixed some endianness bugs on ICMPv6 and PPI. 2014-01-19 14:40:57 -03:00
Matias Fontanini
853e1ce647 tins.h now includes ppi.h. 2014-01-19 14:17:25 -03:00
Matias Fontanini
dbcdda9d36 Rewrote the DNS parsing algorithm. Everything is now done on the read buffer, without any extra data structures, making it work about 400% faster than before. 2014-01-19 13:11:50 -03:00
Matias Fontanini
17ceba6064 Fixed broken strict-aliasing rules on ICMPv6. 2014-01-15 19:56:58 -03:00
Matias Fontanini
52078cc567 Finished porting DHCPv6. 2014-01-15 19:39:07 -03:00
Matias Fontanini
e2656739f1 Ported DHCP and Dot11. Almost ported DHCPv6 completely. 2013-12-23 23:02:58 -03:00
Matias Fontanini
33091ccbae Ported PPPoE and started porting Dot11. 2013-12-18 13:02:41 -03:00
Matias Fontanini
ca6b603478 Finished porting ICMPv6. 2013-12-17 19:00:00 -03:00
Matias Fontanini
069ae82b10 Keep porting ICMPv6 to use PDUOption::to<>. 2013-12-17 00:10:26 -03:00
Matias Fontanini
ea6638c163 IP now uses PDUOption::to<>. Started porting ICMPv6 to do so as well. 2013-12-16 15:50:17 -03:00
Matias Fontanini
112a357726 Added PDUOption::to<>. TCP options now use this method when being converted to their appropriate types. 2013-12-16 14:11:53 -03:00
Matias Fontanini
0e54579200 Layer 3 packets sent using PacketSender::send_recv for which the answer is a different PDU type(such as ICMP destination unreachable), are detected by PacketSender and matched like usual. 2013-12-14 18:10:33 -03:00
Matias Fontanini
ccb8ffd1b5 ICMP::gateway is now an IPv4Address. 2013-12-14 14:28:39 -03:00
Matias Fontanini
b83c1a2a96 Added support for ICMP address mask request/reply. 2013-12-14 14:21:04 -03:00
Matias Fontanini
81a947e3b3 Fixed bug on ICMP checksum calculation when using timestamp request/replies. 2013-12-14 13:42:12 -03:00
Matias Fontanini
1cec0f106d 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. 2013-12-14 12:49:50 -03:00
Matias Fontanini
0acb0fee3e IP packets sent using PacketSender::send_recv now match ICMP responses. 2013-12-14 12:48:56 -03:00
Matias Fontanini
9b57585b62 Added support for ICMP timestamp request/reply packets. ICMP::matches_response now works with these types of packets as well. 2013-12-13 17:23:17 -03:00
Matias Fontanini
2ddec368c3 Fixed bug on IP when serializing fragmented packets.
The original protocol id was being overwritten with 0xff(unknown)
when the inner_pdu was a RawPDU, even if it was just a fragment of
a transport layer PDU. The protocol id is now kept if the packet
is fragmented.
2013-12-04 10:56:48 -03:00
matias
83dc8819b6 Updated README.md. 2013-11-24 16:37:10 -03:00
matias
5e668e6e83 Updated README.md 2013-11-24 13:31:19 -03:00
matias
ca4912ded4 Added README.md and updated README. 2013-11-24 11:07:39 -03:00
Matias Fontanini
295ebb679c Added 1000ms as the default read timeout used when calling pcap_open_live. Added BaseSniffer::set_timeout to modify this parameter. 2013-11-19 20:51:58 -03:00
Matias Fontanini
6355aff3cd Added IPv4Reassembler class. 2013-11-17 15:32:24 -03:00
Matias Fontanini
a6655191d4 Fragmented IP packet's inner_pdu PDUs are not decoded now. 2013-11-16 19:40:08 -03:00
Matias Fontanini
dc6c37777b Updated configure.ac and README files. 2013-11-10 14:14:25 -03:00
Matias Fontanini
23552ea105 Fixed issue with relative include paths in dot11 headers. 2013-11-10 11:55:36 -03:00
Matias Fontanini
9962381fc7 Added the --disable-dot11 configure switch. 2013-11-09 14:41:08 -03:00
Matias Fontanini
93ab8d3b91 Removed useless include directives from ip.cpp and ipv6.cpp. 2013-11-04 23:31:46 -03:00
Matias Fontanini
5345b29f8c Added support for IPSec. 2013-11-04 23:05:00 -03:00
Matias Fontanini
de06fee5ab Fixed bug triggered when ifaddrs::ifa_addr was null. 2013-11-04 15:53:55 -03:00
Matias Fontanini
6d329424f1 Created an overload of Internals::pdu_from_flag for transport layer PDUs. 2013-11-04 13:46:25 -03:00
Matias Fontanini
dfbbea33d5 Added another overload of Utils::route_entries and fixed a bug in Utils::network_interfaces. 2013-11-02 19:19:55 -03:00
Matias Fontanini
0b02af616a Added ARP monitor example. 2013-10-29 21:10:11 -03:00
Matias Fontanini
a101ec9796 Added the missing WPS detector example. 2013-10-29 19:19:53 -03:00
Matias Fontanini
b0868b5d60 Added another Sniffer constructor. 2013-10-21 23:31:07 -03:00
Matias Fontanini
f57b8c189c Added WPS detector example. Updated configure files. 2013-10-21 22:54:18 -03:00
Matias Fontanini
a507355e27 Added tins_cast as a replacement for dynamic_cast when using it on PDU classes. 2013-10-18 09:28:43 -03:00
Matias Fontanini
87fdd62b57 Added some examples. 2013-10-17 20:44:54 -03:00
Matias Fontanini
3337335df2 Fixed compilation error on internals.h. 2013-10-16 14:45:03 -03:00
Matias Fontanini
08113b8f5f Updated the CHANGES file. 2013-10-07 23:50:54 -03:00
Matias Fontanini
6dd949611d Modified some header documentation. 2013-10-07 23:31:22 -03:00
Matias Fontanini
b6a55935b4 Modified some Dot11ManagementFrame documentation. 2013-10-07 14:00:45 -03:00
Matias Fontanini
01b2a9c7b2 Modified some examples fixed some doxygen documentation. 2013-10-06 23:00:20 -03:00
Matias Fontanini
58e2c93e30 Added HWAddress and IPv4Address::is_unicast and a static const member 'broadcast' for both classes. 2013-10-06 22:56:00 -03:00
Matias Fontanini
bcfe26175a BaseSniffer now uses pcap_loop instead of pcap_dispatch. 2013-09-24 08:59:46 -03:00
Matias Fontanini
c4e6a7c0d6 Fixed some compilation errors/warnings and bugs when using Big Endian architectures. 2013-09-24 00:34:14 -03:00
Matias Fontanini
9cbac6b044 BaseSniffer::next_packet now uses pcap_dispatch. 2013-09-23 22:55:18 -03:00
Matias Fontanini
2414edd1e7 Fixed a bug in PPI and Dot1Q triggered when constructing from buffer/serializing. Done some documentation fixes. 2013-09-22 19:37:02 -03:00
Matias Fontanini
74ef177e25 Added address_range.cpp. 2013-09-21 01:21:15 -03:00
Matias Fontanini
54d012b92e Done some fixes on HWAddress. Added HWAddress::operator/ which returns an AddressRange. 2013-09-20 17:37:20 -03:00
Matias Fontanini
1b4efc1520 Rolled the BaseSniffer changes since that was OK. 2013-09-20 12:37:21 -03:00
Matias Fontanini
96ecd054ab Fixed issue with bpf_programs on BaseSniffer. Done some documentation changes. 2013-09-20 11:07:09 -03:00
Matias Fontanini
d7d2dec5cb Done some optimizations on TCP's constructor from buffer. 2013-09-15 16:01:00 -03:00
Matias Fontanini
20f3911e12 BaseSniffer::sniff_loop now uses begin() and end() to process packets, making it around 8% faster. Also added BaseSniffer::link_type to retrieve the pcap handle link type. 2013-09-15 12:16:54 -03:00
Matias Fontanini
f8d71687e1 Modified some classes' documentation. 2013-09-14 19:01:05 -03:00
Matias Fontanini
d393c1fbfc Moved calls to pcap_loop and pcap_breakloop to sniffer.cpp. 2013-09-08 19:20:52 -03:00
Matias Fontanini
e21e34e194 Added IPv4Address, IPv6Address and HWAddress<> 'is_multicast' member function. 2013-09-08 17:23:08 -03:00
Matias Fontanini
a01fff411e Added missing PPI files. 2013-09-05 09:09:56 -03:00
Matias Fontanini
7d4222fb17 Added PPI PDU. 2013-09-05 00:49:11 -03:00
Matias Fontanini
de0ec914cc Fixed bug in RadioTap. The flags field was being used even if it was not present. 2013-09-04 16:34:24 -03:00
Matias Fontanini
15f2896811 Added is_private and is_loopback methods to IPv4 and IPv6 addresses. 2013-09-04 12:57:36 -03:00
Matias Fontanini
b26f353e46 Added helper functions to Dot11Data to retrieve the source, destination and BSSID addresses. 2013-09-03 22:58:07 -03:00
Matias Fontanini
5f2c923c48 Added PDUAllocator class, which makes extending PDUs easier. 2013-08-29 23:31:10 -03:00
Matias Fontanini
4ca21bdad7 Fixed some issues when parsing DNS answers. MX records are now serialized correctly. 2013-08-04 14:27:03 -03:00
Matias Fontanini
2cc0ceb1aa Fixed bug triggered in DNS when parsing some unknown record types. 2013-07-25 10:47:09 -03:00
Matias Fontanini
7063e60af9 Merge branch 'master' of ssh://git.code.sf.net/p/libtins/code 2013-07-24 23:32:55 -03:00
Matias Fontanini
21b80a7370 BaseSniffer is now iterable. 2013-07-24 23:32:33 -03:00
Matias Fontanini
fb8fb92ee6 BaseSniffer::next_packet now loops until either a valid packet is found or pcap_next fails. 2013-07-24 22:27:53 -03:00
Santiago Alessandri
2a5b64526f Replaced tabs for spaces in the previous commit 2013-07-14 13:13:38 -03:00
Santiago Alessandri
02d3a14083 Fixed issue related with EthernetII protocol.
The Ethernet II protocol forces a minimum length of 60 bytes. It is necessary to add a trailer for padding of null-bytes when the inner_pdu's size does not meet the requirement.

Also EthernetII packets received were being incorrectly parsed due to the existance of this padding.

The issue has been solved and several tests were added. All tests successfully pass.
2013-07-12 20:06:55 -03:00
Matias Fontanini
3b349471ea Added AddressRange class template. 2013-07-06 17:48:26 -03:00
Matias Fontanini
f385e4e975 Added a const overload of TCP::get_flag. Added TCP::flags. 2013-06-17 21:25:30 -03:00
Matias Fontanini
acff8f1e1f The --disable-wpa2 switch now works as expected. 2013-06-15 10:00:50 -03:00
Matias Fontanini
59090e62d2 Added -Wno-extra-portability to automake's flags. 2013-06-07 10:28:19 -03:00
Matias Fontanini
74594a3b20 Updated CHANGES file. 2013-06-05 09:08:42 -03:00
Matias Fontanini
681bdc727f Updated configure.ac and README files. 2013-06-04 20:04:10 -03:00
Matias Fontanini
996e0f139e Fixed bug on Dot11QoSData. 2013-06-04 15:49:49 -03:00
Matias Fontanini
c2353314fa WEPDecrypter now returns true iff the packet was decrypted successfully. 2013-06-04 15:49:33 -03:00
Matias Fontanini
5d315c5b6d Fixed a CCMP padding bug. 2013-06-02 16:14:21 -03:00
Matias Fontanini
87ac5acdd8 WPA2Decrypter now decrypts both CCMP and TKIP encrypted traffic. 2013-06-01 21:29:06 -03:00
Matias Fontanini
3b4dc10211 Added HWAddress<>::operator[]. 2013-06-01 12:05:53 -03:00
Matias Fontanini
8c1d71c7b7 Both of WPA2Decrypter::add_supplicant_data overloads work. 2013-06-01 10:48:22 -03:00
Matias Fontanini
5db196a630 Fixed tests dependency file. 2013-05-31 22:33:50 -03:00
Matias Fontanini
ec8374be60 Split dot11.h and dot11.cpp into several files. 2013-05-31 22:16:56 -03:00
Matias Fontanini
eeb62add59 Added WPA2Decrypter tests. 2013-05-31 14:11:12 -03:00
Matias Fontanini
908fcb56e8 Added WPA2Decrypter class. 2013-05-30 23:36:14 -03:00
Matias Fontanini
ddf47365c1 RadioTap now calculates its size always while serializing. Added 2 missing RadioTap fields as well. 2013-05-30 18:14:11 -03:00
Matias Fontanini
b052aa1d88 Added HWAddress<>::is_broadcast. 2013-05-29 11:14:36 -03:00
Matias Fontanini
cacf75995d Added automake foreign option. 2013-05-28 15:19:00 -03:00
Matias Fontanini
4960077495 RSNHandshakeCapturer is now DefaultConstructible. 2013-05-28 10:15:33 -03:00
Matias Fontanini
8147a2bfb7 Added RSNHandshakeCapturer class. 2013-05-25 18:00:20 -03:00
Piotr Haber
28c8d393d6 do not parse Dot11 frame if FCS is wrong
Signed-off-by: Matias Fontanini <matias.fontanini@gmail.com>
2013-05-23 17:54:17 -03:00
Matias Fontanini
ec7e718e38 Implemented std::hash for IPv4Address and IPv6Address. 2013-05-21 13:07:14 -03:00
Matias Fontanini
62740e8e64 Implemented std::hash specialization for HWAddress. 2013-05-04 20:09:32 -03:00
Matias Fontanini
2bb699dc97 Merge branch 'master' of ssh://git.code.sf.net/p/libtins/code 2013-05-01 14:08:16 -03:00
Piotr Haber
14b1a4988b take wildcard SSID into account
Specification states (Ch 8.4.2.2 of IEEE Std 802.11-2007)
that in Probe Reqest frames SSID IE of length 0 signifies
"wildcard" SSID.
Return "BROADCAST" from Dot11ManagementFrame::ssid()
in such case.

Signed-off-by: Matias Fontanini <matias.fontanini@gmail.com>
2013-05-01 14:06:02 -03:00
Matias Fontanini
7f6e4446b4 Fixed the examples. 2013-04-24 12:07:52 -03:00
Matias Fontanini
cf19c8758d UDP now calculates the checksum when the transport layer protocol is IPv6. 2013-04-23 23:00:43 -03:00
Matias Fontanini
5197e7f5f1 Sniffer now differentiates between EthernetII and Dot3 when sniffing. 2013-04-23 22:55:32 -03:00
Matias Fontanini
eb87b82c17 Fixed the CHANGES and README files. 2013-04-23 20:57:56 -03:00
Matias Fontanini
5064a9255b Fixed BSD notice. Updated AUTHORS file. 2013-04-23 20:33:00 -03:00
Matias Fontanini
bf604339f0 Removed the PDU* parameter in several PDU's constructors. 2013-04-23 20:03:08 -03:00
Matias Fontanini
7e85058ef1 Added another overload of Utils::resolv_hwaddr. 2013-04-23 15:19:48 -03:00
Matias Fontanini
ec05a49cce Done minor modifications on configure.ac 2013-04-23 14:46:56 -03:00
Matias Fontanini
b0eefe15f9 Modified the soname. 2013-04-23 13:43:12 -03:00
Matias Fontanini
0f2bc45059 Moved definitions inside TINS_IS_CXX11 into header files. 2013-04-23 13:04:57 -03:00
Matias Fontanini
f8134be8b7 Done some modifications on the configure script. 2013-04-23 13:03:00 -03:00
Matias Fontanini
8afbe14c82 PacketSender is not copyable and movable. 2013-04-23 11:05:44 -03:00
Matias Fontanini
fdfb8b0dea Fixed compilation issues triggered in GNU/kFreeBSD. 2013-04-22 23:48:53 -03:00
Matias Fontanini
9be4f0ca37 Removed IP, UDP and IP checksum setters. Added some checksum tests. 2013-04-22 20:06:35 -03:00
Matias Fontanini
66ff604580 assert() is only called when TINS_DEBUG is defined. 2013-04-22 18:45:56 -03:00
Matias Fontanini
7e0e85db65 Added AC_CANONICAL_SYSTEM to configure.ac. 2013-04-22 13:58:42 -03:00
Matias Fontanini
ed39eb36f5 Dot11BlockAck and Dot11BlockAckRequests' frag_seq, start_sequence and bar_control now use small_uint rather than uintX_t. 2013-04-22 12:54:27 -03:00
Matias Fontanini
7da8de6ea7 Added another test case for RadioTap's constructor from buffer. 2013-04-22 12:53:01 -03:00
Matias Fontanini
d1b64ec48e PDU::matches_response is now const. 2013-04-21 20:03:47 -03:00
Matias Fontanini
69968cbc5c Removed deprecated methods/types. 2013-04-21 19:52:39 -03:00
Matias Fontanini
9e20c0241f Added a default interface to PacketSender. 2013-04-21 19:40:17 -03:00
Matias Fontanini
97f049580b Link layer PDUs no longer contain a NetworkInterface. 2013-04-21 18:50:08 -03:00
Matias Fontanini
6f04329fbe All tests now run successfully on big endian architectures. 2013-04-21 15:40:28 -03:00
Matias Fontanini
077b54bbed Added STP root_id and bridge_id setters/getters. 2013-04-21 13:22:15 -03:00
Matias Fontanini
759e92706f Sniffer::sniff_loop now catches malformed_packet and pdu_not_found, when thrown by the functor argument. 2013-04-21 13:21:47 -03:00
Matias Fontanini
2ea952d6ab Added PDU::rfind_pdu. 2013-04-19 22:27:48 -03:00
Matias Fontanini
91bdcca577 Dot11 now uses option_not_found. Sniffer catches malformed_packet rather than std::runtime_error while sniffing. 2013-04-19 14:06:59 -03:00
Matias Fontanini
75bd445bd3 Dot11 now uses malformed_packet. 2013-04-19 02:05:28 -03:00
Matias Fontanini
9812ad441f Added missing exceptions.h file. 2013-04-18 17:52:53 -03:00
Matias Fontanini
3fd1b3d37d Added malformed_packet exception. Every class except Dot11* use it. 2013-04-18 00:12:20 -03:00
Matias Fontanini
923f51ae15 Fixed bug triggered when parsing Dot11 QoS packets. 2013-04-16 15:01:48 -03:00
Matias Fontanini
804ea411fc Fixed bug in RadioTap when using FCS at the end. 2013-04-16 13:45:30 -03:00
Piotr Haber
9bcfd07896 fix radiotap header parsing
Signed-off-by: Matias Fontanini <matias.fontanini@gmail.com>
2013-04-16 13:37:31 -03:00
Matias Fontanini
58c8eccc46 Makefile issue fix. 2013-04-16 13:15:35 -03:00
Matias F
a674640ef2 Now hopefully make problems are fixed. 2013-04-16 13:00:12 -03:00
Matias F
dde890b24b Fixed make issues. 2013-04-16 12:51:07 -03:00
Matias Fontanini
38ccb4413b STP is now serialized correctly. LLC behaves correctly when it contains an STP is its inner pdu. 2013-04-16 01:05:06 -03:00
Matias F
9631734805 Added STP class. 2013-04-15 14:01:44 -03:00
Matias Fontanini
7faf514496 Merge branch 'master' of ssh://git.code.sf.net/p/libtins/code 2013-04-15 08:49:25 -03:00
Matias Fontanini
08091fc7c2 Added missing the deprecated header ieee802_3.h to Makefile.am. 2013-04-15 08:48:51 -03:00
Matias Fontanini
1450c8cf26 Fixed missing header in Makefile.in as well. 2013-04-15 08:41:21 -03:00
Matias Fontanini
b533775cb4 Added missing the deprecated header ieee802_3.h to Makefile.am. 2013-04-15 08:35:34 -03:00
Matias Fontanini
3f4c48ad9f Fixed bug triggered when parsing EOL and NOP options in IP. 2013-04-15 00:23:29 -03:00
Matias Fontanini
30d6a4f2e0 UDP checksum is now calculated always inside write_serialization. 2013-04-12 13:42:11 -03:00
Matias Fontanini
f4522acd44 IP and TCP now calculate checksums always inside write_serialization. 2013-04-11 00:57:36 -03:00
Matias Fontanini
1fbef641da TCP options now use PDUOption<>::length_field when it is != from data_size. 2013-04-10 18:44:00 -03:00
Matias Fontanini
fee938b46d Added move constructor/assignment operator to PDU. 2013-04-10 18:43:24 -03:00
Matias Fontanini
ae1e1c2ce2 Modified some protocols' internal type names. 2013-04-09 15:40:58 -03:00
Matias Fontanini
20054e6c73 Several classes now use PDUOption::length_field instead of data_size. 2013-04-08 11:58:12 -03:00
Matias Fontanini
f7f5a9bc9a Added PPPoE. 2013-04-07 20:57:43 -03:00
Matias Fontanini
f2a5f73337 Implemented matches_response on several PDUs. Added some test cases. 2013-04-02 21:05:53 -03:00
Matias Fontanini
97049140af Added some helper methods to Dot1Q. 2013-03-26 23:42:43 -03:00
Matias Fontanini
dfc0498b70 DNS, RadioTap and Dot1Q work when using PacketSender::send_recv. 2013-03-26 14:54:24 -03:00
Matias Fontanini
1cec099c0e Dot3::matches_response now works as expected. 2013-03-26 00:25:47 -03:00
Matias Fontanini
3989566608 Renamed IEEE802_3 to Dot3. 2013-03-25 15:35:30 -03:00
Matias Fontanini
b32586e739 Fixed compilation error on IP and TCP. 2013-03-25 15:17:26 -03:00
Matias Fontanini
82ef41dd92 IP now fills automatically the sender address when no link layer PDU is present. Made some protocols work when using PacketSender::send_recv. 2013-03-25 14:08:59 -03:00
Matias Fontanini
b0dc376494 Fixed compilation error in pdu_cacher.h. 2013-03-25 09:55:15 -03:00
Matias Fontanini
8be0c4c23c Marked PDU::clone_packet as deprecated. 2013-03-24 16:08:09 -03:00
Matias Fontanini
d7dd1e131f Added an overload of add_option that takes an rvalue-ref in IP, TCP, DHCP, ICMPv6 and Dot11. 2013-03-24 00:08:53 -03:00
Matias Fontanini
584fe81f04 Optimized TCP, IP and PDUOption<>. 2013-03-23 13:44:33 -03:00
Matias Fontanini
16a99ef35b Added an overload of PacketSender::send that takes a NetworkInterface. 2013-03-20 23:24:43 -03:00
Matias Fontanini
247273e086 Added constructor from buffer test for Dot11BlockAckRequest. 2013-03-18 13:32:34 -03:00
Matias Fontanini
0f27b04a92 Fixed lots of warnings in test cases, due to narrowing conversions. 2013-03-18 11:32:34 -03:00
Matias Fontanini
a8edc2af74 Added serialization test for Dot1Q. 2013-03-18 10:17:43 -03:00
Matias Fontanini
f5ecaa3faa Added Dot1Q class. 2013-03-17 23:27:34 -03:00
Matias Fontanini
b5f9f5095e Added Utils::resolve_domain and resolve_domain6. 2013-03-15 15:43:42 -03:00
Matias Fontanini
02a53da361 Fixed bug triggered when parsing RadioTap in BE architectures. 2013-03-15 15:13:00 -03:00
Matias Fontanini
f86f727810 Added RadioTap::iface. 2013-02-06 14:10:21 -03:00
Matias Fontanini
836dbd8955 Fixed compilation issue in 2 examples. 2013-02-01 13:55:29 -03:00
209 changed files with 35508 additions and 20781 deletions

11
AUTHORS
View File

@@ -1,2 +1,9 @@
Matias Fontanini - matias.fontanini@gmail.com
Santiago Alessandri - salessandri@nasel.com.ar
# Below is a list of people and organizations that have contributed source
# code to libtins. Names are listed using the following format:
#
# Name/Organization <email address>
Matias Fontanini <matias.fontanini@gmail.com>
Santiago Alessandri <san.lt.ss@gmail.com>
Bruno Nery <brunonery@brunonery.com>
Piotr Haber <piotr.haber@sens.us>

211
CHANGES
View File

@@ -1,3 +1,214 @@
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.

View File

@@ -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.3
PROJECT_NUMBER = 1.2
# 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 = ../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
@@ -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

View File

@@ -1,4 +1,4 @@
Copyright (c) 2012, Nasel
Copyright (c) 2012-2014, Matias Fontanini
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -1,4 +1,4 @@
AUTOMAKE_OPTIONS=subdir-objects
AUTOMAKE_OPTIONS=subdir-objects 1.11
ACLOCAL_AMFLAGS=${ACLOCAL_FLAGS} -I m4
# pkg-config stuff
@@ -13,28 +13,35 @@ AM_CXXFLAGS = -Wall -pedantic -I@LIBTINS_INCLUDE_DIR@
libtins_la_SOURCES=src/arp.cpp \
src/bootp.cpp \
src/handshake_capturer.cpp \
src/stp.cpp \
src/pppoe.cpp \
src/crypto.cpp \
src/dhcp.cpp \
src/dhcpv6.cpp \
src/dns.cpp \
src/dns_record.cpp \
src/dot11.cpp \
src/dot3.cpp \
src/dot1q.cpp \
src/eapol.cpp \
src/ethernetII.cpp \
src/icmp.cpp \
src/icmpv6.cpp \
src/ieee802_3.cpp \
src/internals.cpp \
src/ip.cpp src/ip_address.cpp \
src/ip_reassembler.cpp \
src/ip.cpp \
src/ip_address.cpp \
src/ipv6.cpp \
src/ipv6_address.cpp \
src/ipsec.cpp \
src/llc.cpp \
src/loopback.cpp \
src/network_interface.cpp \
src/packet_sender.cpp \
src/packet_writer.cpp \
src/ppi.cpp \
src/pdu.cpp \
src/radiotap.cpp \
src/address_range.cpp \
src/rawpdu.cpp \
src/rsn_information.cpp \
src/sll.cpp \
@@ -43,27 +50,41 @@ libtins_la_SOURCES=src/arp.cpp \
src/tcp.cpp \
src/tcp_stream.cpp \
src/udp.cpp \
src/utils.cpp
src/utils.cpp \
src/dot11/dot11_base.cpp \
src/dot11/dot11_data.cpp \
src/dot11/dot11_mgmt.cpp \
src/dot11/dot11_beacon.cpp \
src/dot11/dot11_assoc.cpp \
src/dot11/dot11_auth.cpp \
src/dot11/dot11_probe.cpp \
src/dot11/dot11_control.cpp
libtins_includedir = $(includedir)/tins
libtins_include_HEADERS = include/internals.h \
libtinsdir = $(includedir)/tins
libtins_HEADERS = include/internals.h \
include/dhcpv6.h \
include/dot11.h \
include/dot1q.h \
include/dot3.h \
include/small_uint.h \
include/ip.h \
include/dns_record.h \
include/ipsec.h \
include/eapol.h \
include/tcp_stream.h \
include/pppoe.h \
include/handshake_capturer.h \
include/ipv6.h \
include/icmpv6.h \
include/ieee802_3.h \
include/endianness.h \
include/rsn_information.h \
include/loopback.h \
include/ieee802_3.h \
include/ethernetII.h \
include/crypto.h \
include/packet.h \
include/llc.h \
include/ip_reassembler.h \
include/icmp.h \
include/hw_address.h \
include/packet_writer.h \
@@ -75,6 +96,7 @@ libtins_include_HEADERS = include/internals.h \
include/bootp.h \
include/network_interface.h \
include/sll.h \
include/ppi.h \
include/radiotap.h \
include/dns.h \
include/rawpdu.h \
@@ -90,4 +112,20 @@ libtins_include_HEADERS = include/internals.h \
include/ipv6_address.h \
include/constants.h \
include/utils.h \
include/cxxstd.h
include/cxxstd.h \
include/stp.h \
include/exceptions.h \
include/config.h \
include/address_range.h \
include/pdu_allocator.h
libtins_dot11_HEADERS = include/dot11/dot11_base.h \
include/dot11/dot11_beacon.h \
include/dot11/dot11_data.h \
include/dot11/dot11_mgmt.h \
include/dot11/dot11_assoc.h \
include/dot11/dot11_auth.h \
include/dot11/dot11_probe.h \
include/dot11/dot11_control.h
libtins_dot11dir = $(includedir)/tins/dot11/

View File

@@ -1,9 +1,8 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -18,6 +17,51 @@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -36,19 +80,25 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(libtins_include_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/libtins.pc.in $(top_srcdir)/configure AUTHORS THANKS \
TODO config.guess config.sub depcomp install-sh ltmain.sh \
missing
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(top_srcdir)/include/config.h.in $(srcdir)/libtins.pc.in \
depcomp $(libtins_HEADERS) $(libtins_dot11_HEADERS) AUTHORS \
README THANKS compile config.guess config.sub install-sh \
missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES = libtins.pc
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -79,42 +129,97 @@ am__uninstall_files_from_dir = { \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
"$(DESTDIR)$(libtins_includedir)"
"$(DESTDIR)$(libtinsdir)" "$(DESTDIR)$(libtins_dot11dir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libtins_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo src/crypto.lo \
src/dhcp.lo src/dhcpv6.lo src/dns.lo src/dns_record.lo \
src/dot11.lo src/eapol.lo src/ethernetII.lo src/icmp.lo \
src/icmpv6.lo src/ieee802_3.lo src/internals.lo src/ip.lo \
src/ip_address.lo src/ipv6.lo src/ipv6_address.lo src/llc.lo \
src/loopback.lo src/network_interface.lo src/packet_sender.lo \
src/packet_writer.lo src/pdu.lo src/radiotap.lo src/rawpdu.lo \
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo \
src/handshake_capturer.lo src/stp.lo src/pppoe.lo \
src/crypto.lo src/dhcp.lo src/dhcpv6.lo src/dns.lo src/dot3.lo \
src/dot1q.lo src/eapol.lo src/ethernetII.lo src/icmp.lo \
src/icmpv6.lo src/internals.lo src/ip_reassembler.lo src/ip.lo \
src/ip_address.lo src/ipv6.lo src/ipv6_address.lo src/ipsec.lo \
src/llc.lo src/loopback.lo src/network_interface.lo \
src/packet_sender.lo src/packet_writer.lo src/ppi.lo \
src/pdu.lo src/radiotap.lo src/address_range.lo src/rawpdu.lo \
src/rsn_information.lo src/sll.lo src/snap.lo src/sniffer.lo \
src/tcp.lo src/tcp_stream.lo src/udp.lo src/utils.lo
src/tcp.lo src/tcp_stream.lo src/udp.lo src/utils.lo \
src/dot11/dot11_base.lo src/dot11/dot11_data.lo \
src/dot11/dot11_mgmt.lo src/dot11/dot11_beacon.lo \
src/dot11/dot11_assoc.lo src/dot11/dot11_auth.lo \
src/dot11/dot11_probe.lo src/dot11/dot11_control.lo
libtins_la_OBJECTS = $(am_libtins_la_OBJECTS)
libtins_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libtins_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libtins_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libtins_la_SOURCES)
DIST_SOURCES = $(libtins_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
DATA = $(pkgconfig_DATA)
HEADERS = $(libtins_include_HEADERS)
HEADERS = $(libtins_HEADERS) $(libtins_dot11_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
AM_RECURSIVE_TARGETS = cscope
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -124,14 +229,17 @@ am__remove_distdir = \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -159,6 +267,7 @@ EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -247,11 +356,15 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects
AUTOMAKE_OPTIONS = subdir-objects 1.11
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
# pkg-config stuff
@@ -262,28 +375,35 @@ libtins_la_LDFLAGS = -version-info @LIBTINS_VERSION@
AM_CXXFLAGS = -Wall -pedantic -I@LIBTINS_INCLUDE_DIR@
libtins_la_SOURCES = src/arp.cpp \
src/bootp.cpp \
src/handshake_capturer.cpp \
src/stp.cpp \
src/pppoe.cpp \
src/crypto.cpp \
src/dhcp.cpp \
src/dhcpv6.cpp \
src/dns.cpp \
src/dns_record.cpp \
src/dot11.cpp \
src/dot3.cpp \
src/dot1q.cpp \
src/eapol.cpp \
src/ethernetII.cpp \
src/icmp.cpp \
src/icmpv6.cpp \
src/ieee802_3.cpp \
src/internals.cpp \
src/ip.cpp src/ip_address.cpp \
src/ip_reassembler.cpp \
src/ip.cpp \
src/ip_address.cpp \
src/ipv6.cpp \
src/ipv6_address.cpp \
src/ipsec.cpp \
src/llc.cpp \
src/loopback.cpp \
src/network_interface.cpp \
src/packet_sender.cpp \
src/packet_writer.cpp \
src/ppi.cpp \
src/pdu.cpp \
src/radiotap.cpp \
src/address_range.cpp \
src/rawpdu.cpp \
src/rsn_information.cpp \
src/sll.cpp \
@@ -292,27 +412,40 @@ libtins_la_SOURCES = src/arp.cpp \
src/tcp.cpp \
src/tcp_stream.cpp \
src/udp.cpp \
src/utils.cpp
src/utils.cpp \
src/dot11/dot11_base.cpp \
src/dot11/dot11_data.cpp \
src/dot11/dot11_mgmt.cpp \
src/dot11/dot11_beacon.cpp \
src/dot11/dot11_assoc.cpp \
src/dot11/dot11_auth.cpp \
src/dot11/dot11_probe.cpp \
src/dot11/dot11_control.cpp
libtins_includedir = $(includedir)/tins
libtins_include_HEADERS = include/internals.h \
libtinsdir = $(includedir)/tins
libtins_HEADERS = include/internals.h \
include/dhcpv6.h \
include/dot11.h \
include/dot1q.h \
include/dot3.h \
include/small_uint.h \
include/ip.h \
include/dns_record.h \
include/ipsec.h \
include/eapol.h \
include/tcp_stream.h \
include/pppoe.h \
include/handshake_capturer.h \
include/ipv6.h \
include/icmpv6.h \
include/ieee802_3.h \
include/endianness.h \
include/rsn_information.h \
include/loopback.h \
include/ieee802_3.h \
include/ethernetII.h \
include/crypto.h \
include/packet.h \
include/llc.h \
include/ip_reassembler.h \
include/icmp.h \
include/hw_address.h \
include/packet_writer.h \
@@ -324,6 +457,7 @@ libtins_include_HEADERS = include/internals.h \
include/bootp.h \
include/network_interface.h \
include/sll.h \
include/ppi.h \
include/radiotap.h \
include/dns.h \
include/rawpdu.h \
@@ -339,8 +473,23 @@ libtins_include_HEADERS = include/internals.h \
include/ipv6_address.h \
include/constants.h \
include/utils.h \
include/cxxstd.h
include/cxxstd.h \
include/stp.h \
include/exceptions.h \
include/config.h \
include/address_range.h \
include/pdu_allocator.h
libtins_dot11_HEADERS = include/dot11/dot11_base.h \
include/dot11/dot11_beacon.h \
include/dot11/dot11_data.h \
include/dot11/dot11_mgmt.h \
include/dot11/dot11_assoc.h \
include/dot11/dot11_auth.h \
include/dot11/dot11_probe.h \
include/dot11/dot11_control.h
libtins_dot11dir = $(includedir)/tins/dot11/
all: all-am
.SUFFIXES:
@@ -379,11 +528,26 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
include/config.h: include/stamp-h1
@test -f $@ || rm -f include/stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) include/stamp-h1
include/stamp-h1: $(top_srcdir)/include/config.h.in $(top_builddir)/config.status
@rm -f include/stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status include/config.h
$(top_srcdir)/include/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f include/stamp-h1
touch $@
distclean-hdr:
-rm -f include/config.h include/stamp-h1
libtins.pc: $(top_builddir)/config.status $(srcdir)/libtins.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -391,6 +555,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -406,12 +572,14 @@ uninstall-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
src/$(am__dirstamp):
@$(MKDIR_P) src
@: > src/$(am__dirstamp)
@@ -420,22 +588,28 @@ src/$(DEPDIR)/$(am__dirstamp):
@: > src/$(DEPDIR)/$(am__dirstamp)
src/arp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/bootp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/handshake_capturer.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/stp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/pppoe.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/crypto.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dhcp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dhcpv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dns.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dns_record.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot11.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot3.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot1q.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/eapol.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ethernetII.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/icmp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/icmpv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ieee802_3.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/internals.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ip_reassembler.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/ip.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ip_address.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipv6_address.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipsec.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/llc.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/loopback.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/network_interface.lo: src/$(am__dirstamp) \
@@ -444,8 +618,11 @@ src/packet_sender.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/packet_writer.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/ppi.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/pdu.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/radiotap.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/address_range.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/rawpdu.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/rsn_information.lo: src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
@@ -456,99 +633,61 @@ src/tcp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/tcp_stream.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/udp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/utils.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot11/$(am__dirstamp):
@$(MKDIR_P) src/dot11
@: > src/dot11/$(am__dirstamp)
src/dot11/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) src/dot11/$(DEPDIR)
@: > src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_base.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_data.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_mgmt.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_beacon.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_assoc.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_auth.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_probe.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
src/dot11/dot11_control.lo: src/dot11/$(am__dirstamp) \
src/dot11/$(DEPDIR)/$(am__dirstamp)
libtins.la: $(libtins_la_OBJECTS) $(libtins_la_DEPENDENCIES) $(EXTRA_libtins_la_DEPENDENCIES)
$(libtins_la_LINK) -rpath $(libdir) $(libtins_la_OBJECTS) $(libtins_la_LIBADD) $(LIBS)
$(AM_V_CXXLD)$(libtins_la_LINK) -rpath $(libdir) $(libtins_la_OBJECTS) $(libtins_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f src/arp.$(OBJEXT)
-rm -f src/arp.lo
-rm -f src/bootp.$(OBJEXT)
-rm -f src/bootp.lo
-rm -f src/crypto.$(OBJEXT)
-rm -f src/crypto.lo
-rm -f src/dhcp.$(OBJEXT)
-rm -f src/dhcp.lo
-rm -f src/dhcpv6.$(OBJEXT)
-rm -f src/dhcpv6.lo
-rm -f src/dns.$(OBJEXT)
-rm -f src/dns.lo
-rm -f src/dns_record.$(OBJEXT)
-rm -f src/dns_record.lo
-rm -f src/dot11.$(OBJEXT)
-rm -f src/dot11.lo
-rm -f src/eapol.$(OBJEXT)
-rm -f src/eapol.lo
-rm -f src/ethernetII.$(OBJEXT)
-rm -f src/ethernetII.lo
-rm -f src/icmp.$(OBJEXT)
-rm -f src/icmp.lo
-rm -f src/icmpv6.$(OBJEXT)
-rm -f src/icmpv6.lo
-rm -f src/ieee802_3.$(OBJEXT)
-rm -f src/ieee802_3.lo
-rm -f src/internals.$(OBJEXT)
-rm -f src/internals.lo
-rm -f src/ip.$(OBJEXT)
-rm -f src/ip.lo
-rm -f src/ip_address.$(OBJEXT)
-rm -f src/ip_address.lo
-rm -f src/ipv6.$(OBJEXT)
-rm -f src/ipv6.lo
-rm -f src/ipv6_address.$(OBJEXT)
-rm -f src/ipv6_address.lo
-rm -f src/llc.$(OBJEXT)
-rm -f src/llc.lo
-rm -f src/loopback.$(OBJEXT)
-rm -f src/loopback.lo
-rm -f src/network_interface.$(OBJEXT)
-rm -f src/network_interface.lo
-rm -f src/packet_sender.$(OBJEXT)
-rm -f src/packet_sender.lo
-rm -f src/packet_writer.$(OBJEXT)
-rm -f src/packet_writer.lo
-rm -f src/pdu.$(OBJEXT)
-rm -f src/pdu.lo
-rm -f src/radiotap.$(OBJEXT)
-rm -f src/radiotap.lo
-rm -f src/rawpdu.$(OBJEXT)
-rm -f src/rawpdu.lo
-rm -f src/rsn_information.$(OBJEXT)
-rm -f src/rsn_information.lo
-rm -f src/sll.$(OBJEXT)
-rm -f src/sll.lo
-rm -f src/snap.$(OBJEXT)
-rm -f src/snap.lo
-rm -f src/sniffer.$(OBJEXT)
-rm -f src/sniffer.lo
-rm -f src/tcp.$(OBJEXT)
-rm -f src/tcp.lo
-rm -f src/tcp_stream.$(OBJEXT)
-rm -f src/tcp_stream.lo
-rm -f src/udp.$(OBJEXT)
-rm -f src/udp.lo
-rm -f src/utils.$(OBJEXT)
-rm -f src/utils.lo
-rm -f src/*.$(OBJEXT)
-rm -f src/*.lo
-rm -f src/dot11/*.$(OBJEXT)
-rm -f src/dot11/*.lo
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/address_range.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/arp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bootp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/crypto.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dhcp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dhcpv6.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dns.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dns_record.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dot11.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dot1q.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dot3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/eapol.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ethernetII.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/handshake_capturer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/icmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/icmpv6.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ieee802_3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/internals.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ip.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ip_address.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ip_reassembler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipsec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipv6.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipv6_address.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/llc.Plo@am__quote@
@@ -557,40 +696,51 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/packet_sender.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/packet_writer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pdu.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ppi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pppoe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/radiotap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rawpdu.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rsn_information.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/snap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sniffer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/stp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tcp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tcp_stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/udp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_assoc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_auth.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_base.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_beacon.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_control.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_data.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_mgmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/dot11/$(DEPDIR)/dot11_probe.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -598,13 +748,17 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-rm -rf src/.libs src/_libs
-rm -rf src/dot11/.libs src/dot11/_libs
distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -619,45 +773,58 @@ uninstall-pkgconfigDATA:
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
install-libtins_includeHEADERS: $(libtins_include_HEADERS)
install-libtinsHEADERS: $(libtins_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(libtins_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libtins_includedir)"
@list='$(libtins_include_HEADERS)'; test -n "$(libtins_includedir)" || list=; \
@list='$(libtins_HEADERS)'; test -n "$(libtinsdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libtinsdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libtinsdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libtins_includedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libtins_includedir)" || exit $$?; \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libtinsdir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libtinsdir)" || exit $$?; \
done
uninstall-libtins_includeHEADERS:
uninstall-libtinsHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libtins_include_HEADERS)'; test -n "$(libtins_includedir)" || list=; \
@list='$(libtins_HEADERS)'; test -n "$(libtinsdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libtins_includedir)'; $(am__uninstall_files_from_dir)
dir='$(DESTDIR)$(libtinsdir)'; $(am__uninstall_files_from_dir)
install-libtins_dot11HEADERS: $(libtins_dot11_HEADERS)
@$(NORMAL_INSTALL)
@list='$(libtins_dot11_HEADERS)'; test -n "$(libtins_dot11dir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libtins_dot11dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libtins_dot11dir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libtins_dot11dir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libtins_dot11dir)" || exit $$?; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
uninstall-libtins_dot11HEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libtins_dot11_HEADERS)'; test -n "$(libtins_dot11dir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libtins_dot11dir)'; $(am__uninstall_files_from_dir)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -669,15 +836,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -686,9 +849,31 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
@@ -731,40 +916,42 @@ distdir: $(DISTFILES)
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
$(am__post_remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
@@ -775,8 +962,6 @@ distcheck: dist
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
@@ -788,18 +973,19 @@ distcheck: dist
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
&& ../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
@@ -822,7 +1008,7 @@ distcheck: dist
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
@@ -856,7 +1042,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libtins_includedir)"; do \
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libtinsdir)" "$(DESTDIR)$(libtins_dot11dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -887,6 +1073,8 @@ distclean-generic:
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f src/$(DEPDIR)/$(am__dirstamp)
-rm -f src/$(am__dirstamp)
-rm -f src/dot11/$(DEPDIR)/$(am__dirstamp)
-rm -f src/dot11/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -898,10 +1086,10 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf src/$(DEPDIR)
-rm -rf src/$(DEPDIR) src/dot11/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
distclean-hdr distclean-libtool distclean-tags
dvi: dvi-am
@@ -915,7 +1103,8 @@ info: info-am
info-am:
install-data-am: install-libtins_includeHEADERS install-pkgconfigDATA
install-data-am: install-libtinsHEADERS install-libtins_dot11HEADERS \
install-pkgconfigDATA
install-dvi: install-dvi-am
@@ -946,7 +1135,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf src/$(DEPDIR)
-rm -rf src/$(DEPDIR) src/dot11/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -963,29 +1152,30 @@ ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES \
uninstall-libtins_includeHEADERS uninstall-pkgconfigDATA
uninstall-am: uninstall-libLTLIBRARIES uninstall-libtinsHEADERS \
uninstall-libtins_dot11HEADERS uninstall-pkgconfigDATA
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \
dist-tarZ dist-xz dist-zip distcheck distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-libLTLIBRARIES \
install-libtins_includeHEADERS install-man install-pdf \
.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
distcheck distclean distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am html html-am info \
info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-libLTLIBRARIES install-libtinsHEADERS \
install-libtins_dot11HEADERS install-man install-pdf \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-libLTLIBRARIES uninstall-libtins_includeHEADERS \
uninstall-pkgconfigDATA
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-libLTLIBRARIES uninstall-libtinsHEADERS \
uninstall-libtins_dot11HEADERS uninstall-pkgconfigDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.

33
README
View File

@@ -1,24 +1,27 @@
------------------------------------------------------------------------
libtins v0.3
libtins v3.0
------------------------------------------------------------------------
-------------------------------- About ---------------------------------
libtins is a C++ library for crafting, sending, sniffing and
interpreting raw network packets.
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 which
show libtins' actual performance, please visit:
In order to read tutorials, examples and checkout some benchmarks of the
library, please visit:
http://libtins.sourceforge.net
http://libtins.github.io/
------------------------------- Compiling ------------------------------
libtins depends on libpcap and openssl, although the latter is not
necessary if some features of the library are disabled.
In order to compile, execute:
./configure
@@ -32,11 +35,23 @@ like to generate a static library file as well, run:
The generated static/shared library files will be located in the .libs
directory.
If you want to enable C++11 features, such as move semantics, use the
--enable-c++11 switch:
libtins is noticeable 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 --enable-c++11 switch:
./configure --enable-c++11
If you want to disable WPA2 decryption support, which will remove
openssl as a dependency for compilation, use the --disable-wpa2 switch:
./configure --disable-wpa2
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 --disable-dot11 switch:
./configure --disable-dot11
------------------------------ Installing-------------------------------
Once you're done, if you want to install the header files and the
@@ -55,4 +70,4 @@ ldconfig
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.sourceforge.net/index.php?page=examples
http://libtins.github.io/examples/

85
README.md Normal file
View File

@@ -0,0 +1,85 @@
libtins
=======
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
./configure
make
```
Note that by default, only the shared object is compiled. If you would
like to generate a static library file as well, run:
```Shell
./configure --enable-static
```
The generated static/shared library files will be located in the .libs
directory.
libtins is noticeable 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 --enable-c++11 switch:
```Shell
./configure --enable-c++11
```
If you want to disable WPA2 decryption support, which will remove
openssl as a dependency for compilation, use the --disable-wpa2 switch:
```Shell
./configure --disable-wpa2
```
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 --disable-dot11 switch:
```Shell
./configure --disable-dot11
```
## 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
```
## 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/

3
THANKS
View File

@@ -1,7 +1,4 @@
We'd like to thank the following people, who have been of great help
through the development of libtins:
- Bruno Nery <brunonery@brunonery.com> - For several bug reports and new
feature requests.
- Raúl Benencia <rbenencia@gmail.com> - For creating the Debian package.

9316
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

11
config.sub vendored
View File

@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
timestamp='2012-02-10'
timestamp='2012-04-18'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -225,6 +225,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@@ -1537,6 +1543,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;

2063
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,7 @@
AC_INIT([libtins], [0.3], [matias.fontanini@gmail.com], [libtins], [http://libtins.sourceforge.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_INIT([libtins], [3.0], [matias.fontanini@gmail.com], [libtins], [http://libtins.sourceforge.net])
AC_CANONICAL_SYSTEM
AC_CONFIG_HEADER(include/config.h)
AM_INIT_AUTOMAKE([-Wall -Werror -Wno-extra-portability foreign])
LT_INIT([disable-static])
AC_CONFIG_MACRO_DIR([m4])
AM_MAINTAINER_MODE([enable])
@@ -9,25 +11,8 @@ AC_LANG(C++)
AC_PROG_LIBTOOL
if test -n "$debug"
then
CXXFLAGS="$CXXFLAGS -DTINS_DEBUG -g"
else
CXXFLAGS="$CXXFLAGS -O3"
fi
CXXFLAGS="$CXXFLAGS -Iinclude"
AC_ARG_ENABLE(
c++11,
[ --enable-c++11 enable C++11 features],
[CXXFLAGS="$CXXFLAGS -std=c++0x"]
)
# Check that libpcap exists
# Get libpcap library and include locations
AC_ARG_WITH([pcap-include-path],
[AS_HELP_STRING([--with-pcap-include-path],
[location of the libpcap headers, defaults to /usr/include/pcap])],
@@ -49,11 +34,52 @@ AC_CHECK_HEADERS([pcap.h], [], [AC_MSG_ERROR([libpcap headers are missing!])])
CPPFLAGS=$old_cppflags
# Options
wpa2_msg="WPA2 decryption(which requires openssl) can be disabled using the --disable-wpa2 flag."
AC_ARG_ENABLE(
c++11,
[ --enable-c++11 enable C++11 features],
[AX_CXX_COMPILE_STDCXX_11(noext)]
)
AC_ARG_ENABLE(
dot11,
[ --disable-dot11 disable IEEE 802.11 support],
[],
[
AC_DEFINE([HAVE_DOT11], 1, Have IEEE 802.11 support)
# Only allow enabling WPA2 if Dot11 is enabled.
AC_ARG_ENABLE(
wpa2,
[ --disable-wpa2 disable WPA2 decryption features],
[],
[
AC_CHECK_HEADERS(
[openssl/evp.h openssl/hmac.h openssl/aes.h],
[],
[AC_MSG_ERROR([openssl headers are missing! $wpa2_msg ])]
AC_DEFINE([HAVE_WPA2_DECRYPTION], 0, Have WPA2 decryption library)
)
AC_CHECK_LIB(
crypto,
PKCS5_PBKDF2_HMAC_SHA1,
[],
[AC_MSG_ERROR([openssl library is missing! $wpa2_msg ])]
)
AC_DEFINE([HAVE_WPA2_DECRYPTION], 1, Have WPA2 decryption library)
]
)
]
)
# Substitute options
AC_SUBST(CXXFLAGS)
AC_SUBST(LIBS)
AC_SUBST(LIBTINS_INCLUDE_DIR)
AC_SUBST([LIBTINS_VERSION], [0:3:0])
AC_SUBST([LIBTINS_VERSION], [3:0:0])
AC_CONFIG_FILES([Makefile libtins.pc])
AC_OUTPUT

124
depcomp
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2011-12-04.11; # UTC
scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011 Free Software Foundation, Inc.
# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ scriptversion=2011-12-04.11; # UTC
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
@@ -40,8 +40,8 @@ as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
@@ -57,6 +57,12 @@ EOF
;;
esac
# A tabulation character.
tab=' '
# A newline character.
nl='
'
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
@@ -102,6 +108,12 @@ if test "$depmode" = msvc7msys; then
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
@@ -156,15 +168,14 @@ gcc)
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
@@ -203,18 +214,15 @@ sgi)
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
@@ -226,10 +234,17 @@ sgi)
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
@@ -259,12 +274,11 @@ aix)
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
@@ -275,23 +289,26 @@ aix)
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
# However on
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
# tcc 0.9.26 (FIXME still under development at the moment of writing)
# will emit a similar output, but also prepend the continuation lines
# with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
@@ -300,15 +317,21 @@ icc)
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Each line is of the form 'foo.o: dependent.h',
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
< "$tmpdepfile" > "$depfile"
sed '
s/[ '"$tab"'][ '"$tab"']*/ /g
s/^ *//
s/ *\\*$//
s/^[^:]*: *//
/^$/d
/:$/d
s/$/ :/
' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
@@ -344,7 +367,7 @@ hp2)
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
@@ -359,9 +382,9 @@ hp2)
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
@@ -407,8 +430,7 @@ tru64)
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
@@ -443,11 +465,11 @@ msvc7)
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/ \1 \\/p
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/ /
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
@@ -478,7 +500,7 @@ dashmstdout)
shift
fi
# Remove `-o $object'.
# Remove '-o $object'.
IFS=" "
for arg
do
@@ -498,15 +520,14 @@ dashmstdout)
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -562,8 +583,7 @@ makedepend)
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -583,7 +603,7 @@ cpp)
shift
fi
# Remove `-o $object'.
# Remove '-o $object'.
IFS=" "
for arg
do
@@ -652,8 +672,8 @@ msvisualcpp)
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;

View File

@@ -1,7 +1,7 @@
CXX=@CXX@
CXXFLAGS=-Wall @CXXFLAGS@
LDFLAGS=-ltins
EXECUTABLES=arpspoof portscan traceroute beacon_display
EXECUTABLES=arpspoofing arpmonitor portscan traceroute beacon_display dns_queries dns_spoof dns_stats wps_detect
all: $(EXECUTABLES)
@@ -9,11 +9,26 @@ compile: $(OBJECTS)
recompile: clean all
arpspoof:
arpspoofing:
$(CXX) arpspoofing.cpp -o arpspoofing $(CXXFLAGS) $(LDFLAGS)
arpmonitor:
$(CXX) arpmonitor.cpp -o arpmonitor -std=c++0x $(CXXFLAGS) $(LDFLAGS)
dns_queries:
$(CXX) dns_queries.cpp -o dns_queries -std=c++0x $(CXXFLAGS) $(LDFLAGS)
dns_spoof:
$(CXX) dns_spoof.cpp -o dns_spoof -std=c++0x $(CXXFLAGS) $(LDFLAGS)
dns_stats:
$(CXX) dns_stats.cpp -o dns_stats -std=c++0x $(CXXFLAGS) $(LDFLAGS) -lpthread
beacon_display:
$(CXX) beacon_display.cpp -o beacon_display $(CXXFLAGS) $(LDFLAGS)
wps_detect:
$(CXX) wps_detect.cpp -o wps_detect -std=c++0x $(CXXFLAGS) $(LDFLAGS)
portscan:
$(CXX) portscan.cpp -o portscan $(CXXFLAGS) $(LDFLAGS) -lpthread

96
examples/arpmonitor.cpp Normal file
View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2014, 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 namespace Tins;
class arp_monitor {
public:
void run(Sniffer &sniffer);
private:
bool callback(const PDU &pdu);
std::map<IPv4Address, HWAddress<6>> addresses;
};
void arp_monitor::run(Sniffer &sniffer)
{
sniffer.sniff_loop(
std::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()});
std::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) {
std::cout << "[WARNING] " << arp.sender_ip_addr() << " is at "
<< iter->second << " but also at " << arp.sender_hw_addr()
<< std::endl;
}
}
}
return true;
}
int main(int argc, char *argv[])
{
if(argc != 2) {
std::cout << "Usage: " << *argv << " <interface>\n";
return 1;
}
arp_monitor monitor;
// Sniff on the provided interface in promiscuous mode
Sniffer sniffer(argv[1], Sniffer::PROMISC);
// Only capture arp packets
sniffer.set_filter("arp");
monitor.run(sniffer);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
#include <string>
#include <stdexcept>
#include <cstdlib>
#include <unistd.h>
#include <tins/arp.h>
#include <tins/network_interface.h>
#include <tins/utils.h>
@@ -42,23 +43,18 @@ using namespace std;
using namespace Tins;
int do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address victim,
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,22 +62,22 @@ 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);
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);
sender.send(to_gw, iface);
sender.send(to_victim, iface);
sleep(5);
}
}
@@ -115,7 +111,7 @@ int main(int argc, char *argv[]) {
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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,17 +47,17 @@ private:
};
void BeaconSniffer::run(const std::string &iface) {
Sniffer sniffer(iface, 1500, true, "type mgt subtype beacon");
Sniffer sniffer(iface, Sniffer::PROMISC, "type mgt subtype beacon", true);
sniffer.sniff_loop(make_sniffer_handler(this, &BeaconSniffer::callback));
}
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()) {
@@ -66,7 +66,7 @@ bool BeaconSniffer::callback(PDU &pdu) {
/* If no ssid option is set, then Dot11::ssid will throw
* a std::runtime_error.
*/
std::string ssid = beacon->ssid();
std::string ssid = beacon.ssid();
// Save it so we don't show it again.
ssids.insert(addr);
// Display the tuple "address - ssid".

460
examples/configure vendored
View File

@@ -1,11 +1,9 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.67 for myconfig 0.1.
# Generated by GNU Autoconf 2.69 for myconfig 0.1.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
# Foundation, Inc.
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -89,6 +87,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -133,6 +132,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# Use a proper internal environment variable to ensure we don't fall
# into an infinite loop, continuously re-executing ourselves.
if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
_as_can_reexec=no; export _as_can_reexec;
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;;
*x* ) as_opts=-x ;;
* ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
fi
# We don't want this to propagate to other subprocesses.
{ _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -166,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1"
test x\$exitcode = x0 || exit 1
test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -211,14 +236,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
export CONFIG_SHELL
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;;
*x* ) as_opts=-x ;;
* ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi
if test x$as_have_required = xno; then :
@@ -320,6 +356,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -441,6 +485,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
# If we had to re-execute with $CONFIG_SHELL, we're ensured to have
# already done that, so ensure we don't try to do so again and fall
# in an infinite loop. This has already happened in practice.
_as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -475,16 +523,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -p'.
# In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -p'
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -496,28 +544,8 @@ else
as_mkdir_p=false
fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x'
else
if ls -dL / >/dev/null 2>&1; then
as_ls_L_option=L
else
as_ls_L_option=
fi
as_test_x='
eval sh -c '\''
if test -d "$1"; then
test -d "$1/.";
else
case $1 in #(
-*)set "./$1";;
esac;
case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
???[sx]*):;;*)false;;esac;fi
'\'' sh
'
fi
as_executable_p=$as_test_x
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -592,7 +620,6 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
CFLAGS
EGREP
GREP
CXXCPP
@@ -1059,7 +1086,7 @@ Try \`$0 --help' for more information"
$as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
$as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
: ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
: "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
@@ -1110,8 +1137,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
$as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1339,9 +1364,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
myconfig configure 0.1
generated by GNU Autoconf 2.67
generated by GNU Autoconf 2.69
Copyright (C) 2010 Free Software Foundation, Inc.
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1385,11 +1410,57 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_compile
# ac_fn_cxx_try_link LINENO
# -------------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_cxx_try_link ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext conftest$ac_exeext
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_cxx_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
test -x conftest$ac_exeext
}; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_link
# ac_fn_cxx_try_cpp LINENO
# ------------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1422,7 +1493,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_cpp
@@ -1435,10 +1506,10 @@ fi
ac_fn_cxx_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if eval "test \"\${$3+set}\"" = set; then :
if eval \${$3+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval "test \"\${$3+set}\"" = set; then :
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
@@ -1501,7 +1572,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval "test \"\${$3+set}\"" = set; then :
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
@@ -1510,7 +1581,7 @@ eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_header_mongrel
@@ -1551,7 +1622,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=$ac_status
fi
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_run
@@ -1565,7 +1636,7 @@ ac_fn_cxx_check_header_compile ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval "test \"\${$3+set}\"" = set; then :
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1583,61 +1654,15 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_header_compile
# ac_fn_cxx_try_link LINENO
# -------------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_cxx_try_link ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext conftest$ac_exeext
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_cxx_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_link
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by myconfig $as_me 0.1, which was
generated by GNU Autoconf 2.67. Invocation command line was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -1895,7 +1920,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
fi
done
@@ -2001,7 +2026,7 @@ if test -z "$CXX"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_prog_CXX+set}" = set; then :
if ${ac_cv_prog_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CXX"; then
@@ -2013,7 +2038,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2045,7 +2070,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
if ${ac_cv_prog_ac_ct_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CXX"; then
@@ -2057,7 +2082,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -2209,7 +2234,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C++ compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -2252,7 +2277,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -2311,7 +2336,7 @@ $as_echo "$ac_try_echo"; } >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C++ compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
@@ -2322,7 +2347,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if test "${ac_cv_objext+set}" = set; then :
if ${ac_cv_objext+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2363,7 +2388,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -2373,7 +2398,7 @@ OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
if ${ac_cv_cxx_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2410,7 +2435,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set}
ac_save_CXXFLAGS=$CXXFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
$as_echo_n "checking whether $CXX accepts -g... " >&6; }
if test "${ac_cv_prog_cxx_g+set}" = set; then :
if ${ac_cv_prog_cxx_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
@@ -2499,13 +2524,30 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
if test -n "$debug"
then
CFLAGS="-DDEBUG -g"
else
CFLAGS="-O3"
fi
saved_libs="${LIBS}"
LIBS="${LIBS} -ltins"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking libtins" >&5
$as_echo_n "checking libtins... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <tins/dns.h>
int
main ()
{
Tins::DNS dummy
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
echo done
else
echo error; echo *** libtins is not installed. Aborting... ***; exit 1
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS="${saved_libs}"
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
@@ -2515,7 +2557,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
if test -z "$CXXCPP"; then
if test "${ac_cv_prog_CXXCPP+set}" = set; then :
if ${ac_cv_prog_CXXCPP+:} false; then :
$as_echo_n "(cached) " >&6
else
# Double quotes because CXXCPP needs to be expanded
@@ -2631,7 +2673,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5 ; }
See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=cpp
@@ -2643,7 +2685,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if test "${ac_cv_path_GREP+set}" = set; then :
if ${ac_cv_path_GREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$GREP"; then
@@ -2657,7 +2699,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -2706,7 +2748,7 @@ $as_echo "$ac_cv_path_GREP" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if test "${ac_cv_path_EGREP+set}" = set; then :
if ${ac_cv_path_EGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -2723,7 +2765,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
{ test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -2773,7 +2815,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if test "${ac_cv_header_stdc+set}" = set; then :
if ${ac_cv_header_stdc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2900,65 +2942,20 @@ fi
done
for ac_header in pcap.h
for ac_header in tins/tins.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "pcap.h" "ac_cv_header_pcap_h" "$ac_includes_default"
if test "x$ac_cv_header_pcap_h" = x""yes; then :
ac_fn_cxx_check_header_mongrel "$LINENO" "tins/tins.h" "ac_cv_header_tins_tins_h" "$ac_includes_default"
if test "x$ac_cv_header_tins_tins_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_PCAP_H 1
#define HAVE_TINS_TINS_H 1
_ACEOF
else
echo "*** Error: libtins' headers are absent ***"; exit 1;
fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_loop in -lpcap" >&5
$as_echo_n "checking for pcap_loop in -lpcap... " >&6; }
if test "${ac_cv_lib_pcap_pcap_loop+set}" = set; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpcap $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pcap_loop ();
int
main ()
{
return pcap_loop ();
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
ac_cv_lib_pcap_pcap_loop=yes
else
ac_cv_lib_pcap_pcap_loop=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcap_pcap_loop" >&5
$as_echo "$ac_cv_lib_pcap_pcap_loop" >&6; }
if test "x$ac_cv_lib_pcap_pcap_loop" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBPCAP 1
_ACEOF
LIBS="-lpcap $LIBS"
else
as_fn_error $? "pcap library is needed!" "$LINENO" 5
fi
ac_config_files="$ac_config_files Makefile"
@@ -3026,10 +3023,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
test "x$cache_file" != "x/dev/null" &&
if test "x$cache_file" != "x/dev/null"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
cat confcache >$cache_file
if test ! -f "$cache_file" || test -h "$cache_file"; then
cat confcache >"$cache_file"
else
case $cache_file in #(
*/* | ?:*)
mv -f confcache "$cache_file"$$ &&
mv -f "$cache_file"$$ "$cache_file" ;; #(
*)
mv -f confcache "$cache_file" ;;
esac
fi
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -3097,7 +3105,7 @@ LTLIBOBJS=$ac_ltlibobjs
: ${CONFIG_STATUS=./config.status}
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -3198,6 +3206,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3393,16 +3402,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -p'.
# In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -p'
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -p'
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -3462,28 +3471,16 @@ else
as_mkdir_p=false
fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x'
else
if ls -dL / >/dev/null 2>&1; then
as_ls_L_option=L
else
as_ls_L_option=
fi
as_test_x='
eval sh -c '\''
if test -d "$1"; then
test -d "$1/.";
else
case $1 in #(
-*)set "./$1";;
esac;
case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
???[sx]*):;;*)false;;esac;fi
'\'' sh
'
fi
as_executable_p=$as_test_x
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -3505,7 +3502,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling.
ac_log="
This file was extended by myconfig $as_me 0.1, which was
generated by GNU Autoconf 2.67. Invocation command line was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -3558,10 +3555,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
myconfig config.status 0.1
configured by $0, generated by GNU Autoconf 2.67,
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
Copyright (C) 2010 Free Software Foundation, Inc.
Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -3638,7 +3635,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -3669,7 +3666,7 @@ do
case $ac_config_target in
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -3690,9 +3687,10 @@ fi
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
tmp=
tmp= ac_tmp=
trap 'exit_status=$?
{ test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
: "${ac_tmp:=$tmp}"
{ test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
@@ -3700,12 +3698,13 @@ $debug ||
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
@@ -3727,7 +3726,7 @@ else
ac_cs_awk_cr=$ac_cr
fi
echo 'BEGIN {' >"$tmp/subs1.awk" &&
echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF
@@ -3755,7 +3754,7 @@ done
rm -f conf$$subs.sh
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h
@@ -3803,7 +3802,7 @@ t delim
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
cat >>"\$tmp/subs1.awk" <<_ACAWK &&
cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
@@ -3835,7 +3834,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
|| as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
@@ -3875,7 +3874,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
:L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
:L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -3894,7 +3893,7 @@ do
for ac_f
do
case $ac_f in
-) ac_f="$tmp/stdin";;
-) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
@@ -3903,7 +3902,7 @@ do
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -3929,8 +3928,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
esac
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
*:-:* | *:-) cat >"$ac_tmp/stdin" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
@@ -4055,21 +4054,22 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
>$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
"$ac_tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$tmp/stdin"
rm -f "$ac_tmp/stdin"
case $ac_file in
-) cat "$tmp/out" && rm -f "$tmp/out";;
*) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
-) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
*) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
esac \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;

View File

@@ -3,14 +3,15 @@ AC_INIT(myconfig, 0.1)
AC_PROG_CXX()
AC_LANG(C++)
if test -n "$debug"
then
CFLAGS="-DDEBUG -g"
else
CFLAGS="-O3"
fi
saved_libs="${LIBS}"
LIBS="${LIBS} -ltins"
AC_MSG_CHECKING(libtins)
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <tins/dns.h>],
[Tins::DNS dummy])],
[echo done],
[echo error; echo *** libtins is not installed. Aborting... ***; exit 1])
LIBS="${saved_libs}"
AC_CHECK_HEADERS([tins/tins.h], , [echo "*** Error: libtins' headers are absent ***"; exit 1;])
AC_CHECK_HEADERS([pcap.h])
AC_CHECK_LIB(pcap, pcap_loop, [], [AC_MSG_ERROR([pcap library is needed!])])
AC_SUBST(CFLAGS)
AC_OUTPUT(Makefile)

65
examples/dns_queries.cpp Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2014, 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 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())
std::cout << query.dname() << std::endl;
return true;
}
int main(int argc, char *argv[])
{
if(argc != 2) {
std::cout << "Usage: " << *argv << " <interface>" << std::endl;
return 1;
}
// Sniff on the provided interface in promiscuos mode
Sniffer sniffer(argv[1], Sniffer::PROMISC);
// Only capture udp packets sent to port 53
sniffer.set_filter("udp and dst port 53");
// Start the capture
sniffer.sniff_loop(callback);
}

103
examples/dns_spoof.cpp Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2014, 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 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.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) {
std::cout << "Usage: " << *argv << " <interface>" << std::endl;
return 1;
}
// Sniff on the provided interface in promiscuos mode
Sniffer sniffer(argv[1], Sniffer::PROMISC);
// Only capture udp packets sent to port 53
sniffer.set_filter("udp and dst port 53");
// All packets will be sent through the provided interface
sender.default_interface(argv[1]);
// Start the capture
sniffer.sniff_loop(callback);
}

189
examples/dns_stats.cpp Normal file
View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2014, 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 <mutex>
#include <chrono>
#include <map>
#include <thread>
#include <algorithm>
#include <tins/tins.h>
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:
using duration_type = Duration;
using locker_type = std::lock_guard<std::mutex>;
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 = std::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 std::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
using duration_type = std::chrono::milliseconds;
// The statistics type used.
using statistics_type = statistics<duration_type>;
void run(BaseSniffer& sniffer);
const statistics_type& stats() const {
return m_stats;
}
private:
using packet_info = std::tuple<IPv4Address, IPv4Address, uint16_t>;
using clock_type = std::chrono::steady_clock;
using time_point_type = std::chrono::time_point<clock_type>;
bool callback(const PDU& pdu);
static packet_info make_packet_info(const PDU& pdu, const DNS& dns);
statistics_type m_stats;
std::map<packet_info, time_point_type> m_packet_info;
};
void dns_monitor::run(BaseSniffer& sniffer)
{
sniffer.sniff_loop(
std::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(
std::chrono::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 std::make_tuple(
// smallest address first
std::min(ip.src_addr(), ip.dst_addr()),
// largest address second
std::max(ip.src_addr(), ip.dst_addr()),
dns.id()
);
}
int main(int argc, char *argv[]) {
if(argc != 2) {
std::cout << "Usage: " << *argv << " <interface>\n";
return 1;
}
try {
Sniffer sniffer(argv[1], Sniffer::PROMISC);
sniffer.set_filter("udp and port 53");
dns_monitor monitor;
std::thread thread(
[&]() {
monitor.run(sniffer);
}
);
while(true) {
auto info = monitor.stats().get_information();
std::cout << "\rAverage " << info.average.count()
<< "ms. Worst: " << info.worst.count() << "ms. Count: "
<< info.count;
std::cout.flush();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch(std::exception& ex) {
std::cout << "[-] Error: " << ex.what() << std::endl;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
#include <string>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <tins/ip.h>
#include <tins/tcp.h>
#include <tins/ip_address.h>
@@ -53,19 +54,17 @@ typedef std::pair<Sniffer*, std::string> sniffer_data;
* the scanned port's status.
*/
bool handler(PDU &pdu) {
TCP *tcp = pdu.find_pdu<TCP>();
if(tcp) {
// Ok, it's a TCP PDU. Is RST flag on? Then port is closed.
if(tcp->get_flag(TCP::RST)) {
// This indicates we should stop sniffing.
if(tcp->get_flag(TCP::SYN))
return false;
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";
const TCP &tcp = pdu.rfind_pdu<TCP>();
// Ok, it's a TCP PDU. Is RST flag on? Then port is closed.
if(tcp.get_flag(TCP::RST)) {
// This indicates we should stop sniffing.
if(tcp.get_flag(TCP::SYN))
return false;
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
}
// Is SYN flag on? Then port is open!
else if(tcp.flags() == (TCP::SYN | TCP::ACK))
cout << "Port: " << setw(5) << tcp.sport() << " open\n";
return true;
}
@@ -74,17 +73,18 @@ void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<
// 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) {
// Set the new port and send the packet!
tcp->dport(atoi(it->c_str()));
tcp.dport(atoi(it->c_str()));
sender.send(ip);
}
// Wait 1 second.
@@ -92,12 +92,12 @@ 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);
// 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) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,11 @@ public:
PacketSender sender;
// Create our handler
auto handler = make_sniffer_handler(this, &Traceroute::sniff_callback);
auto handler = std::bind(
&Traceroute::sniff_callback,
this,
std::placeholders::_1
);
// We're running
running = true;
// Start the sniff thread
@@ -74,7 +78,7 @@ private:
void send_packets(PacketSender &sender) {
// ICMPs are icmp-requests by default
IP ip(addr, iface.addresses().ip_addr, new ICMP());
IP ip = IP(addr, iface.addresses().ip_addr) / ICMP();
// We'll find at most 10 hops.
for(auto i = 1; i <= 10; ++i) {
@@ -98,30 +102,20 @@ private:
}
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());
}
const IP &ip = pdu.rfind_pdu<IP>();
ttl_map::const_iterator iter;
// Fetch the IP PDU attached to the ICMP response
const IP inner_ip = pdu.rfind_pdu<RawPDU>().to<IP>();
// Critical section
{
std::lock_guard<std::mutex> _(lock);
iter = ttls.find(inner_ip.id());
}
// It's an actual response
if(iter != ttls.end()) {
// Store it
results[inner_ip.id()] = ip->src_addr();
}
// It's an actual response
if(iter != ttls.end()) {
// Store it
results[inner_ip.id()] = ip.src_addr();
}
return running;
}

74
examples/wps_detect.cpp Normal file
View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2014, 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
Sniffer sniffer(argv[1], 2000, true, "wlan type mgt subtype beacon");
sniffer.sniff_loop(handler);
}

331
include/address_range.h Normal file
View File

@@ -0,0 +1,331 @@
/*
* Copyright (c) 2014, 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 <stdexcept>
#include <iterator>
#include "endianness.h"
#include "internals.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 &addr)
: addr(addr), reached_end(false)
{
}
/**
* Constructs an iterator.
*
* \param first The address held by this iterator.
*/
AddressRangeIterator(const value_type &address, end_iterator)
: addr(address)
{
reached_end = Internals::increment(addr);
}
/**
* Retrieves the current address pointed by this iterator.
*/
const value_type& operator*() const {
return addr;
}
/**
* Retrieves a pointer to the current address pointed by this iterator.
*/
const value_type* operator->() const {
return &addr;
}
/**
* 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 && addr == rhs.addr;
}
/**
* 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(addr);
return *this;
}
/**
* Increments this iterator.
*/
AddressRangeIterator operator++(int) {
AddressRangeIterator copy(*this);
(*this)++;
return copy;
}
private:
Address addr;
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 std::runtime_error("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,
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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,10 +71,18 @@ namespace Tins {
};
/**
* \brief Default constructor for ARP PDU objects.
*
* \brief Constructs an ARP object using the provided addresses.
*
* ARP requests and replies can be constructed easily using
* ARP::make_arp_request/reply static functions.
* 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(),
@@ -82,8 +90,14 @@ namespace Tins {
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.
* \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.
*/
@@ -119,41 +133,42 @@ namespace Tins {
ipaddress_type target_ip_addr() const { return ipaddress_type(_arp.ar_tip); }
/**
* \brief Getter for the hardware address format.
* \brief Getter for the hardware address format field.
*
* \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.
* \brief Getter for the protocol address format field.
*
* \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.
* \brief Getter for the hardware address length field.
*
* \return The hardware address length.
*/
uint8_t hw_addr_length() const { return _arp.ar_hln; }
/**
* \brief Getter for the protocol address length.
* \brief Getter for the protocol address length field.
*
* \return The protocol address length.
*/
uint8_t prot_addr_length() const { return _arp.ar_pln; }
/**
* \brief Getter for the ARP opcode.
* \brief Getter for the ARP opcode field.
*
* \return The ARP opcode.
*/
uint16_t opcode() const { return Endian::be_to_host(_arp.ar_op); }
/** \brief Getter for the header size.
/**
* \brief Getter for the header size.
* \return Returns the ARP header size.
* \sa PDU::header_size
*/
@@ -189,35 +204,35 @@ namespace Tins {
void target_ip_addr(ipaddress_type new_tgt_ip_addr);
/**
* \brief Setter for the hardware address format.
* \brief Setter for the hardware address format field.
*
* \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.
* \brief Setter for the protocol address format field.
*
* \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.
* \brief Setter for the hardware address length field.
*
* \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.
* \brief Setter for the protocol address length field.
*
* \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.
* \brief Setter for the ARP opcode field.
*
* \param new_opcode Flag enum value of the ARP opcode to set.
*/
@@ -227,57 +242,46 @@ namespace Tins {
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::ARP; }
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Creates an ARP Request within a Layer 2 PDU using uint32_t for target and sender.
* \brief Creates an ARP Request within an EthernetII PDU.
*
* 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.
* Creates an ARP Request PDU and embeds it inside an EthernetII
* PDU.
*
* \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.
* \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(const NetworkInterface& iface, ipaddress_type target,
static EthernetII make_arp_request(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.
* \brief Creates an ARP Reply within an EthernetII PDU.
*
* 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.
* Creates an ARP Reply PDU and embeds it inside an EthernetII
* PDU.
*
* \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.
* \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 EthetnetII containing the ARP Replay.
*/
static EthernetII make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
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 wether ptr points to a valid response for this PDU.
/**
* \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);
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \sa PDU::clone

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -84,8 +84,11 @@ namespace Tins {
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.
* \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.
@@ -272,7 +275,8 @@ namespace Tins {
_bootp.chaddr
);
// Fill what's left with zeros
std::fill(end, _bootp.chaddr + chaddr_type::address_size, 0);
if(end < _bootp.chaddr + chaddr_type::address_size)
std::fill(end, _bootp.chaddr + chaddr_type::address_size, 0);
}
/**
@@ -293,11 +297,22 @@ namespace Tins {
*/
void vend(const vend_type &new_vend);
/**
* \brief Check wether 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::BOOTP; }
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone

89
include/config.h.in Normal file
View File

@@ -0,0 +1,89 @@
/* include/config.h.in. Generated from configure.ac by autoheader. */
/* define if the compiler supports basic C++11 syntax */
#undef HAVE_CXX11
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Have IEEE 802.11 support */
#undef HAVE_DOT11
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `pcap' library (-lpcap). */
#undef HAVE_LIBPCAP
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <openssl/aes.h> header file. */
#undef HAVE_OPENSSL_AES_H
/* Define to 1 if you have the <openssl/evp.h> header file. */
#undef HAVE_OPENSSL_EVP_H
/* Define to 1 if you have the <openssl/hmac.h> header file. */
#undef HAVE_OPENSSL_HMAC_H
/* Define to 1 if you have the <pcap.h> header file. */
#undef HAVE_PCAP_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Have WPA2 decryption library */
#undef HAVE_WPA2_DECRYPTION
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -84,6 +84,7 @@ namespace Tins {
VLAN = 0x8100, /* IEEE 802.1Q VLAN tagging */
IPX = 0x8137, /* IPX */
IPV6 = 0x86dd, /* IP protocol version 6 */
PPPOED = 0x8863, /* PPPoE Discovery */
EAPOL = 0x888e, /* EAPOL */
LOOPBACK = 0x9000 /* used to test interfaces */
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,22 +27,72 @@
*
*/
#ifndef TINS_CRYPTO_H
#include "config.h"
#if !defined(TINS_CRYPTO_H) && defined(HAVE_DOT11)
#define TINS_CRYPTO_H
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include "dot11.h"
#include "utils.h"
#include "snap.h"
#include "rawpdu.h"
#include "handshake_capturer.h"
namespace Tins {
class PDU;
class Dot11;
class Dot11Data;
namespace Crypto {
/**
* \cond
*/
struct RC4Key;
#ifdef HAVE_WPA2_DECRYPTION
namespace WPA2 {
class invalid_handshake : public std::exception {
public:
const char *what() const throw() {
return "invalid handshake";
}
};
class SessionKeys {
public:
typedef Internals::byte_array<80> ptk_type;
typedef Internals::byte_array<32> pmk_type;
SessionKeys();
SessionKeys(const RSNHandshake &hs, const pmk_type &pmk);
SNAP *decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const;
private:
SNAP *ccmp_decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const;
SNAP *tkip_decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const;
RC4Key generate_rc4_key(const Dot11Data &dot11, const RawPDU &raw) const;
ptk_type ptk;
bool is_ccmp;
};
class SupplicantData {
public:
typedef HWAddress<6> address_type;
typedef SessionKeys::pmk_type pmk_type;
SupplicantData(const std::string &psk, const std::string &ssid);
const pmk_type &pmk() const;
private:
pmk_type pmk_;
};
}
#endif // HAVE_WPA2_DECRYPTION
/**
* \endcond
*/
/**
* \brief RC4 Key abstraction.
*/
@@ -65,11 +115,11 @@ namespace Crypto {
};
/**
*
* \brief Decrypts WEP-encrypted traffic.
*/
class WEPDecrypter {
public:
typedef Dot11::address_type address_type;
typedef HWAddress<6> address_type;
/**
* \brief Constructs a WEPDecrypter object.
@@ -93,19 +143,18 @@ namespace Crypto {
void remove_password(const address_type &addr);
/**
* \brief Decrypts the provided PDU and forwards the decrypted
* PDU to the functor held by this object.
* \brief Decrypts the provided PDU.
*
* 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.
* If the CRC found after decrypting is invalid, false is
* returned.
*
* \return false if decryption failed due to invalid CRC, true
* otherwise.
* \return false if no decryption was performed or decryption
* failed, true otherwise.
*/
bool decrypt(PDU &pdu);
private:
@@ -117,6 +166,96 @@ namespace Crypto {
std::vector<uint8_t> key_buffer;
};
#ifdef HAVE_WPA2_DECRYPTION
/**
* \brief Decrypts WPA2-encrypted traffic.
*
* This class takes valid PSK and SSID tuples, captures client handshakes,
* and decrypts their traffic afterwards.
*/
class WPA2Decrypter {
public:
/*
* \brief The type used to store Dot11 addresses.
*/
typedef HWAddress<6> address_type;
/**
* \brief Adds an access points's information.
*
* This associates an SSID with a PSK, and allows the decryption of
* any BSSIDs that broadcast the same SSID.
*
* The decrypter will inspect beacon frames, looking for SSID tags
* that contain the given SSID.
*
* Note that using this overload, the decryption of data frames and
* handshake capturing will be disabled until any access point
* broadcasts the provided SSID(this shouldn't take long at all).
* If this is not the desired behaviour, then you should check out
* the ovther add_ap_data overload.
*
* \param psk The PSK associated with the SSID.
* \param ssid The network's SSID.
*/
void add_ap_data(const std::string &psk, const std::string &ssid);
/**
* \brief Adds a access points's information, including its BSSID.
*
* This overload can be used if the BSSID associated with this SSID is
* known beforehand. The addr parameter indicates which specific BSSID
* is associated to the SSID.
*
* Note that if any other access point broadcasts the provided SSID,
* it will be taken into account as well.
*
* \param psk The PSK associated with this SSID.
* \param ssid The network's SSID.
* \param addr The access point's BSSID.
*/
void add_ap_data(const std::string &psk, const std::string &ssid, const address_type &addr);
/**
* \brief Decrypts the provided PDU.
*
* A Dot11Data PDU is looked up inside the provided PDU chain.
* If no such PDU exists or no PSK was associated with the SSID
* broadcasted by the Dot11 packet's BSSID, or no EAPOL handshake
* was captured for the client involved in the communication,
* then the PDU is left intact.
*
* Otherwise, the packet is decrypted using the generated PTK.
* If the resulting MIC is invalid, then the packet is left intact.
*
* \return false if no decryption was performed, or the decryption
* failed, true otherwise.
*/
bool decrypt(PDU &pdu);
private:
typedef std::map<std::string, WPA2::SupplicantData> pmks_map;
typedef std::map<address_type, WPA2::SupplicantData> bssids_map;
typedef std::pair<address_type, address_type> addr_pair;
typedef std::map<addr_pair, WPA2::SessionKeys> keys_map;
void try_add_keys(const Dot11Data &dot11, const RSNHandshake &hs);
addr_pair make_addr_pair(const address_type &addr1, const address_type &addr2) {
return (addr1 < addr2) ?
std::make_pair(addr1, addr2) :
std::make_pair(addr2, addr1);
}
addr_pair extract_addr_pair(const Dot11Data &dot11);
addr_pair extract_addr_pair_dst(const Dot11Data &dot11);
bssids_map::const_iterator find_ap(const Dot11Data &dot11);
void add_access_point(const std::string &ssid, const address_type &addr);
RSNHandshakeCapturer capturer;
pmks_map pmks;
bssids_map aps;
keys_map keys;
};
#endif // HAVE_WPA2_DECRYPTION
/**
* \brief Pluggable decrypter object which can be used to decrypt
* data on sniffing sessions.
@@ -183,7 +322,7 @@ namespace Crypto {
void rc4(ForwardIterator start, ForwardIterator end, RC4Key &key, OutputIterator output);
/**
* \brief Wrapper function to create DecrypterProxyes using a
* \brief Wrapper function to create a DecrypterProxy using a
* WEPDecrypter as the Decrypter template parameter.
*
* \param functor The functor to be forwarded to the DecrypterProxy
@@ -191,6 +330,20 @@ namespace Crypto {
*/
template<typename Functor>
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor &functor);
#ifdef HAVE_WPA2_DECRYPTION
/**
* \brief Wrapper function to create a DecrypterProxy using a
* WPA2Decrypter as the Decrypter template parameter.
*
* \param functor The functor to be forwarded to the DecrypterProxy
* constructor.
*/
template<typename Functor>
DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor &functor) {
return DecrypterProxy<Functor, WPA2Decrypter>(functor);
}
#endif // HAVE_WPA2_DECRYPTION
// Implementation section
@@ -229,7 +382,7 @@ namespace Crypto {
{
return DecrypterProxy<Functor, WEPDecrypter>(functor);
}
// RC4 stuff
template<typename ForwardIterator>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,12 +30,29 @@
#ifndef TINS_CXXSTD_H
#define TINS_CXXSTD_H
#include <memory>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#define TINS_CXXSTD_GCC_FIX 1
#else
#define TINS_CXXSTD_GCC_FIX 0
#endif // __GXX_EXPERIMENTAL_CXX0X__
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
#ifndef TINS_IS_CXX11
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1 || _MSC_VER >= 1800)
#endif // TINS_IS_CXX11
namespace Tins{
namespace Internals {
template<typename T>
struct smart_ptr {
#if TINS_IS_CXX11
typedef std::unique_ptr<T> type;
#else
typedef std::auto_ptr<T> type;
#endif
};
}
}
#endif // TINS_CXXSTD_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,15 +32,19 @@
#include <list>
#include <vector>
#include <string>
#include "bootp.h"
#include "pdu_option.h"
#include "cxxstd.h"
namespace Tins {
/**
* \brief Class that represents the DHCP PDU.
*
* The end option is added automatically at the end of the option list.
*
* When adding options, the "End" option is not added automatically.
*
* \sa DHCP::end
*/
class DHCP : public BootP {
public:
@@ -66,7 +70,7 @@ namespace Tins {
/**
* \brief DHCP options enum.
*/
enum Options {
enum OptionTypes {
PAD,
SUBNET_MASK,
TIME_OFFSET,
@@ -142,12 +146,12 @@ namespace Tins {
/**
* The DHCP option type.
*/
typedef PDUOption<uint8_t> dhcp_option;
typedef PDUOption<uint8_t, DHCP> option;
/**
* The type used to store the DHCP options.
*/
typedef std::list<dhcp_option> options_type;
typedef std::list<option> options_type;
/**
* \brief Creates an instance of DHCP.
@@ -158,35 +162,57 @@ namespace Tins {
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.
* \brief Constructs a DHCP object from a buffer.
*
* If there is not enough size for a BootP header, or any of
* the TLV options contains an invalid size field, 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.
* 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.
* \param opt The option to be added.
*/
void add_option(const dhcp_option &option);
void add_option(const option &opt);
#if TINS_IS_CXX11
/**
* \brief Adds a new option to this DHCP PDU.
*
* The option is move-constructed.
*
* \param opt The option to be added.
*/
void add_option(option &&opt) {
internal_add_option(opt);
_options.push_back(std::move(opt));
}
#endif
/**
* \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;
const option *search_option(OptionTypes opt) const;
/**
* \brief Adds a type option the the option list.
* \brief Adds a type option to the option list.
*
* The new option is appended at the end of the list.
*
* \param type The type of this DHCP PDU.
*/
void type(Flags type);
/**
* \brief Adds an end option the the option list.
* \brief Adds an end option to the option list.
*
* The new option is appended at the end of the 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
@@ -196,70 +222,109 @@ namespace Tins {
/**
* \brief Adds a server identifier option.
* \param ip The ip of the server.
*
* The new option is appended at the end of the list.
*
* \param ip The server's IP address.
*/
void server_identifier(ipaddress_type ip);
/**
* \brief Adds an IP address lease time option.
*
* The new option is appended at the end of the list.
*
* \param time The lease time.
*/
void lease_time(uint32_t time);
/**
* \brief Adds a lease renewal time option.
*
* The new option is appended at the end of the list.
*
* \param time The lease renew time.
*/
void renewal_time(uint32_t time);
/**
* \brief Adds a rebind time option.
*
* The new option is appended at the end of the list.
*
* \param time The lease rebind time.
*/
void rebind_time(uint32_t time);
/**
* \brief Adds a subnet mask option.
*
* The new option is appended at the end of the list.
*
* \param mask The subnet mask.
*/
void subnet_mask(ipaddress_type mask);
/**
* \brief Adds a routers option.
*
* The new option is appended at the end of the list.
*
* \param routers A list of ip addresses.
*/
void routers(const std::list<ipaddress_type> &routers);
void routers(const std::vector<ipaddress_type> &routers);
/**
* \brief Adds a domain name servers option.
*
* The new option is appended at the end of the list.
*
* \param dns A list of ip addresses.
*/
void domain_name_servers(const std::list<ipaddress_type> &dns);
void domain_name_servers(const std::vector<ipaddress_type> &dns);
/**
* \brief Adds a broadcast address option.
*
* The new option is appended at the end of the list.
*
* \param addr The broadcast address.
*/
void broadcast(ipaddress_type addr);
/**
* \brief Adds a requested address option.
*
* The new option is appended at the end of the list.
*
* \param addr The requested address.
*/
void requested_ip(ipaddress_type addr);
/**
* \brief Adds a domain name option.
*
* The new option is appended at the end of the list.
*
* \param name The domain name.
*/
void domain_name(const std::string &name);
/**
* \brief Adds a hostname option.
*
* The new option is appended at the end of the list.
*
* \param name The hostname.
*/
void hostname(const std::string &name);
// Option getters
/**
* \brief Searchs for a type option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return uint8_t containing the type option.
@@ -269,7 +334,7 @@ namespace Tins {
/**
* \brief Searchs for a server identifier option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the server identifier.
@@ -279,7 +344,7 @@ namespace Tins {
/**
* \brief Searchs for a lease time option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return uint32_t Containing the lease time.
@@ -289,7 +354,7 @@ namespace Tins {
/**
* \brief Searchs for a lease renewal time option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return uint32_t Containing the renewal time.
@@ -299,7 +364,7 @@ namespace Tins {
/**
* \brief Searchs for a rebind time option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return uint32_t Containing the rebind time.
@@ -309,7 +374,7 @@ namespace Tins {
/**
* \brief Searchs for a subnet mask option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the subnet mask.
@@ -319,29 +384,29 @@ namespace Tins {
/**
* \brief Searchs for a routers option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return std::list<ipaddress_type> Containing the routers
* \return std::vector<ipaddress_type> Containing the routers
* option data.
*/
std::list<ipaddress_type> routers() const;
std::vector<ipaddress_type> routers() const;
/**
* \brief Searchs for a dns option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return std::list<ipaddress_type> Contanining the DNS servers
* provided.
*/
std::list<ipaddress_type> domain_name_servers() const;
std::vector<ipaddress_type> domain_name_servers() const;
/**
* \brief Searchs for a broadcast option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the broadcast address.
@@ -351,7 +416,7 @@ namespace Tins {
/**
* \brief Searchs for a requested option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return ipaddress_type Containing the requested IP address.
@@ -361,14 +426,25 @@ namespace Tins {
/**
* \brief Searchs for a domain name option.
*
* If the option is not found, a option_not_found exception
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return std::string Containing the domain name.
*/
std::string domain_name() const;
/**
* \brief Searchs for a hostname option.
*
* If the option is not found, an option_not_found exception
* is thrown.
*
* \return std::string Containing the hostname.
*/
std::string hostname() const;
/** \brief Getter for the options list.
/**
* \brief Getter for the options list.
* \return The option list.
*/
const options_type options() const { return _options; }
@@ -377,7 +453,7 @@ namespace Tins {
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::DHCP; }
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Getter for the header size.
@@ -394,26 +470,19 @@ namespace Tins {
}
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
T search_and_convert(OptionTypes opt) const {
const option *option = search_option(opt);
if(!option)
throw option_not_found();
return option->to<T>();
}
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);
void internal_add_option(const option &opt);
serialization_type serialize_list(const std::vector<ipaddress_type> &ip_list);
options_type _options;
uint32_t _size;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@
#ifndef TINS_DHCPV6_H
#define TINS_DHCPV6_H
#include <cstring>
#include <list>
#include "pdu.h"
#include "endianness.h"
@@ -46,79 +47,7 @@ public:
/**
* Represents a DHCPv6 option.
*/
class dhcpv6_option {
public:
typedef std::vector<uint8_t> container_type;
typedef container_type::value_type data_type;
typedef uint16_t 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).
*/
dhcpv6_option(option_type opt = 0, size_t length = 0, const data_type *data = 0)
: option_(opt), option_size_(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>
dhcpv6_option(option_type opt, ForwardIterator start, ForwardIterator end)
: option_(opt), option_size_(std::distance(start, end))
{
value_.insert(value_.end(), start, end);
}
/**
* Retrieves this option's type.
* \return uint8_t containing this option's size.
*/
uint16_t option() const {
return option_;
}
/**
* Sets this option's type
* \param opt The option type to be set.
*/
void option(uint16_t opt) {
option_ = opt;
}
/**
* 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 data_type& containing this option's value.
*/
const data_type *data_ptr() const {
return &*value_.begin();
}
/**
* Retrieves the length of this option's data.
*/
uint16_t data_size() const {
return option_size_;
}
private:
option_type option_;
uint16_t option_size_;
container_type value_;
};
typedef PDUOption<uint16_t, DHCPv6> option;
/**
* The message types.
@@ -146,7 +75,7 @@ public:
/**
* The DHCPv6 options.
*/
enum Option {
enum OptionTypes {
CLIENTID = 1,
SERVERID,
IA_NA,
@@ -226,7 +155,7 @@ public:
/**
* The type used to store the DHCPv6 options.
*/
typedef std::list<dhcpv6_option> options_type;
typedef std::list<option> options_type;
/**
* The type used to store IP addresses.
@@ -251,6 +180,8 @@ public:
ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
const options_type& options = options_type())
: id(id), t1(t1), t2(t2), options(options) {}
static ia_na_type from_option(const option &opt);
};
/**
@@ -266,6 +197,8 @@ public:
ia_ta_type(uint32_t id = 0,
const options_type& options = options_type())
: id(id), options(options) {}
static ia_ta_type from_option(const option &opt);
};
/**
@@ -283,6 +216,8 @@ public:
const options_type& options = options_type())
: address(address), preferred_lifetime(preferred_lifetime),
valid_lifetime(valid_lifetime), options(options) {}
static ia_address_type from_option(const option &opt);
};
/**
@@ -300,6 +235,8 @@ public:
const auth_info_type &auth_info = auth_info_type())
: protocol(protocol), algorithm(algorithm), rdm(rdm),
replay_detection(replay_detection), auth_info(auth_info) {}
static authentication_type from_option(const option &opt);
};
/**
@@ -311,6 +248,8 @@ public:
status_code_type(uint16_t code = 0, const std::string &message = "")
: code(code), message(message) { }
static status_code_type from_option(const option &opt);
};
/**
@@ -325,6 +264,8 @@ public:
vendor_info_type(uint32_t enterprise_number = 0,
const data_type &data = data_type())
: enterprise_number(enterprise_number), data(data) { }
static vendor_info_type from_option(const option &opt);
};
@@ -336,7 +277,19 @@ public:
/**
* The type used to store the User Class option.
*/
typedef std::vector<class_option_data_type> user_class_type;
//typedef std::vector<class_option_data_type> user_class_type;
struct user_class_type {
typedef std::vector<class_option_data_type> data_type;
data_type data;
user_class_type(const data_type &data = data_type())
: data(data)
{
}
static user_class_type from_option(const option &opt);
};
/**
* The type used to store the Vendor Class option.
@@ -351,6 +304,8 @@ public:
const class_data_type &vendor_class_data = class_data_type())
: enterprise_number(enterprise_number),
vendor_class_data(vendor_class_data) { }
static vendor_class_type from_option(const option &opt);
};
/**
@@ -433,12 +388,14 @@ public:
duid_type(const duid_ll &identifier)
: id(duid_en::duid_id), data(identifier.serialize()) {}
static duid_type from_option(const option &opt);
};
/**
* The type used to store the Option Request option.
*/
typedef std::vector<Option> option_request_type;
typedef std::vector<uint16_t> option_request_type;
/**
* The type used to store the Relay Message option.
@@ -456,9 +413,12 @@ public:
DHCPv6();
/**
* \brief Constructor which constructs a DHCPv6 object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
* \brief Constructs a DHCPv6 object from a buffer.
*
* If there is not enough size for the DHCPv6 header, or any
* of the TLV options contains an invalid size field, 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.
*/
@@ -511,7 +471,6 @@ public:
* \return The stored options.
*/
const options_type &options() const { return options_; }
;
// Setters
/**
@@ -851,9 +810,9 @@ public:
* The option is added after the last option in the option
* fields.
*
* \param option The option to be added
* \param opt The option to be added
*/
void add_option(const dhcpv6_option &option);
void add_option(const option &opt);
/**
* \brief Searchs for an option that matchs the given flag.
@@ -864,7 +823,7 @@ public:
*
* \param id The option identifier to be searched.
*/
const dhcpv6_option *search_option(Option id) const;
const option *search_option(OptionTypes id) const;
// PDU stuff
@@ -875,6 +834,15 @@ public:
*/
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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
@@ -889,61 +857,72 @@ public:
}
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
uint8_t* write_option(const dhcpv6_option &option, uint8_t* buffer) const;
uint8_t* write_option(const option &option, uint8_t* buffer) const;
template<template <typename> class Functor>
const dhcpv6_option *safe_search_option(Option opt, uint32_t size) const {
const dhcpv6_option *option = search_option(opt);
const option *safe_search_option(OptionTypes opt, uint32_t size) const {
const option *option = search_option(opt);
if(!option || Functor<uint32_t>()(option->data_size(), size))
throw option_not_found();
return option;
}
template<typename InputIterator>
void class_option_data2option(InputIterator start, InputIterator end,
std::vector<uint8_t>& buffer, size_t start_index = 0)
{
size_t index = start_index;
while(start != end) {
buffer.resize(buffer.size() + sizeof(uint16_t) + start->size());
*(uint16_t*)&buffer[index] = Endian::host_to_be<uint16_t>(start->size());
index += sizeof(uint16_t);
std::copy(start->begin(), start->end(), buffer.begin() + index);
index += start->size();
start++;
}
}
template<typename OutputType>
OutputType option2class_option_data(const uint8_t *ptr, uint32_t total_sz) const
{
typedef typename OutputType::value_type value_type;
OutputType output;
size_t index = 0;
while(index + 2 < total_sz) {
uint16_t size = Endian::be_to_host(
*(const uint16_t*)(ptr + index)
);
index += sizeof(uint16_t);
if(index + size > total_sz)
throw option_not_found();
output.push_back(
value_type(ptr + index, ptr + index + size)
);
index += size;
}
if(index != total_sz)
template<typename T>
T search_and_convert(OptionTypes opt) const {
const option *option = search_option(opt);
if(!option)
throw option_not_found();
return output;
return option->to<T>();
}
uint8_t header_data[4];
uint32_t options_size;
ipaddress_type link_addr, peer_addr;
options_type options_;
};
};
namespace Internals {
template<typename InputIterator>
void class_option_data2option(InputIterator start, InputIterator end,
std::vector<uint8_t>& buffer, size_t start_index = 0)
{
size_t index = start_index;
uint16_t uint16_t_buffer;
while(start != end) {
buffer.resize(buffer.size() + sizeof(uint16_t) + start->size());
uint16_t_buffer = Endian::host_to_be<uint16_t>(start->size());
std::memcpy(&buffer[index], &uint16_t_buffer, sizeof(uint16_t));
index += sizeof(uint16_t);
std::copy(start->begin(), start->end(), buffer.begin() + index);
index += start->size();
start++;
}
}
template<typename OutputType>
OutputType option2class_option_data(const uint8_t *ptr, uint32_t total_sz)
{
typedef typename OutputType::value_type value_type;
OutputType output;
size_t index = 0;
while(index + 2 < total_sz) {
uint16_t size;
std::memcpy(&size, ptr + index, sizeof(uint16_t));
size = Endian::be_to_host(size);
index += sizeof(uint16_t);
if(index + size > total_sz)
throw option_not_found();
output.push_back(
value_type(ptr + index, ptr + index + size)
);
index += size;
}
if(index != total_sz)
throw malformed_option();
return output;
}
}
}
#endif // TINS_DHCPV6_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,6 @@
#include "macros.h"
#include "pdu.h"
#include "endianness.h"
#include "dns_record.h"
namespace Tins {
class IPv4Address;
@@ -200,14 +199,24 @@ namespace Tins {
*/
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) {}
/**
* Constructs a Resource object.
*
* \param dname The domain name for which this records
* provides an answer.
* \param data The resource's payload.
* \param type The type of this record.
* \param rclass The class of this record.
* \param ttl The time-to-live of this record.
*/
Resource(const std::string &dname, const std::string &data,
uint16_t type, uint16_t rclass, uint32_t ttl)
: dname_(dname), data_(data), type_(type), qclass_(rclass), ttl_(ttl) {}
Resource() : type_(), qclass_(), ttl_() {}
/**
* \brief Getter for the dname field.
* \brief Getter for the domain name field.
*
* This returns the domain name for which this record
* provides an answer.
@@ -215,9 +224,9 @@ namespace Tins {
const std::string &dname() const { return dname_; }
/**
* Getter for the type field.
* Getter for the data field.
*/
const std::string &data() const { return addr_; }
const std::string &data() const { return data_; }
/**
* Getter for the query type field.
@@ -233,8 +242,52 @@ namespace Tins {
* Getter for the type field.
*/
uint32_t ttl() const { return ttl_; }
/**
* Setter for the domain name field.
*/
void dname(const std::string &data) {
dname_ = data;
}
/**
* \brief Setter for the data field.
*
* The data will be encoded properly by the DNS class before
* being added to this packet. That means that if the type is
* A or AAAA, it will be properly encoded as an IPv4 or
* IPv6 address.
*
* The same happens for records that contain domain names,
* such as NS or CNAME. This data will be encoded using
* DNS domain name encoding.
*/
void data(const std::string &data) {
data_ = data;
}
/**
* Setter for the type field.
*/
void type(uint16_t data) {
type_ = data;
}
/**
* Setter for the class field.
*/
void query_class(uint16_t data) {
qclass_ = data;
}
/**
* Setter for the time-to-live field.
*/
void ttl(uint16_t data) {
ttl_ = data;
}
private:
std::string dname_, addr_;
std::string dname_, data_;
uint16_t type_, qclass_;
uint32_t ttl_;
};
@@ -252,7 +305,11 @@ namespace Tins {
DNS();
/**
* \brief Constructor which creates a DNS object from a buffer.
* \brief Constructs a DNS object from a buffer.
*
* If there's not enough size for the DNS header, or any of the
* records are malformed, a malformed_packet is be thrown.
*
* \param buffer The buffer from which this PDU will be
* constructed.
* \param total_sz The total size of the buffer.
@@ -478,93 +535,79 @@ namespace Tins {
void add_query(const Query &query);
/**
* \brief Add a query response.
* \brief Add an answer resource record.
*
* \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.
* \param resource The resource to be added.
*/
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, address_type ip);
void add_answer(const Resource &resource);
/**
* \brief Add a query response.
* \brief Add an authority resource record.
*
* \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.
* \param resource The resource to be added.
*/
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, address_v6_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);
void add_authority(const Resource &resource);
/**
* \brief Add an authority record.
* \brief Add an additional resource 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.
* \param resource The resource to be added.
*/
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);
void add_additional(const Resource &resource);
/**
* \brief Getter for this PDU's DNS queries.
* \return std::list<Query> containing the queries in this
* record.
*
* \return The query records in this PDU.
*/
queries_type queries() const;
/**
* \brief Getter for this PDU's DNS answers
* \return std::list<Resource> containing the answers in this
* record.
*
* \return The answer records in this PDU.
*/
resources_type answers() const;
/**
* \brief Getter for this PDU's DNS authority records.
*
* \return The authority records in this PDU.
*/
resources_type authority() const;
/**
* \brief Getter for this PDU's DNS additional records.
*
* \return The additional records in this PDU.
*/
resources_type additional() const;
/**
* \brief Encodes a domain name.
*
* This processes the input domain name and returns the encoded
* version. Each label in the original domain name will be
* prefixed with a byte that indicates the label's length.
* The null-terminator byte <b>will</b> be included in the encoded
* string. No compression is performed.
*
* For example, given the input "www.example.com", the output would
* be "\x03www\x07example\x03com\x00".
*
* \param domain_name The domain name to encode.
* \return The encoded domain name.
*/
static std::string encode_domain_name(const std::string &domain_name);
/**
* \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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \sa PDU::clone
@@ -572,17 +615,6 @@ namespace Tins {
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:
TINS_BEGIN_PACK
struct dnshdr {
@@ -616,35 +648,23 @@ namespace Tins {
authority, additional;
} TINS_END_PACK;
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;
typedef std::vector<std::pair<uint32_t*, uint32_t> > sections_type;
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 ;
const uint8_t* compose_name(const uint8_t *ptr, char *out_ptr) const;
void convert_records(const uint8_t *ptr, const uint8_t *end, resources_type &res) const;
const uint8_t* find_section_end(const uint8_t *ptr, const uint32_t num_records) const;
const uint8_t* find_dname_end(const uint8_t *ptr) const;
void update_records(uint32_t &section_start, uint32_t num_records, uint32_t threshold, uint32_t offset);
uint8_t *update_dname(uint8_t *ptr, uint32_t threshold, uint32_t offset);
static void inline_convert_v4(uint32_t value, char *output);
static bool contains_dname(uint16_t type);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
void add_record(const Resource &resource, const sections_type &sections);
dnshdr dns;
uint32_t extra_size;
std::list<Query> queries_;
ResourcesType ans, arity, addit;
mutable SuffixMap suffixes;
mutable SuffixIndices suffix_indices;
byte_array records_data;
uint32_t answers_idx, authority_idx, additional_idx;
};
}

View File

@@ -1,259 +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>
#include "cxxstd.h"
#include "macros.h"
namespace Tins {
class DNSRRImpl;
/**
* \brief Abstracts a DNS resource record.
*/
class DNSResourceRecord {
public:
/**
* \brief The type used to store resource records' information.
*/
TINS_BEGIN_PACK
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() {}
} TINS_END_PACK;
/**
* \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);
#if TINS_IS_CXX11
/**
* Move constructor.
*/
DNSResourceRecord(DNSResourceRecord &&rhs) noexcept;
/**
* Move assignment operator.
*/
DNSResourceRecord& operator=(DNSResourceRecord &&rhs) noexcept;
#endif // TINS_IS_CXX11
/**
* \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

File diff suppressed because it is too large Load Diff

622
include/dot11/dot11_assoc.h Normal file
View File

@@ -0,0 +1,622 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_ASSOC_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_ASSOC_H
#include "../dot11/dot11_mgmt.h"
namespace Tins {
/**
* \brief Class representing a Disassociation frame in the IEEE 802.11 Protocol.
*
*/
class Dot11Disassoc : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_DIASSOC;
/**
* \brief Constructor for creating a 802.11 Disassociation.
*
* Constructs a 802.11 Disassociation taking the destination
* and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11Disassoc(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11Disassoc object from a buffer and
* adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Disassoc(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the reason code field.
*
* \return The stored reason code.
*/
uint16_t reason_code() const { return Endian::le_to_host(_body.reason_code); }
/**
* \brief Setter for the reason code field.
*
* \param new_reason_code The reason code to be set.
*/
void reason_code(uint16_t new_reason_code);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Disassoc *clone() const {
return new Dot11Disassoc(*this);
}
private:
struct DisassocBody {
uint16_t reason_code;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
DisassocBody _body;
};
/**
* \brief Class representing an Association Request frame in the IEEE 802.11 Protocol.
*
*/
class Dot11AssocRequest : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_ASSOC_REQ;
/**
* \brief Constructor for creating a 802.11 Association Request.
*
* Constructs a 802.11 Association Request taking the
* destination and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11AssocRequest(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11AssocRequest object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11AssocRequest(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the Capabilities Information.
*
* \return A constant refereence to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability;}
/**
* \brief Getter for the Capabilities Information.
*
* \return A refereence to the stored Capabilities Information
* field.
*/
capability_information& capabilities() { return _body.capability;}
/**
* \brief Getter for the listen interval field.
*
* \return The stored listen interval field.
*/
uint16_t listen_interval() const { return Endian::le_to_host(_body.listen_interval); }
/**
* \brief Setter for the listen interval field.
*
* \param new_listen_interval The listen interval to be set.
*/
void listen_interval(uint16_t new_listen_interval);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11AssocRequest *clone() const {
return new Dot11AssocRequest(*this);
}
private:
struct AssocReqBody {
capability_information capability;
uint16_t listen_interval;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
AssocReqBody _body;
};
/**
* \brief Class representing an Association Response frame in the IEEE 802.11 Protocol.
*
*/
class Dot11AssocResponse : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_ASSOC_RESP;
/**
* \brief Constructor for creating a 802.11 Association Response.
*
* Constructors a 802.11 Association Response taking destination
* and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11AssocResponse(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructor which creates a Dot11AssocResponse object
* from a buffer and adds all identifiable PDUs found in the
* buffer as children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11AssocResponse(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the Capabilities Information field.
*
* \return A constant reference to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability;}
/**
* \brief Getter for the Capabilities Information field.
*
* \return A reference to the stored Capabilities
* Information field.
*/
capability_information& capabilities() { return _body.capability;}
/**
* \brief Getter for the status code field.
*
* \return The stored status code.
*/
uint16_t status_code() const { return Endian::le_to_host(_body.status_code); }
/**
* \brief Getter for the AID field.
*
* \return The stored AID field.
*/
uint16_t aid() const { return Endian::le_to_host(_body.aid); }
/**
* \brief Setter for the status code.
*
* \param new_status_code The status code to be set.
*/
void status_code(uint16_t new_status_code);
/**
* \brief Setter for the AID field.
*
* \param new_aid The AID value to be set.
*/
void aid(uint16_t new_aid);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11AssocResponse *clone() const {
return new Dot11AssocResponse(*this);
}
private:
struct AssocRespBody {
capability_information capability;
uint16_t status_code;
uint16_t aid;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
AssocRespBody _body;
};
/**
* \brief Class representing an ReAssociation Request frame in the IEEE 802.11 Protocol.
*
*/
class Dot11ReAssocRequest : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_REASSOC_REQ;
/**
* \brief Constructor for creating a 802.11 ReAssociation Request.
*
* Constructors a 802.11 Association Request taking the destination
* and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11ReAssocRequest(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11AssocRequest object from a buffer
* and adds all identifiable PDUs found in the buffer as
* children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11ReAssocRequest(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the Capabilities Information.
*
* \return A constant reference to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability;}
/**
* \brief Getter for the Capabilities Information.
*
* \return A reference to the stored Capabilities Information
* field.
*/
capability_information& capabilities() { return _body.capability;}
/**
* \brief Getter for the listen interval field.
*
* \return The stored listen interval.
*/
uint16_t listen_interval() const { return Endian::le_to_host(_body.listen_interval); }
/**
* \brief Getter for the current ap field.
*
* \return The current ap.
*/
address_type current_ap() const { return _body.current_ap; }
/**
* \brief Setter for the listen interval field.
*
* \param new_listen_interval The listen interval to be set.
*/
void listen_interval(uint16_t new_listen_interval);
/**
* \brief Setter for the current ap.
*
* \param new_current_ap The address of the current ap.
*/
void current_ap(const address_type &new_current_ap);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11ReAssocRequest *clone() const {
return new Dot11ReAssocRequest(*this);
}
private:
struct ReAssocReqBody {
capability_information capability;
uint16_t listen_interval;
uint8_t current_ap[address_type::address_size];
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
ReAssocReqBody _body;
};
/**
* \brief IEEE 802.11 ReAssociation Response frame.
*
*/
class Dot11ReAssocResponse : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_REASSOC_RESP;
/**
* \brief Constructor for creating a 802.11 Association Response.
*
* Constructs a 802.11 ReAssociation Response taking the
* destination and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11ReAssocResponse(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11ReAssocResponse object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11ReAssocResponse(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the Capabilities Information.
*
* \return A constant reference to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability;}
/**
* \brief Getter for the Capabilities Information.
*
* \return A reference to the stored Capabilities Information
* field.
*/
capability_information& capabilities() { return _body.capability;}
/**
* \brief Getter for the status code field.
*
* \return The stored status code.
*/
uint16_t status_code() const { return Endian::le_to_host(_body.status_code); }
/**
* \brief Getter for the AID field.
*
* \return The stored AID field value.
*/
uint16_t aid() const { return Endian::le_to_host(_body.aid); }
/**
* \brief Setter for the status code field.
*
* \param new_status_code The status code to be set.
*/
void status_code(uint16_t new_status_code);
/**
* \brief Setter for the AID field.
*
* \param new_aid The AID to be set.
*/
void aid(uint16_t new_aid);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11ReAssocResponse *clone() const {
return new Dot11ReAssocResponse(*this);
}
private:
struct ReAssocRespBody {
capability_information capability;
uint16_t status_code;
uint16_t aid;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
ReAssocRespBody _body;
};
} // namespace Tins
#endif // TINS_DOT11_DOT11_ASSOC_H

260
include/dot11/dot11_auth.h Normal file
View File

@@ -0,0 +1,260 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_AUTH_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_AUTH_H
#include "../dot11/dot11_mgmt.h"
namespace Tins {
/**
* \brief IEEE 802.11 Authentication Request frame.
*/
class Dot11Authentication : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_AUTH;
/**
* \brief Constructor for creating a 802.11 Authentication.
*
* Constructs a 802.11 Dot11Authentication taking the
* destination and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11Authentication(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11Authentication object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Authentication(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the Authetication Algorithm Number field.
*
* \return The stored authentication algorithm number.
*/
uint16_t auth_algorithm() const {return Endian::le_to_host(_body.auth_algorithm); }
/**
* \brief Getter for the Authetication Sequence Number field.
*
* \return The stored authentication sequence number.
*/
uint16_t auth_seq_number() const {return Endian::le_to_host(_body.auth_seq_number); }
/**
* \brief Getter for the status code field.
*
* \return The stored status code.
*/
uint16_t status_code() const { return Endian::le_to_host(_body.status_code); }
/**
* \brief Setter for the Authetication Algorithm Number field.
*
* \param new_auth_algorithm The Authetication Algorithm Number
* to be set.
*/
void auth_algorithm(uint16_t new_auth_algorithm);
/**
* \brief Setter for the Authetication Sequence Number field.
*
* \param new_auth_seq_number The Authetication Sequence Number
* to be set.
*/
void auth_seq_number(uint16_t new_auth_seq_number);
/**
* \brief Setter for the status code field.
*
* \param new_status_code The status code to be set.
*/
void status_code(uint16_t new_status_code);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Authentication *clone() const {
return new Dot11Authentication(*this);
}
private:
struct AuthBody {
uint16_t auth_algorithm;
uint16_t auth_seq_number;
uint16_t status_code;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
AuthBody _body;
};
/**
* \brief IEEE 802.11 Deauthentication frame.
*
*/
class Dot11Deauthentication : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_DEAUTH;
/**
* \brief Constructor for creating a 802.11 Deauthentication.
*
* Constructs a 802.11 Deauthentication taking the
* destination and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11Deauthentication(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11Deauthentication object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Deauthentication(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the reason code field.
*
* \return The reason code to be set.
*/
uint16_t reason_code() const { return Endian::le_to_host(_body.reason_code); }
/**
* \brief Setter for the reason code field.
*
* \param new_reason_code The reason code to be set.
*/
void reason_code(uint16_t new_reason_code);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Deauthentication *clone() const {
return new Dot11Deauthentication(*this);
}
private:
struct DeauthBody {
uint16_t reason_code;
};
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
DeauthBody _body;
};
} // namespace Tins
#endif // TINS_DOT11_DOT11_AUTH_H

522
include/dot11/dot11_base.h Normal file
View File

@@ -0,0 +1,522 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_H
#include <list>
#include "../pdu.h"
#include "../pdu_option.h"
#include "../small_uint.h"
#include "../hw_address.h"
#include "../endianness.h"
#include "../cxxstd.h"
#include "../macros.h"
namespace Tins {
class RSNInformation;
/**
* \brief Class representing an 802.11 frame.
*/
class Dot11 : public PDU {
public:
/**
* The type used to store hardware addresses.
*/
typedef HWAddress<6> address_type;
/**
* \brief IEEE 802.11 options struct.
*/
typedef PDUOption<uint8_t, Dot11> option;
/**
* The type used to store tagged options.
*/
typedef std::list<option> options_type;
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11;
/**
* \brief Broadcast hardware address.
*/
static const address_type BROADCAST;
/**
* The endianness used by Dot11.
*/
static const endian_type endianness = LE;
/**
* \brief Enum for the different types of 802.11 frames.
*
*/
enum Types {
MANAGEMENT = 0,
CONTROL = 1,
DATA = 2
};
/**
* \brief Enum for the different types of tagged options.
*/
enum OptionTypes {
SSID,
SUPPORTED_RATES,
FH_SET,
DS_SET,
CF_SET,
TIM,
IBSS_SET,
COUNTRY,
HOPPING_PATTERN_PARAMS,
HOPPING_PATTERN_TABLE,
REQUEST_INFORMATION,
BSS_LOAD,
EDCA,
TSPEC,
TCLAS,
SCHEDULE,
CHALLENGE_TEXT,
POWER_CONSTRAINT = 32,
POWER_CAPABILITY,
TPC_REQUEST,
TPC_REPORT,
SUPPORTED_CHANNELS,
CHANNEL_SWITCH,
MEASUREMENT_REQUEST,
MEASUREMENT_REPORT,
QUIET,
IBSS_DFS,
ERP_INFORMATION,
TS_DELAY,
TCLAS_PROCESSING,
QOS_CAPABILITY = 46,
RSN = 48,
EXT_SUPPORTED_RATES = 50,
VENDOR_SPECIFIC = 221
};
/**
* \brief Enum for the different subtypes of 802.11 management frames.
*
*/
enum ManagementSubtypes {
ASSOC_REQ = 0,
ASSOC_RESP = 1,
REASSOC_REQ = 2,
REASSOC_RESP = 3,
PROBE_REQ = 4,
PROBE_RESP = 5,
BEACON = 8,
ATIM = 9,
DISASSOC = 10,
AUTH = 11,
DEAUTH = 12
};
/**
* \brief Enum for the different subtypes of 802.11 control frames.
*
*/
enum ControlSubtypes {
BLOCK_ACK_REQ = 8,
BLOCK_ACK = 9,
PS = 10,
RTS = 11,
CTS = 12,
ACK = 13,
CF_END = 14,
CF_END_ACK = 15
};
/**
* \brief Enum fro the different subtypes of 802.11 data frames.
*
*/
enum DataSubtypes {
DATA_DATA = 0,
DATA_CF_ACK = 1,
DATA_CF_POLL = 2,
DATA_CF_ACK_POLL = 3,
DATA_NULL = 4,
CF_ACK = 5,
CF_POLL = 6,
CF_ACK_POLL = 7,
QOS_DATA_DATA = 8,
QOS_DATA_CF_ACK = 9,
QOS_DATA_CF_POLL = 10,
QOS_DATA_CF_ACK_POLL = 11,
QOS_DATA_NULL = 12
};
/**
* \brief Constructs an 802.11 PDU.
*
* \param dst_hw_addr The destination hardware address.
*/
Dot11(const address_type &dst_hw_addr = address_type());
/**
* \brief Constructs 802.11 PDU from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a 802.11 header in the
* buffer, 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.
*/
Dot11(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the protocol version field.
*
* \return The stored protocol version field.
*/
small_uint<2> protocol() const { return _header.control.protocol; }
/**
* \brief Getter for the Type field.
*
* \return The stored Type field.
*/
small_uint<2> type() const { return _header.control.type; }
/**
* \brief Getter for the Subtype field.
*
* \return The stored Subtype field.
*/
small_uint<4> subtype() const { return _header.control.subtype; }
/**
* \brief Getter for the To-DS field.
*
* \return The stored To-DS field.
*/
small_uint<1> to_ds() const { return _header.control.to_ds; }
/**
* \brief Getter for the From-DS field.
*
* \return The stored From-DS field.
*/
small_uint<1> from_ds() const { return _header.control.from_ds; }
/**
* \brief Getter for the More-Frag field.
*
* \return The stored More-Frag field.
*/
small_uint<1> more_frag() const { return _header.control.more_frag; }
/**
* \brief Getter for the Retry field.
*
* \return The stored Retry field.
*/
small_uint<1> retry() const { return _header.control.retry; }
/**
* \brief Getter for the Power-Management field.
*
* \return The stored Power-Management field.
*/
small_uint<1> power_mgmt() const { return _header.control.power_mgmt; }
/**
* \brief Getter for the WEP field.
*
* \return The stored WEP field.
*/
small_uint<1> wep() const { return _header.control.wep; }
/**
* \brief Getter for the Order field.
*
* \return The stored Order field.
*/
small_uint<1> order() const { return _header.control.order; }
/**
* \brief Getter for the Duration-ID field.
*
* \return The stored Duration-ID field.
*/
uint16_t duration_id() const { return Endian::le_to_host(_header.duration_id); }
/**
* \brief Getter for the first address.
*
* \return The stored first address.
*/
address_type addr1() const { return _header.addr1; }
// Setters
/**
* \brief Setter for the protocol version field.
*
* \param new_proto The new protocol version field value.
*/
void protocol(small_uint<2> new_proto);
/**
* \brief Setter for the type field.
*
* \param new_type The new type field value.
*/
void type(small_uint<2> new_type);
/**
* \brief Setter for the subtype field.
*
* \param new_subtype The new subtype field value.
*/
void subtype(small_uint<4> new_subtype);
/**
* \brief Setter for the To-DS field.
*
* \param new_value The new To-DS field value.
*/
void to_ds(small_uint<1> new_value);
/**
* \brief Setter for the From-DS field.
*
* \param new_value The new From-DS field value.
*/
void from_ds(small_uint<1> new_value);
/**
* \brief Setter for the More-Frag field.
*
* \param new_value The new More-Frag field value.
*/
void more_frag(small_uint<1> new_value);
/**
* \brief Setter for the Retry field.
*
* \param new_value The new Retry field value.
*/
void retry(small_uint<1> new_value);
/**
* \brief Setter for the Power-Management field.
*
* \param new_value The new Power-Management field value.
*/
void power_mgmt(small_uint<1> new_value);
/**
* \brief Setter for the WEP field.
*
* \param new_value The new WEP field value.
*/
void wep(small_uint<1> new_value);
/**
* \brief Setter for the Order field.
*
* \param new_value The new Order field value.
*/
void order(small_uint<1> new_value);
/**
* \brief Setter for the Duration-ID field.
*
* \param new_duration_id The new Duration-ID field value.
*/
void duration_id(uint16_t new_duration_id);
/**
* \brief Setter for the first address.
*
* \param new_addr1 The new first address.
*/
void addr1(const address_type &new_addr1);
/* Virtual methods */
/**
* \brief Returns the 802.11 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, const NetworkInterface &iface);
#endif // WIN32
/**
* \brief Adds a new option to this Dot11 PDU.
* \param opt The option to be added.
*/
void add_option(const option &opt);
#if TINS_IS_CXX11
/**
* \brief Adds a new option to this Dot11 PDU.
*
* The option is move-constructed
*
* \param opt The option to be added.
*/
void add_option(option &&opt) {
internal_add_option(opt);
_options.push_back(std::move(opt));
}
#endif
/**
* \brief Looks up a tagged option in the option list.
*
* The returned pointer <b>must not</b> be free'd.
*
* \param opt The option identifier.
* \return The option found, or 0 if no such option has been set.
*/
const option *search_option(OptionTypes opt) const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
Dot11 *clone() const {
return new Dot11(*this);
}
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag;
}
/**
* \brief Getter for the option list.
*
* \return The options list.
*/
const options_type &options() const { return _options; }
/**
* \brief Allocates an Dot11 PDU from a buffer.
*
* This can be used somehow as a "virtual constructor". This
* method instantiates the appropriate subclass of Dot11 from the
* given buffer.
*
* The allocated class' type will be figured out from the
* information provided in the buffer.
*
* \param buffer The buffer from which to take the PDU data.
* \param total_sz The total size of the buffer.
* \return The allocated Dot11 PDU.
*/
static Dot11 *from_bytes(const uint8_t *buffer, uint32_t total_sz);
protected:
virtual uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz) { return 0; }
virtual uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { return 0; }
void parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz);
void add_tagged_option(OptionTypes opt, uint8_t len, const uint8_t *val);
protected:
/**
* Struct that represents the 802.11 header
*/
TINS_BEGIN_PACK
struct ieee80211_header {
TINS_BEGIN_PACK
struct {
#if TINS_IS_LITTLE_ENDIAN
uint16_t protocol:2,
type:2,
subtype:4,
to_ds:1,
from_ds:1,
more_frag:1,
retry:1,
power_mgmt:1,
more_data:1,
wep:1,
order:1;
#elif TINS_IS_BIG_ENDIAN
uint16_t subtype:4,
type:2,
protocol:2,
order:1,
wep:1,
more_data:1,
power_mgmt:1,
retry:1,
more_frag:1,
from_ds:1,
to_ds:1;
#endif
} TINS_END_PACK control;
uint16_t duration_id;
uint8_t addr1[address_type::address_size];
} TINS_END_PACK;
private:
Dot11(const ieee80211_header *header_ptr);
void internal_add_option(const option &opt);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
ieee80211_header _header;
uint32_t _options_size;
options_type _options;
};
}
#endif // TINS_DOT11_DOT11_H

View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_BEACON_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_BEACON_H
#include "../dot11/dot11_mgmt.h"
namespace Tins {
/**
* \brief Class representing an 802.11 Beacon.
*
*/
class Dot11Beacon : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_BEACON;
/**
* \brief Constructor for creating a 802.11 Beacon.
*
* Constructs a 802.11 Beacon taking destination and source
* hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11Beacon(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11Beacon object from a buffer and adds
* all identifiable PDUs found in the buffer as children of this
* one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Beacon(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the timestamp field.
*
* \return The stored timestamp value.
*/
uint64_t timestamp() const { return Endian::le_to_host(_body.timestamp); }
/**
* \brief Getter for the interval field.
*
* \return The stored interval value.
*/
uint16_t interval() const { return Endian::le_to_host(_body.interval); }
/**
* \brief Getter for the Capabilities Information structure.
*
* \return A constant refereence to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability; }
/**
* \brief Getter for the Capabilities Information.
*
* \return A refereence to the stored Capabilities Information
* field.
*/
capability_information& capabilities() { return _body.capability; }
/**
* \brief Setter for the timestamp field.
*
* \param new_timestamp The timestamp to be set.
*/
void timestamp(uint64_t new_timestamp);
/**
* \brief Setter for the interval field.
*
* \param new_interval The interval to be set.
*/
void interval(uint16_t new_interval);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with the header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Beacon *clone() const {
return new Dot11Beacon(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
private:
TINS_BEGIN_PACK
struct BeaconBody {
uint64_t timestamp;
uint16_t interval;
capability_information capability;
} TINS_END_PACK;
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
BeaconBody _body;
};
} // namespace Tins
#endif // TINS_DOT11_DOT11_BEACON_H

View File

@@ -0,0 +1,746 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_CONTROL_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_CONTROL_H
#include "../dot11/dot11_base.h"
namespace Tins {
/**
* \brief Class that represents an 802.11 control frame.
*/
class Dot11Control : public Dot11 {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL;
/**
* \brief Constructor for creating a 802.11 control frame PDU
*
* Constructs a 802.11 Control PDU taking the destination and
* source hardware addresses.
*
* \param dst_addr The destination hardware address.
*/
Dot11Control(const address_type &dst_addr = address_type());
/**
* \brief Constructs a Dot11Control object from a buffer and
* adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Control(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::DOT11_CONTROL; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == PDU::DOT11_CONTROL || Dot11::matches_flag(flag);
}
};
/**
* \brief Class that represents an abstraction of the 802.11 control frames
* that contain a target address.
*/
class Dot11ControlTA : public Dot11Control {
public:
/**
* \brief Getter for the target address field.
*/
address_type target_addr() const { return _taddr; }
/**
* \brief Setter for the target address field.
* \param addr The new target address.
*/
void target_addr(const address_type &addr);
protected:
/**
* \brief Constructor for creating a 802.11 control frame TA PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11ControlTA(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11ControlTA object from a buffer and
* adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11ControlTA(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Returns the 802.11 frame's header length.
*
* \return An uint32_t with the header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
protected:
/**
* \brief Getter for the control ta additional fields size.
*/
uint32_t controlta_size() const { return _taddr.size() + sizeof(ieee80211_header); }
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
private:
address_type _taddr;
};
/**
* \brief IEEE 802.11 RTS frame.
*/
class Dot11RTS : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_RTS;
/**
* \brief Constructor for creating a 802.11 RTS frame PDU
*
* Constructs a 802.11 RTS PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11RTS(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11RTS object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11RTS(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11RTS *clone() const {
return new Dot11RTS(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
};
class Dot11PSPoll : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_PS_POLL;
/**
* \brief Constructor for creating a 802.11 PS-Poll frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11PSPoll(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11PSPoll object from a buffer and
* adds all identifiable PDUs found in the buffer as children of
* this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11PSPoll(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11PSPoll *clone() const {
return new Dot11PSPoll(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
};
class Dot11CFEnd : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_CF_END;
/**
* \brief Constructor for creating a 802.11 CF-End frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11CFEnd(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11CFEnd object from a buffer and adds
* all identifiable PDUs found in the buffer as children of this
* one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11CFEnd(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11CFEnd *clone() const {
return new Dot11CFEnd(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
};
class Dot11EndCFAck : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_END_CF_ACK;
/**
* \brief Constructor for creating a 802.11 End-CF-Ack frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11EndCFAck(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11EndCFAck frame object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11EndCFAck(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11EndCFAck *clone() const {
return new Dot11EndCFAck(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
};
class Dot11Ack : public Dot11Control {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_ACK;
/**
* \brief Constructor for creating a 802.11 Ack frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
*/
Dot11Ack(const address_type &dst_addr = address_type());
/**
* \brief Constructs a Dot11Ack frame object from a buffer and
* adds all identifiable PDUs found in the buffer as children of
* this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Ack(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Ack *clone() const {
return new Dot11Ack(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
};
/**
* \brief Class that represents an 802.11 Block Ack Request PDU.
*/
class Dot11BlockAckRequest : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_BLOCK_ACK_REQ;
/**
* \brief Constructor for creating a 802.11 Block Ack request frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11BlockAckRequest(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11BlockAckRequest object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11BlockAckRequest(const uint8_t *buffer, uint32_t total_sz);
/* Getter */
/**
* \brief Getter for the bar control field.
* \return The stored bar control field.
*/
small_uint<4> bar_control() const {
#if TINS_IS_LITTLE_ENDIAN
return _bar_control & 0xf;
#else
return (_bar_control >> 8) & 0xf;
#endif
}
/**
* \brief Getter for the start sequence field.
* \return The stored start sequence.
*/
small_uint<12> start_sequence() const {
#if TINS_IS_LITTLE_ENDIAN
return (_start_sequence >> 4) & 0xfff;
#else
return (Endian::le_to_host<uint16_t>(_start_sequence) >> 4) & 0xfff;
#endif
}
/**
* \brief Getter for the fragment number field.
* \return The stored fragment number field.
*/
small_uint<4> fragment_number() const {
#if TINS_IS_LITTLE_ENDIAN
return _start_sequence & 0xf;
#else
return (_start_sequence >> 8) & 0xf;
#endif
}
/**
* \brief Returns the 802.11 frame's header length.
*
* \return The header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
/* Setter */
/**
* \brief Setter for the bar control field.
* \param bar The bar control field to be set.
*/
void bar_control(small_uint<4> bar);
/**
* \brief Setter for the start sequence field.
* \param bar The start sequence field to be set.
*/
void start_sequence(small_uint<12> seq);
/**
* \brief Setter for the fragment number field.
* \param frag The fragment number field to be set.
*/
void fragment_number(small_uint<4> frag);
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11BlockAckRequest *clone() const {
return new Dot11BlockAckRequest(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
protected:
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
private:
void init_block_ack();
uint16_t _bar_control;
uint16_t _start_sequence;
};
/**
* \brief Class that represents an 802.11 block ack frame.
*/
class Dot11BlockAck : public Dot11ControlTA {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_BLOCK_ACK;
/**
* The size of the bitmap field.
*/
static const size_t bitmap_size = 8;
/**
* \brief Constructor for creating a 802.11 Block Ack frame PDU
*
* Constructs a 802.11 PDU taking the destination and source
* hardware addresses.
*
* \param dst_addr The destination hardware address.
* \param target_addr The source hardware address.
*/
Dot11BlockAck(const address_type &dst_addr = address_type(),
const address_type &target_addr = address_type());
/**
* \brief Constructs a Dot11BlockAck frame object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz);
/* Getters */
/**
* \brief Getter for the bar control field.
* \return The stored bar control field.
*/
small_uint<4> bar_control() const {
#if TINS_IS_LITTLE_ENDIAN
return _bar_control & 0xf;
#else
return (_bar_control >> 8) & 0xf;
#endif
}
/**
* \brief Getter for the start sequence field.
* \return The stored start sequence.
*/
small_uint<12> start_sequence() const {
#if TINS_IS_LITTLE_ENDIAN
return (_start_sequence >> 4) & 0xfff;
#else
return (Endian::le_to_host<uint16_t>(_start_sequence) >> 4) & 0xfff;
#endif
}
/**
* \brief Getter for the fragment number field.
* \return The stored fragment number field.
*/
small_uint<4> fragment_number() const {
#if TINS_IS_LITTLE_ENDIAN
return _start_sequence & 0xf;
#else
return (_start_sequence >> 8) & 0xf;
#endif
}
/**
* \brief Returns the 802.11 frame's header length.
*
* \return An uint32_t with the header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
/* Setters */
/**
* \brief Setter for the bar control field.
* \param bar The bar control field to be set.
*/
void bar_control(small_uint<4> bar);
/**
* \brief Setter for the start sequence field.
* \param bar The start sequence field to be set.
*/
void start_sequence(small_uint<12> seq);
/**
* \brief Setter for the fragment number field.
* \param frag The fragment number field to be set.
*/
void fragment_number(small_uint<4> frag);
/**
* \brief Getter for the bitmap field.
*
* The returned pointer <b>must not</b> be free'd.
*
* \return The bitmap field.
*/
const uint8_t *bitmap() const { return _bitmap; }
/**
* \brief Setter for the bitmap field.
* \param bit The new bitmap field to be set.
*/
void bitmap(const uint8_t *bit);
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11Control::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11BlockAck *clone() const {
return new Dot11BlockAck(*this);
}
private:
void init_block_ack();
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
uint16_t _bar_control, _start_sequence;
uint8_t _bitmap[bitmap_size];
};
} // namespace Tins
#endif // TINS_DOT11_DOT11_CONTROL_H

345
include/dot11/dot11_data.h Normal file
View File

@@ -0,0 +1,345 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_DATA_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_DATA_H
#include "../dot11/dot11_base.h"
namespace Tins {
class Dot11Data : public Dot11 {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_DATA;
/**
* \brief Constructor for creating a 802.11 Data frame.
*
* Constructs a 802.11 Data frame taking the
* destination and source hardware addresses.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11Data(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11Data object from a buffer and adds
* all identifiable PDUs found in the buffer as children of
* this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11Data(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the second address.
*
* \return The stored second address.
*/
address_type addr2() const { return _ext_header.addr2; }
/**
* \brief Getter for the third address.
*
* \return The stored third address.
*/
address_type addr3() const { return _ext_header.addr3; }
/**
* \brief Getter for the fragment number field.
*
* \return The stored fragment number.
*/
small_uint<4> frag_num() const {
#if TINS_IS_LITTLE_ENDIAN
return _ext_header.frag_seq & 0xf;
#else
return (_ext_header.frag_seq >> 8) & 0xf;
#endif
}
/**
* \brief Getter for the sequence number field.
*
* \return The stored sequence number.
*/
small_uint<12> seq_num() const {
#if TINS_IS_LITTLE_ENDIAN
return (_ext_header.frag_seq >> 4) & 0xfff;
#else
return (Endian::le_to_host<uint16_t>(_ext_header.frag_seq) >> 4) & 0xfff;
#endif
}
/**
* \brief Getter for the fourth address.
*
* \return The fourth address.
*/
address_type addr4() const { return _addr4; }
/**
* \brief Setter for the second address.
*
* \param new_addr2 The second address to be set.
*/
void addr2(const address_type &new_addr2);
/**
* \brief Setter for the third address.
*
* \param new_addr3 The third address to be set.
*/
void addr3(const address_type &new_addr3);
/**
* \brief Setter for the fragment number field.
*
* \param new_frag_num The fragment number to be set.
*/
void frag_num(small_uint<4> new_frag_num);
/**
* \brief Setter for the sequence number field.
*
* \param new_seq_num The sequence number to be set.
*/
void seq_num(small_uint<12> new_seq_num);
/**
* \brief Setter for the fourth address field.
*
* \param new_addr4 The fourth address to be set.
*/
void addr4(const address_type &new_addr4);
/**
* \brief Retrieves the frame's source address.
*
* This is a wrapper over the addr* member functions which
* takes into account the value of the FromDS and ToDS bits.
*
* If FromDS == ToDS == 1, the return value is not defined.
*/
address_type src_addr() const {
if(!from_ds() && !to_ds())
return addr2();
if(!from_ds() && to_ds())
return addr2();
return addr3();
}
/**
* \brief Retrieves the frame's destination address.
*
* This is a wrapper over the addr* member functions which
* takes into account the value of the FromDS and ToDS bits.
*
* If FromDS == ToDS == 1, the return value is not defined.
*/
address_type dst_addr() const {
if(!from_ds() && !to_ds())
return addr1();
if(!from_ds() && to_ds())
return addr3();
return addr1();
}
/**
* \brief Retrieves the frame's BSSID address.
*
* This is a wrapper over the addr* member functions which
* takes into account the value of the FromDS and ToDS bits.
*
* If FromDS == ToDS == 1, the return value is not defined.
*/
address_type bssid_addr() const {
if(!from_ds() && !to_ds())
return addr3();
if(!from_ds() && to_ds())
return addr1();
return addr2();
}
/**
* \brief Returns the 802.11 frame's header length.
*
* \return An uint32_t with 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_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11Data *clone() const {
return new Dot11Data(*this);
}
protected:
TINS_BEGIN_PACK
struct ExtendedHeader {
uint8_t addr2[address_type::address_size];
uint8_t addr3[address_type::address_size];
uint16_t frag_seq;
} TINS_END_PACK;
struct no_inner_pdu { };
Dot11Data(const uint8_t *buffer, uint32_t total_sz, no_inner_pdu);
uint32_t init(const uint8_t *buffer, uint32_t total_sz);
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
uint32_t data_frame_size() {
return Dot11::header_size() + sizeof(_ext_header) +
((from_ds() && to_ds()) ? _addr4.size() : 0);
}
private:
ExtendedHeader _ext_header;
address_type _addr4;
};
class Dot11QoSData : public Dot11Data {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_QOS_DATA;
/**
* \brief Constructor for creating a 802.11 QoS Data PDU
*
* Constructs a 802.11 QoS Data PDU taking the
* destination and source hardware addresses.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11QoSData(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructors Dot11QoSData object from a buffer and adds
* all identifiable PDUs found in the buffer as children of this
* one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11QoSData(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the QOS Control field.
*
* \return The stored QOS Control field value.
*/
uint16_t qos_control() const { return Endian::le_to_host(_qos_control); }
/**
* \brief Setter for the QOS Control field.
*
* \param new_qos_control The QOS Control to be set.
*/
void qos_control(uint16_t new_qos_control);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with the header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
Dot11QoSData *clone() const {
return new Dot11QoSData(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::DOT11_QOS_DATA; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == PDU::DOT11_QOS_DATA || Dot11Data::matches_flag(flag);
}
private:
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
uint16_t _qos_control;
};
}
#endif // TINS_DOT11_DOT11_DATA_H

1160
include/dot11/dot11_mgmt.h Normal file

File diff suppressed because it is too large Load Diff

233
include/dot11/dot11_probe.h Normal file
View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2014, 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 "../config.h"
#if !defined(TINS_DOT11_DOT11_PROBE_H) && defined(HAVE_DOT11)
#define TINS_DOT11_DOT11_PROBE_H
#include "../dot11/dot11_mgmt.h"
namespace Tins {
/**
* \brief Class representing an Probe Request frame in the IEEE 802.11 Protocol.
*
*/
class Dot11ProbeRequest : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_PROBE_REQ;
/**
* \brief Constructor for creating a 802.11 Probe Request.
*
* Constructs a 802.11 Probe Request taking the
* destination and source hardware address.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11ProbeRequest(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11ProbeRequest object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11ProbeRequest(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::DOT11_PROBE_REQ; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
/**
* \brief Clones this PDU.
*
* \sa PDU::clone()
*/
Dot11ProbeRequest* clone() const {
return new Dot11ProbeRequest(*this);
}
};
/**
* \brief Class representing an Probe Response frame in the IEEE 802.11 Protocol.
*
*/
class Dot11ProbeResponse : public Dot11ManagementFrame {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT11_PROBE_RESP;
/**
* \brief Constructor for creating a 802.11 Probe Response.
*
* Constructs a 802.11 Probe Response taking the
* destination and source hardware addresses.
*
* \param dst_hw_addr The destination hardware address.
* \param src_hw_addr The source hardware address.
*/
Dot11ProbeResponse(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot11ProbeResponse object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for the header in the buffer
* or the input data is malformed, 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.
*/
Dot11ProbeResponse(const uint8_t *buffer, uint32_t total_sz);
/**
* \brief Getter for the timestamp field.
*
* \return The stored timestamp value.
*/
uint64_t timestamp() const { return Endian::le_to_host(_body.timestamp); }
/**
* \brief Getter for the interval field.
*
* \return The stored interval value.
*/
uint16_t interval() const { return Endian::le_to_host(_body.interval); }
/**
* \brief Getter for the Capabilities Information.
*
* \return A constant reference to the stored Capabilities
* Information field.
*/
const capability_information& capabilities() const { return _body.capability;}
/**
* \brief Getter for the Capabilities Information.
*
* \return A reference to the stored Capabilities Information
* field.
*/
capability_information& capabilities() { return _body.capability;}
/**
* \brief Setter for the timestamp field.
*
* \param new_timestamp The timestamp to be set.
*/
void timestamp(uint64_t new_timestamp);
/**
* \brief Setter for the interval field.
*
* \param new_interval The interval to be set.
*/
void interval(uint16_t new_interval);
/**
* \brief Returns the frame's header length.
*
* \return An uint32_t with the header's size.
* \sa PDU::header_size()
*/
uint32_t header_size() const;
/**
* \brief Clones this PDU.
*
* \sa PDU::clone()
*/
Dot11ProbeResponse* clone() const {
return new Dot11ProbeResponse(*this);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Check wether this PDU matches the specified flag.
* \param flag The flag to match
* \sa PDU::matches_flag
*/
bool matches_flag(PDUType flag) const {
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
}
protected:
private:
TINS_BEGIN_PACK
struct ProbeResp {
uint64_t timestamp;
uint16_t interval;
capability_information capability;
} TINS_END_PACK;
ProbeResp _body;
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
};
} // namespace Tins
#endif // TINS_DOT11_DOT11_PROBE_H

212
include/dot1q.h Normal file
View File

@@ -0,0 +1,212 @@
/*
* Copyright (c) 2014, 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_DOT1Q_H
#define TINS_DOT1Q_H
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
namespace Tins {
/**
* Represents an IEEE 802.1q PDU.
*/
class Dot1Q : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT1Q;
/**
* Default constructor
*/
Dot1Q(small_uint<12> tag_id = 0, bool append_pad = true);
/**
* \brief Constructs a Dot1Q object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a Dot1Q header in the buffer,
* 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.
*/
Dot1Q(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_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;
/**
* \brief Getter for the priority field.
* \return The stored priority field value.
*/
small_uint<3> priority() const {
return _header.priority;
}
/**
* \brief Getter for the Canonical Format Identifier field.
* \return The stored CFI field value.
*/
small_uint<1> cfi() const {
return _header.cfi;
}
/**
* \brief Getter for the VLAN ID field.
* \return The stored VLAN ID field value.
*/
small_uint<12> id() const {
#if TINS_IS_LITTLE_ENDIAN
return _header.idL | (_header.idH << 8);
#else
return _header.id;
#endif
}
/**
* \brief Getter for the payload type field.
* \return The stored type field value.
*/
uint16_t payload_type() const {
return Endian::be_to_host(_header.type);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
Dot1Q *clone() const {
return new Dot1Q(*this);
}
/**
* \brief Retrieves the flag indicating whether padding will be
* appended at the end of this packet.
*/
bool append_padding() const {
return _append_padding;
}
// Setters
/**
* \brief Setter for the priority field.
* \param new_priority The new priority field value.
*/
void priority(small_uint<3> new_priority);
/**
* \brief Setter for the Canonical Format Identifie field.
* \param new_cfi The new CFI field value.
*/
void cfi(small_uint<1> new_cfi);
/**
* \brief Setter for the VLAN ID field.
* \param new_id The new VLAN ID field value.
*/
void id(small_uint<12> new_id);
/**
* \brief Setter for the payload type field.
* \param new_type The new type field value.
*/
void payload_type(uint16_t new_type);
/**
* \brief Indicates whether the appropriate padding will be
* at the end of the packet.
*
* This flag could be disabled in case two or more contiguous Dot1Q
* PDUs are added to a packet. In that case, only the Dot1Q which is
* closer to the link layer should add the padding at the end.
*
* \param value A boolean indicating whether padding will be appended.
*/
void append_padding(bool value);
/**
* \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(const uint8_t *ptr, uint32_t total_sz) const;
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
TINS_BEGIN_PACK
struct dot1q_hdr {
#if TINS_IS_BIG_ENDIAN
uint16_t priority:3,
cfi:1,
id:12;
uint16_t type;
#else
uint16_t idH:4,
cfi:1,
priority:3,
idL:8;
uint16_t type;
#endif
} TINS_END_PACK;
static uint16_t get_id(const dot1q_hdr *hdr);
dot1q_hdr _header;
bool _append_padding;
};
}
#endif // TINS_DOT1Q_H

193
include/dot3.h Normal file
View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2014, 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_DOT3_H
#define TINS_DOT3_H
#include <stdint.h>
#include "macros.h"
#include "pdu.h"
#include "endianness.h"
#include "hw_address.h"
namespace Tins {
/**
* \brief Class representing an Ethernet II PDU.
*/
class Dot3 : 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 Dot3 broadcast address.
*/
static const address_type BROADCAST;
/**
* \brief Constructor for creating an Dot3 PDU
*
* Constructor that builds an Dot3 PDU taking the interface name,
* destination's and source's MAC.
*
* \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.
*/
Dot3(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructs a Dot3 object from a buffer and adds a
* LLC object with the remaining data as the inner PDU.
*
* If there is not enough size for a Dot3 header, 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.
*/
Dot3(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 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 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 Dot3 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, const NetworkInterface &iface);
#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(const uint8_t *ptr, uint32_t total_sz) const;
#ifndef WIN32
/**
* \sa PDU::recv_response
*/
PDU *recv_response(PacketSender &sender, const NetworkInterface &iface);
#endif // WIN32
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
Dot3 *clone() const {
return new Dot3(*this);
}
private:
/**
* Struct that represents the Ethernet II header
*/
TINS_BEGIN_PACK
struct ethhdr {
uint8_t dst_mac[address_type::address_size];
uint8_t src_mac[address_type::address_size];
uint16_t length;
} TINS_END_PACK;
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
ethhdr _eth;
};
}
#endif // TINS_DOT3_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,12 @@ namespace Tins {
/**
* \brief Static method to instantiate the correct EAPOL subclass
* based on a raw buffer.
*
* If no valid EAPOL type is detected, a null pointer is returned.
*
* \sa RC4EAPOL
* \sa RSNEAPOL
*
* \param buffer The buffer from which the data will be taken.
* \param total_sz The total size of the buffer.
*/
@@ -197,12 +203,16 @@ namespace Tins {
static const size_t key_sign_size = 16;
/**
* \brief Creates an instance of RC4EAPOL
* \brief Default constructor.
*/
RC4EAPOL();
/**
* \brief Constructor which creates an RC4EAPOL object from a buffer.
* \brief Constructs a RC4EAPOL object from a buffer.
*
* If there is not enough size for a RC4EAPOL header in the
* buffer, 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.
*/
@@ -396,7 +406,11 @@ namespace Tins {
RSNEAPOL();
/**
* \brief Constructor which creates an RSNEAPOL object from a buffer.
* \brief Constructs a RSNEAPOL object from a buffer.
*
* If there is not enough size for the RSNEAPOL header, 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.
*/
@@ -459,8 +473,8 @@ namespace Tins {
const key_type &key() const { return _key; }
/**
* \brief Getter for the key_mic field.
* \return The key_mic field.
* \brief Getter for the key mic field.
* \return 1 if this EAPOL PDU contains a valid MIC, 0 otherwise.
*/
small_uint<1> key_mic() const { return _header.key_mic; };
@@ -486,17 +500,18 @@ namespace Tins {
* \brief Getter for the encrypted field.
* \return The encrypted field.
*/
small_uint<1 > encrypted() const { return _header.encrypted; };
small_uint<1> encrypted() const { return _header.encrypted; };
/**
* \brief Getter for the key_descriptor field.
* \return The key_descriptor field.
* \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.
* \brief Getter for the key type field.
*
* \return 1 if this is a pairwise key, 0 otherwise.
*/
small_uint<1> key_t() const { return _header.key_t; };

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,16 @@
namespace Tins {
namespace Endian {
/**
* \brief "Changes" a 8-bit integral value's endianess. This is an
* identity function.
*
* \param data The data to convert.
*/
inline uint8_t do_change_endian(uint8_t data) {
return data;
}
/**
* \brief Changes a 16-bit integral value's endianess.
*
@@ -80,7 +90,7 @@ namespace Endian {
* \param data The data to convert.
*/
inline uint64_t do_change_endian(uint64_t data) {
return (((uint64_t)(do_change_endian((uint32_t)((data << 32) >> 32))) << 32) |
return (((uint64_t)(do_change_endian((uint32_t)(data & 0xffffffff))) << 32) |
(do_change_endian(((uint32_t)(data >> 32)))));
}
@@ -100,6 +110,11 @@ namespace Endian {
template<size_t>
struct conversion_dispatcher;
template<>
struct conversion_dispatcher<sizeof(uint8_t)>
: public conversion_dispatch_helper<uint8_t>
{ };
template<>
struct conversion_dispatcher<sizeof(uint16_t)>
: public conversion_dispatch_helper<uint16_t>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,6 @@
#include "pdu.h"
#include "endianness.h"
#include "hw_address.h"
#include "network_interface.h"
namespace Tins {
@@ -60,24 +59,23 @@ namespace Tins {
static const address_type BROADCAST;
/**
* \brief Constructor for creating an ethernet PDU
* \brief Constructs an ethernet II 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).
* \param dst_hw_addr address_type containing the destination's MAC.
* \param src_hw_addr address_type containing the source's MAC.
*/
EthernetII(const NetworkInterface& iface = NetworkInterface(),
const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type(),
PDU* child = 0);
EthernetII(const address_type &dst_hw_addr = address_type(),
const address_type &src_hw_addr = address_type());
/**
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
* PDUs found in the buffer as children of this one.
* \brief Constructs a EthernetII object from a buffer and adds
* all identifiable PDUs found in the buffer as children of
* this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a EthernetII header in the
* buffer, 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.
@@ -100,13 +98,6 @@ namespace Tins {
*/
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.
@@ -129,13 +120,6 @@ namespace Tins {
*/
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.
*
@@ -152,29 +136,38 @@ namespace Tins {
*/
uint32_t header_size() const;
/**
* \brief Returns the ethernet II frame's padding.
*
* \return An uint32_t with the padding size.
* \sa PDU::trailer_size()
*/
uint32_t trailer_size() const;
// Windows does not support sending L2 PDUs.
#ifndef WIN32
/**
* \sa PDU::send()
*/
void send(PacketSender &sender);
void send(PacketSender &sender, const NetworkInterface &iface);
#endif // WIN32
/** \brief Check wether ptr points to a valid response for this PDU.
/**
* \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);
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
#ifndef WIN32
/** \brief Receives a matching response for this packet.
/**
* \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);
PDU *recv_response(PacketSender &sender, const NetworkInterface &iface);
#endif // WIN32
/**
@@ -183,16 +176,6 @@ namespace Tins {
*/
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
*/
@@ -213,7 +196,6 @@ namespace Tins {
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
ethhdr _eth;
NetworkInterface _iface;
};
}

173
include/exceptions.h Normal file
View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2014, 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_EXCEPTIONS_H
#define TINS_EXCEPTIONS_H
#include <string>
#include <stdexcept>
namespace Tins {
/**
* \brief Exception thrown when an option is not found.
*/
class option_not_found : public std::runtime_error {
public:
option_not_found()
: std::runtime_error(std::string()) { }
// try to avoid allocations by doing this.
const char* what() const throw() {
return "Option not found";
}
};
/**
* \brief Exception thrown when a malformed packet is parsed.
*/
class malformed_packet : public std::runtime_error {
public:
malformed_packet()
: std::runtime_error(std::string()) { }
const char* what() const throw() {
return "Malformed packet";
}
};
/**
* \brief Exception thrown when a PDU is not found when using PDU::rfind_pdu.
*/
class pdu_not_found : public std::runtime_error {
public:
pdu_not_found()
: std::runtime_error(std::string()) { }
const char* what() const throw() {
return "PDU not found";
}
};
/**
* \brief Exception thrown when PDU::send requires a valid interface,
* but an invalid is used.
*/
class invalid_interface : public std::runtime_error {
public:
invalid_interface()
: std::runtime_error(std::string()) { }
const char* what() const throw() {
return "Invalid interface";
}
};
/**
* \brief Exception thrown when PacketSender fails to open a socket.
*/
class socket_open_error : public std::runtime_error {
public:
socket_open_error(const std::string &msg)
: std::runtime_error(msg) { }
};
/**
* \brief Exception thrown when PacketSender fails to close a socket.
*/
class socket_close_error : public std::runtime_error {
public:
socket_close_error(const std::string &msg)
: std::runtime_error(msg) { }
};
/**
* \brief Exception thrown when PacketSender fails to write on a socket.
*/
class socket_write_error : public std::runtime_error {
public:
socket_write_error(const std::string &msg)
: std::runtime_error(msg) { }
};
/**
* \brief Exception thrown when an invalid socket type is provided
* to PacketSender.
*/
class invalid_socket_type : public std::exception {
public:
const char *what() const throw() {
return "The provided socket type is invalid";
}
};
/**
* \brief Exception thrown when an unkown link layer PDU type is
* found while sniffing.
*/
class unknown_link_type : public std::exception {
public:
const char *what() const throw() {
return "The sniffed link layer PDU type is unknown";
}
};
/**
* \brief Exception thrown when a malformed option is found.
*/
class malformed_option : public std::exception {
public:
const char *what() const throw() {
return "Malformed option";
}
};
/**
* \brief Exception thrown when a call to tins_cast fails.
*/
class bad_tins_cast : public std::exception {
public:
const char *what() const throw() {
return "Bad Tins cast";
}
};
/**
* \brief Exception thrown when sniffing a protocol that
* has been disabled at compile time.
*/
class protocol_disabled : public std::exception {
public:
const char *what() const throw() {
return "Protocol disabled";
}
};
} // Tins
#endif // TINS_EXCEPTIONS_H

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 2014, 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 "config.h"
#if !defined(TINS_HANDSHAKE_CAPTURER_H) && defined(HAVE_DOT11)
#define TINS_HANDSHAKE_CAPTURER_H
#include <vector>
#include <map>
#include <utility>
#include "hw_address.h"
#include "eapol.h"
// .h
namespace Tins {
/**
* \brief Generic EAPOL handshake.
*
* Stores both the client and supplicant addresses, as well as
* all of the EAPOL packets used during the handshake.
*/
template<typename T>
class EAPOLHandshake {
public:
typedef std::vector<T> container_type;
typedef HWAddress<6> address_type;
/**
* \brief Default constructor.
*/
EAPOLHandshake() { }
/**
* Constructs an EAPOLHandshake object.
*
* \param client_address The client address.
* \param supplicant_address The supplicant address.
* \param cont The container that holds the EAPOL packets used
* in the handshake.
*/
EAPOLHandshake(const address_type &client_address,
const address_type &supplicant_address, const container_type &cont)
: cl_address_(client_address), suppl_address_(supplicant_address),
handshake_(cont)
{
}
/**
* \return const address_type&
*/
const address_type &client_address() const {
return cl_address_;
}
/**
* \return const address_type&
*/
const address_type &supplicant_address() const {
return suppl_address_;
}
/**
* \return const container_type&
*/
const container_type &handshake() const {
return handshake_;
}
private:
address_type cl_address_, suppl_address_;
container_type handshake_;
};
/**
* The type used to store RSN handshakes.
*/
typedef EAPOLHandshake<RSNEAPOL> RSNHandshake;
/**
* Captures 802.1X RSN handshakes.
*/
class RSNHandshakeCapturer {
public:
/**
* The type of handshakes that will be captured.
*/
typedef RSNHandshake handshake_type;
/**
* The type in which all of the captured handshakes
* will be stored.
*/
typedef std::vector<handshake_type> handshakes_type;
/**
* \brief Processes a packet.
*
* This will fetch the RSNEAPOL layer, if any, and store
* it in an intermediate storage. When a handshake is
* completed, it will be stored separately.
*
* \sa RSNHandshakeCapturer::handshakes
*/
bool process_packet(const PDU &pdu);
/**
* \brief Retrieves the completed handshakes.
*
* This will return the handshakes that have been completed
* so far. A handshake is completed when the 4-way handshake
* is captured.
*
* \sa RSNHandshakeCapturer::clear_handshakes
*/
const handshakes_type &handshakes() const {
return completed_handshakes_;
}
/**
* \brief Clears the completed handshakes.
*
* Since completed handshakes are stored in a std::vector,
* it is advisable to remove all of them once they have been
* processed.
*/
void clear_handshakes() {
completed_handshakes_.clear();
}
private:
typedef handshake_type::address_type address_type;
typedef handshake_type::container_type eapol_list;
typedef std::map<std::pair<address_type, address_type>, eapol_list> handshake_map;
bool do_insert(const handshake_map::key_type &key, const RSNEAPOL *eapol,
size_t expected);
handshake_map handshakes_;
handshakes_type completed_handshakes_;
};
}
#endif // TINS_HANDSHAKE_CAPTURER_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
#include <iomanip>
#include <iostream>
#include <sstream>
#include "cxxstd.h"
namespace Tins {
/**
@@ -68,6 +69,11 @@ public:
* elements in this address.
*/
static const size_t address_size = n;
/**
* \brief The broadcast address.
*/
static const HWAddress<n, Storage> broadcast;
/**
* \brief Constructor from a const storage_type*.
@@ -137,11 +143,18 @@ public:
*/
template<size_t i>
HWAddress(const HWAddress<i> &rhs) {
std::copy(
rhs.begin(),
rhs.begin() + std::min(i, n),
begin()
// Fill extra bytes
std::fill(
// Copy as most as we can
std::copy(
rhs.begin(),
rhs.begin() + std::min(i, n),
begin()
),
end(),
0
);
}
/**
@@ -226,6 +239,27 @@ public:
return address_size;
}
/**
* \brief Indicates whether this is a broadcast address.
*/
bool is_broadcast() const {
return *this == broadcast;
}
/**
* \brief Indicates whether this is a multicast address.
*/
bool is_multicast() const {
return (buffer[0] & 0x01);
}
/**
* \brief Indicates whether this is an unicast address.
*/
bool is_unicast() const {
return !is_broadcast() && !is_multicast();
}
/**
* \brief Convert this address to a hex-notation std::string address.
*
@@ -236,6 +270,15 @@ public:
oss << *this;
return oss.str();
}
/**
* \brief Retrieves the i-th storage_type in this address.
*
* \param i The element to retrieve.
*/
storage_type operator[](size_t i) const {
return buffer[i];
}
/**
* \brief Writes this HWAddress in hex-notation to a std::ostream.
@@ -295,13 +338,16 @@ void HWAddress<n, Storage>::convert(const std::string &hw_addr,
OutputIterator output)
{
unsigned i(0);
size_t count(0);
storage_type tmp;
while(i < hw_addr.size()) {
while(i < hw_addr.size() && count < n) {
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] >= '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] == ':')
@@ -311,6 +357,7 @@ void HWAddress<n, Storage>::convert(const std::string &hw_addr,
i++;
}
*(output++) = tmp;
count++;
if(i < hw_addr.size()) {
if(hw_addr[i] == ':')
i++;
@@ -318,6 +365,23 @@ void HWAddress<n, Storage>::convert(const std::string &hw_addr,
throw std::runtime_error("Invalid separator");
}
}
while(count++ < n) {
*(output++) = storage_type();
}
}
}
template<size_t n, typename Storage>
const HWAddress<n, Storage> HWAddress<n, Storage>::broadcast("ff:ff:ff:ff:ff:ff");
} // namespace Tins
#if TINS_IS_CXX11
namespace std
{
template<size_t n>
struct hash<Tins::HWAddress<n>> {
size_t operator()(const Tins::HWAddress<n> &addr) const {
return std::hash<std::string>()(addr.to_string());
}
};
} // namespace std
#endif
#endif // TINS_HWADDRESS_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,9 +30,22 @@
#ifndef TINS_ICMP_H
#define TINS_ICMP_H
// Windows likes to define macros with not-so-common-names, which break
// this code
#ifdef WIN32
#ifdef TIMESTAMP_REQUEST
#undef TIMESTAMP_REQUEST
#endif // TIMESTAMP_REQUEST
#ifdef TIMESTAMP_REPLY
#undef TIMESTAMP_REPLY
#endif // TIMESTAMP_REPLY
#endif // WIN32
#include "macros.h"
#include "pdu.h"
#include "endianness.h"
#include "ip_address.h"
namespace Tins {
@@ -48,6 +61,11 @@ namespace Tins {
*/
static const PDU::PDUType pdu_flag = PDU::ICMP;
/**
* The type used to store addresses.
*/
typedef IPv4Address address_type;
/** \brief ICMP flags
*/
enum Flags {
@@ -58,8 +76,12 @@ namespace Tins {
ECHO_REQUEST = 8,
TIME_EXCEEDED = 11,
PARAM_PROBLEM = 12,
TIMESTAMP_REQUEST = 13,
TIMESTAMP_REPLY = 14,
INFO_REQUEST = 15,
INFO_REPLY = 16
INFO_REPLY = 16,
ADDRESS_MASK_REQUEST = 17,
ADDRESS_MASK_REPLY = 18
};
/**
@@ -71,8 +93,13 @@ namespace Tins {
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.
* \brief Constructs an ICMP object from a buffer.
*
* If there is not enough size for an ICMP header, a
* malformed_packet exception is thrown.
*
* Any extra data in the buffer will be stored in a RawPDU.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
@@ -91,13 +118,6 @@ namespace Tins {
*/
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.
*
@@ -115,9 +135,9 @@ namespace Tins {
/**
* \brief Setter for the gateway field.
*
* \param new_gw uint32_t with the new gateway.
* \param new_gw The new value for the gateway field.
*/
void gateway(uint32_t new_gw);
void gateway(address_type new_gw);
/**
* \brief Setter for the mtu field.
@@ -133,6 +153,34 @@ namespace Tins {
*/
void pointer(uint8_t new_pointer);
/**
* \brief Setter for the original timestamp field.
*
* \param new_timestamp the value to be set.
*/
void original_timestamp(uint32_t new_timestamp);
/**
* \brief Setter for the receive timestamp field.
*
* \param new_timestamp the value to be set.
*/
void receive_timestamp(uint32_t new_timestamp);
/**
* \brief Setter for the transmit timestamp field.
*
* \param new_timestamp the value to be set.
*/
void transmit_timestamp(uint32_t new_timestamp);
/**
* \brief Setter for the address mask field.
*
* \param new_mask the value to be set.
*/
void address_mask(address_type new_mask);
/**
* \brief Sets echo request flag for this PDU.
*
@@ -201,7 +249,7 @@ namespace Tins {
* \param address Address of the gateway to which traffic should
* be sent.
*/
void set_redirect(uint8_t icode, uint32_t address);
void set_redirect(uint8_t icode, address_type address);
/**
* \brief Getter for the ICMP type flag.
@@ -222,7 +270,7 @@ namespace Tins {
*
* \return Returns the checksum as an unit16_t.
*/
uint16_t check() const { return Endian::be_to_host(this->_icmp.check); }
uint16_t checksum() const { return Endian::be_to_host(_icmp.check); }
/**
* \brief Getter for the echo id.
@@ -241,23 +289,55 @@ namespace Tins {
/**
* \brief Getter for the gateway field.
*
* \return Returns the gateways in an unit32_t.
* \return Returns the gateway field value.
*/
uint32_t gateway() const { return Endian::be_to_host(this->_icmp.un.gateway); }
address_type gateway() const {
return address_type(Endian::be_to_host(_icmp.un.gateway));
}
/**
* \brief Getter for the pointer field.
*
* \return Returns the pointer value.
* \return Returns the pointer field 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.
* \return Returns the mtu field value.
*/
uint16_t mtu() const { return Endian::be_to_host(this->_icmp.un.frag.mtu); }
uint16_t mtu() const { return Endian::be_to_host(_icmp.un.frag.mtu); }
/**
* \brief Getter for the original timestamp field.
*
* \return Returns the original timestamp value.
*/
uint32_t original_timestamp() const { return Endian::be_to_host(_orig_timestamp_or_address_mask); }
/**
* \brief Getter for the receive timestamp field.
*
* \return Returns the receive timestamp value.
*/
uint32_t receive_timestamp() const { return Endian::be_to_host(_recv_timestamp); }
/**
* \brief Getter for the transmit timestamp field.
*
* \return Returns the transmit timestamp value.
*/
uint32_t transmit_timestamp() const { return Endian::be_to_host(_trans_timestamp); }
/**
* \brief Getter for the address mask field.
*
* \return Returns the address mask value.
*/
address_type address_mask() const {
return address_type(Endian::be_to_host(_orig_timestamp_or_address_mask));
}
/**
* \brief Returns the header size.
@@ -274,7 +354,7 @@ namespace Tins {
* \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);
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Getter for the PDU's type.
@@ -282,17 +362,6 @@ namespace Tins {
* \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
@@ -319,6 +388,8 @@ namespace Tins {
uint8_t pointer;
} un;
} TINS_END_PACK;
void checksum(uint16_t new_check);
/** \brief Serialices this ICMP PDU.
* \param buffer The buffer in which the PDU will be serialized.
@@ -328,6 +399,7 @@ namespace Tins {
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
icmphdr _icmp;
uint32_t _orig_timestamp_or_address_mask, _recv_timestamp, _trans_timestamp;
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@
#include "small_uint.h"
#include "hw_address.h"
#include "small_uint.h"
#include "cxxstd.h"
namespace Tins {
/**
@@ -83,7 +84,7 @@ public:
/**
* The types of ICMPv6 options.
*/
enum Options {
enum OptionTypes {
SOURCE_ADDRESS = 1,
TARGET_ADDRESS,
PREFIX_INFO,
@@ -134,40 +135,63 @@ public:
/**
* The type used to represent ICMPv6 options.
*/
typedef PDUOption<uint8_t> icmpv6_option;
typedef PDUOption<uint8_t, ICMPv6> option;
/**
* The type used to store options.
*/
typedef std::list<icmpv6_option> options_type;
typedef std::list<option> options_type;
/**
* \brief The type used to store the new home agent information
* option data.
*
* The first member contains the home agent preference field, while
* the second one contains the home agent lifetime.
*/
typedef std::pair<uint16_t, uint16_t> new_ha_info_type;
typedef std::vector<uint16_t> new_ha_info_type;
/**
* The type used to store the source/target address list options.
*/
typedef std::vector<ipaddress_type> addr_list_type;
struct addr_list_type {
typedef std::vector<ipaddress_type> addresses_type;
uint8_t reserved[6];
addresses_type addresses;
addr_list_type(const addresses_type &addresses = addresses_type())
: addresses(addresses)
{
std::fill(reserved, reserved + sizeof(reserved), 0);
}
static addr_list_type from_option(const option &opt);
};
/**
* The type used to store the nonce option data.
*/
typedef std::vector<uint8_t> nonce_type;
/**
* The type used to store the MTU option.
*/
typedef std::pair<uint16_t, uint32_t> mtu_type;
/**
* \brief The type used to store the neighbour advertisement
* acknowledgement option data.
*
* The first member contains the option code field, while
* the second one contains the status.
*/
typedef std::pair<uint8_t, uint8_t> naack_type;
struct naack_type {
uint8_t code, status;
uint8_t reserved[4];
naack_type(uint8_t code = 0, uint8_t status = 0)
: code(code), status(status)
{
std::fill(reserved, reserved + 4, 0);
}
static naack_type from_option(const option &opt);
};
/**
* \brief The type used to store the link layer address option data.
@@ -206,6 +230,8 @@ public:
{
}
static lladdr_type from_option(const option &opt);
};
/**
@@ -225,6 +251,8 @@ public:
: prefix_len(prefix_len), A(A), L(L),
valid_lifetime(valid_lifetime), preferred_lifetime(preferred_lifetime),
prefix(prefix) { }
static prefix_info_type from_option(const option &opt);
};
/**
@@ -289,6 +317,8 @@ public:
{
std::fill(key_hash, key_hash + sizeof(key_hash), 0);
}
static rsa_sign_type from_option(const option &opt);
};
/**
@@ -302,6 +332,8 @@ public:
const ipaddress_type &address = ipaddress_type())
: option_code(option_code), prefix_len(prefix_len), address(address)
{}
static ip_prefix_type from_option(const option &opt);
};
/**
@@ -318,6 +350,8 @@ public:
const ipaddress_type &address = ipaddress_type())
: dist(dist), pref(pref), r(r), valid_lifetime(valid_lifetime),
address(address) { }
static map_type from_option(const option &opt);
};
/**
@@ -335,6 +369,8 @@ public:
uint32_t route_lifetime = 0, const prefix_type &prefix = prefix_type())
: prefix_len(prefix_len), pref(pref), route_lifetime(route_lifetime),
prefix(prefix) { }
static route_info_type from_option(const option &opt);
};
/**
@@ -349,6 +385,8 @@ public:
recursive_dns_type(uint32_t lifetime = 0,
const servers_type &servers = servers_type())
: lifetime(lifetime), servers(servers) {}
static recursive_dns_type from_option(const option &opt);
};
/**
@@ -363,6 +401,8 @@ public:
handover_key_req_type(small_uint<4> AT = 0,
const key_type &key = key_type())
: AT(AT), key(key) { }
static handover_key_req_type from_option(const option &opt);
};
/**
@@ -374,6 +414,8 @@ public:
handover_key_reply_type(uint16_t lifetime = 0, small_uint<4> AT = 0,
const key_type &key = key_type())
: handover_key_req_type(AT, key), lifetime(lifetime) { }
static handover_key_reply_type from_option(const option &opt);
};
/**
@@ -388,6 +430,8 @@ public:
handover_assist_info_type(uint8_t option_code=0,
const hai_type &hai = hai_type())
: option_code(option_code), hai(hai) { }
static handover_assist_info_type from_option(const option &opt);
};
/**
@@ -402,6 +446,8 @@ public:
mobile_node_id_type(uint8_t option_code=0,
const mn_type &mn = mn_type())
: option_code(option_code), mn(mn) { }
static mobile_node_id_type from_option(const option &opt);
};
/**
@@ -416,8 +462,58 @@ public:
dns_search_list_type(uint32_t lifetime = 0,
const domains_type &domains = domains_type())
: lifetime(lifetime), domains(domains) { }
static dns_search_list_type from_option(const option &opt);
};
/**
* The type used to store the timestamp option.
*/
struct timestamp_type {
uint8_t reserved[6];
uint64_t timestamp;
timestamp_type(uint64_t timestamp = 0)
: timestamp(timestamp)
{
std::fill(reserved, reserved + sizeof(reserved), 0);
}
static timestamp_type from_option(const option &opt);
};
/**
* The type used to store the shortcut limit option.
*/
struct shortcut_limit_type {
uint8_t limit, reserved1;
uint32_t reserved2;
shortcut_limit_type(uint8_t limit = 0)
: limit(limit), reserved1(), reserved2()
{
}
static shortcut_limit_type from_option(const option &opt);
};
/**
* The type used to store new advertisement interval option.
*/
struct new_advert_interval_type {
uint16_t reserved;
uint32_t interval;
new_advert_interval_type(uint32_t interval = 0)
: reserved(), interval(interval)
{
}
static new_advert_interval_type from_option(const option &opt);
};
/**
* \brief Constructs an ICMPv6 object.
*
@@ -429,8 +525,12 @@ public:
ICMPv6(Types tp = 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.
* \brief Constructs an ICMPv6 object from a buffer.
*
* If there is not enough size for an ICMPv6 header, a
* malformed_packet exception is thrown.
*
* Any 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.
@@ -736,7 +836,21 @@ public:
*
* \param option The option to be added
*/
void add_option(const icmpv6_option &option);
void add_option(const option &option);
#if TINS_IS_CXX11
/**
* \brief Adds an ICMPv6 option.
*
* The option is move-constructed.
*
* \param option The option to be added.
*/
void add_option(option &&option) {
internal_add_option(option);
_options.push_back(std::move(option));
}
#endif
/**
* \brief Returns the header size.
@@ -745,6 +859,15 @@ public:
* 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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Searchs for an option that matchs the given flag.
@@ -755,7 +878,7 @@ public:
*
* \param id The option identifier to be searched.
*/
const icmpv6_option *search_option(Options id) const;
const option *search_option(OptionTypes id) const;
/**
* \sa PDU::clone
@@ -792,33 +915,30 @@ public:
/**
* \brief Setter for the redirect header option.
*
* This method appends the 6 reserved bytes and inserts the
* necessary padding at the end.
*
* \param data The redirect header option data.
*/
void redirect_header(PDU::serialization_type data);
void redirect_header(const byte_array &data);
/**
* \brief Setter for the MTU option.
*
* \param value The MTU option data.
*/
void mtu(uint32_t value);
void mtu(const mtu_type& value);
/**
* \brief Setter for the shortcut limit option.
*
* \param value The shortcut limit option data.
*/
void shortcut_limit(uint8_t value);
void shortcut_limit(const shortcut_limit_type& value);
/**
* \brief Setter for the new advertisement interval option.
*
* \param value The new advertisement interval option data.
*/
void new_advert_interval(uint32_t value);
void new_advert_interval(const new_advert_interval_type &value);
/**
* \brief Setter for the new home agent information option.
@@ -853,7 +973,7 @@ public:
*
* \param value The new timestamp option data.
*/
void timestamp(uint64_t value);
void timestamp(const timestamp_type &value);
/**
* \brief Setter for the new nonce option.
@@ -973,7 +1093,7 @@ public:
* This method will throw an option_not_found exception if the
* option is not found.
*/
PDU::serialization_type redirect_header() const;
byte_array redirect_header() const;
/**
* \brief Getter for the MTU option.
@@ -981,7 +1101,7 @@ public:
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint32_t mtu() const;
mtu_type mtu() const;
/**
* \brief Getter for the shortcut limit option.
@@ -989,7 +1109,7 @@ public:
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint8_t shortcut_limit() const;
shortcut_limit_type shortcut_limit() const;
/**
* \brief Getter for the new advertisement interval option.
@@ -997,7 +1117,7 @@ public:
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint32_t new_advert_interval() const;
new_advert_interval_type new_advert_interval() const;
/**
* \brief Getter for the new home agent information option.
@@ -1037,7 +1157,7 @@ public:
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint64_t timestamp() const;
timestamp_type timestamp() const;
/**
* \brief Getter for the nonce option.
@@ -1181,21 +1301,30 @@ private:
};
} TINS_END_PACK;
void internal_add_option(const option &option);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
bool has_options() const;
uint8_t *write_option(const icmpv6_option &opt, uint8_t *buffer);
uint8_t *write_option(const option &opt, uint8_t *buffer);
void parse_options(const uint8_t *&buffer, uint32_t &total_sz);
void add_addr_list(uint8_t type, const addr_list_type &value);
addr_list_type search_addr_list(Options type) const;
addr_list_type search_addr_list(OptionTypes type) const;
template<template <typename> class Functor>
const icmpv6_option *safe_search_option(Options opt, uint32_t size) const {
const icmpv6_option *option = search_option(opt);
const option *safe_search_option(OptionTypes opt, uint32_t size) const {
const option *option = search_option(opt);
if(!option || Functor<uint32_t>()(option->data_size(), size))
throw option_not_found();
return option;
}
template<typename T>
T search_and_convert(OptionTypes type) const {
const option *opt = search_option(type);
if(!opt)
throw option_not_found();
return opt->to<T>();
}
icmp6hdr _header;
ipaddress_type _target_address, _dest_address;
options_type _options;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,190 +30,10 @@
#ifndef TINS_IEEE802_3_H
#define TINS_IEEE802_3_H
#include <stdint.h>
#include "macros.h"
#include "pdu.h"
#include "endianness.h"
#include "hw_address.h"
#include "network_interface.h"
#include "dot3.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
*/
TINS_BEGIN_PACK
struct ethhdr {
uint8_t dst_mac[address_type::address_size];
uint8_t src_mac[address_type::address_size];
uint16_t length;
} TINS_END_PACK;
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
ethhdr _eth;
NetworkInterface _iface;
};
typedef Dot3 IEEE802_3;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,31 +35,171 @@
#include <stdint.h>
#include "constants.h"
#include "pdu.h"
#include "hw_address.h"
/**
* \cond
*/
namespace Tins {
namespace Internals {
void skip_line(std::istream &input);
bool from_hex(const std::string &str, uint32_t &result);
template<bool, typename>
struct enable_if {
};
class IPv4Address;
class IPv6Address;
template<typename T>
struct enable_if<true, T> {
typedef T type;
};
namespace Internals {
template<size_t n>
class byte_array {
public:
typedef uint8_t* iterator;
typedef const uint8_t* const_iterator;
PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
uint32_t size, bool rawpdu_on_no_match = true);
byte_array() {
std::fill(begin(), end(), 0);
}
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
template<typename InputIterator>
byte_array(InputIterator start, InputIterator last) {
std::copy(start, last, data);
}
template<typename InputIterator>
byte_array(InputIterator start) {
std::copy(start, n, data);
}
uint8_t &operator[](size_t i) {
return data[i];
}
uint8_t operator[](size_t i) const{
return data[i];
}
iterator begin() {
return data;
}
iterator end() {
return data + n;
}
const_iterator begin() const {
return data;
}
const_iterator end() const {
return data + n;
}
size_t size() const {
return n;
}
private:
uint8_t data[n];
};
void skip_line(std::istream &input);
bool from_hex(const std::string &str, uint32_t &result);
template<bool, typename T = void>
struct enable_if {
typedef T type;
};
template<typename T>
struct enable_if<false, T> {
};
PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
uint32_t size, bool rawpdu_on_no_match = true);
PDU *pdu_from_flag(Constants::IP::e flag, const uint8_t *buffer,
uint32_t size, bool rawpdu_on_no_match = true);
PDU *pdu_from_flag(PDU::PDUType type, const uint8_t *buffer, uint32_t size);
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
template<typename T>
bool increment_buffer(T &addr) {
typename T::iterator it = addr.end() - 1;
while(it >= addr.begin() && *it == 0xff) {
*it = 0;
--it;
}
// reached end
if(it < addr.begin())
return true;
(*it)++;
return false;
}
template<typename T>
bool decrement_buffer(T &addr) {
typename T::iterator it = addr.end() - 1;
while(it >= addr.begin() && *it == 0) {
*it = 0xff;
--it;
}
// reached end
if(it < addr.begin())
return true;
(*it)--;
return false;
}
bool increment(IPv4Address &addr);
bool increment(IPv6Address &addr);
bool decrement(IPv4Address &addr);
bool decrement(IPv6Address &addr);
template<size_t n>
bool increment(HWAddress<n> &addr) {
return increment_buffer(addr);
}
template<size_t n>
bool decrement(HWAddress<n> &addr) {
return decrement_buffer(addr);
}
IPv4Address last_address_from_mask(IPv4Address addr, IPv4Address mask);
IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address &mask);
template<size_t n>
HWAddress<n> last_address_from_mask(HWAddress<n> addr, const HWAddress<n> &mask) {
typename HWAddress<n>::iterator addr_iter = addr.begin();
for(typename HWAddress<n>::const_iterator it = mask.begin(); it != mask.end(); ++it, ++addr_iter) {
*addr_iter = *addr_iter | ~*it;
}
return addr;
}
inline bool is_dot3(const uint8_t *ptr, size_t sz) {
return (sz >= 13 && ptr[12] < 8);
}
template<typename T>
struct is_unsigned_integral {
static const bool value = false;
};
template<>
struct is_unsigned_integral<uint8_t> {
static const bool value = true;
};
template<>
struct is_unsigned_integral<uint16_t> {
static const bool value = true;
};
template<>
struct is_unsigned_integral<uint32_t> {
static const bool value = true;
};
template<>
struct is_unsigned_integral<uint64_t> {
static const bool value = true;
};
} // namespace Internals
} // namespace Tins
/**
* \endcond
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
#include "ip_address.h"
#include "pdu_option.h"
#include "macros.h"
#include "cxxstd.h"
namespace Tins {
@@ -168,7 +169,7 @@ namespace Tins {
/**
* The IP options type.
*/
typedef PDUOption<option_identifier> ip_option;
typedef PDUOption<option_identifier, IP> option;
/**
* The type of the security option.
@@ -183,6 +184,8 @@ namespace Tins {
: security(sec), compartments(comp),
handling_restrictions(hand_res), transmission_control(tcc)
{}
static security_type from_option(const option &opt);
};
/**
@@ -197,6 +200,8 @@ namespace Tins {
generic_route_option_type(uint8_t ptr = 0,
routes_type rts = routes_type())
: pointer(ptr), routes(rts) {}
static generic_route_option_type from_option(const option &opt);
};
/**
@@ -217,7 +222,7 @@ namespace Tins {
/**
* The type used to store IP options.
*/
typedef std::list<ip_option> options_type;
typedef std::list<option> options_type;
/**
* \brief Constructor for building the IP PDU.
@@ -228,17 +233,18 @@ namespace Tins {
*
* \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);
address_type ip_src = address_type());
/**
* \brief Constructor which constructs an IP object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
* \brief Constructs an IP object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an IP header, 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.
*/
@@ -302,7 +308,7 @@ namespace Tins {
*
* \return The checksum for this IP PDU.
*/
uint16_t check() const { return Endian::be_to_host(_ip.check); }
uint16_t checksum() const { return Endian::be_to_host(_ip.check); }
/**
* \brief Getter for the source address field.
@@ -331,13 +337,6 @@ namespace Tins {
/* 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.
*
@@ -345,13 +344,6 @@ namespace Tins {
*/
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.
*
@@ -376,17 +368,21 @@ namespace Tins {
/**
* \brief Setter for the protocol field.
*
* Note that this protocol will be overwritten using the
* inner_pdu's protocol type during serialization unless the IP
* datagram is fragmented.
*
* If the packet is fragmented and was originally sniffed, the
* original protocol type will be kept when serialized.
*
* If this packet has been crafted manually and the inner_pdu
* is, for example, a RawPDU, then setting the protocol yourself
* is necessary.
*
* \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.
*
@@ -414,9 +410,37 @@ namespace Tins {
* The option is added after the last option in the option
* fields.
*
* \param option The option to be added
* \param opt The option to be added
*/
void add_option(const ip_option &option);
void add_option(const option &opt);
#if TINS_IS_CXX11
/**
* \brief Adds an IP option.
*
* The option is move-constructed.
*
* \param opt The option to be added.
*/
void add_option(option &&opt) {
internal_add_option(opt);
_ip_options.push_back(std::move(opt));
}
/**
* \brief Adds an IP option.
*
* The option is constructed from the provided parameters.
*
* \param args The arguments to be used in the option's
* constructor.
*/
template<typename... Args>
void add_option(Args&&... args) {
_ip_options.emplace_back(std::forward<Args>(args)...);
internal_add_option(_ip_options.back());
}
#endif
/**
* \brief Searchs for an option that matchs the given flag.
@@ -427,7 +451,7 @@ namespace Tins {
*
* \param id The option identifier to be searched.
*/
const ip_option *search_option(option_identifier id) const;
const option *search_option(option_identifier id) const;
// Option setters
@@ -554,7 +578,7 @@ namespace Tins {
/**
* \sa PDU::send()
*/
void send(PacketSender &sender);
void send(PacketSender &sender, const NetworkInterface &);
/**
* \brief Check wether ptr points to a valid response for this PDU.
@@ -563,7 +587,7 @@ namespace Tins {
* \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);
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Receives a matching response for this packet.
@@ -571,7 +595,14 @@ namespace Tins {
* \sa PDU::recv_response
* \param sender The packet sender which will receive the packet.
*/
PDU *recv_response(PacketSender &sender);
PDU *recv_response(PacketSender &sender, const NetworkInterface &);
/**
* Indicates whether this PDU is fragmented.
*
* \return true if this PDU is fragmented, false otherwise.
*/
bool is_fragmented() const;
/**
* \brief Getter for the PDU's type.
@@ -579,17 +610,6 @@ namespace Tins {
*/
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
*/
@@ -620,15 +640,22 @@ namespace Tins {
/*The options start here. */
} TINS_END_PACK;
void head_len(small_uint<4> new_head_len);
void tot_len(uint16_t new_tot_len);
void prepare_for_serialize(const PDU *parent);
void internal_add_option(const option &option);
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);
uint8_t* write_option(const 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;
void checksum(uint16_t new_check);
iphdr _ip;
uint16_t _options_size, _padded_options_size;
options_type _ip_options;
uint32_t _options_size, _padded_options_size;
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,110 +33,167 @@
#include <string>
#include <iostream>
#include <stdint.h>
#include "cxxstd.h"
namespace Tins {
/**
* \class IPv4Address
* \brief Abstraction of an IPv4 address.
*/
class IPv4Address {
public:
/**
* \class IPv4Address
* \brief Abstraction of an IPv4 address.
* The address size.
*/
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);
static const size_t address_size = sizeof(uint32_t);
/**
* The broadcast address.
*/
static const IPv4Address broadcast;
/**
* \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);
uint32_t ip_addr;
};
}
/**
* \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 Returns true if this is a private IPv4 address.
*
* This takes into account the private network ranges defined in
* RFC 1918. Therefore, this method returns true if this address
* is in any of the following network ranges, false otherwise:
*
* - 192.168.0.0/16
* - 10.0.0.0/8
* - 172.16.0.0/12
*/
bool is_private() const;
/**
* \brief Returns true if this is a loopback IPv4 address.
*
* This method returns true if this address is in the address range
* 127.0.0.0/8, false otherwise.
*/
bool is_loopback() const;
/**
* \brief Returns true if this is a multicast IPv4 address.
*
* This method returns true if this address is in the address range
* 224.0.0.0/4, false otherwise.
*/
bool is_multicast() const;
/**
* \brief Returns true if this is an unicast IPv4 address.
*/
bool is_unicast() const;
/**
* \brief Returns true if this is a broadcast IPv4 address.
*/
bool is_broadcast() const;
/**
* \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;
};
} //namespace Tins
#if TINS_IS_CXX11
namespace std
{
template<>
struct hash<Tins::IPv4Address> {
size_t operator()(const Tins::IPv4Address &addr) const {
return std::hash<uint32_t>()(addr);
}
};
} // namespace std
#endif
#endif // TINS_IPADDRESS_H

216
include/ip_reassembler.h Normal file
View File

@@ -0,0 +1,216 @@
/*
* Copyright (c) 2014, 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_IP_REASSEMBLER_H
#define TINS_IP_REASSEMBLER_H
#include <vector>
#include <map>
#include "pdu.h"
#include "ip_address.h"
namespace Tins {
/**
* \cond
*/
class IP;
namespace Internals {
class IPv4Fragment {
public:
typedef PDU::serialization_type payload_type;
IPv4Fragment() : offset_() { }
template<typename T>
IPv4Fragment(T *pdu, uint16_t offset)
: payload_(pdu->serialize()), offset_(offset)
{
}
const payload_type &payload() const {
return payload_;
}
uint16_t offset() const {
return offset_;
}
private:
payload_type payload_;
uint16_t offset_;
};
class IPv4Stream {
public:
IPv4Stream();
void add_fragment(IP *ip);
bool is_complete() const;
PDU *allocate_pdu() const;
private:
typedef std::vector<IPv4Fragment> fragments_type;
uint16_t extract_offset(const IP *ip);
bool extract_more_frag(const IP *ip);
fragments_type fragments;
bool received_end;
uint8_t transport_proto;
size_t received_size, total_size;
};
} // namespace Internals
/**
* \endcond
*/
/**
* \brief Reassembles fragmented IP packets.
*/
class IPv4Reassembler {
public:
/**
* The status of each processed packet.
*/
enum packet_status {
NOT_FRAGMENTED,
FRAGMENTED,
REASSEMBLED
};
/**
* The type used to represent the overlapped segment
* reassembly technique to be used.
*/
enum overlapping_technique {
NONE
};
/**
* Constructs an IPV4Reassembler.
* \param technique The technique to be used for reassembling
* overlapped fragments.
*/
IPv4Reassembler(overlapping_technique technique = NONE);
/**
* \brief Processes a PDU and tries to reassemble it.
*
* This method tries to reassemble the provided packet. If
* the packet is successfully reassembled using previously
* processed packets, its contents will be modified so that
* it contains the whole payload and not just a fragment.
*
* \param pdu The PDU to process.
* \return NOT_FRAGMENTED if the PDU does not contain an IP
* layer or is not fragmented, FRAGMENTED if the packet is
* fragmented or REASSEMBLED if the packet was fragmented
* but has now been reassembled.
*/
packet_status process(PDU &pdu);
/**
* Removes all of the packets and data stored.
*/
void clear_streams();
/**
* \brief Removes all of the packets and data stored that
* belongs to IP headers whose identifier, source and destination
* addresses are equal to the provided parameters.
*
* \param id The idenfier to search.
* \param addr1 The source address to search.
* \param addr2 The destinatin address to search.
* \sa IP::id
*/
void remove_stream(uint16_t id, IPv4Address addr1, IPv4Address addr2);
private:
typedef std::pair<IPv4Address, IPv4Address> address_pair;
typedef std::pair<uint16_t, address_pair> key_type;
typedef std::map<key_type, Internals::IPv4Stream> streams_type;
key_type make_key(const IP *ip) const;
address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const;
streams_type streams;
overlapping_technique technique;
};
/**
* Proxy functor class that reassembles PDUs.
*/
template<typename Functor>
class IPv4ReassemblerProxy {
public:
/**
* Constructs the proxy from a functor object.
*
* \param func The functor object.
*/
IPv4ReassemblerProxy(Functor func)
: functor_(func)
{
}
/**
* \brief Tries to reassemble the packet and forwards it to
* the functor.
*
* \param pdu The packet to process
* \return true if the packet wasn't forwarded, otherwise
* the value returned by the functor.
*/
bool operator()(PDU &pdu) {
// Forward it unless it's fragmented.
if(reassembler.process(pdu) != IPv4Reassembler::FRAGMENTED)
return functor_(pdu);
else
return true;
}
private:
IPv4Reassembler reassembler;
Functor functor_;
};
/**
* Helper function that creates an IPv4ReassemblerProxy.
*
* \param func The functor object to use in the IPv4ReassemblerProxy.
* \return An IPv4ReassemblerProxy.
*/
template<typename Functor>
IPv4ReassemblerProxy<Functor> make_ipv4_reassembler_proxy(Functor func) {
return IPv4ReassemblerProxy<Functor>(func);
}
}
#endif // TINS_IP_REASSEMBLER_H

264
include/ipsec.h Normal file
View File

@@ -0,0 +1,264 @@
/*
* Copyright (c) 2014, 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_IPSEC_H
#define TINS_IPSEC_H
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
namespace Tins {
/**
* \brief Represents an IPSec Authentication Header.
*/
class IPSecAH : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::IPSEC_AH;
/**
* \brief Default constructor.
*
* The ICV field is initialized with four 0 bytes. The length
* field is initialized appropriately.
*/
IPSecAH();
/**
* \brief Constructs an IPSecAH object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an IPSecAH header, 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.
*/
IPSecAH(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the Next header field.
* \return The stored Next header field value.
*/
uint8_t next_header() const {
return _header.next_header;
}
/**
* \brief Getter for the Length field.
* \return The stored Length field value.
*/
uint8_t length() const {
return _header.length;
}
/**
* \brief Getter for the Security Parameters Index field.
* \return The stored Security Parameters Index field value.
*/
uint32_t spi() const {
return Endian::be_to_host(_header.spi);
}
/**
* \brief Getter for the Sequence number field.
* \return The stored Sequence number field value.
*/
uint32_t seq_number() const {
return Endian::be_to_host(_header.seq_number);
}
/**
* \brief Getter for the ICV field.
* \return The stored ICV field value.
*/
const byte_array &icv() const {
return _icv;
}
// Setters
/**
* \brief Setter for the Next header field.
* \param new_next_header The new Next header field value.
*/
void next_header(uint8_t new_next_header);
/**
* \brief Setter for the Length field.
* \param new_length The new Length field value.
*/
void length(uint8_t new_length);
/**
* \brief Setter for the Security Parameters Index field.
* \param new_spi The new Security Parameters Index field value.
*/
void spi(uint32_t new_spi);
/**
* \brief Setter for the Sequence number field.
* \param new_seq_number The new Sequence number field value.
*/
void seq_number(uint32_t new_seq_number);
/**
* \brief Setter for the ICV field.
* \param new_icv The new ICV field value.
*/
void icv(const byte_array &new_icv);
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_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_flag; }
/**
* \sa PDU::clone
*/
IPSecAH *clone() const {
return new IPSecAH(*this);
}
private:
struct header {
uint8_t next_header, length;
uint32_t spi, seq_number;
};
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
header _header;
byte_array _icv;
};
/**
* \brief Represents an IPSec Authentication Header.
*/
class IPSecESP : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::IPSEC_ESP;
/**
* \brief Default constructor.
*/
IPSecESP();
/**
* \brief Constructs an IPSecESP object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an IPSecESP header, 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.
*/
IPSecESP(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the Security Parameters Index field.
* \return The stored Security Parameters Index field value.
*/
uint32_t spi() const {
return Endian::be_to_host(_header.spi);
}
/**
* \brief Getter for the Sequence number field.
* \return The stored Sequence number field value.
*/
uint32_t seq_number() const {
return Endian::be_to_host(_header.seq_number);
}
// Setters
/**
* \brief Setter for the Security Parameters Index field.
* \param new_spi The new Security Parameters Index field value.
*/
void spi(uint32_t new_spi);
/**
* \brief Setter for the Sequence number field.
* \param new_seq_number The new Sequence number field value.
*/
void seq_number(uint32_t new_seq_number);
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_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_flag; }
/**
* \sa PDU::clone
*/
IPSecESP *clone() const {
return new IPSecESP(*this);
}
private:
struct header {
uint32_t spi, seq_number;
};
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
header _header;
};
}
#endif // TINS_IPSEC_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,12 +60,12 @@ public:
/**
* The type used to represent IPv6 extension headers.
*/
typedef PDUOption<uint8_t> ipv6_ext_header;
typedef PDUOption<uint8_t, IPv6> ext_header;
/**
* The type used to store the extension headers.
*/
typedef std::list<ipv6_ext_header> headers_type;
typedef std::list<ext_header> headers_type;
/**
* The values used to identify extension headers.
@@ -82,17 +82,6 @@ public:
NO_NEXT_HEADER = 59
};
/**
* Exception thrown when an invalid extension header size is
* encountered.
*/
class header_size_error : public std::exception {
public:
const char *what() const throw() {
return "Not enough size for an extension header";
}
};
/**
* \brief Constructs an IPv6 object.
*
@@ -106,9 +95,11 @@ public:
PDU *child = 0);
/**
* \brief Constructor which creates an IPv6 object from a buffer and
* adds all identifiable PDUs found in the buffer as children of this
* one.
* \brief Constructs an IPv6 object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If there is not enough size for an IPv6 header, 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.
@@ -257,6 +248,15 @@ public:
*/
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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \sa PDU::clone
*/
@@ -274,7 +274,7 @@ public:
/**
* \sa PDU::send()
*/
void send(PacketSender &sender);
void send(PacketSender &sender, const NetworkInterface &);
#endif
/**
@@ -282,7 +282,7 @@ public:
*
* \param header The extension header to be added.
*/
void add_ext_header(const ipv6_ext_header &header);
void add_ext_header(const ext_header &header);
/**
* \brief Searchs for an extension header that matchs the given
@@ -294,11 +294,11 @@ public:
*
* \param id The header identifier to be searched.
*/
const ipv6_ext_header *search_header(ExtensionHeader id) const;
const ext_header *search_header(ExtensionHeader id) const;
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
void set_last_next_header(uint8_t value);
static uint8_t *write_header(const ipv6_ext_header &header, uint8_t *buffer);
static uint8_t *write_header(const ext_header &header, uint8_t *buffer);
static bool is_extension_header(uint8_t header_id);
TINS_BEGIN_PACK

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,13 @@
#include <string>
#include <stdexcept>
#include <stdint.h>
#include "cxxstd.h"
namespace Tins {
/**
* Represents an IPv6 address.
*/
class IPv6Address {
public:
/**
@@ -177,6 +182,22 @@ public:
return std::copy(begin(), end(), iter);
}
/**
* \brief Returns true if this is a loopback IPv6 address.
*
* This method returns true if this address is the ::1/128 address,
* false otherwise.
*/
bool is_loopback() const;
/**
* \brief Returns true if this is a multicast IPv6 address.
*
* This method returns true if this address is in the address range
* ff00::/8, false otherwise.
*/
bool is_multicast() const;
/**
* \brief Writes this address in hex-notation to a std::ostream.
*
@@ -192,6 +213,18 @@ private:
uint8_t address[address_size];
};
}
} //namespace Tins
#if TINS_IS_CXX11
namespace std
{
template<>
struct hash<Tins::IPv6Address> {
size_t operator()(const Tins::IPv6Address &addr) const {
return std::hash<std::string>()(addr.to_string());
}
};
} // namespace std
#endif
#endif // TINS_IPV6_ADDRESS

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,10 @@ namespace Tins {
* \brief Represents the LLC global DSAP address.
*/
static const uint8_t GLOBAL_DSAP_ADDR;
/**
* \brief Represents the LLC NULL address.
*/
static const uint8_t NULL_ADDR;
/**
@@ -90,22 +94,25 @@ namespace Tins {
};
/**
* \brief Creates an instance of LLC
* \param child The child PDU.(optional)
* \brief Default constructor.
*/
LLC(PDU *child = 0);
LLC();
/**
* \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.
* \brief Constructs an instance of LLC, setting the dsap and ssap.
* The control field is set 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);
LLC(uint8_t dsap, uint8_t ssap);
/**
* \brief Constructor which creates a LLC object from a buffer and adds all identifiable
* PDUs found in the buffer as children of this one.
* \brief Constructs a LLC object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If there is not enough size for a LLC header, 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.
*/
@@ -299,7 +306,7 @@ namespace Tins {
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::LLC; }
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Delete all the information fields added.
@@ -376,7 +383,6 @@ namespace Tins {
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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,6 @@
#include "pdu.h"
#include "macros.h"
#include "network_interface.h"
namespace Tins {
class Loopback : public PDU {
@@ -48,20 +47,16 @@ public:
* The family identifier is left as zero.
*/
Loopback();
/**
* \brief Construct a Loopback object.
*
* The NetworkInterface object will only be used in *BSD, where
* Null/Loopback PDUs can actually be sent.
*
* \param iface The network interface in which to send this PDU.
* \param inner_pdu The inner pdu to be set.
*/
Loopback(const NetworkInterface &iface, PDU *inner_pdu = 0);
/**
* \brief Construct a Loopback object from a buffer.
* \brief Construct a Loopback object from a buffer and adds
* all identifiable PDUs found in the buffer as children of
* this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a Loopback header, 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.
@@ -89,19 +84,7 @@ public:
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::IP; }
/**
* \brief Getter for the interface member.
*/
const NetworkInterface &iface() const { return _iface; }
/**
* \brief Setter for the interface member.
*
* \param new_iface The new interface to be set.
*/
void iface(const NetworkInterface &new_iface);
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
@@ -114,13 +97,12 @@ public:
/**
* \sa PDU::send()
*/
void send(PacketSender &sender);
void send(PacketSender &sender, const NetworkInterface &iface);
#endif // BSD
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint32_t _family;
NetworkInterface _iface;
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,10 +39,14 @@
#define TINS_BEGIN_PACK __pragma( pack(push, 1) )
#define TINS_END_PACK __pragma( pack(pop) )
#define TINS_PACKED(DECLARATION) __pragma( pack(push, 1) ) DECLARATION __pragma( pack(pop) )
#define TINS_DEPRECATED(func) __declspec(deprecated) func
#define NOEXCEPT
#else
#define TINS_BEGIN_PACK
#define TINS_END_PACK __attribute__((packed))
#define TINS_PACKED(DECLARATION) DECLARATION __attribute__((packed))
#define TINS_DEPRECATED(func) func __attribute__ ((deprecated))
#define NOEXCEPT noexcept
#endif
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -128,6 +128,13 @@ private:
*/
class Packet {
public:
/**
* Tag used to specify that a Packet should own a PDU pointer.
*/
struct own_pdu {
};
/**
* \brief Default constructs a Packet.
*
@@ -143,6 +150,17 @@ public:
*/
Packet(const PDU *apdu, const Timestamp &tstamp)
: pdu_(apdu->clone()), ts(tstamp) { }
/**
* \brief Constructs a Packet from a PDU* and a Timestamp.
*
* The PDU* will be owned by the Packet. This means you
* <b>do not</b> have to explicitly delete the pointer, that
* will be done automatically by the Packet when it goes out
* of scope.
*/
Packet(PDU *apdu, const Timestamp &tstamp, own_pdu)
: pdu_(apdu), ts(tstamp) { }
/**
* \brief Constructs a Packet from a const PDU&.
@@ -197,14 +215,14 @@ public:
/**
* Move constructor.
*/
Packet(Packet &&rhs) noexcept : pdu_(rhs.pdu()), ts(rhs.timestamp()) {
Packet(Packet &&rhs) NOEXCEPT : pdu_(rhs.pdu()), ts(rhs.timestamp()) {
rhs.pdu_ = nullptr;
}
/**
* Move assignment operator.
*/
Packet& operator=(Packet &&rhs) noexcept {
Packet& operator=(Packet &&rhs) NOEXCEPT {
if(this != &rhs) {
std::swap(pdu_, rhs.pdu_);
ts = rhs.timestamp();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
#include <map>
#include "network_interface.h"
#include "macros.h"
#include "cxxstd.h"
struct timeval;
struct sockaddr;
@@ -63,7 +64,9 @@ namespace Tins {
*/
enum SocketType {
ETHER_SOCKET,
IP_SOCKET,
IP_TCP_SOCKET,
IP_UDP_SOCKET,
IP_RAW_SOCKET,
ARP_SOCKET,
ICMP_SOCKET,
IPV6_SOCKET,
@@ -73,9 +76,43 @@ namespace Tins {
/**
* \brief Constructor for PacketSender objects.
*
* \param iface The default interface in which to send the packets.
* \param recv_timeout The timeout which will be used when receiving responses.
*/
PacketSender(uint32_t recv_timeout = DEFAULT_TIMEOUT, uint32_t usec = 0);
PacketSender(const NetworkInterface &iface = NetworkInterface(),
uint32_t recv_timeout = DEFAULT_TIMEOUT, uint32_t usec = 0);
#if TINS_IS_CXX11
/**
* \brief Move constructor.
* \param rhs The sender to be moved.
*/
PacketSender(PacketSender &&rhs) NOEXCEPT {
*this = std::move(rhs);
}
/**
* \brief Move assignment operator.
* \param rhs The sender to be moved.
*/
PacketSender& operator=(PacketSender &&rhs) NOEXCEPT {
_sockets = std::move(rhs._sockets);
rhs._sockets = std::vector<int>(SOCKETS_END, INVALID_RAW_SOCKET);
#ifndef WIN32
#if defined(BSD) || defined(__FreeBSD_kernel__)
_ether_socket = std::move(rhs._ether_socket);
#else
_ether_socket = rhs._ether_socket;
rhs._ether_socket = INVALID_RAW_SOCKET;
#endif
#endif
_types = rhs._types; // no move
_timeout = rhs._timeout;
_timeout_usec = rhs._timeout_usec;
default_iface = rhs.default_iface;
return *this;
}
#endif
/**
* \brief PacketSender destructor.
@@ -88,7 +125,7 @@ namespace Tins {
/**
* \brief Opens a layer 2 socket.
*
* If this operation fails, then a SocketOpenError will be thrown.
* If this operation fails, then a socket_open_error will be thrown.
*/
void open_l2_socket(const NetworkInterface& iface = NetworkInterface());
#endif // WIN32
@@ -97,9 +134,9 @@ namespace Tins {
* \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.
* If this operation fails, then a socket_open_error will be thrown.
* If the provided socket type is not valid, an invalid_socket_type
* exception will be throw.
*
* \param type The type of socket which will be used to pick the protocol flag
* for this socket.
@@ -110,26 +147,63 @@ namespace Tins {
* \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.
* exists, an invalid_socket_type exception is thrown.
*
* If any socket close errors are encountered, a SocketCloseError
* If any socket close errors are encountered, a socket_close_error
* is thrown.
*
* \param type The type of the socket to be closed.
*/
void close_socket(SocketType type, const NetworkInterface &iface = NetworkInterface());
/**
* \brief Sets the default interface.
*
* The interface will be used whenever PacketSender::send(PDU&)
* is called.
*/
void default_interface(const NetworkInterface &iface);
/**
* \brief Gets the default interface.
*
* \sa PacketSender::default_interface
*/
const NetworkInterface& default_interface() const;
/**
* \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.
* If any send error occurs, then a socket_write_error is thrown.
*
* If the PDU contains a link layer protocol, then default_interface
* is used.
*
* \sa PacketSender::default_interface
*
* \param pdu The PDU to be sent.
*/
void send(PDU &pdu);
/**
* \brief Sends a PDU.
*
* \sa PacketSender::send
*
* This overload takes a NetworkInterface. The packet is sent
* through that interface if a link-layer PDU is present,
* otherwise this call is equivalent to send(PDU&).
*
* The interface stored in the link layer PDU(if any), is restored
* after this method ends.
*
* \param pdu The PDU to be sent.
* \param iface The network interface to use.
*/
void send(PDU &pdu, const NetworkInterface &iface);
/**
* \brief Sends a PDU and waits for its response.
@@ -143,6 +217,20 @@ namespace Tins {
* \return Returns the response PDU, 0 if not response was received.
*/
PDU *send_recv(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.
* \param iface The network interface in which to send and receive.
* \return Returns the response PDU, 0 if not response was received.
*/
PDU *send_recv(PDU &pdu, const NetworkInterface &iface);
#ifndef WIN32
/**
@@ -166,7 +254,7 @@ namespace Tins {
* using the corresponding flag, according to the given type of
* protocol.
*
* If any socket write error occurs, a SocketWriteError is thrown.
* If any socket write error occurs, a socket_write_error is thrown.
*
* \param pdu The PDU to send.
* \param link_addr The sockaddr struct which will be used to send the PDU.
@@ -196,7 +284,7 @@ namespace Tins {
* 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.
* If any socket write error occurs, a socket_write_error is thrown.
*
* \param pdu The PDU to send.
* \param link_addr The sockaddr struct which will be used to send the PDU.
@@ -209,18 +297,25 @@ namespace Tins {
typedef std::map<SocketType, int> SocketTypeMap;
PacketSender(const PacketSender&);
PacketSender& operator=(const PacketSender&);
int find_type(SocketType type);
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
#ifndef WIN32
bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
int get_ether_socket(const NetworkInterface& iface = NetworkInterface());
bool ether_socket_initialized(const NetworkInterface& iface = NetworkInterface()) const;
int get_ether_socket(const NetworkInterface& iface = NetworkInterface());
#endif
template<typename T>
void send(PDU &pdu, const NetworkInterface &iface) {
static_cast<T&>(pdu).send(*this, iface);
}
PDU *recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen);
PDU *recv_match_loop(const std::vector<int>& sockets, PDU &pdu, struct sockaddr* link_addr,
uint32_t addrlen);
std::vector<int> _sockets;
#ifndef WIN32
#ifdef BSD
#if defined(BSD) || defined(__FreeBSD_kernel__)
typedef std::map<uint32_t, int> BSDEtherSockets;
BSDEtherSockets _ether_socket;
#else
@@ -229,32 +324,11 @@ namespace Tins {
#endif
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";
}
NetworkInterface default_iface;
// In BSD we need to store the buffer size, retrieved using BIOCGBLEN
#if defined(BSD) || defined(__FreeBSD_kernel__)
int buffer_size;
#endif
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@ public:
RADIOTAP = DLT_IEEE802_11_RADIO,
DOT11 = DLT_IEEE802_11,
ETH2 = DLT_EN10MB,
DOT3 = DLT_EN10MB,
SLL = DLT_LINUX_SLL
};
@@ -75,7 +76,9 @@ public:
*
* \param rhs The PacketWriter to be moved.
*/
PacketWriter(PacketWriter &&rhs) noexcept;
PacketWriter(PacketWriter &&rhs) NOEXCEPT {
*this = std::move(rhs);
}
/**
* \brief Move assignment operator.
@@ -85,7 +88,13 @@ public:
*
* \param rhs The PacketWriter to be moved.
*/
PacketWriter& operator=(PacketWriter &&rhs) noexcept;
PacketWriter& operator=(PacketWriter &&rhs) NOEXCEPT {
handle = 0;
dumper = 0;
std::swap(handle, rhs.handle);
std::swap(dumper, rhs.dumper);
return *this;
}
#endif
/**
@@ -98,6 +107,18 @@ public:
*/
void write(PDU &pdu);
/**
* \brief Writes a PDU to this file.
*
* The template parameter T must at some point yield a PDU& after
* applying operator* one or more than one time. This accepts both
* raw and smart pointers.
*/
template<typename T>
void write(T &pdu) {
write(Utils::dereference_until_pdu(pdu));
}
/**
* \brief Writes all the PDUs in the range [start, end)
* \param start A forward iterator pointing to the first PDU

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,12 +33,21 @@
#include <stdint.h>
#include <vector>
#include "macros.h"
#include "cxxstd.h"
#include "exceptions.h"
/** \brief The Tins namespace.
*/
namespace Tins {
class PacketSender;
class NetworkInterface;
/**
* The type used to store several PDU option values.
*/
typedef std::vector<uint8_t> byte_array;
/** \brief Base class for protocol data units.
*
@@ -54,7 +63,15 @@ namespace Tins {
/**
* The type that will be returned when serializing PDUs.
*/
typedef std::vector<uint8_t> serialization_type;
typedef byte_array serialization_type;
/**
* The typep used to identify the endianness of every PDU.
*/
enum endian_type {
BE,
LE
};
/**
* \brief Enum which identifies each type of PDU.
@@ -105,18 +122,52 @@ namespace Tins {
IPv6,
ICMPv6,
SLL,
DHCPv6
DHCPv6,
DOT1Q,
PPPOE,
STP,
PPI,
IPSEC_AH,
IPSEC_ESP,
USER_DEFINED_PDU = 1000
};
/** \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.
/**
* The endianness used by this PDU. This can be overriden
* by subclasses.
*/
PDU(PDU *next_pdu = 0);
static const endian_type endianness = BE;
/** \brief PDU destructor.
/**
* \brief Default constructor.
*/
PDU();
#if TINS_IS_CXX11
/**
* \brief Move constructor.
*
* \param rhs The PDU to be moved.
*/
PDU(PDU &&rhs) NOEXCEPT
: _inner_pdu(0)
{
std::swap(_inner_pdu, rhs._inner_pdu);
}
/**
* \brief Move assignment operator.
*
* \param rhs The PDU to be moved.
*/
PDU& operator=(PDU &&rhs) NOEXCEPT {
std::swap(_inner_pdu, rhs._inner_pdu);
return *this;
}
#endif
/**
* \brief PDU destructor.
*
* Deletes the inner pdu, as a consequence every child pdu is
* deleted.
@@ -163,11 +214,21 @@ namespace Tins {
/**
* \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.
*
* \param next_pdu The new child PDU.
*/
void inner_pdu(PDU *next_pdu);
/**
* \brief Sets the child PDU.
*
* The PDU parameter is cloned using PDU::clone.
*
* \param next_pdu The new child PDU.
*/
void inner_pdu(const PDU &next_pdu);
/**
@@ -182,14 +243,14 @@ namespace Tins {
serialization_type serialize();
/**
* \brief Find and returns the first PDU that matches the given flag.
* \brief Finds 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>
template<typename T>
T *find_pdu(PDUType type = T::pdu_flag) {
PDU *pdu = this;
while(pdu) {
@@ -201,15 +262,42 @@ namespace Tins {
}
/**
* \brief Find and returns the first PDU that matches the given flag.
* \brief Finds and returns the first PDU that matches the given flag.
*
* \param flag The flag which being searched.
*/
template<class T>
template<typename T>
const T *find_pdu(PDUType type = T::pdu_flag) const {
return const_cast<PDU*>(this)->find_pdu<T>();
}
/**
* \brief Finds and returns the first PDU that matches the given flag.
*
* If the PDU is not found, a pdu_not_found exception is thrown.
*
* \sa PDU::find_pdu
*
* \param flag The flag which being searched.
*/
template<typename T>
T &rfind_pdu(PDUType type = T::pdu_flag) {
T *ptr = find_pdu<T>(type);
if(!ptr)
throw pdu_not_found();
return *ptr;
}
/**
* \brief Finds and returns the first PDU that matches the given flag.
*
* \param flag The flag which being searched.
*/
template<typename T>
const T &rfind_pdu(PDUType type = T::pdu_flag) const {
return const_cast<PDU*>(this)->rfind_pdu<T>();
}
/**
* \brief Clones this packet.
*
@@ -220,25 +308,37 @@ namespace Tins {
*/
virtual PDU *clone() const = 0;
/** \brief Send the stack of PDUs through a PacketSender.
/**
* \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.
*
* If this PDU does not represent a link layer protocol, then
* the interface argument will be ignored.
*
* \param sender The PacketSender which will send the packet.
* \param iface The network interface in which this packet will
* be sent.
*/
virtual void send(PacketSender &sender);
virtual void send(PacketSender &sender, const NetworkInterface &iface);
/** \brief Receives a matching response for this packet.
/**
* \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.
* \param iface The interface in which to expect the response.
*/
virtual PDU *recv_response(PacketSender &sender);
virtual PDU *recv_response(PacketSender &sender, const NetworkInterface &iface);
/** \brief Check wether ptr points to a valid response for this PDU.
/**
* \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
@@ -247,7 +347,9 @@ namespace Tins {
* \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; }
virtual bool matches_response(const uint8_t *ptr, uint32_t total_sz) const {
return false;
}
/**
* \brief Check wether this PDU matches the specified flag.
@@ -267,15 +369,6 @@ namespace Tins {
* \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.
@@ -293,6 +386,20 @@ namespace Tins {
*/
void copy_inner_pdu(const PDU &pdu);
/**
* \brief Prepares this PDU for serialization.
*
* This method is called before the inner PDUs are serialized.
* It's useful in situations such as when serializing IP PDUs,
* which don't contain any link layer encapsulation, and therefore
* require to set the source IP address before the TCP/UDP checksum
* is calculated.
*
* By default, this method does nothing
*
* \param parent The parent PDU.
*/
virtual void prepare_for_serialize(const PDU *parent) { }
/**
* \brief Serializes this PDU and propagates this action to child PDUs.
@@ -303,16 +410,6 @@ namespace Tins {
*/
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.
*
@@ -375,6 +472,34 @@ namespace Tins {
*lop /= rop;
return lop;
}
namespace Internals {
template<typename T>
struct remove_pointer {
typedef T type;
};
template<typename T>
struct remove_pointer<T*> {
typedef T type;
};
}
template<typename T, typename U>
T tins_cast(U *pdu) {
typedef typename Internals::remove_pointer<T>::type TrueT;
return pdu && (TrueT::pdu_flag == pdu->pdu_type()) ?
static_cast<T>(pdu) :
0;
}
template<typename T, typename U>
T &tins_cast(U &pdu) {
T *ptr = tins_cast<T*>(&pdu);
if(!ptr)
throw bad_tins_cast();
return *ptr;
}
}
#endif // TINS_PDU_H

182
include/pdu_allocator.h Normal file
View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2014, 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_PDU_ALLOCATOR_H
#define TINS_PDU_ALLOCATOR_H
#include <map>
#include "pdu.h"
namespace Tins {
/**
* \cond
*/
class EthernetII;
class SNAP;
class Dot1Q;
class SLL;
class IP;
class IPv6;
namespace Internals {
template<typename PDUType>
PDU *default_allocator(const uint8_t *buffer, uint32_t size)
{
return new PDUType(buffer, size);
}
template<typename Tag>
class PDUAllocator {
public:
typedef typename Tag::identifier_type id_type;
typedef PDU *(*allocator_type)(const uint8_t *, uint32_t);
template<typename PDUType>
static void register_allocator(id_type identifier)
{
allocators[identifier] = &default_allocator<PDUType>;
pdu_types[PDUType::pdu_flag] = identifier;
}
static PDU *allocate(id_type identifier, const uint8_t *buffer, uint32_t size)
{
typename allocators_type::const_iterator it = allocators.find(identifier);
return (it == allocators.end()) ? 0 : (*it->second)(buffer, size);
}
static bool pdu_type_registered(PDU::PDUType type)
{
return pdu_types.count(type) != 0;
}
static id_type pdu_type_to_id(PDU::PDUType type)
{
typename pdu_map_types::const_iterator it = pdu_types.find(type);
return it->second;
}
private:
typedef std::map<id_type, allocator_type> allocators_type;
typedef std::map<PDU::PDUType, id_type> pdu_map_types;
static allocators_type allocators;
static pdu_map_types pdu_types;
};
template<typename Tag>
typename PDUAllocator<Tag>::allocators_type PDUAllocator<Tag>::allocators;
template<typename Tag>
typename PDUAllocator<Tag>::pdu_map_types PDUAllocator<Tag>::pdu_types;
template<typename IDType>
struct pdu_tag {
typedef IDType identifier_type;
};
template<typename PDUType>
struct pdu_tag_mapper;
#define TINS_GENERATE_TAG_MAPPER(pdu, id_type) \
template<> \
struct pdu_tag_mapper<pdu> { \
typedef pdu_tag<id_type> type; \
};
TINS_GENERATE_TAG_MAPPER(EthernetII, uint16_t)
TINS_GENERATE_TAG_MAPPER(SNAP, uint16_t)
TINS_GENERATE_TAG_MAPPER(SLL, uint16_t)
TINS_GENERATE_TAG_MAPPER(Dot1Q, uint16_t)
TINS_GENERATE_TAG_MAPPER(IP, uint8_t)
TINS_GENERATE_TAG_MAPPER(IPv6, uint8_t)
#undef TINS_GENERATE_TAG_MAPPER
template<typename PDUType>
PDU* allocate(
typename pdu_tag_mapper<PDUType>::type::identifier_type id,
const uint8_t *buffer,
uint32_t size)
{
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::allocate(id, buffer, size);
}
template<typename PDUType>
bool pdu_type_registered(PDU::PDUType type)
{
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_registered(type);
}
template<typename PDUType>
typename pdu_tag_mapper<PDUType>::type::identifier_type pdu_type_to_id(PDU::PDUType type)
{
return PDUAllocator<typename pdu_tag_mapper<PDUType>::type>::pdu_type_to_id(type);
}
} // namespace Interals
/**
* \endcond
*/
/**
* \brief Defines inner PDU allocators.
*/
namespace Allocators {
/**
* \brief Registers an allocator for the provided PDU type.
*
* Registering a certain allocator for a PDU type is useful for
* extending the library. Once an allocator is registered, it will
* be taken into account while constructing a PDU from a buffer.
*
* If PDU finds that it cannot define which is the protocol
* that should be allocated based on its protocol identifier, it
* will try using the registered allocators if any.
*
* \code
* // Register the 0x666 identifer. Now if EthernetII finds a
* // network layer identifier field whose value is 0x666, it will
* // use SomePDUType as its inner PDU type.
* Allocators::register_allocator<EthernetII, SomePDUType>(0x666);
* \endcode
*
* Note that some PDU types are grouped together. For example,
* registering an allocator for EthernetII will make it work for
* the rest of the link layer protocols, sine they should all work
* the same way.
*/
template<typename PDUType, typename AllocatedType>
void register_allocator(typename Internals::pdu_tag_mapper<PDUType>::type::identifier_type id)
{
Internals::PDUAllocator<
typename Internals::pdu_tag_mapper<PDUType>::type
>::template register_allocator<AllocatedType>(id);
}
} // namespace Allocators
} // namespace Tins
#endif // TINS_PDU_ALLOCATOR_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
#include <algorithm>
#include "pdu.h"
#include "macros.h"
namespace Tins {
/**
@@ -94,21 +95,21 @@ public:
/**
* Forwards the call to the cached PDU. \sa PDU::send.
*/
void send(PacketSender &sender) {
cached.send(sender);
void send(PacketSender &sender, const NetworkInterface &iface) {
cached.send(sender, iface);
}
/**
* Forwards the call to the cached PDU. \sa PDU::recv_responde.
*/
PDU *recv_response(PacketSender &sender) {
return cached.recv_response(sender);
PDU *recv_response(PacketSender &sender, const NetworkInterface &iface) {
return cached.recv_response(sender, iface);
}
/**
* Forwards the call to the cached PDU. \sa PDU::matches_response.
*/
bool matches_response(uint8_t *ptr, uint32_t total_sz) {
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const {
return cached.matches_response(ptr, total_sz);
}
@@ -125,13 +126,6 @@ public:
PDUType pdu_type() const {
return cached.pdu_type();
}
/**
* Forwards the call to the cached PDU. \sa PDU::clone_packet.
*/
PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz) {
return cached.clone_packet(ptr, total_sz);
}
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
if(cached_serialization.size() != total_sz) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,19 +32,260 @@
#include <vector>
#include <iterator>
#include <cstring>
#include <algorithm>
#include <string>
#include <stdint.h>
#include "exceptions.h"
#include "endianness.h"
#include "internals.h"
#include "ip_address.h"
#include "ipv6_address.h"
#include "hw_address.h"
namespace Tins {
/**
* \brief Exception thrown when an option is not found.
* \cond
*/
class option_not_found : public std::exception {
public:
const char* what() const throw() {
return "Option not found";
template<typename OptionType, class PDUType>
class PDUOption;
namespace Internals {
template<typename T, typename X, typename PDUType>
T convert_to_integral(const PDUOption<X, PDUType> & opt) {
if(opt.data_size() != sizeof(T))
throw malformed_option();
T data = *(T*)opt.data_ptr();
if(PDUType::endianness == PDUType::BE)
data = Endian::be_to_host(data);
else
data = Endian::le_to_host(data);
return data;
}
};
template<typename T, typename = void>
struct converter {
template<typename X, typename PDUType>
static T convert(const PDUOption<X, PDUType>& opt) {
return T::from_option(opt);
}
};
template<>
struct converter<uint8_t> {
template<typename X, typename PDUType>
static uint8_t convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() != 1)
throw malformed_option();
return *opt.data_ptr();
}
};
template<>
struct converter<uint16_t> {
template<typename X, typename PDUType>
static uint16_t convert(const PDUOption<X, PDUType>& opt) {
return convert_to_integral<uint16_t>(opt);
}
};
template<>
struct converter<uint32_t> {
template<typename X, typename PDUType>
static uint32_t convert(const PDUOption<X, PDUType>& opt) {
return convert_to_integral<uint32_t>(opt);
}
};
template<>
struct converter<uint64_t> {
template<typename X, typename PDUType>
static uint64_t convert(const PDUOption<X, PDUType>& opt) {
return convert_to_integral<uint64_t>(opt);
}
};
template<size_t n>
struct converter<HWAddress<n> > {
template<typename X, typename PDUType>
static HWAddress<n> convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() != n)
throw malformed_option();
return HWAddress<n>(opt.data_ptr());
}
};
template<>
struct converter<IPv4Address> {
template<typename X, typename PDUType>
static IPv4Address convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() != sizeof(uint32_t))
throw malformed_option();
const uint32_t *ptr = (const uint32_t*)opt.data_ptr();
if(PDUType::endianness == PDUType::BE)
return IPv4Address(*ptr);
else
return IPv4Address(Endian::change_endian(*ptr));
}
};
template<>
struct converter<IPv6Address> {
template<typename X, typename PDUType>
static IPv6Address convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() != IPv6Address::address_size)
throw malformed_option();
return IPv6Address(opt.data_ptr());
}
};
template<>
struct converter<std::string> {
template<typename X, typename PDUType>
static std::string convert(const PDUOption<X, PDUType>& opt) {
return std::string(
opt.data_ptr(),
opt.data_ptr() + opt.data_size()
);
}
};
template<>
struct converter<std::vector<float> > {
template<typename X, typename PDUType>
static std::vector<float> convert(const PDUOption<X, PDUType>& opt) {
std::vector<float> output;
const uint8_t *ptr = opt.data_ptr(), *end = ptr + opt.data_size();
while(ptr != end) {
output.push_back(float(*(ptr++) & 0x7f) / 2);
}
return output;
}
};
template<typename T>
struct converter<std::vector<T>, typename enable_if<is_unsigned_integral<T>::value>::type> {
template<typename X, typename PDUType>
static std::vector<T> convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() % sizeof(T) != 0)
throw malformed_option();
const T *ptr = (const T*)opt.data_ptr();
const T *end = (const T*)(opt.data_ptr() + opt.data_size());
std::vector<T> output(std::distance(ptr, end));
typename std::vector<T>::iterator it = output.begin();
while(ptr < end) {
if(PDUType::endianness == PDUType::BE)
*it++ = Endian::be_to_host(*ptr++);
else
*it++ = Endian::le_to_host(*ptr++);
}
return output;
}
};
template<typename T, typename U>
struct converter<
std::vector<std::pair<T, U> >,
typename enable_if<
is_unsigned_integral<T>::value && is_unsigned_integral<U>::value
>::type
> {
template<typename X, typename PDUType>
static std::vector<std::pair<T, U> > convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() % (sizeof(T) + sizeof(U)) != 0)
throw malformed_option();
const uint8_t *ptr = opt.data_ptr(), *end = ptr + opt.data_size();
std::vector<std::pair<T, U> > output;
while(ptr < end) {
std::pair<T, U> data;
data.first = *(const T*)ptr;
ptr += sizeof(T);
data.second = *(const U*)ptr;
ptr += sizeof(U);
if(PDUType::endianness == PDUType::BE) {
data.first = Endian::be_to_host(data.first);
data.second = Endian::be_to_host(data.second);
}
else {
data.first = Endian::le_to_host(data.first);
data.second = Endian::le_to_host(data.second);
}
output.push_back(data);
}
return output;
}
};
template<>
struct converter<std::vector<IPv4Address> > {
template<typename X, typename PDUType>
static std::vector<IPv4Address> convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() % 4 != 0)
throw malformed_option();
const uint32_t *ptr = (const uint32_t*)opt.data_ptr();
const uint32_t *end = (const uint32_t*)(opt.data_ptr() + opt.data_size());
std::vector<IPv4Address> output(std::distance(ptr, end));
std::vector<IPv4Address>::iterator it = output.begin();
while(ptr < end) {
if(PDUType::endianness == PDUType::BE)
*it++ = IPv4Address(*ptr++);
else
*it++ = IPv4Address(Endian::change_endian(*ptr++));
}
return output;
}
};
template<>
struct converter<std::vector<IPv6Address> > {
template<typename X, typename PDUType>
static std::vector<IPv6Address> convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() % IPv6Address::address_size != 0)
throw malformed_option();
const uint8_t *ptr = opt.data_ptr(), *end = opt.data_ptr() + opt.data_size();
std::vector<IPv6Address> output;
while(ptr < end) {
output.push_back(IPv6Address(ptr));
ptr += IPv6Address::address_size;
}
return output;
}
};
template<typename T, typename U>
struct converter<
std::pair<T, U>,
typename enable_if<
is_unsigned_integral<T>::value && is_unsigned_integral<U>::value
>::type
> {
template<typename X, typename PDUType>
static std::pair<T, U> convert(const PDUOption<X, PDUType>& opt) {
if(opt.data_size() != sizeof(T) + sizeof(U))
throw malformed_option();
std::pair<T, U> output;
std::memcpy(&output.first, opt.data_ptr(), sizeof(T));
std::memcpy(&output.second, opt.data_ptr() + sizeof(T), sizeof(U));
if(PDUType::endianness == PDUType::BE) {
output.first = Endian::be_to_host(output.first);
output.second = Endian::be_to_host(output.second);
}
else {
output.first = Endian::le_to_host(output.first);
output.second = Endian::le_to_host(output.second);
}
return output;
}
};
}
/**
* \endcond
*/
/**
* \class PDUOption
* \brief Represents a PDU option field.
@@ -55,17 +296,13 @@ public:
*
* 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> >
template<typename OptionType, class PDUType>
class PDUOption {
private:
static const int small_buffer_size = 8;
public:
typedef Container container_type;
typedef typename container_type::value_type data_type;
typedef uint8_t data_type;
typedef OptionType option_type;
/**
@@ -75,10 +312,79 @@ public:
* \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);
: option_(opt), size_(length) {
set_payload_contents(data, data + (data ? length : 0));
}
/**
* \brief Copy constructor.
* \param rhs The PDUOption to be copied.
*/
PDUOption(const PDUOption& rhs) {
real_size_ = 0;
*this = rhs;
}
#if TINS_IS_CXX11
/**
* \brief Move constructor.
* \param rhs The PDUOption to be moved.
*/
PDUOption(PDUOption&& rhs) {
real_size_ = 0;
*this = std::move(rhs);
}
/**
* \brief Move assignment operator.
* \param rhs The PDUOption to be moved.
*/
PDUOption& operator=(PDUOption&& rhs) {
option_ = rhs.option_;
size_ = rhs.size_;
if(real_size_ > small_buffer_size) {
delete[] payload_.big_buffer_ptr;
}
real_size_ = rhs.real_size_;
if(real_size_ > small_buffer_size) {
payload_.big_buffer_ptr = nullptr;
std::swap(payload_.big_buffer_ptr, rhs.payload_.big_buffer_ptr);
rhs.real_size_ = 0;
}
else {
std::copy(
rhs.data_ptr(),
rhs.data_ptr() + rhs.data_size(),
payload_.small_buffer
);
}
return *this;
}
#endif // TINS_IS_CXX11
/**
* \brief Copy assignment operator.
* \param rhs The PDUOption to be copied.
*/
PDUOption& operator=(const PDUOption& rhs) {
option_ = rhs.option_;
size_ = rhs.size_;
if(real_size_ > small_buffer_size) {
delete[] payload_.big_buffer_ptr;
}
real_size_ = rhs.real_size_;
set_payload_contents(rhs.data_ptr(), rhs.data_ptr() + rhs.data_size());
return *this;
}
/**
* \brief Destructor.
*/
~PDUOption() {
if(real_size_ > small_buffer_size) {
delete[] payload_.big_buffer_ptr;
}
}
/**
@@ -91,9 +397,29 @@ public:
*/
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);
: option_(opt), size_(std::distance(start, end)) {
set_payload_contents(start, end);
}
/**
* \brief Constructs a PDUOption from iterators, which
* indicate the data to be stored in it.
*
* The length parameter indicates the contents of the length field
* when this option is serialized. Note that this can be different
* to std::distance(start, end).
*
* \sa length_field
*
* \param opt The option type.
* \param length The length of this option.
* \param start The beginning of the option data.
* \param end The end of the option data.
*/
template<typename ForwardIterator>
PDUOption(option_type opt, size_t length, ForwardIterator start, ForwardIterator end)
: option_(opt), size_(length) {
set_payload_contents(start, end);
}
/**
@@ -122,18 +448,74 @@ public:
* \return const data_type& containing this option's value.
*/
const data_type *data_ptr() const {
return &*(++value_.begin());
return real_size_ <= small_buffer_size ?
payload_.small_buffer :
payload_.big_buffer_ptr;
}
/**
* Retrieves the length of this option's data.
* \brief Retrieves the length of this option's data.
*
* This is the actual size of the data.
*/
size_t data_size() const {
return value_.empty() ? 0 : (value_.size() - 1);
return real_size_;
}
/**
* \brief Retrieves the data length field.
*
* This is what the size field will contain when this option is
* serialized. It can differ from the actual data size.
*
* This will be equal to data_size unless the constructor that takes
* both a data length and two iterators is used.
*
* \sa data_size.
*/
size_t length_field() const {
return size_;
}
/**
* \brief Constructs a T from this PDUOption.
*
* Use this method to convert a PDUOption to the specific type that
* represents it. For example, if you know an option is of type
* PDU::SACK, you could use option.to<TCP::sack_type>().
*/
template<typename T>
T to() const {
return Internals::converter<T>::convert(*this);
}
private:
template<typename ForwardIterator>
void set_payload_contents(ForwardIterator start, ForwardIterator end) {
real_size_ = std::distance(start, end);
if(real_size_ <= small_buffer_size) {
std::copy(
start,
end,
payload_.small_buffer
);
}
else {
payload_.big_buffer_ptr = new data_type[real_size_];
std::copy(
start,
end,
payload_.big_buffer_ptr
);
}
}
option_type option_;
container_type value_;
uint16_t size_, real_size_;
union {
data_type small_buffer[small_buffer_size];
data_type* big_buffer_ptr;
} payload_;
};
} // namespace Tins
#endif // TINS_PDU_OPTION_H

134
include/ppi.h Normal file
View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2014, 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_PPI_H
#define TINS_PPI_H
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
namespace Tins {
/**
* \brief Represents a Per-Packet Information PDU.
*
* This PDU can only be constructed from a buffer, and
* cannot be serialized. Therefore, it is only useful while
* sniffing packets.
*/
class PPI : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::PPI;
/**
* \brief Constructs an PPI object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an PPI header, 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.
*/
PPI(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the version field.
* \return The stored version field value.
*/
uint8_t version() const {
return _header.version;
}
/**
* \brief Getter for the flags field.
* \return The stored flags field value.
*/
uint8_t flags() const {
return _header.flags;
}
/**
* \brief Getter for the length field.
* \return The stored length field value.
*/
uint16_t length() const {
return Endian::le_to_host(_header.length);
}
/**
* \brief Getter for the Data Link Type field.
* \return The stored Data Link Type field value.
*/
uint32_t dlt() const {
return Endian::le_to_host(_header.dlt);
}
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_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_flag; }
/**
* \brief Clones this PDU.
*
* \sa PDU::clone
*/
PPI *clone() const {
return new PPI(*this);
}
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
struct header {
uint8_t version, flags;
uint16_t length;
uint32_t dlt;
};
header _header;
byte_array _data;
};
}
#endif // TINS_PPI_H

430
include/pppoe.h Normal file
View File

@@ -0,0 +1,430 @@
/*
* Copyright (c) 2014, 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_PPPoE_H
#define TINS_PPPoE_H
#include <list>
#include <string>
#include <vector>
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
#include "pdu_option.h"
#include "cxxstd.h"
namespace Tins {
class PPPoE : public PDU {
public:
/**
* The tag types enum.
*/
enum TagTypes {
END_OF_LIST = 0,
SERVICE_NAME = 0x101,
#if TINS_IS_LITTLE_ENDIAN
AC_NAME = 0x201,
HOST_UNIQ = 0x301,
AC_COOKIE = 0x401,
VENDOR_SPECIFIC = 0x501,
RELAY_SESSION_ID = 0x101,
SERVICE_NAME_ERROR = 0x201,
AC_SYSTEM_ERROR = 0x202,
GENERIC_ERROR = 0x302
#else
AC_NAME = 0x102,
HOST_UNIQ = 0x103,
AC_COOKIE = 0x104,
VENDOR_SPECIFIC = 0x105,
RELAY_SESSION_ID = 0x110,
SERVICE_NAME_ERROR = 0x201,
AC_SYSTEM_ERROR = 0x202,
GENERIC_ERROR = 0x203
#endif
};
/**
* The type used to store a TLV option.
*/
typedef PDUOption<TagTypes, PPPoE> tag;
/**
* The type used to store the options.
*/
typedef std::list<tag> tags_type;
/**
* The type used to store the Vendor-Specific tag's value.
*/
struct vendor_spec_type {
typedef std::vector<uint8_t> data_type;
uint32_t vendor_id;
data_type data;
vendor_spec_type(uint32_t vendor_id = 0, const data_type &data = data_type())
: vendor_id(vendor_id), data(data) { }
static vendor_spec_type from_option(const tag &opt);
};
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::PPPOE;
/**
* \brief Default constructor.
*
* This sets the version and type fields to 0x1.
*/
PPPoE();
/**
* \brief Constructor which creates an PPPoE object from a buffer.
*
* If there is not enough size for a PPPoE header, 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.
*/
PPPoE(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the version field.
* \return The stored version field value.
*/
small_uint<4> version() const {
return _header.version;
}
/**
* \brief Getter for the type field.
* \return The stored type field value.
*/
small_uint<4> type() const {
return _header.type;
}
/**
* \brief Getter for the code field.
* \return The stored code field value.
*/
uint8_t code() const {
return _header.code;
}
/**
* \brief Getter for the session_id field.
* \return The stored session_id field value.
*/
uint16_t session_id() const {
return Endian::be_to_host(_header.session_id);
}
/**
* \brief Getter for the payload_length field.
* \return The stored payload_length field value.
*/
uint16_t payload_length() const {
return Endian::be_to_host(_header.payload_length);
}
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Returns the list of tags.
*/
const tags_type &tags() const {
return _tags;
}
/**
* \sa PDU::clone
*/
PPPoE *clone() const {
return new PPPoE(*this);
}
const tag *search_tag(TagTypes identifier) const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
// Setters
/**
* \brief Setter for the version field.
* \param new_version The new version field value.
*/
void version(small_uint<4> new_version);
/**
* \brief Setter for the type field.
* \param new_type The new type field value.
*/
void type(small_uint<4> new_type);
/**
* \brief Setter for the code field.
* \param new_code The new code field value.
*/
void code(uint8_t new_code);
/**
* \brief Setter for the session_id field.
* \param new_session_id The new session_id field value.
*/
void session_id(uint16_t new_session_id);
/**
* \brief Setter for the payload_length field.
* \param new_payload_length The new payload_length field value.
*/
void payload_length(uint16_t new_payload_length);
/**
* \brief Adds a PPPoE tag.
*
* \param option The option to be added.
*/
void add_tag(const tag &option);
#if TINS_IS_CXX11
/**
* \brief Adds a PPPoE tag.
*
* This move-constructs the option.
*
* \param option The option to be added.
*/
void add_tag(tag &&option) {
_tags_size += option.data_size() + sizeof(uint16_t) * 2;
_tags.push_back(std::move(option));
}
#endif
// Option setters
/**
* \brief Adds an end-of-list tag.
*/
void end_of_list();
/**
* \brief Adds a service-name tag.
*
* \param value The service name.
*/
void service_name(const std::string &value);
/**
* \brief Adds a AC-name tag.
*
* \param value The AC name.
*/
void ac_name(const std::string &value);
/**
* \brief Adds a host-uniq tag.
*
* \param value The tag's value.
*/
void host_uniq(const byte_array &value);
/**
* \brief Adds a AC-Cookie tag.
*
* \param value The tag's value.
*/
void ac_cookie(const byte_array &value);
/**
* \brief Adds a Vendor-Specific tag.
*
* \param value The tag's value.
*/
void vendor_specific(const vendor_spec_type &value);
/**
* \brief Adds a Relay-Session-Id tag.
*
* \param value The tag's value.
*/
void relay_session_id(const byte_array &value);
/**
* \brief Adds a Service-Name-Error tag.
*
* \param value The tag's value.
*/
void service_name_error(const std::string &value);
/**
* \brief Adds a AC-System-Error tag.
*
* \param value The tag's value.
*/
void ac_system_error(const std::string &value);
/**
* \brief Adds a Generic-Error tag.
*
* \param value The tag's value.
*/
void generic_error(const std::string &value);
// Option getters
/**
* \brief Getter for the service-name tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
std::string service_name() const;
/**
* \brief Getter for the AC-name tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
std::string ac_name() const;
/**
* \brief Getter for the host-uniq tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
byte_array host_uniq() const;
/**
* \brief Getter for the AC-Cookie tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
byte_array ac_cookie() const;
/**
* \brief Getter for the Vendor-Specific tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
vendor_spec_type vendor_specific() const;
/**
* \brief Getter for the Vendor-Specific tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
byte_array relay_session_id() const;
/**
* \brief Getter for the Service-Name-Error tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
std::string service_name_error() const;
/**
* \brief Getter for the AC-System-Error tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
std::string ac_system_error() const;
/**
* \brief Getter for the Generic-Error tag.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
std::string generic_error() const;
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
template<typename T>
void add_tag_iterable(TagTypes id, const T &data) {
add_tag(
tag(
id,
data.begin(),
data.end()
)
);
}
template<typename T>
T search_and_convert(TagTypes id) const {
const tag *t = search_tag(id);
if(!t)
throw option_not_found();
return t->to<T>();
}
TINS_BEGIN_PACK
struct pppoe_hdr {
#if TINS_IS_LITTLE_ENDIAN
uint8_t version:4,
type:4;
uint8_t code;
#else
uint16_t version:4,
type:4,
code:8;
#endif
uint16_t session_id;
uint16_t payload_length;
} TINS_END_PACK;
pppoe_hdr _header;
tags_type _tags;
uint16_t _tags_size;
};
}
#endif // TINS_PPPoE_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,13 +27,14 @@
*
*/
#ifndef TINS_RADIOTAP_H
#include "config.h"
#if !defined(TINS_RADIOTAP_H) && defined(HAVE_DOT11)
#define TINS_RADIOTAP_H
#include "macros.h"
#include "pdu.h"
#include "endianness.h"
#include "network_interface.h"
namespace Tins {
class PacketSender;
@@ -90,7 +91,8 @@ namespace Tins {
ANTENNA = 2048,
DB_SIGNAL = 4096,
DB_NOISE = 8192,
RX_FLAGS = 16382
RX_FLAGS = 16382,
CHANNEL_PLUS = 262144
};
/**
@@ -108,16 +110,17 @@ namespace Tins {
};
/**
* \brief Creates an instance of RadioTap.
* \param iface The interface in which to send this PDU.
* \param child The child PDU.(optional)
* \brief Default constructor.
*/
RadioTap(const NetworkInterface &iface = NetworkInterface(),
PDU *child = 0);
RadioTap();
/**
* \brief Constructor which creates a RadioTap object from a buffer and adds all
* \brief Constructs a RadioTap object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If there is not enough size for a RadioTap header, 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.
*/
@@ -129,7 +132,7 @@ namespace Tins {
/**
* \sa PDU::send()
*/
void send(PacketSender &sender);
void send(PacketSender &sender, const NetworkInterface &iface);
#endif
/**
@@ -187,12 +190,24 @@ namespace Tins {
*/
void dbm_noise(uint8_t new_dbm_noise);
/**
* \brief Setter for the signal quality field.
* \param new_antenna The signal quality signal.
*/
void signal_quality(uint8_t new_signal_quality);
/**
* \brief Setter for the antenna field.
* \param new_antenna The antenna signal.
*/
void antenna(uint8_t new_antenna);
/**
* \brief Setter for the db signal field.
* \param new_antenna The db signal signal.
*/
void db_signal(uint8_t new_db_signal);
/**
* \brief Setter for the rx flag field.
* \param new_rx_flag The antenna signal.
@@ -261,17 +276,29 @@ namespace Tins {
*/
uint8_t dbm_noise() const { return _dbm_noise; }
/**
* \brief Getter for the signal quality field.
* \return The signal quality field.
*/
uint16_t signal_quality() const { return _signal_quality; }
/**
* \brief Getter for the antenna field.
* \return The antenna field.
*/
uint8_t antenna() const { return _antenna; }
/**
* \brief Getter for the db signal field.
* \return The db signal field.
*/
uint8_t db_signal() const { return _db_signal; }
/**
* \brief Getter for the channel+ field.
* \return The channel+ field.
*/
uint32_t channel_plus() const { return Endian::le_to_host(_channel_type); }
uint32_t channel_plus() const { return Endian::le_to_host<uint32_t>(_channel_type); }
/**
* \brief Getter for the rx flags field.
@@ -289,9 +316,18 @@ namespace Tins {
* if its corresponding bit flag is set in the present field.
*/
PresentFlags present() const {
return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1);
//return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1);
return (PresentFlags)Endian::le_to_host(_radio.flags_32);
}
/** \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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Returns the RadioTap frame's header length.
*
@@ -325,50 +361,60 @@ namespace Tins {
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;
union {
struct {
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;
} flags;
uint32_t flags_32;
};
#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;
union {
struct {
uint32_t lock_quality:1,
dbm_noise:1,
dbm_signal:1,
fhss:1,
channel:1,
rate:1,
flags:1,
tsft:1,
reserved3:1,
rx_flags:1,
db_tx_attenuation:1,
dbm_tx_attenuation:1,
antenna:1,
db_signal:1,
db_noise:1,
tx_attenuation:1,
reserved2:5,
channel_plus:1,
reserved1:2,
reserved4:7,
ext:1;
} flags;
uint32_t flags_32;
};
#endif
} TINS_END_PACK;
@@ -377,12 +423,10 @@ namespace Tins {
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;
uint16_t _channel_type, _channel_freq, _rx_flags, _signal_quality;
uint8_t _antenna, _flags, _rate, _dbm_signal, _dbm_noise, _channel, _max_power, _db_signal;
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -116,12 +116,33 @@ namespace Tins {
return _payload.size();
}
/**
* \brief Check wether ptr points to a valid response for this PDU.
*
* This always returns true, since we don't know what this
* RawPDU is holding.
*
* \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::RAW; }
/**
* \brief Constructs the given PDU type from the raw data stored
* in this RawPDU.
*/
template<typename T>
T to() const {
return T(&_payload[0], _payload.size());
}
/**
* \sa PDU::clone
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,9 @@
*
*/
#ifndef TINS_RSN_INFORMATION
#include "config.h"
#if !defined(TINS_RSN_INFORMATION) && defined(HAVE_DOT11)
#define TINS_RSN_INFORMATION
#include <stdint.h>
@@ -35,149 +37,160 @@
#include "endianness.h"
namespace Tins{
class Dot11;
template<typename T, typename U>
class PDUOption;
/**
* \brief Class that models the RSN information structure.
*/
class RSNInformation {
public:
/**
* \brief Class that models the RSN information structure.
* \brief Enum that represents the different cypher suites.
*/
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;
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 Constructs an RSNInformation object.
*
* By default, the version is set to 1.
*/
RSNInformation();
/**
* \brief Constructs an RSNInformation object from a
* serialization_type object.
*
* \param buffer The buffer from which to construct this object.
*/
RSNInformation(const serialization_type &buffer);
/**
* \brief Constructs a RSNInformation from a buffer.
*
* If the input is malformed, a malformed_packet exception is
* thrown.
*
* \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 an 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;
/**
* Constructs an RSNInformation object from a Dot11 tagged option.
*/
static RSNInformation from_option(const PDUOption<uint8_t, Dot11> &opt);
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

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,9 +54,14 @@ public:
SLL();
/**
* \brief Constructor which constructs an SLL object from a buffer
* and adds all identifiable PDUs found in the buffer as children
* of this one.
* \brief Constructs a SLL object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a SLL header in the
* buffer, 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.
*/
@@ -65,40 +70,40 @@ public:
// Getters
/**
* \brief Getter for the packet_type field.
* \return The stored packet_type field value.
* \brief Getter for the Packet Type field.
* \return The stored Packet Type field value.
*/
uint16_t packet_type() const {
return Endian::be_to_host(_header.packet_type);
}
/**
* \brief Getter for the lladdr_type field.
* \return The stored lladdr_type field value.
* \brief Getter for the LLADDR Type field.
* \return The stored LLADDR Type field value.
*/
uint16_t lladdr_type() const {
return Endian::be_to_host(_header.lladdr_type);
}
/**
* \brief Getter for the lladdr_len field.
* \return The stored lladdr_len field value.
* \brief Getter for the LLADDR Length field.
* \return The stored LLADDR Length field value.
*/
uint16_t lladdr_len() const {
return Endian::be_to_host(_header.lladdr_len);
}
/**
* \brief Getter for the address field.
* \return The stored address field value.
* \brief Getter for the Address field.
* \return The stored Address field value.
*/
address_type address() const {
return _header.address;
}
/**
* \brief Getter for the protocol field.
* \return The stored protocol field value.
* \brief Getter for the Protocol field.
* \return The stored Protocol field value.
*/
uint16_t protocol() const {
return Endian::be_to_host(_header.protocol);
@@ -113,32 +118,32 @@ public:
// Setters
/**
* \brief Setter for the packet_type field.
* \param new_packet_type The new packet_type field value.
* \brief Setter for the Packet Type field.
* \param new_packet_type The new Packet Type field value.
*/
void packet_type(uint16_t new_packet_type);
/**
* \brief Setter for the lladdr_type field.
* \param new_lladdr_type The new lladdr_type field value.
* \brief Setter for the LLADDR Type field.
* \param new_lladdr_type The new LLADDR Type field value.
*/
void lladdr_type(uint16_t new_lladdr_type);
/**
* \brief Setter for the lladdr_len field.
* \param new_lladdr_len The new lladdr_len field value.
* \brief Setter for the LLADDR Length field.
* \param new_lladdr_len The new LLADDR Length field value.
*/
void lladdr_len(uint16_t new_lladdr_len);
/**
* \brief Setter for the address field.
* \param new_address The new address field value.
* \brief Setter for the Address field.
* \param new_address The new Address field value.
*/
void address(const address_type &new_address);
/**
* \brief Setter for the protocol field.
* \param new_protocol The new protocol field value.
* \brief Setter for the Protocol field.
* \param new_protocol The new Protocol field value.
*/
void protocol(uint16_t new_protocol);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,13 +56,18 @@ namespace Tins {
* \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);
SNAP();
/**
* \brief Constructor which creates a SNAP object from a buffer and adds all identifiable
* PDUs found in the buffer as children of this one.
* \brief Constructs a SNAP object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this one.
*
* If the next PDU is not recognized, then a RawPDU is used.
*
* If there is not enough size for a SNAP header in the
* buffer, 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.
*/
@@ -71,40 +76,40 @@ namespace Tins {
/* Setters */
/**
* \brief Setter for the control field.
* \param new_id The new control to be set.
* \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.
* \brief Setter for the Organization Code field.
* \param new_org The new Organization 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.
* \brief Setter for the Ethernet Type field.
* \param new_eth The new Ethernet Type to be set.
*/
void eth_type(uint16_t new_eth);
/* Getters */
/**
* \brief Getter for the dsap field.
* \return The dsap field.
* \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.
* \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.
* \brief Getter for the Control field.
* \return The Control field.
*/
uint8_t control() const {
#if TINS_IS_LITTLE_ENDIAN
@@ -115,8 +120,8 @@ namespace Tins {
}
/**
* \brief Getter for the org code field.
* \return The org code field.
* \brief Getter for the Organization Code field.
* \return The Organization Code field.
*/
small_uint<24> org_code() const {
#if TINS_IS_LITTLE_ENDIAN
@@ -127,8 +132,8 @@ namespace Tins {
}
/**
* \brief Getter for the eth type field.
* \return The eth field.
* \brief Getter for the Ethernet Type field.
* \return The Ethernet Type field.
*/
uint16_t eth_type() const { return Endian::be_to_host(_snap.eth_type); }
@@ -144,7 +149,7 @@ namespace Tins {
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return PDU::SNAP; }
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Clones this PDU.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,16 +36,16 @@
#include <string>
#include <memory>
#include <stdexcept>
#include <iterator>
#include "pdu.h"
#include "ethernetII.h"
#include "radiotap.h"
#include "packet.h"
#include "loopback.h"
#include "dot11.h"
#include "sll.h"
#include "cxxstd.h"
#include "exceptions.h"
#include "internals.h"
namespace Tins {
class SnifferIterator;
/**
* \class BaseSniffer
* \brief Base class for sniffers.
@@ -58,18 +58,33 @@ namespace Tins {
*/
class BaseSniffer {
public:
/**
* The iterator type.
*/
typedef SnifferIterator iterator;
#if TINS_IS_CXX11
/**
* \brief Move constructor.
* This constructor is available only in C++11.
*/
BaseSniffer(BaseSniffer &&rhs) noexcept;
BaseSniffer(BaseSniffer &&rhs) NOEXCEPT
: handle(nullptr), mask()
{
*this = std::move(rhs);
}
/**
* \brief Move assignment operator.
* This opeartor is available only in C++11.
* This operator is available only in C++11.
*/
BaseSniffer& operator=(BaseSniffer &&rhs) noexcept;
BaseSniffer& operator=(BaseSniffer &&rhs) NOEXCEPT
{
using std::swap;
swap(handle, rhs.handle);
swap(mask, rhs.mask);
return *this;
}
#endif
/**
@@ -81,7 +96,7 @@ namespace Tins {
/**
* \brief Compiles a filter and uses it to capture one packet.
*
* This method returns the first sniffed packet that matches the
* This method returns the first valid sniffed packet that matches the
* sniffer's filter, or the first sniffed packet if no filter has
* been set.
*
@@ -101,48 +116,57 @@ namespace Tins {
* \code
* // bad!!
* PtrPacket p = s.next_packet();
*
* \endcode
*
* Is not, since PtrPacket can't be copy constructed.
*
* \sa Packet::release_pdu
*
* \return The captured packet, matching the given filter.
* If an error occured(probably compiling the filter), PtrPacket::pdu
* will return 0. Caller takes ownership of the PDU * stored in
* \return A captured packet. If an error occured, PtrPacket::pdu
* will return 0. Caller takes ownership of the PDU pointer stored in
* the PtrPacket.
*/
PtrPacket next_packet();
/**
* \brief Starts a sniffing loop, using a callback object for every
* \brief Starts a sniffing loop, using a callback functor for every
* sniffed packet.
*
* The callback object must implement an operator with some of
* the following(or compatible) signatures:
* The functor must implement an operator with one of the
* following signatures:
*
* \code
* bool operator()(PDU&);
* bool operator()(RefPacket&);
* bool(PDU&);
* bool(const PDU&);
* \endcode
*
* This operator will be called using the sniffed packets
* as arguments. You can modify the parameter argument as you wish.
* Calling PDU methods like PDU::release_inner_pdu is perfectly
* valid.
* This functor will be called using the each of the sniffed packets
* as its argument. Using PDU member functions that modify the PDU,
* such as PDU::release_inner_pdu, is perfectly valid.
*
* The callback taking a RefPacket will contain a timestamp
* indicating the moment in which the packet was taken out of
* the wire/pcap file.
*
* Note that the Functor object will be copied using its copy
* constructor, so that object should be some kind of proxy to
* Note that if you're using a functor object, it will be copied using
* its copy constructor, so it should be some kind of proxy to
* another object which will process the packets(e.g. std::bind).
*
* Sniffing will stop when either max_packets are sniffed(if it is != 0),
* or when the functor returns false.
*
* This method catches both malformed_packet and pdu_not_found exceptions,
* which allows writing much cleaner code, since you can call PDU::rfind_pdu
* without worrying about catching the exception that can be thrown. This
* allows writing code such as the following:
*
* \code
* bool callback(const PDU& pdu) {
* // If either RawPDU is not found, or construction of the DNS
* // object fails, the BaseSniffer object will trap the exceptions,
* // so we don't need to worry about it.
* DNS dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
* return true;
* }
* \endcode
*
* \sa RefPacket
*
* \param cback_handler The callback handler object which should process packets.
* \param function The callback handler object which should process packets.
* \param max_packets The maximum amount of packets to sniff. 0 == infinite.
*/
template<class Functor>
@@ -157,6 +181,9 @@ namespace Tins {
/**
* \brief Stops sniffing loops.
*
* This method must be called from the same thread from which
* BaseSniffer::sniff_loop was called.
*/
void stop_sniff();
@@ -164,6 +191,48 @@ namespace Tins {
* \brief Gets the file descriptor associated with the sniffer.
*/
int get_fd();
/**
* \brief Sets the read timeout for this sniffer.
*
* This calls pcap_set_timeout using the provided parameter.
* \param ms The amount of milliseconds.
*/
void set_timeout(int ms);
/**
* \brief Sets whether to extract RawPDUs or fully parsed packets.
*
* By default, packets will be parsed starting from link layer.
* However, if you're parsing a lot of traffic, then you might
* want to extract packets and push them into a queue,
* so a consumer can parse them when they're popped.
*
* This method allows doing that. If the parameter is true,
* then packets taken from this BaseSniffer will only contain
* a RawPDU which will have to entire contents of the packet.
*
* \param value Whether to extract RawPDUs or not.
*/
void set_extract_raw_pdus(bool value);
/**
* \brief Retrieves this sniffer's link type.
*
* This calls pcap_datalink on the stored pcap handle and
* returns its result.
*/
int link_type() const;
/**
* Retrieves an iterator to the next packet in this sniffer.
*/
iterator begin();
/**
* Retrieves an end iterator.
*/
iterator end();
protected:
/**
* Default constructor.
@@ -181,61 +250,61 @@ namespace Tins {
*/
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, const struct pcap_pkthdr *header);
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;
bool extract_raw;
};
/**
* \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.
* \brief Sniffs packets from a network interface.
*/
class Sniffer : public BaseSniffer {
public:
enum promisc_type {
NON_PROMISC,
PROMISC
};
/**
* \brief Constructs an instance of Sniffer.
* Constructs an instance of Sniffer.
*
* By default the interface won't be put into promiscuous mode, and won't
* be put into monitor mode.
*
* \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);
* \param rfmon Indicates if the interface should be put in monitor mode.(optional);
*/
Sniffer(const std::string &device, unsigned max_packet_size,
bool promisc = false, const std::string &filter = "");
bool promisc = false, const std::string &filter = "", bool rfmon = false);
/**
* \brief Constructs an instance of Sniffer.
*
* The maximum capture size is set to 65535. By default the interface won't
* be put into promiscuous mode, and won't be put into monitor mode.
*
* \param device The device which will be sniffed.
* \param promisc Indicates if the interface should be put in promiscuous mode.
* \param filter A capture filter to be used on the sniffing session.(optional);
* \param rfmon Indicates if the interface should be put in monitor mode.(optional);
*/
Sniffer(const std::string &device, promisc_type promisc = NON_PROMISC,
const std::string &filter = "", bool rfmon = false);
private:
void init_sniffer(const std::string &device, unsigned max_packet_size,
bool promisc = false, const std::string &filter = "", bool rfmon = false);
};
/**
* \class FileSniffer
* \brief Parses pcap files and interprets the packets in it.
* \brief Reads 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.
@@ -249,52 +318,6 @@ namespace Tins {
*/
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,
const struct pcap_pkthdr *header)
{
ConcretePDU some_pdu((const uint8_t*)packet, header->caplen);
Timestamp ts(header->ts);
RefPacket pck(some_pdu, ts);
return data->c_handler(pck);
}
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);
else if(data->iface_type == DLT_IEEE802_11_RADIO)
ret_val = call_functor<Tins::RadioTap>(data, packet, header);
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()) {
RefPacket pck(*pdu, header->ts);
ret_val = data->c_handler(pck);
}
}
else if(data->iface_type == DLT_NULL)
ret_val = call_functor<Tins::Loopback>(data, packet, header);
else if(data->iface_type == DLT_LINUX_SLL)
ret_val = call_functor<Tins::SLL>(data, packet, header);
if(!ret_val)
pcap_breakloop(data->handle);
}
catch(std::runtime_error&) {
}
}
template<class T>
class HandlerProxy {
@@ -318,6 +341,96 @@ namespace Tins {
{
return HandlerProxy<T>(ptr, function);
}
/**
* \brief Iterates over packets sniffed by a BaseSniffer.
*/
class SnifferIterator : public std::iterator<std::forward_iterator_tag, PDU> {
public:
/**
* Constructs a SnifferIterator.
* \param sniffer The sniffer to iterate.
*/
SnifferIterator(BaseSniffer *sniffer = 0)
: sniffer(sniffer)
{
if(sniffer)
advance();
}
/**
* Advances the iterator.
*/
SnifferIterator& operator++() {
advance();
return *this;
}
/**
* Advances the iterator.
*/
SnifferIterator operator++(int) {
SnifferIterator other(*this);
advance();
return other;
}
/**
* Dereferences the iterator.
* \return reference to the current packet.
*/
PDU &operator*() {
return *pkt.pdu();
}
/**
* Dereferences the iterator.
* \return pointer to the current packet.
*/
PDU *operator->() {
return &(**this);
}
/**
* Compares this iterator for equality.
* \param rhs The iterator to be compared to.
*/
bool operator==(const SnifferIterator &rhs) const {
return sniffer == rhs.sniffer;
}
/**
* Compares this iterator for in-equality.
* \param rhs The iterator to be compared to.
*/
bool operator!=(const SnifferIterator &rhs) const {
return !(*this == rhs);
}
private:
void advance() {
pkt = sniffer->next_packet();
if(!pkt)
sniffer = 0;
}
BaseSniffer *sniffer;
Packet pkt;
};
template<class Functor>
void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) {
for(iterator it = begin(); it != end(); ++it) {
try {
// If the functor returns false, we're done
if(!function(*it))
return;
}
catch(malformed_packet&) { }
catch(pdu_not_found&) { }
if(max_packets && --max_packets == 0)
return;
}
}
}
#endif // TINS_SNIFFER_H

307
include/stp.h Normal file
View File

@@ -0,0 +1,307 @@
/*
* Copyright (c) 2014, 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_STP_H
#define TINS_STP_H
#include "pdu.h"
#include "endianness.h"
#include "hw_address.h"
#include "small_uint.h"
namespace Tins {
class STP : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::STP;
/**
* The type used to store BPDU identifier addresses.
*/
typedef HWAddress<6> address_type;
/**
* The type used to store the BPDU identifiers.
*/
struct bpdu_id_type {
small_uint<4> priority;
small_uint<12> ext_id;
address_type id;
bpdu_id_type(small_uint<4> priority=0, small_uint<12> ext_id=0,
const address_type& id=address_type())
: priority(priority), ext_id(ext_id), id(id) { }
};
/**
* \brief Default constructor.
*/
STP();
/**
* \brief Constructs a STP object from a buffer.
*
* If there is not enough size for a STP header, 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.
*/
STP(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the Protocol ID field.
* \return The stored Protocol ID field value.
*/
uint16_t proto_id() const {
return Endian::be_to_host(_header.proto_id);
}
/**
* \brief Getter for the Protocol Version field.
* \return The stored Protocol Version field value.
*/
uint8_t proto_version() const {
return _header.proto_version;
}
/**
* \brief Getter for the BDU Type field.
* \return The stored BDU Type field value.
*/
uint8_t bpdu_type() const {
return _header.bpdu_type;
}
/**
* \brief Getter for the BDU Flags field.
* \return The stored BDU Flags field value.
*/
uint8_t bpdu_flags() const {
return _header.bpdu_flags;
}
/**
* \brief Getter for the Root Path Cost field.
* \return The stored Root Path Cost field value.
*/
uint32_t root_path_cost() const {
return Endian::be_to_host(_header.root_path_cost);
}
/**
* \brief Getter for the Port ID field.
* \return The stored Port ID field value.
*/
uint16_t port_id() const {
return Endian::be_to_host(_header.port_id);
}
/**
* \brief Getter for the Message Age field.
* \return The stored Message Age field value.
*/
uint16_t msg_age() const {
return Endian::be_to_host(_header.msg_age) / 256;
}
/**
* \brief Getter for the Maximum Age field.
* \return The stored Maximum Age field value.
*/
uint16_t max_age() const {
return Endian::be_to_host(_header.max_age) / 256;
}
/**
* \brief Getter for the Hello Time field.
* \return The stored Hello Time field value.
*/
uint16_t hello_time() const {
return Endian::be_to_host(_header.hello_time) / 256;
}
/**
* \brief Getter for the Forward Delay field.
* \return The stored Forward Delay field value.
*/
uint16_t fwd_delay() const {
return Endian::be_to_host(_header.fwd_delay) / 256;
}
/**
* \brief Getter for the Root ID field.
* \return The stored Root ID field value.
*/
bpdu_id_type root_id() const;
/**
* \brief Getter for the Bridge ID field.
* \return The stored Bridge ID field value.
*/
bpdu_id_type bridge_id() const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
STP *clone() const {
return new STP(*this);
}
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. \sa PDU::header_size
*/
uint32_t header_size() const;
// Setters
/**
* \brief Setter for the Protocol ID field.
* \param new_proto_id The new Protocol ID field value.
*/
void proto_id(uint16_t new_proto_id);
/**
* \brief Setter for the Protocol Version field.
* \param new_proto_version The new Protocol Version field value.
*/
void proto_version(uint8_t new_proto_version);
/**
* \brief Setter for the BPDU Type field.
* \param new_bpdu_type The new BPDU Type field value.
*/
void bpdu_type(uint8_t new_bpdu_type);
/**
* \brief Setter for the BPDU Flags field.
* \param new_bpdu_flags The new BPDU Flags field value.
*/
void bpdu_flags(uint8_t new_bpdu_flags);
/**
* \brief Setter for the Root Path Cost field.
* \param new_root_path_cost The new Root Path Cost field value.
*/
void root_path_cost(uint32_t new_root_path_cost);
/**
* \brief Setter for the Port ID field.
* \param new_port_id The new Port ID field value.
*/
void port_id(uint16_t new_port_id);
/**
* \brief Setter for the Message Age field.
* \param new_msg_age The new Message Age field value.
*/
void msg_age(uint16_t new_msg_age);
/**
* \brief Setter for the Maximum Age field.
* \param new_max_age The new Maximum Age field value.
*/
void max_age(uint16_t new_max_age);
/**
* \brief Setter for the Hello Time field.
* \param new_hello_time The new Hello Time field value.
*/
void hello_time(uint16_t new_hello_time);
/**
* \brief Setter for the Forward Delay field.
* \param new_fwd_delay The new Forward Delay field value.
*/
void fwd_delay(uint16_t new_fwd_delay);
/**
* \brief Setter for the Root ID field.
* \param new_fwd_delay The new Root ID field value.
*/
void root_id(const bpdu_id_type &id);
/**
* \brief Setter for the Bridge ID field.
* \param new_fwd_delay The new Bridge ID field value.
*/
void bridge_id(const bpdu_id_type &id);
private:
TINS_BEGIN_PACK
struct pvt_bpdu_id {
#if TINS_IS_LITTLE_ENDIAN
// fixme
uint16_t ext_id:4,
priority:4,
ext_idL:8;
#else
uint16_t priority:4,
ext_id:12;
#endif
uint8_t id[6];
} TINS_END_PACK;
TINS_BEGIN_PACK
struct stphdr {
uint16_t proto_id;
uint8_t proto_version;
uint8_t bpdu_type;
uint8_t bpdu_flags;
pvt_bpdu_id root_id;
uint32_t root_path_cost;
pvt_bpdu_id bridge_id;
uint16_t port_id;
uint16_t msg_age;
uint16_t max_age;
uint16_t hello_time;
uint16_t fwd_delay;
} TINS_END_PACK;
static bpdu_id_type convert(const pvt_bpdu_id &id);
static pvt_bpdu_id convert(const bpdu_id_type &id);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
stphdr _header;
};
}
#endif // TINS_STP_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@
#include "endianness.h"
#include "small_uint.h"
#include "pdu_option.h"
#include "cxxstd.h"
namespace Tins {
/**
@@ -63,14 +64,14 @@ namespace Tins {
* These flags identify those supported by the TCP PDU.
*/
enum Flags {
FIN,
SYN,
RST,
PSH,
ACK,
URG,
ECE,
CWR
FIN = 1,
SYN = 2,
RST = 4,
PSH = 8,
ACK = 16,
URG = 32,
ECE = 64,
CWR = 128
};
/**
@@ -78,8 +79,7 @@ namespace Tins {
*
* This enum identifies valid options supported by TCP PDU.
*/
enum Option {
enum OptionTypes {
EOL = 0,
NOP = 1,
MSS = 2,
@@ -99,12 +99,15 @@ namespace Tins {
CHK_16FLETCHER
};
typedef PDUOption<uint8_t> tcp_option;
/**
* The type used to store TCP options.
*/
typedef PDUOption<uint8_t, TCP> option;
/**
* The type used to store the options.
*/
typedef std::list<tcp_option> options_type;
typedef std::list<option> options_type;
/**
* The type used to store the sack option.
@@ -122,9 +125,14 @@ namespace Tins {
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.
* \brief Constructs TCP object from a buffer.
*
* If there is not enough size for a TCP header, or any of the
* TLV options are malformed a malformed_packet exception is
* thrown.
*
* Any extra data will be stored in a RawPDU.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
@@ -170,7 +178,7 @@ namespace Tins {
*
* \return The checksum field in an uint16_t.
*/
uint16_t check() const { return Endian::be_to_host(_tcp.check); }
uint16_t checksum() const { return Endian::be_to_host(_tcp.check); }
/**
* \brief Getter for the urgent pointer field.
@@ -199,7 +207,25 @@ namespace Tins {
* \param tcp_flag The polled flag.
* \return The value of the flag.
*/
small_uint<1> get_flag(Flags tcp_flag);
small_uint<1> get_flag(Flags tcp_flag) const;
/**
*
* \brief Gets the flags' values.
*
* All of the set flags will be joined together into
* a 12 bit value. This way, you can check for multiple
* flags at the same time:
*
* \code
* TCP tcp = ...;
* if(tcp.flags() == (TCP::SYN | TCP::ACK))
* // It's a SYN+ACK!
* \endcode
*
* \return The value of the flags field.
*/
small_uint<12> flags() const;
/* Setters */
@@ -238,13 +264,6 @@ namespace Tins {
*/
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.
*
@@ -351,15 +370,60 @@ namespace Tins {
* \param value The new value for this flag. Must be 0 or 1.
*/
void set_flag(Flags tcp_flag, small_uint<1> value);
/**
* \brief Sets the value of the flag fields.
*
* This method can be used to set several flags at the
* same time.
*
* \code
* TCP tcp = ...;
* tcp.flags(TCP::SYN | TCP::ACK);
* // ...
* // only set the ACK, keeping the rest of the old flags.
* tcp.flags(tcp.flags() | TCP::ACK);
* \endcode
*
* \param value The new value of the flags.
*/
void flags(small_uint<12> 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).
* \param option The option to be added.
*/
void add_option(Option option, uint8_t length = 0, const uint8_t *data = 0);
void add_option(const option &opt);
#if TINS_IS_CXX11
/**
* \brief Adds a TCP option.
*
* This move-constructs the option.
*
* \param option The option to be added.
*/
void add_option(option &&opt) {
internal_add_option(opt);
_options.push_back(std::move(opt));
}
/**
* \brief Adds a TCP option using the provided arguments.
*
* The option is constructed from the provided parameters.
*
* \param args The arguments to be used in the option's
* constructor.
*/
template<typename... Args>
void add_option(Args&&... args) {
_options.emplace_back(std::forward<Args>(args)...);
internal_add_option(_options.back());
}
#endif
/**
* \brief Returns the header size.
@@ -370,6 +434,15 @@ namespace Tins {
* \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(const uint8_t *ptr, uint32_t total_sz) const;
/**
* \brief Getter for the PDU's type.
@@ -383,7 +456,7 @@ namespace Tins {
* \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;
const option *search_option(OptionTypes opt) const;
/**
* \sa PDU::clone
@@ -431,20 +504,22 @@ namespace Tins {
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();
T generic_search(OptionTypes opt_type) const {
const option *opt = search_option(opt_type);
if(!opt)
throw option_not_found();
return opt->to<T>();
}
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint8_t *write_option(const tcp_option &opt, uint8_t *buffer);
void internal_add_option(const option &option);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
void checksum(uint16_t new_check);
uint8_t *write_option(const option &opt, uint8_t *buffer);
tcphdr _tcp;
uint16_t _options_size, _total_options_size;
options_type _options;
uint32_t _options_size, _total_options_size;
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -185,7 +185,9 @@ private:
static fragments_type clone_fragments(const fragments_type &frags);
bool generic_process(uint32_t &my_seq, uint32_t &other_seq,
payload_type &pload, fragments_type &frags, TCP *tcp, RawPDU *raw);
payload_type &pload, fragments_type &frags, TCP *tcp);
void safe_insert(fragments_type &frags, uint32_t seq, RawPDU *raw);
uint32_t client_seq, server_seq;
@@ -298,11 +300,6 @@ private:
EndFunctor end_fun;
};
void clear_state() {
sessions.clear();
last_identifier = 0;
}
template<typename DataFunctor, typename EndFunctor>
bool callback(PDU &pdu, const DataFunctor &fun, const EndFunctor &end_fun);
static void dummy_function(TCPStream&) { }
@@ -315,7 +312,6 @@ template<typename DataFunctor, typename EndFunctor>
void TCPStreamFollower::follow_streams(BaseSniffer &sniffer, DataFunctor data_fun, EndFunctor end_fun) {
typedef proxy_caller<DataFunctor, EndFunctor> proxy_type;
proxy_type proxy = { this, data_fun, end_fun };
clear_state();
sniffer.sniff_loop(make_sniffer_handler(&proxy, &proxy_type::callback));
}
@@ -323,7 +319,6 @@ template<typename ForwardIterator, typename DataFunctor, typename EndFunctor>
void TCPStreamFollower::follow_streams(ForwardIterator start, ForwardIterator end,
DataFunctor data_fun, EndFunctor end_fun)
{
clear_state();
while(start != end) {
if(!callback(Utils::dereference_until_pdu(start), data_fun, end_fun))
return;
@@ -345,36 +340,34 @@ void TCPStreamFollower::follow_streams(ForwardIterator start, ForwardIterator en
template<typename DataFunctor, typename EndFunctor>
bool TCPStreamFollower::callback(PDU &pdu, const DataFunctor &data_fun, const EndFunctor &end_fun) {
IP *ip = pdu.find_pdu<IP>();
TCP *tcp = pdu.find_pdu<TCP>();
if(ip && tcp) {
TCPStream::StreamInfo info(
ip->src_addr(), ip->dst_addr(),
tcp->sport(), tcp->dport()
);
sessions_type::iterator it = sessions.find(info);
if(it == sessions.end()) {
std::swap(info.client_addr, info.server_addr);
std::swap(info.client_port, info.server_port);
if((it = sessions.find(info)) == sessions.end()) {
if(tcp->get_flag(TCP::SYN) && !tcp->get_flag(TCP::ACK)) {
sessions.insert(
std::make_pair(
info,
TCPStream(ip, tcp, last_identifier++)
)
);
}
return true;
IP &ip = pdu.rfind_pdu<IP>();
TCP &tcp = pdu.rfind_pdu<TCP>();
TCPStream::StreamInfo info(
ip.src_addr(), ip.dst_addr(),
tcp.sport(), tcp.dport()
);
sessions_type::iterator it = sessions.find(info);
if(it == sessions.end()) {
std::swap(info.client_addr, info.server_addr);
std::swap(info.client_port, info.server_port);
if((it = sessions.find(info)) == sessions.end()) {
if(tcp.get_flag(TCP::SYN) && !tcp.get_flag(TCP::ACK)) {
sessions.insert(
std::make_pair(
info,
TCPStream(&ip, &tcp, last_identifier++)
)
);
}
return true;
}
if(it->second.update(ip, tcp))
data_fun(it->second);
// We're done with this stream
if(it->second.is_finished()) {
end_fun(it->second);
sessions.erase(it);
}
}
if(it->second.update(&ip, &tcp))
data_fun(it->second);
// We're done with this stream
if(it->second.is_finished()) {
end_fun(it->second);
sessions.erase(it);
}
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,6 @@
#define TINS_TIMESTAMP_H
#ifdef WIN32
#define NOMINMAX
#include <winsock2.h>
#else
#include <sys/time.h>
@@ -73,6 +72,22 @@ public:
* Default constructs the timestamp.
*/
Timestamp() : tv() {}
#if TINS_IS_CXX11
/**
* Constructs a Timestamp from a std::chrono::duration.
*/
template<typename Rep, typename Period>
Timestamp(const std::chrono::duration<Rep, Period>& ts) {
using std::chrono::duration_cast;
using std::chrono::microseconds;
using std::chrono::seconds;
tv.tv_sec = duration_cast<seconds>(ts).count();
tv.tv_usec = duration_cast<microseconds>(
ts - seconds(tv.tv_sec)).count();
}
#endif
/**
* Constructs a timestamp from a timeval object.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,8 @@
#include "icmp.h"
#include "icmpv6.h"
#include "dot11.h"
#include "dot1q.h"
#include "dot3.h"
#include "ip.h"
#include "ipv6.h"
#include "packet_sender.h"
@@ -63,5 +65,13 @@
#include "timestamp.h"
#include "sll.h"
#include "dhcpv6.h"
#include "pppoe.h"
#include "stp.h"
#include "handshake_capturer.h"
#include "address_range.h"
#include "pdu_allocator.h"
#include "ipsec.h"
#include "ip_reassembler.h"
#include "ppi.h"
#endif // TINS_TINS_H

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,17 +51,22 @@ namespace Tins {
/**
* \brief UDP constructor.
*
* Creates an instance of UDP. Destination and source port can
* be provided, otherwise both will be 0.
* Constructs an instance of UDP. The destination and source
* port can be provided, otherwise both of them will be 0.
*
* \param dport Destination port.
* \param sport Source port.
* \param child The child PDU(optional).
* */
UDP(uint16_t dport = 0, uint16_t sport = 0, PDU *child = 0);
UDP(uint16_t dport = 0, uint16_t sport = 0);
/**
* \brief Constructor which creates an UDP object from a buffer and adds all identifiable
* PDUs found in the buffer as children of this one.
* \brief Constructs an UDP object from a buffer.
*
* If there is not enough size for a UDP header a malformed_packet
* exception is thrown.
*
* Any extra data will be stored in a RawPDU.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
@@ -84,6 +89,12 @@ namespace Tins {
* \return The length of the datagram.
*/
uint16_t length() const { return Endian::be_to_host(_udp.len); }
/**
* \brief Getter for the checksum of the datagram.
* \return The datagram's checksum.
*/
uint16_t checksum() const { return Endian::be_to_host(_udp.check); }
/**
* \brief Set the destination port.
@@ -91,19 +102,34 @@ namespace Tins {
*/
void dport(uint16_t new_dport);
/** \brief Set the source port.
/**
* \brief Set the source port.
*
* \param new_sport The new source port.
*/
void sport(uint16_t new_sport);
/** \brief Getter for the length field.
/**
* \brief Getter for the length field.
* \param new_len The new length field.
* \return The length field.
*/
void length(uint16_t new_len);
/** \brief Returns the header size.
/**
* \brief Check wether ptr points to a valid response for this PDU.
*
* This compares the source and destination ports in the provided
* response with those stored in 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;
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. This size includes the
* payload and options size. \sa PDU::header_size
@@ -119,7 +145,7 @@ namespace Tins {
/**
* \sa PDU::clone
*/
PDU *clone() const {
UDP *clone() const {
return new UDP(*this);
}
private:
@@ -131,7 +157,6 @@ namespace Tins {
uint16_t check;
} TINS_END_PACK;
void copy_fields(const UDP *other);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
udphdr _udp;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Nasel
* Copyright (c) 2014, Matias Fontanini
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,13 +33,12 @@
#ifndef WIN32
#include <ifaddrs.h>
#else
#define NOMINMAX
#include <winsock2.h>
#include <iphlpapi.h>
#undef interface
#endif
#include "macros.h"
#ifdef BSD
#if defined(BSD) || defined(__FreeBSD_kernel__)
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -95,7 +94,7 @@ namespace Tins {
*/
IPv4Address mask;
};
/**
* \brief Resolves a domain name and returns its corresponding ip address.
*
@@ -104,20 +103,17 @@ namespace Tins {
*
* \param to_resolve The domain name/ip address to resolve.
*/
IPv4Address resolve_ip(const std::string &to_resolve);
IPv4Address resolve_domain(const std::string &to_resolve);
/**
* \brief Resolves the hardware address for a given ip.
* \brief Resolves a domain name and returns its corresponding ip address.
*
* \param iface The interface in which the packet will be sent.
* \param ip The ip to resolve, in integer format.
* \param buffer The buffer in which the host's hardware address will be stored.
* \param sender The sender to use to send and receive the ARP requests.
* \return Returns true if the hardware address was resolved successfully,
* false otherwise.
* If an ip address is given, its integer representation is returned.
* Otherwise, the domain name is resolved and its ip address is returned.
*
* \param to_resolve The domain name/ip address to resolve.
*/
bool resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip,
HWAddress<6> *address, PacketSender &sender);
IPv6Address resolve_domain6(const std::string &to_resolve);
/**
* \brief Resolves the hardware address for a given ip.
@@ -132,6 +128,21 @@ namespace Tins {
*/
HWAddress<6> resolve_hwaddr(const NetworkInterface &iface,
IPv4Address ip, PacketSender &sender);
/**
* \brief Resolves the hardware address for a given ip.
*
* If the address can't be resolved, a std::runtime_error
* exception is thrown.
*
* This method sends and receives the packet through
* PacketSender::default_interface.
*
* \param ip The ip to resolve, in integer format.
* \param sender The sender to use to send and receive the ARP requests.
* \return HWAddress<6> containing the resolved hardware address.
*/
HWAddress<6> resolve_hwaddr(IPv4Address ip, PacketSender &sender);
/** \brief List all network interfaces.
*
@@ -156,13 +167,20 @@ namespace Tins {
/**
* \brief Retrieves entries int the routing table.
* \brief Retrieves entries in the routing table.
*
* \brief output ForwardIterator in which entries will be stored.
*/
template<class ForwardIterator>
void route_entries(ForwardIterator output);
/**
* \brief Retrieves entries in the routing table.
*
* \return a vector which contains all of the route entries.
*/
std::vector<RouteEntry> route_entries();
/** \brief Returns the 32 bit crc of the given buffer.
*
* \param data The input buffer.
@@ -179,10 +197,17 @@ namespace Tins {
/**
* \brief Converts mhz units to the appropriate channel number.
* \param channel The mhz units to be converted.
* \param mhz The mhz units to be converted.
* \return The channel number.
*/
uint16_t mhz_to_channel(uint16_t mhz);
/**
* \brief Converts a PDUType to a string.
* \param pduType The PDUType to be converted.
* \return A string representation, for example "DOT11_QOS_DATA".
*/
std::string to_string(PDU::PDUType pduType);
/** \brief Does the 16 bits sum of all 2 bytes elements between start and end.
*
@@ -283,7 +308,7 @@ namespace Tins {
dereference_until_pdu(T &value) {
return dereference_until_pdu(*value);
}
#ifdef BSD
#if defined(BSD) || defined(__FreeBSD_kernel__)
inline std::vector<char> query_route_table() {
int mib[6];
std::vector<char> buf;
@@ -325,7 +350,7 @@ namespace Tins {
#endif
}
}
#ifdef BSD
#if defined(BSD) || defined(__FreeBSD_kernel__)
template<class ForwardIterator>
void Tins::Utils::route_entries(ForwardIterator output) {
std::vector<char> buffer = query_route_table();

View File

@@ -70,7 +70,7 @@
# compiler: $LTCC
# compiler flags: $LTCFLAGS
# linker: $LD (gnu? $with_gnu_ld)
# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1
# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu2
# automake: $automake_version
# autoconf: $autoconf_version
#
@@ -80,7 +80,7 @@
PROGRAM=libtool
PACKAGE=libtool
VERSION="2.4.2 Debian-2.4.2-1ubuntu1"
VERSION="2.4.2 Debian-2.4.2-1ubuntu2"
TIMESTAMP=""
package_revision=1.3337

View File

@@ -0,0 +1,134 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

1
m4/libtool.m4 vendored
View File

@@ -1 +0,0 @@
/usr/share/aclocal/libtool.m4

8001
m4/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

1
m4/ltoptions.m4 vendored
View File

@@ -1 +0,0 @@
/usr/share/aclocal/ltoptions.m4

384
m4/ltoptions.m4 vendored Normal file
View File

@@ -0,0 +1,384 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

1
m4/ltsugar.m4 vendored
View File

@@ -1 +0,0 @@
/usr/share/aclocal/ltsugar.m4

123
m4/ltsugar.m4 vendored Normal file
View File

@@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

1
m4/ltversion.m4 vendored
View File

@@ -1 +0,0 @@
/usr/share/aclocal/ltversion.m4

Some files were not shown because too many files have changed in this diff Show More