mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +01:00
Compare commits
222 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d8f3e6741 | ||
|
|
5d0ba22ac4 | ||
|
|
8a44b29d92 | ||
|
|
1b47623484 | ||
|
|
282cd0913c | ||
|
|
aed5ccdfca | ||
|
|
8e6ddfd764 | ||
|
|
1c2bfd42ca | ||
|
|
b9db3ea1d3 | ||
|
|
52b0ee7ceb | ||
|
|
3ef85aae38 | ||
|
|
3bb310dd6b | ||
|
|
a918229d4b | ||
|
|
95a9d18b6b | ||
|
|
7371b95ebc | ||
|
|
416edc34f7 | ||
|
|
2dff95700f | ||
|
|
46b52ad26e | ||
|
|
22e7c1d7c4 | ||
|
|
dd2ed5daa4 | ||
|
|
c25d4738b4 | ||
|
|
3d4f509a62 | ||
|
|
c9e955903e | ||
|
|
201ea885a1 | ||
|
|
356ea2a68a | ||
|
|
559c963d63 | ||
|
|
4bf5876adf | ||
|
|
b2788fad63 | ||
|
|
c249ff608c | ||
|
|
bd55307b47 | ||
|
|
6b17dc78e5 | ||
|
|
5fe4ab0de8 | ||
|
|
4ee89662f2 | ||
|
|
86e3f138f8 | ||
|
|
cd2b9aab98 | ||
|
|
f05840b9e9 | ||
|
|
8c2abf9249 | ||
|
|
64d35b4903 | ||
|
|
10421fe945 | ||
|
|
7c8aefccfe | ||
|
|
60404296fb | ||
|
|
dbc3ab4c32 | ||
|
|
f83521f778 | ||
|
|
6fb8cbfc86 | ||
|
|
0acf388277 | ||
|
|
4c4a5f6c03 | ||
|
|
fbef2e765d | ||
|
|
ea927caa4b | ||
|
|
60f9116af1 | ||
|
|
75c6bb46dc | ||
|
|
0a2f3b477b | ||
|
|
e73ea43f7b | ||
|
|
17933765d3 | ||
|
|
ed175e0ad6 | ||
|
|
c5404a6111 | ||
|
|
6d7e06535a | ||
|
|
853e1ce647 | ||
|
|
dbcdda9d36 | ||
|
|
17ceba6064 | ||
|
|
52078cc567 | ||
|
|
e2656739f1 | ||
|
|
33091ccbae | ||
|
|
ca6b603478 | ||
|
|
069ae82b10 | ||
|
|
ea6638c163 | ||
|
|
112a357726 | ||
|
|
0e54579200 | ||
|
|
ccb8ffd1b5 | ||
|
|
b83c1a2a96 | ||
|
|
81a947e3b3 | ||
|
|
1cec0f106d | ||
|
|
0acb0fee3e | ||
|
|
9b57585b62 | ||
|
|
2ddec368c3 | ||
|
|
83dc8819b6 | ||
|
|
5e668e6e83 | ||
|
|
ca4912ded4 | ||
|
|
295ebb679c | ||
|
|
6355aff3cd | ||
|
|
a6655191d4 | ||
|
|
dc6c37777b | ||
|
|
23552ea105 | ||
|
|
9962381fc7 | ||
|
|
93ab8d3b91 | ||
|
|
5345b29f8c | ||
|
|
de06fee5ab | ||
|
|
6d329424f1 | ||
|
|
dfbbea33d5 | ||
|
|
0b02af616a | ||
|
|
a101ec9796 | ||
|
|
b0868b5d60 | ||
|
|
f57b8c189c | ||
|
|
a507355e27 | ||
|
|
87fdd62b57 | ||
|
|
3337335df2 | ||
|
|
08113b8f5f | ||
|
|
6dd949611d | ||
|
|
b6a55935b4 | ||
|
|
01b2a9c7b2 | ||
|
|
58e2c93e30 | ||
|
|
bcfe26175a | ||
|
|
c4e6a7c0d6 | ||
|
|
9cbac6b044 | ||
|
|
2414edd1e7 | ||
|
|
74ef177e25 | ||
|
|
54d012b92e | ||
|
|
1b4efc1520 | ||
|
|
96ecd054ab | ||
|
|
d7d2dec5cb | ||
|
|
20f3911e12 | ||
|
|
f8d71687e1 | ||
|
|
d393c1fbfc | ||
|
|
e21e34e194 | ||
|
|
a01fff411e | ||
|
|
7d4222fb17 | ||
|
|
de0ec914cc | ||
|
|
15f2896811 | ||
|
|
b26f353e46 | ||
|
|
5f2c923c48 | ||
|
|
4ca21bdad7 | ||
|
|
2cc0ceb1aa | ||
|
|
7063e60af9 | ||
|
|
21b80a7370 | ||
|
|
fb8fb92ee6 | ||
|
|
2a5b64526f | ||
|
|
02d3a14083 | ||
|
|
3b349471ea | ||
|
|
f385e4e975 | ||
|
|
acff8f1e1f | ||
|
|
59090e62d2 | ||
|
|
74594a3b20 | ||
|
|
681bdc727f | ||
|
|
996e0f139e | ||
|
|
c2353314fa | ||
|
|
5d315c5b6d | ||
|
|
87ac5acdd8 | ||
|
|
3b4dc10211 | ||
|
|
8c1d71c7b7 | ||
|
|
5db196a630 | ||
|
|
ec8374be60 | ||
|
|
eeb62add59 | ||
|
|
908fcb56e8 | ||
|
|
ddf47365c1 | ||
|
|
b052aa1d88 | ||
|
|
cacf75995d | ||
|
|
4960077495 | ||
|
|
8147a2bfb7 | ||
|
|
28c8d393d6 | ||
|
|
ec7e718e38 | ||
|
|
62740e8e64 | ||
|
|
2bb699dc97 | ||
|
|
14b1a4988b | ||
|
|
7f6e4446b4 | ||
|
|
cf19c8758d | ||
|
|
5197e7f5f1 | ||
|
|
eb87b82c17 | ||
|
|
5064a9255b | ||
|
|
bf604339f0 | ||
|
|
7e85058ef1 | ||
|
|
ec05a49cce | ||
|
|
b0eefe15f9 | ||
|
|
0f2bc45059 | ||
|
|
f8134be8b7 | ||
|
|
8afbe14c82 | ||
|
|
fdfb8b0dea | ||
|
|
9be4f0ca37 | ||
|
|
66ff604580 | ||
|
|
7e0e85db65 | ||
|
|
ed39eb36f5 | ||
|
|
7da8de6ea7 | ||
|
|
d1b64ec48e | ||
|
|
69968cbc5c | ||
|
|
9e20c0241f | ||
|
|
97f049580b | ||
|
|
6f04329fbe | ||
|
|
077b54bbed | ||
|
|
759e92706f | ||
|
|
2ea952d6ab | ||
|
|
91bdcca577 | ||
|
|
75bd445bd3 | ||
|
|
9812ad441f | ||
|
|
3fd1b3d37d | ||
|
|
923f51ae15 | ||
|
|
804ea411fc | ||
|
|
9bcfd07896 | ||
|
|
58c8eccc46 | ||
|
|
a674640ef2 | ||
|
|
dde890b24b | ||
|
|
38ccb4413b | ||
|
|
9631734805 | ||
|
|
7faf514496 | ||
|
|
08091fc7c2 | ||
|
|
1450c8cf26 | ||
|
|
b533775cb4 | ||
|
|
3f4c48ad9f | ||
|
|
30d6a4f2e0 | ||
|
|
f4522acd44 | ||
|
|
1fbef641da | ||
|
|
fee938b46d | ||
|
|
ae1e1c2ce2 | ||
|
|
20054e6c73 | ||
|
|
f7f5a9bc9a | ||
|
|
f2a5f73337 | ||
|
|
97049140af | ||
|
|
dfc0498b70 | ||
|
|
1cec099c0e | ||
|
|
3989566608 | ||
|
|
b32586e739 | ||
|
|
82ef41dd92 | ||
|
|
b0dc376494 | ||
|
|
8be0c4c23c | ||
|
|
d7dd1e131f | ||
|
|
584fe81f04 | ||
|
|
16a99ef35b | ||
|
|
247273e086 | ||
|
|
0f27b04a92 | ||
|
|
a8edc2af74 | ||
|
|
f5ecaa3faa | ||
|
|
b5f9f5095e | ||
|
|
02a53da361 | ||
|
|
f86f727810 | ||
|
|
836dbd8955 |
11
AUTHORS
11
AUTHORS
@@ -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
211
CHANGES
@@ -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.
|
||||
|
||||
6
Doxyfile
6
Doxyfile
@@ -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
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
60
Makefile.am
60
Makefile.am
@@ -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/
|
||||
|
||||
604
Makefile.in
604
Makefile.in
@@ -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
33
README
@@ -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
85
README.md
Normal 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
3
THANKS
@@ -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
9316
aclocal.m4
vendored
File diff suppressed because it is too large
Load Diff
11
config.sub
vendored
11
config.sub
vendored
@@ -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
|
||||
;;
|
||||
|
||||
66
configure.ac
66
configure.ac
@@ -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
124
depcomp
@@ -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"
|
||||
;;
|
||||
|
||||
@@ -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
96
examples/arpmonitor.cpp
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
460
examples/configure
vendored
@@ -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
|
||||
;;
|
||||
|
||||
@@ -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
65
examples/dns_queries.cpp
Normal 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
103
examples/dns_spoof.cpp
Normal 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
189
examples/dns_stats.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
74
examples/wps_detect.cpp
Normal 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
331
include/address_range.h
Normal 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
|
||||
102
include/arp.h
102
include/arp.h
@@ -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
|
||||
|
||||
@@ -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
89
include/config.h.in
Normal 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
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
179
include/crypto.h
179
include/crypto.h
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
163
include/dhcp.h
163
include/dhcp.h
@@ -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;
|
||||
|
||||
233
include/dhcpv6.h
233
include/dhcpv6.h
@@ -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
|
||||
|
||||
246
include/dns.h
246
include/dns.h
@@ -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 §ion_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 §ions);
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
3390
include/dot11.h
3390
include/dot11.h
File diff suppressed because it is too large
Load Diff
622
include/dot11/dot11_assoc.h
Normal file
622
include/dot11/dot11_assoc.h
Normal 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
260
include/dot11/dot11_auth.h
Normal 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
522
include/dot11/dot11_base.h
Normal 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
|
||||
166
include/dot11/dot11_beacon.h
Normal file
166
include/dot11/dot11_beacon.h
Normal 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
|
||||
746
include/dot11/dot11_control.h
Normal file
746
include/dot11/dot11_control.h
Normal 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
345
include/dot11/dot11_data.h
Normal 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
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
233
include/dot11/dot11_probe.h
Normal 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
212
include/dot1q.h
Normal 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
193
include/dot3.h
Normal 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
|
||||
@@ -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; };
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
173
include/exceptions.h
Normal 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
|
||||
169
include/handshake_capturer.h
Normal file
169
include/handshake_capturer.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
136
include/icmp.h
136
include/icmp.h
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
199
include/icmpv6.h
199
include/icmpv6.h
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
129
include/ip.h
129
include/ip.h
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
216
include/ip_reassembler.h
Normal 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
264
include/ipsec.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
207
include/pdu.h
207
include/pdu.h
@@ -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
182
include/pdu_allocator.h
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
134
include/ppi.h
Normal 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
430
include/pppoe.h
Normal 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
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
307
include/stp.h
Normal 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
|
||||
153
include/tcp.h
153
include/tcp.h
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
134
m4/ax_cxx_compile_stdcxx_11.m4
Normal file
134
m4/ax_cxx_compile_stdcxx_11.m4
Normal 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
1
m4/libtool.m4
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/aclocal/libtool.m4
|
||||
8001
m4/libtool.m4
vendored
Normal file
8001
m4/libtool.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
m4/ltoptions.m4
vendored
1
m4/ltoptions.m4
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/aclocal/ltoptions.m4
|
||||
384
m4/ltoptions.m4
vendored
Normal file
384
m4/ltoptions.m4
vendored
Normal 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
1
m4/ltsugar.m4
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/aclocal/ltsugar.m4
|
||||
123
m4/ltsugar.m4
vendored
Normal file
123
m4/ltsugar.m4
vendored
Normal 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
1
m4/ltversion.m4
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/aclocal/ltversion.m4
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user