mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +01:00
Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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>
|
||||
|
||||
94
CHANGES
94
CHANGES
@@ -1,3 +1,97 @@
|
||||
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
|
||||
|
||||
49
Makefile.am
49
Makefile.am
@@ -13,17 +13,20 @@ 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/ipv6.cpp \
|
||||
@@ -33,8 +36,10 @@ libtins_la_SOURCES=src/arp.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,23 +48,36 @@ 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/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 \
|
||||
@@ -75,6 +93,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 +109,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/
|
||||
|
||||
308
Makefile.in
308
Makefile.in
@@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.11.3 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
@@ -18,6 +18,23 @@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
@@ -36,19 +53,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 = README $(am__configure_deps) $(libtins_HEADERS) \
|
||||
$(libtins_dot11_HEADERS) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/libtins.pc.in \
|
||||
$(top_srcdir)/configure $(top_srcdir)/include/config.h.in \
|
||||
AUTHORS COPYING INSTALL THANKS TODO config.guess config.sub \
|
||||
depcomp install-sh ltmain.sh missing
|
||||
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,24 +102,30 @@ 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/dns_record.lo src/dot3.lo src/dot1q.lo src/eapol.lo \
|
||||
src/ethernetII.lo src/icmp.lo src/icmpv6.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/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) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
$(CXXFLAGS) $(libtins_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
@@ -111,8 +140,13 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
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)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@@ -159,6 +193,7 @@ EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_CXX11 = @HAVE_CXX11@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
@@ -247,7 +282,11 @@ 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@
|
||||
@@ -262,17 +301,20 @@ 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/ipv6.cpp \
|
||||
@@ -282,8 +324,10 @@ libtins_la_SOURCES = src/arp.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,23 +336,35 @@ 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/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 \
|
||||
@@ -324,6 +380,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 +396,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 +451,25 @@ $(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
|
||||
@if test ! -f $@; then rm -f include/stamp-h1; else :; fi
|
||||
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) include/stamp-h1; else :; fi
|
||||
|
||||
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 +477,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)"; \
|
||||
}
|
||||
@@ -420,17 +508,21 @@ 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.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/ip_address.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
|
||||
@@ -444,8 +536,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,11 +551,35 @@ 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)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
-rm -f src/address_range.$(OBJEXT)
|
||||
-rm -f src/address_range.lo
|
||||
-rm -f src/arp.$(OBJEXT)
|
||||
-rm -f src/arp.lo
|
||||
-rm -f src/bootp.$(OBJEXT)
|
||||
@@ -475,18 +594,36 @@ mostlyclean-compile:
|
||||
-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/dot11/dot11_assoc.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_assoc.lo
|
||||
-rm -f src/dot11/dot11_auth.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_auth.lo
|
||||
-rm -f src/dot11/dot11_base.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_base.lo
|
||||
-rm -f src/dot11/dot11_beacon.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_beacon.lo
|
||||
-rm -f src/dot11/dot11_control.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_control.lo
|
||||
-rm -f src/dot11/dot11_data.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_data.lo
|
||||
-rm -f src/dot11/dot11_mgmt.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_mgmt.lo
|
||||
-rm -f src/dot11/dot11_probe.$(OBJEXT)
|
||||
-rm -f src/dot11/dot11_probe.lo
|
||||
-rm -f src/dot1q.$(OBJEXT)
|
||||
-rm -f src/dot1q.lo
|
||||
-rm -f src/dot3.$(OBJEXT)
|
||||
-rm -f src/dot3.lo
|
||||
-rm -f src/eapol.$(OBJEXT)
|
||||
-rm -f src/eapol.lo
|
||||
-rm -f src/ethernetII.$(OBJEXT)
|
||||
-rm -f src/ethernetII.lo
|
||||
-rm -f src/handshake_capturer.$(OBJEXT)
|
||||
-rm -f src/handshake_capturer.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)
|
||||
@@ -509,6 +646,10 @@ mostlyclean-compile:
|
||||
-rm -f src/packet_writer.lo
|
||||
-rm -f src/pdu.$(OBJEXT)
|
||||
-rm -f src/pdu.lo
|
||||
-rm -f src/ppi.$(OBJEXT)
|
||||
-rm -f src/ppi.lo
|
||||
-rm -f src/pppoe.$(OBJEXT)
|
||||
-rm -f src/pppoe.lo
|
||||
-rm -f src/radiotap.$(OBJEXT)
|
||||
-rm -f src/radiotap.lo
|
||||
-rm -f src/rawpdu.$(OBJEXT)
|
||||
@@ -521,6 +662,8 @@ mostlyclean-compile:
|
||||
-rm -f src/snap.lo
|
||||
-rm -f src/sniffer.$(OBJEXT)
|
||||
-rm -f src/sniffer.lo
|
||||
-rm -f src/stp.$(OBJEXT)
|
||||
-rm -f src/stp.lo
|
||||
-rm -f src/tcp.$(OBJEXT)
|
||||
-rm -f src/tcp.lo
|
||||
-rm -f src/tcp_stream.$(OBJEXT)
|
||||
@@ -533,6 +676,7 @@ mostlyclean-compile:
|
||||
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@
|
||||
@@ -540,12 +684,13 @@ distclean-compile:
|
||||
@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@
|
||||
@@ -557,16 +702,27 @@ 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$$||'`;\
|
||||
@@ -598,13 +754,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,24 +779,48 @@ 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
|
||||
|
||||
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)
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
@@ -788,7 +972,7 @@ distcheck: dist
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||
chmod -R a-w $(distdir); chmod u+w $(distdir)
|
||||
mkdir $(distdir)/_build
|
||||
mkdir $(distdir)/_inst
|
||||
chmod a-w $(distdir)
|
||||
@@ -856,7 +1040,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 +1071,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 +1084,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 +1101,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 +1133,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,8 +1150,8 @@ 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
|
||||
|
||||
@@ -972,20 +1159,21 @@ uninstall-am: uninstall-libLTLIBRARIES \
|
||||
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 \
|
||||
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
|
||||
uninstall-libLTLIBRARIES uninstall-libtinsHEADERS \
|
||||
uninstall-libtins_dot11HEADERS uninstall-pkgconfigDATA
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
|
||||
2
README
2
README
@@ -1,5 +1,5 @@
|
||||
------------------------------------------------------------------------
|
||||
libtins v0.3
|
||||
libtins v1.1
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
8622
aclocal.m4
vendored
8622
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
|
||||
;;
|
||||
|
||||
56
configure.ac
56
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], [1.2], [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,42 @@ 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(
|
||||
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], [1:1: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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -53,11 +53,11 @@ void BeaconSniffer::run(const std::string &iface) {
|
||||
|
||||
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".
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, 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;
|
||||
}
|
||||
|
||||
331
include/address_range.h
Normal file
331
include/address_range.h
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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) 2012, 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) 2012, 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
|
||||
|
||||
86
include/config.h.in
Normal file
86
include/config.h.in
Normal file
@@ -0,0 +1,86 @@
|
||||
/* 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
|
||||
|
||||
/* 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) 2012, 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 */
|
||||
};
|
||||
|
||||
176
include/crypto.h
176
include/crypto.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,15 +34,64 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "dot11.h"
|
||||
#include "utils.h"
|
||||
#include "snap.h"
|
||||
#include "rawpdu.h"
|
||||
#include "handshake_capturer.h"
|
||||
#include "config.h"
|
||||
|
||||
namespace Tins {
|
||||
class PDU;
|
||||
class Dot11;
|
||||
class Dot11Data;
|
||||
|
||||
namespace Crypto {
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
class 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 +114,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 +142,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 +165,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 +321,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 +329,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 +381,7 @@ namespace Crypto {
|
||||
{
|
||||
return DecrypterProxy<Functor, WEPDecrypter>(functor);
|
||||
}
|
||||
|
||||
|
||||
// RC4 stuff
|
||||
|
||||
template<typename ForwardIterator>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,6 +30,8 @@
|
||||
#ifndef TINS_CXXSTD_H
|
||||
#define TINS_CXXSTD_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
#define TINS_CXXSTD_GCC_FIX 1
|
||||
#else
|
||||
@@ -38,4 +40,17 @@
|
||||
|
||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
|
||||
|
||||
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
|
||||
|
||||
123
include/dhcp.h
123
include/dhcp.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,12 +35,15 @@
|
||||
#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 +69,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief DHCP options enum.
|
||||
*/
|
||||
enum Options {
|
||||
enum OptionTypes {
|
||||
PAD,
|
||||
SUBNET_MASK,
|
||||
TIME_OFFSET,
|
||||
@@ -142,12 +145,12 @@ namespace Tins {
|
||||
/**
|
||||
* The DHCP option type.
|
||||
*/
|
||||
typedef PDUOption<uint8_t> dhcp_option;
|
||||
typedef PDUOption<uint8_t> 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 +161,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,60 +221,90 @@ 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);
|
||||
|
||||
/**
|
||||
* \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);
|
||||
|
||||
/**
|
||||
* \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);
|
||||
@@ -259,7 +314,7 @@ namespace Tins {
|
||||
/**
|
||||
* \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 +324,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 +334,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 +344,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 +354,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 +364,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,7 +374,7 @@ 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
|
||||
@@ -330,7 +385,7 @@ namespace Tins {
|
||||
/**
|
||||
* \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
|
||||
@@ -341,7 +396,7 @@ namespace Tins {
|
||||
/**
|
||||
* \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 +406,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 +416,15 @@ 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 Getter for the options list.
|
||||
/**
|
||||
* \brief Getter for the options list.
|
||||
* \return The option list.
|
||||
*/
|
||||
const options_type options() const { return _options; }
|
||||
@@ -377,7 +433,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.
|
||||
@@ -401,17 +457,18 @@ namespace Tins {
|
||||
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);
|
||||
T generic_search(OptionTypes opt, type2type<T>) const {
|
||||
const option *option = search_option(opt);
|
||||
if(option && option->data_size() == sizeof(T))
|
||||
return *(const T*)option->data_ptr();
|
||||
else
|
||||
throw option_not_found();
|
||||
}
|
||||
|
||||
std::list<ipaddress_type> generic_search(Options opt, type2type<std::list<ipaddress_type> >) const;
|
||||
std::string generic_search(Options opt, type2type<std::string>) const;
|
||||
ipaddress_type generic_search(Options opt, type2type<ipaddress_type>) const;
|
||||
void internal_add_option(const option &opt);
|
||||
std::list<ipaddress_type> generic_search(OptionTypes opt, type2type<std::list<ipaddress_type> >) const;
|
||||
std::string generic_search(OptionTypes opt, type2type<std::string>) const;
|
||||
ipaddress_type generic_search(OptionTypes opt, type2type<ipaddress_type>) const;
|
||||
|
||||
serialization_type serialize_list(const std::list<ipaddress_type> &ip_list);
|
||||
|
||||
|
||||
113
include/dhcpv6.h
113
include/dhcpv6.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -46,79 +46,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> option;
|
||||
|
||||
/**
|
||||
* The message types.
|
||||
@@ -146,7 +74,7 @@ public:
|
||||
/**
|
||||
* The DHCPv6 options.
|
||||
*/
|
||||
enum Option {
|
||||
enum OptionTypes {
|
||||
CLIENTID = 1,
|
||||
SERVERID,
|
||||
IA_NA,
|
||||
@@ -226,7 +154,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.
|
||||
@@ -438,7 +366,7 @@ public:
|
||||
/**
|
||||
* The type used to store the Option Request option.
|
||||
*/
|
||||
typedef std::vector<Option> option_request_type;
|
||||
typedef std::vector<OptionTypes> option_request_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Relay Message option.
|
||||
@@ -456,9 +384,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 +442,6 @@ public:
|
||||
* \return The stored options.
|
||||
*/
|
||||
const options_type &options() const { return options_; }
|
||||
;
|
||||
|
||||
// Setters
|
||||
/**
|
||||
@@ -851,9 +781,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 +794,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 +805,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,11 +828,11 @@ 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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -252,7 +252,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.
|
||||
@@ -554,6 +558,9 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Getter for this PDU's DNS queries.
|
||||
*
|
||||
* This method is <b>not thread safe</b>.
|
||||
*
|
||||
* \return std::list<Query> containing the queries in this
|
||||
* record.
|
||||
*/
|
||||
@@ -561,11 +568,23 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Getter for this PDU's DNS answers
|
||||
*
|
||||
* This method is <b>not thread safe</b>.
|
||||
*
|
||||
* \return std::list<Resource> containing the answers in this
|
||||
* record.
|
||||
*/
|
||||
resources_type answers() 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
|
||||
*/
|
||||
@@ -574,7 +593,7 @@ namespace Tins {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create a resource record information
|
||||
* Helper function to create a resource record information.
|
||||
*
|
||||
* \param type The type of the query.
|
||||
* \param qclass The class of the query.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -37,7 +37,17 @@
|
||||
#include "macros.h"
|
||||
|
||||
namespace Tins {
|
||||
class DNSRRImpl;
|
||||
/**
|
||||
* \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;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Abstracts a DNS resource record.
|
||||
@@ -68,6 +78,10 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Constructs a record.
|
||||
*
|
||||
* If the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer A pointer to the start of the data buffer.
|
||||
* \param len The length of the data.
|
||||
*/
|
||||
@@ -104,12 +118,23 @@ public:
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
DNSResourceRecord(DNSResourceRecord &&rhs) noexcept;
|
||||
DNSResourceRecord(DNSResourceRecord &&rhs) noexcept
|
||||
: info_(rhs.info_), data(std::move(rhs.data)), impl(0) {
|
||||
std::swap(impl, rhs.impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move assignment operator.
|
||||
*/
|
||||
DNSResourceRecord& operator=(DNSResourceRecord &&rhs) noexcept;
|
||||
DNSResourceRecord& operator=(DNSResourceRecord &&rhs) noexcept
|
||||
{
|
||||
info_ = rhs.info_;
|
||||
data = std::move(rhs.data);
|
||||
delete impl;
|
||||
impl = 0;
|
||||
std::swap(impl, rhs.impl);
|
||||
return *this;
|
||||
}
|
||||
#endif // TINS_IS_CXX11
|
||||
|
||||
/**
|
||||
@@ -198,18 +223,6 @@ private:
|
||||
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);
|
||||
|
||||
3386
include/dot11.h
3386
include/dot11.h
File diff suppressed because it is too large
Load Diff
620
include/dot11/dot11_assoc.h
Normal file
620
include/dot11/dot11_assoc.h
Normal file
@@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_ASSOC_H
|
||||
#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
|
||||
258
include/dot11/dot11_auth.h
Normal file
258
include/dot11/dot11_auth.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_AUTH_H
|
||||
#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
|
||||
515
include/dot11/dot11_base.h
Normal file
515
include/dot11/dot11_base.h
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_H
|
||||
#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> 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;
|
||||
|
||||
/**
|
||||
* \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
|
||||
164
include/dot11/dot11_beacon.h
Normal file
164
include/dot11/dot11_beacon.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_BEACON_H
|
||||
#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
|
||||
743
include/dot11/dot11_control.h
Normal file
743
include/dot11/dot11_control.h
Normal file
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_CONTROL_H
|
||||
#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
|
||||
343
include/dot11/dot11_data.h
Normal file
343
include/dot11/dot11_data.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_DATA_H
|
||||
#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
|
||||
1126
include/dot11/dot11_mgmt.h
Normal file
1126
include/dot11/dot11_mgmt.h
Normal file
File diff suppressed because it is too large
Load Diff
230
include/dot11/dot11_probe.h
Normal file
230
include/dot11/dot11_probe.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_DOT11_DOT11_PROBE_H
|
||||
#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) 2012, 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) 2012, 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) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -80,7 +80,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)))));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
150
include/exceptions.h
Normal file
150
include/exceptions.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 <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";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_EXCEPTIONS_H
|
||||
167
include/handshake_capturer.h
Normal file
167
include/handshake_capturer.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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_HANDSHAKE_CAPTURER_H
|
||||
#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) 2012, 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -71,8 +71,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 +96,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.
|
||||
*
|
||||
@@ -222,7 +220,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 check() const { return Endian::be_to_host(_icmp.check); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the echo id.
|
||||
@@ -243,7 +241,7 @@ namespace Tins {
|
||||
*
|
||||
* \return Returns the gateways in an unit32_t.
|
||||
*/
|
||||
uint32_t gateway() const { return Endian::be_to_host(this->_icmp.un.gateway); }
|
||||
uint32_t gateway() const { return Endian::be_to_host(_icmp.un.gateway); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the pointer field.
|
||||
@@ -257,7 +255,7 @@ namespace Tins {
|
||||
*
|
||||
* \return Returns the mtu value in an uint16_t.
|
||||
*/
|
||||
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 Returns the header size.
|
||||
@@ -274,7 +272,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 +280,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 +306,8 @@ namespace Tins {
|
||||
uint8_t pointer;
|
||||
} un;
|
||||
} TINS_END_PACK;
|
||||
|
||||
void check(uint16_t new_check);
|
||||
|
||||
/** \brief Serialices this ICMP PDU.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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,12 +135,12 @@ public:
|
||||
/**
|
||||
* The type used to represent ICMPv6 options.
|
||||
*/
|
||||
typedef PDUOption<uint8_t> icmpv6_option;
|
||||
typedef PDUOption<uint8_t> 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
|
||||
@@ -429,8 +430,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 +741,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 +764,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 +783,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
|
||||
@@ -1181,16 +1209,17 @@ 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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,31 +35,144 @@
|
||||
#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, end, 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>
|
||||
struct enable_if {
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct enable_if<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
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(PDU::PDUType type, const uint8_t *buffer, uint32_t size);
|
||||
|
||||
Constants::Ethernet::e pdu_flag_to_ether_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);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace Tins
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
93
include/ip.h
93
include/ip.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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> option;
|
||||
|
||||
/**
|
||||
* The type of the security option.
|
||||
@@ -217,7 +218,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 +229,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 +304,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 +333,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 +340,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.
|
||||
*
|
||||
@@ -380,13 +368,6 @@ namespace Tins {
|
||||
*/
|
||||
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 +395,23 @@ 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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given flag.
|
||||
@@ -427,7 +422,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 +549,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 +558,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 +566,7 @@ 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 &);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
@@ -579,17 +574,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 +604,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) 2012, 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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> 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) 2012, 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) 2012, 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) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,10 +39,12 @@
|
||||
#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
|
||||
#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))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, 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) 2012, 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,24 @@ 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);
|
||||
|
||||
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 +323,7 @@ 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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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
|
||||
|
||||
161
include/pdu.h
161
include/pdu.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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,7 @@ namespace Tins {
|
||||
/**
|
||||
* The type that will be returned when serializing PDUs.
|
||||
*/
|
||||
typedef std::vector<uint8_t> serialization_type;
|
||||
typedef byte_array serialization_type;
|
||||
|
||||
/**
|
||||
* \brief Enum which identifies each type of PDU.
|
||||
@@ -105,18 +114,44 @@ namespace Tins {
|
||||
IPv6,
|
||||
ICMPv6,
|
||||
SLL,
|
||||
DHCPv6
|
||||
DHCPv6,
|
||||
DOT1Q,
|
||||
PPPOE,
|
||||
STP,
|
||||
PPI,
|
||||
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.
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*/
|
||||
PDU(PDU *next_pdu = 0);
|
||||
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.
|
||||
/**
|
||||
* \brief PDU destructor.
|
||||
*
|
||||
* Deletes the inner pdu, as a consequence every child pdu is
|
||||
* deleted.
|
||||
@@ -163,11 +198,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 +227,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 +246,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 +292,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 +331,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 +353,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 +370,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 +394,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.
|
||||
*
|
||||
|
||||
182
include/pdu_allocator.h
Normal file
182
include/pdu_allocator.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,18 +33,9 @@
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Exception thrown when an option is not found.
|
||||
*/
|
||||
class option_not_found : public std::exception {
|
||||
public:
|
||||
const char* what() const throw() {
|
||||
return "Option not found";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \class PDUOption
|
||||
* \brief Represents a PDU option field.
|
||||
@@ -75,10 +66,8 @@ 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), value_(data, data + (data ? length : 0)) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,9 +80,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)), value_(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), value_(start, end) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,17 +131,36 @@ public:
|
||||
* \return const data_type& containing this option's value.
|
||||
*/
|
||||
const data_type *data_ptr() const {
|
||||
return &*(++value_.begin());
|
||||
return &*value_.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 value_.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_;
|
||||
}
|
||||
private:
|
||||
option_type option_;
|
||||
uint16_t size_;
|
||||
container_type value_;
|
||||
};
|
||||
} // namespace Tins
|
||||
|
||||
134
include/ppi.h
Normal file
134
include/ppi.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 _header.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Data Link Type field.
|
||||
* \return The stored Data Link Type field value.
|
||||
*/
|
||||
uint32_t dlt() const {
|
||||
return _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
|
||||
436
include/pppoe.h
Normal file
436
include/pppoe.h
Normal file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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> 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) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 retrieve_tag_iterable(TagTypes id) const {
|
||||
const tag *tag = search_tag(id);
|
||||
if(!tag)
|
||||
throw option_not_found();
|
||||
return T(tag->data_ptr(), tag->data_ptr() + tag->data_size());
|
||||
}
|
||||
|
||||
template<template <typename> class Functor>
|
||||
const tag *safe_search_tag(TagTypes opt, uint32_t size) const {
|
||||
const tag *option = search_tag(opt);
|
||||
if(!option || Functor<uint32_t>()(option->data_size(), size))
|
||||
throw option_not_found();
|
||||
return option;
|
||||
}
|
||||
|
||||
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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "macros.h"
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "network_interface.h"
|
||||
|
||||
namespace Tins {
|
||||
class PacketSender;
|
||||
@@ -90,7 +89,8 @@ namespace Tins {
|
||||
ANTENNA = 2048,
|
||||
DB_SIGNAL = 4096,
|
||||
DB_NOISE = 8192,
|
||||
RX_FLAGS = 16382
|
||||
RX_FLAGS = 16382,
|
||||
CHANNEL_PLUS = 262144
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -108,16 +108,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 +130,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
void send(PacketSender &sender, const NetworkInterface &iface);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -187,12 +188,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 +274,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 +314,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 +359,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 +421,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) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -74,14 +74,14 @@ namespace Tins{
|
||||
typedef std::vector<uint8_t> serialization_type;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation.
|
||||
* \brief Constructs an RSNInformation object.
|
||||
*
|
||||
* By default, the version is set to 1.
|
||||
*/
|
||||
RSNInformation();
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation from a
|
||||
* \brief Constructs an RSNInformation object from a
|
||||
* serialization_type object.
|
||||
*
|
||||
* \param buffer The buffer from which to construct this object.
|
||||
@@ -89,7 +89,10 @@ namespace Tins{
|
||||
RSNInformation(const serialization_type &buffer);
|
||||
|
||||
/**
|
||||
* \brief Constructor from 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.
|
||||
@@ -110,7 +113,7 @@ namespace Tins{
|
||||
void add_pairwise_cypher(CypherSuites cypher);
|
||||
|
||||
/**
|
||||
* \brief Adds a akm suite.
|
||||
* \brief Adds an akm suite.
|
||||
* \param akm The akm suite to be added.
|
||||
*/
|
||||
void add_akm_cypher(AKMSuites akm);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, 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) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -36,16 +36,23 @@
|
||||
#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 "dot11/dot11_base.h"
|
||||
#include "dot3.h"
|
||||
#include "sll.h"
|
||||
#include "cxxstd.h"
|
||||
#include "exceptions.h"
|
||||
#include "internals.h"
|
||||
#include "ppi.h"
|
||||
|
||||
namespace Tins {
|
||||
class SnifferIterator;
|
||||
|
||||
/**
|
||||
* \class BaseSniffer
|
||||
* \brief Base class for sniffers.
|
||||
@@ -58,18 +65,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 +103,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 +123,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 +188,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 +198,24 @@ namespace Tins {
|
||||
* \brief Gets the file descriptor associated with the sniffer.
|
||||
*/
|
||||
int get_fd();
|
||||
|
||||
/**
|
||||
* \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,44 +233,16 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* \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:
|
||||
@@ -235,7 +259,7 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \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 +273,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 +296,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) 2012, 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
|
||||
133
include/tcp.h
133
include/tcp.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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> 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,46 @@ 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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
@@ -370,6 +420,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 +442,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 +490,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);
|
||||
T generic_search(OptionTypes opt) const {
|
||||
const option *option = search_option(opt);
|
||||
if(option && option->data_size() == sizeof(T))
|
||||
return *(const T*)(&option->data_ptr()[0]);
|
||||
throw option_not_found();
|
||||
}
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
uint8_t *write_option(const tcp_option &opt, uint8_t *buffer);
|
||||
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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -345,36 +345,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) 2012, 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) 2012, 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,10 @@
|
||||
#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"
|
||||
|
||||
#endif // TINS_TINS_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, 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) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,7 +39,7 @@
|
||||
#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 +95,7 @@ namespace Tins {
|
||||
*/
|
||||
IPv4Address mask;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Resolves a domain name and returns its corresponding ip address.
|
||||
*
|
||||
@@ -104,20 +104,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 +129,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.
|
||||
*
|
||||
@@ -283,7 +295,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 +337,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
|
||||
23
m4/ltversion.m4
vendored
Normal file
23
m4/ltversion.m4
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 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.
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 3337 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.2])
|
||||
m4_define([LT_PACKAGE_REVISION], [1.3337])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.2'
|
||||
macro_revision='1.3337'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
||||
1
m4/lt~obsolete.m4
vendored
1
m4/lt~obsolete.m4
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/aclocal/lt~obsolete.m4
|
||||
98
m4/lt~obsolete.m4
vendored
Normal file
98
m4/lt~obsolete.m4
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 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 5 lt~obsolete.m4
|
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||
#
|
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
|
||||
# which have later been changed to m4_define as they aren't part of the
|
||||
# exported API, or moved to Autoconf or Automake where they belong.
|
||||
#
|
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||
# and doesn't know about Autoconf macros at all.)
|
||||
#
|
||||
# So we provide this file, which has a silly filename so it's always
|
||||
# included after everything else. This provides aclocal with the
|
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||
# because those macros already exist, or will be overwritten later.
|
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||
#
|
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||
# Yes, that means every name once taken will need to remain here until
|
||||
# we give up compatibility with versions before 1.7, at which point
|
||||
# we need to keep only those names which we still refer to.
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
57
src/address_range.cpp
Normal file
57
src/address_range.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 "address_range.h"
|
||||
#include "ip_address.h"
|
||||
#include "ipv6_address.h"
|
||||
|
||||
namespace Tins {
|
||||
IPv4Range operator/(const IPv4Address &addr, int mask) {
|
||||
if(mask > 32)
|
||||
throw std::logic_error("Prefix length cannot exceed 32");
|
||||
return IPv4Range::from_mask(
|
||||
addr,
|
||||
IPv4Address(Endian::host_to_be(0xffffffff << (32 - mask)))
|
||||
);
|
||||
}
|
||||
|
||||
IPv6Range operator/(const IPv6Address &addr, int mask) {
|
||||
if(mask > 128)
|
||||
throw std::logic_error("Prefix length cannot exceed 128");
|
||||
IPv6Address last_addr;
|
||||
IPv6Address::iterator it = last_addr.begin();
|
||||
while(mask > 8) {
|
||||
*it = 0xff;
|
||||
++it;
|
||||
mask -= 8;
|
||||
}
|
||||
*it = 0xff << (8 - mask);
|
||||
return IPv6Range::from_mask(addr, last_addr);
|
||||
}
|
||||
}
|
||||
53
src/arp.cpp
53
src/arp.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "rawpdu.h"
|
||||
#include "constants.h"
|
||||
#include "network_interface.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
|
||||
using std::runtime_error;
|
||||
@@ -59,9 +60,10 @@ ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip,
|
||||
ARP::ARP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(arphdr))
|
||||
throw runtime_error("Not enough size for an ARP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_arp, buffer, sizeof(arphdr));
|
||||
total_sz -= sizeof(arphdr);
|
||||
//TODO: Check whether this should be removed or not.
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer + sizeof(arphdr), total_sz));
|
||||
}
|
||||
@@ -107,54 +109,41 @@ uint32_t ARP::header_size() const {
|
||||
}
|
||||
|
||||
void ARP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(arphdr));
|
||||
#endif
|
||||
memcpy(buffer, &_arp, sizeof(arphdr));
|
||||
}
|
||||
|
||||
bool ARP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
||||
bool ARP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(arphdr))
|
||||
return false;
|
||||
arphdr *arp_ptr = (arphdr*)ptr;
|
||||
const arphdr *arp_ptr = (const arphdr*)ptr;
|
||||
return arp_ptr->ar_sip == _arp.ar_tip && arp_ptr->ar_tip == _arp.ar_sip;
|
||||
}
|
||||
|
||||
PDU *ARP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(arphdr))
|
||||
return 0;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sizeof(arphdr)) {
|
||||
child = PDU::clone_inner_pdu(ptr + sizeof(arphdr), total_sz - sizeof(arphdr));
|
||||
if(!child)
|
||||
return 0;
|
||||
}
|
||||
cloned = new ARP(ptr, std::min(total_sz, (uint32_t)sizeof(_arp)));
|
||||
cloned->inner_pdu(child);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
EthernetII ARP::make_arp_request(const NetworkInterface& iface,
|
||||
ipaddress_type target, ipaddress_type sender, const hwaddress_type &hw_snd)
|
||||
EthernetII ARP::make_arp_request(ipaddress_type target, ipaddress_type sender,
|
||||
const hwaddress_type &hw_snd)
|
||||
{
|
||||
/* Create ARP packet and set its attributes */
|
||||
ARP* arp = new ARP();
|
||||
arp->target_ip_addr(target);
|
||||
arp->sender_ip_addr(sender);
|
||||
arp->sender_hw_addr(hw_snd);
|
||||
arp->opcode(REQUEST);
|
||||
ARP arp;
|
||||
arp.target_ip_addr(target);
|
||||
arp.sender_ip_addr(sender);
|
||||
arp.sender_hw_addr(hw_snd);
|
||||
arp.opcode(REQUEST);
|
||||
|
||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||
return EthernetII(iface, EthernetII::BROADCAST, hw_snd, arp);
|
||||
return EthernetII(EthernetII::BROADCAST, hw_snd) / arp;
|
||||
}
|
||||
|
||||
EthernetII ARP::make_arp_reply(const NetworkInterface& iface,
|
||||
ipaddress_type target, ipaddress_type sender, const hwaddress_type &hw_tgt,
|
||||
const hwaddress_type &hw_snd)
|
||||
EthernetII ARP::make_arp_reply(ipaddress_type target, ipaddress_type sender,
|
||||
const hwaddress_type &hw_tgt, const hwaddress_type &hw_snd)
|
||||
{
|
||||
/* Create ARP packet and set its attributes */
|
||||
ARP* arp = new ARP(target, sender, hw_tgt, hw_snd);
|
||||
arp->opcode(REPLY);
|
||||
ARP arp(target, sender, hw_tgt, hw_snd);
|
||||
arp.opcode(REPLY);
|
||||
|
||||
/* Create the EthernetII PDU with the ARP PDU as its inner PDU */
|
||||
return EthernetII(iface, hw_tgt, hw_snd, arp);
|
||||
return EthernetII(hw_tgt, hw_snd) / arp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "bootp.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins{
|
||||
BootP::BootP()
|
||||
@@ -42,7 +43,7 @@ BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size)
|
||||
: _vend(vend_field_size)
|
||||
{
|
||||
if(total_sz < sizeof(bootphdr) + vend_field_size)
|
||||
throw std::runtime_error("Not enough size for a BootP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_bootp, buffer, sizeof(bootphdr));
|
||||
buffer += sizeof(bootphdr);
|
||||
total_sz -= sizeof(bootphdr);
|
||||
@@ -113,8 +114,17 @@ void BootP::vend(const vend_type &new_vend) {
|
||||
}
|
||||
|
||||
void BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(bootphdr) + _vend.size());
|
||||
#endif
|
||||
std::memcpy(buffer, &_bootp, sizeof(bootphdr));
|
||||
std::copy(_vend.begin(), _vend.end(), buffer + sizeof(bootphdr));
|
||||
}
|
||||
|
||||
bool BootP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(bootphdr))
|
||||
return false;
|
||||
const bootphdr *bootp_ptr = (const bootphdr *)ptr;
|
||||
return bootp_ptr->xid == _bootp.xid;
|
||||
}
|
||||
}
|
||||
|
||||
456
src/crypto.cpp
456
src/crypto.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -26,8 +26,15 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto.h"
|
||||
#ifdef HAVE_WPA2_DECRYPTION
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/aes.h>
|
||||
#endif // HAVE_WPA2_DECRYPTION
|
||||
#include "dot11/dot11_data.h"
|
||||
#include "dot11/dot11_beacon.h"
|
||||
|
||||
namespace Tins {
|
||||
namespace Crypto {
|
||||
@@ -63,14 +70,16 @@ bool WEPDecrypter::decrypt(PDU &pdu) {
|
||||
passwords_type::iterator it = passwords.find(addr);
|
||||
if(it != passwords.end()) {
|
||||
dot11->inner_pdu(decrypt(*raw, it->second));
|
||||
dot11->wep(0);
|
||||
// Invalid WEP packet(CRC check failed). Skip it.
|
||||
if(!dot11->inner_pdu())
|
||||
return false;
|
||||
// If its valid, then return true
|
||||
if(dot11->inner_pdu()) {
|
||||
// it's no longer encrypted.
|
||||
dot11->wep(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
PDU *WEPDecrypter::decrypt(RawPDU &raw, const std::string &password) {
|
||||
@@ -98,5 +107,438 @@ PDU *WEPDecrypter::decrypt(RawPDU &raw, const std::string &password) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_WPA2_DECRYPTION
|
||||
// WPA2Decrypter
|
||||
|
||||
const HWAddress<6> &min(const HWAddress<6>& lhs, const HWAddress<6>& rhs) {
|
||||
return lhs < rhs ? lhs : rhs;
|
||||
}
|
||||
|
||||
const HWAddress<6> &max(const HWAddress<6>& lhs, const HWAddress<6>& rhs) {
|
||||
return lhs < rhs ? rhs : lhs;
|
||||
}
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||
void xor_range(InputIterator1 src1, InputIterator2 src2, OutputIterator dst, size_t sz) {
|
||||
for(size_t i = 0; i < sz; ++i) {
|
||||
*dst++ = *src1++ ^ *src2++;
|
||||
}
|
||||
}
|
||||
|
||||
const uint16_t sbox_table[2][256]= {
|
||||
{
|
||||
0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
|
||||
0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
|
||||
0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
|
||||
0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
|
||||
0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
|
||||
0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
|
||||
0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
|
||||
0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
|
||||
0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
|
||||
0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
|
||||
0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
|
||||
0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
|
||||
0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
|
||||
0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
|
||||
0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
|
||||
0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
|
||||
0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
|
||||
0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
|
||||
0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
|
||||
0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
|
||||
0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
|
||||
0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
|
||||
0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
|
||||
0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
|
||||
0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
|
||||
0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
|
||||
0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
|
||||
0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
|
||||
0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
|
||||
0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
|
||||
0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
|
||||
0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A
|
||||
},
|
||||
{
|
||||
0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
|
||||
0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
|
||||
0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
|
||||
0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
|
||||
0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
|
||||
0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
|
||||
0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
|
||||
0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
|
||||
0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
|
||||
0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
|
||||
0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
|
||||
0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
|
||||
0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
|
||||
0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
|
||||
0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
|
||||
0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
|
||||
0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
|
||||
0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
|
||||
0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
|
||||
0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
|
||||
0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
|
||||
0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
|
||||
0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
|
||||
0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
|
||||
0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
|
||||
0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
|
||||
0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
|
||||
0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
|
||||
0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
|
||||
0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
|
||||
0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
|
||||
0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C
|
||||
}
|
||||
};
|
||||
|
||||
uint16_t sbox(uint16_t i) {
|
||||
return sbox_table[0][i & 0xff] ^ sbox_table[1][(i >> 8)];
|
||||
}
|
||||
|
||||
uint16_t join_bytes(uint8_t b1, uint8_t b2) {
|
||||
return (static_cast<uint16_t>(b1) << 8) | b2;
|
||||
}
|
||||
|
||||
uint16_t rotate(uint16_t value) {
|
||||
return ((value >> 1) & 0x7fff) | (value << 15);
|
||||
}
|
||||
|
||||
uint16_t upper_byte(uint16_t value) {
|
||||
return (value >> 8) & 0xff;
|
||||
}
|
||||
|
||||
uint16_t lower_byte(uint16_t value) {
|
||||
return value & 0xff;
|
||||
}
|
||||
|
||||
HWAddress<6> get_bssid(const Dot11Data &dot11) {
|
||||
if(dot11.from_ds() && !dot11.to_ds())
|
||||
return dot11.addr3();
|
||||
else if(!dot11.from_ds() && dot11.to_ds())
|
||||
return dot11.addr2();
|
||||
else
|
||||
return dot11.addr2();
|
||||
}
|
||||
|
||||
namespace WPA2 {
|
||||
|
||||
SessionKeys::SessionKeys() {
|
||||
|
||||
}
|
||||
|
||||
SessionKeys::SessionKeys(const RSNHandshake &hs, const pmk_type &pmk) {
|
||||
uint8_t PKE[100] = "Pairwise key expansion";
|
||||
uint8_t MIC[16];
|
||||
min(hs.client_address(), hs.supplicant_address()).copy(PKE + 23);
|
||||
max(hs.client_address(), hs.supplicant_address()).copy(PKE + 29);
|
||||
const uint8_t *nonce1 = hs.handshake()[1].nonce(),
|
||||
*nonce2 = hs.handshake()[2].nonce();
|
||||
if(std::lexicographical_compare(nonce1, nonce1 + 32, nonce2, nonce2 + 32)) {
|
||||
std::copy(nonce1, nonce1 + 32, PKE + 35);
|
||||
std::copy(nonce2, nonce2 + 32, PKE + 67);
|
||||
}
|
||||
else {
|
||||
std::copy(nonce2, nonce2 + 32, PKE + 35);
|
||||
std::copy(nonce1, nonce1 + 32, PKE + 67);
|
||||
}
|
||||
for(int i(0); i < 4; ++i) {
|
||||
PKE[99] = i;
|
||||
HMAC(EVP_sha1(), pmk.begin(), pmk.size(), PKE, 100, ptk.begin() + i * 20, 0);
|
||||
}
|
||||
PDU::serialization_type buffer = const_cast<RSNEAPOL&>(hs.handshake()[3]).serialize();
|
||||
std::fill(buffer.begin() + 81, buffer.begin() + 81 + 16, 0);
|
||||
if(hs.handshake()[3].key_descriptor() == 2)
|
||||
HMAC(EVP_sha1(), ptk.begin(), 16, &buffer[0], buffer.size(), MIC, 0);
|
||||
else
|
||||
HMAC(EVP_md5(), ptk.begin(), 16, &buffer[0], buffer.size(), MIC, 0);
|
||||
|
||||
if(!std::equal(MIC, MIC + sizeof(MIC), hs.handshake()[3].mic()))
|
||||
throw invalid_handshake();
|
||||
is_ccmp = (hs.handshake()[3].key_descriptor() == 2);
|
||||
}
|
||||
|
||||
SNAP *SessionKeys::ccmp_decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const {
|
||||
RawPDU::payload_type &pload = raw.payload();
|
||||
uint8_t MIC[16] = {0};
|
||||
uint8_t PN[6] = {
|
||||
pload[7],
|
||||
pload[6],
|
||||
pload[5],
|
||||
pload[4],
|
||||
pload[1],
|
||||
pload[0]
|
||||
};
|
||||
|
||||
uint8_t AAD[32] = {0};
|
||||
AAD[0] = 0;
|
||||
AAD[1] = 22 + 6 * int(dot11.from_ds() && dot11.to_ds());
|
||||
if(dot11.subtype() == Dot11::QOS_DATA_DATA)
|
||||
AAD[1] += 2;
|
||||
AAD[2] = dot11.protocol() | (dot11.type() << 2) | ((dot11.subtype() << 4) & 0x80);
|
||||
AAD[3] = 0x40 | dot11.to_ds() | (dot11.from_ds() << 1) |
|
||||
(dot11.more_frag() << 2) | (dot11.order() << 7);
|
||||
dot11.addr1().copy(AAD + 4);
|
||||
dot11.addr2().copy(AAD + 10);
|
||||
dot11.addr3().copy(AAD + 16);
|
||||
|
||||
AAD[22] = dot11.frag_num();
|
||||
AAD[23] = 0;
|
||||
|
||||
if(dot11.from_ds() && dot11.to_ds())
|
||||
dot11.addr4().copy(AAD + 24);
|
||||
|
||||
AES_KEY ctx;
|
||||
AES_set_encrypt_key(ptk.begin() + 32, 128, &ctx);
|
||||
uint8_t crypted_block[16];
|
||||
size_t total_sz = raw.payload_size() - 16, offset = 8, blocks = (total_sz + 15) / 16;
|
||||
|
||||
uint8_t counter[16];
|
||||
counter[0] = 0x59;
|
||||
counter[1] = 0;
|
||||
dot11.addr2().copy(counter + 2);
|
||||
std::copy(PN, PN + 6, counter + 8);
|
||||
counter[14] = (total_sz >> 8) & 0xff;
|
||||
counter[15] = total_sz & 0xff;
|
||||
|
||||
AES_encrypt(counter, MIC, &ctx);
|
||||
xor_range(MIC, AAD, MIC, 16);
|
||||
AES_encrypt(MIC, MIC, &ctx);
|
||||
xor_range(MIC, AAD + 16, MIC, 16);
|
||||
AES_encrypt(MIC, MIC, &ctx);
|
||||
|
||||
counter[0] = 1;
|
||||
counter[14] = counter[15] = 0;
|
||||
AES_encrypt(counter, crypted_block, &ctx);
|
||||
uint8_t nice_MIC[8];
|
||||
std::copy(pload.begin() + pload.size() - 8, pload.end(), nice_MIC);
|
||||
xor_range(crypted_block, nice_MIC, nice_MIC, 8);
|
||||
for(size_t i = 1; i <= blocks; ++i) {
|
||||
size_t block_sz = (i == blocks) ? (total_sz % 16) : 16;
|
||||
if(block_sz == 0)
|
||||
block_sz = 16;
|
||||
counter[14] = (i >> 8) & 0xff;
|
||||
counter[15] = i & 0xff;
|
||||
AES_encrypt(counter, crypted_block, &ctx );
|
||||
|
||||
xor_range(crypted_block, &pload[offset], &pload[(i - 1) * 16], block_sz);
|
||||
|
||||
xor_range(MIC, &pload[(i - 1) * 16], MIC, block_sz);
|
||||
AES_encrypt(MIC, MIC, &ctx);
|
||||
offset += block_sz;
|
||||
}
|
||||
return (std::equal(nice_MIC, nice_MIC + sizeof(nice_MIC), MIC)) ?
|
||||
new SNAP(&pload[0], total_sz) :
|
||||
0;
|
||||
}
|
||||
|
||||
RC4Key SessionKeys::generate_rc4_key(const Dot11Data &dot11, const RawPDU &raw) const {
|
||||
const RawPDU::payload_type &pload = raw.payload();
|
||||
const uint8_t *tk = ptk.begin() + 32;
|
||||
Internals::byte_array<16> rc4_key;
|
||||
uint16_t ppk[6];
|
||||
const Dot11::address_type addr = get_bssid(dot11);
|
||||
// Phase 1
|
||||
ppk[0] = join_bytes(pload[4], pload[5]);
|
||||
ppk[1] = join_bytes(pload[6], pload[7]);
|
||||
ppk[2] = join_bytes(addr[1], addr[0]);
|
||||
ppk[3] = join_bytes(addr[3], addr[2]);
|
||||
ppk[4] = join_bytes(addr[5], addr[4]);
|
||||
|
||||
for(size_t i = 0; i < 4; ++i) {
|
||||
ppk[0] += sbox(ppk[4] ^ join_bytes(tk[1], tk[0]));
|
||||
ppk[1] += sbox(ppk[0] ^ join_bytes(tk[5], tk[4]));
|
||||
ppk[2] += sbox(ppk[1] ^ join_bytes(tk[9], tk[8]));
|
||||
ppk[3] += sbox(ppk[2] ^ join_bytes(tk[13], tk[12]));
|
||||
ppk[4] += sbox(ppk[3] ^ join_bytes(tk[1], tk[0])) + 2*i;
|
||||
ppk[0] += sbox(ppk[4] ^ join_bytes(tk[3], tk[2]));
|
||||
ppk[1] += sbox(ppk[0] ^ join_bytes(tk[7], tk[6]));
|
||||
ppk[2] += sbox(ppk[1] ^ join_bytes(tk[11], tk[10]));
|
||||
ppk[3] += sbox(ppk[2] ^ join_bytes(tk[15], tk[14]));
|
||||
ppk[4] += sbox(ppk[3] ^ join_bytes(tk[3], tk[2])) + 2*i + 1;
|
||||
}
|
||||
|
||||
// Phase 2, step 1
|
||||
ppk[5] = ppk[4] + join_bytes(pload[0], pload[2]);
|
||||
|
||||
// Phase 2, step 2
|
||||
ppk[0] += sbox(ppk[5] ^ join_bytes(tk[1], tk[0]));
|
||||
ppk[1] += sbox(ppk[0] ^ join_bytes(tk[3], tk[2]));
|
||||
ppk[2] += sbox(ppk[1] ^ join_bytes(tk[5], tk[4]));
|
||||
ppk[3] += sbox(ppk[2] ^ join_bytes(tk[7], tk[6]));
|
||||
ppk[4] += sbox(ppk[3] ^ join_bytes(tk[9], tk[8]));
|
||||
ppk[5] += sbox(ppk[4] ^ join_bytes(tk[11], tk[10]));
|
||||
|
||||
ppk[0] += rotate(ppk[5] ^ join_bytes(tk[13], tk[12]));
|
||||
ppk[1] += rotate(ppk[0] ^ join_bytes(tk[15], tk[14]));
|
||||
ppk[2] += rotate(ppk[1]);
|
||||
ppk[3] += rotate(ppk[2]);
|
||||
ppk[4] += rotate(ppk[3]);
|
||||
ppk[5] += rotate(ppk[4]);
|
||||
|
||||
// Phase 2, step 3
|
||||
rc4_key[0] = upper_byte(join_bytes(pload[0], pload[2]));
|
||||
rc4_key[1] = (rc4_key[0] | 0x20) & 0x7f;
|
||||
rc4_key[2] = lower_byte(join_bytes(pload[0], pload[2]));
|
||||
rc4_key[3] = lower_byte((ppk[5] ^ join_bytes(tk[1], tk[0])) >> 1);
|
||||
rc4_key[4] = lower_byte(ppk[0]);
|
||||
rc4_key[5] = upper_byte(ppk[0]);
|
||||
rc4_key[6] = lower_byte(ppk[1]);
|
||||
rc4_key[7] = upper_byte(ppk[1]);
|
||||
rc4_key[8] = lower_byte(ppk[2]);
|
||||
rc4_key[9] = upper_byte(ppk[2]);
|
||||
rc4_key[10] = lower_byte(ppk[3]);
|
||||
rc4_key[11] = upper_byte(ppk[3]);
|
||||
rc4_key[12] = lower_byte(ppk[4]);
|
||||
rc4_key[13] = upper_byte(ppk[4]);
|
||||
rc4_key[14] = lower_byte(ppk[5]);
|
||||
rc4_key[15] = upper_byte(ppk[5]);
|
||||
return RC4Key(rc4_key.begin(), rc4_key.end());
|
||||
}
|
||||
|
||||
SNAP *SessionKeys::tkip_decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const {
|
||||
// at least 20 bytes for IV + crc + stuff
|
||||
if(raw.payload_size() <= 20)
|
||||
return 0;
|
||||
Crypto::RC4Key key = generate_rc4_key(dot11, raw);
|
||||
RawPDU::payload_type &pload = raw.payload();
|
||||
rc4(pload.begin() + 8, pload.end(), key, pload.begin());
|
||||
|
||||
uint32_t crc = Utils::crc32(&pload[0], pload.size() - 12);
|
||||
if(pload[pload.size() - 12] != (crc & 0xff) ||
|
||||
pload[pload.size() - 11] != ((crc >> 8) & 0xff) ||
|
||||
pload[pload.size() - 10] != ((crc >> 16) & 0xff) ||
|
||||
pload[pload.size() - 9] != ((crc >> 24) & 0xff))
|
||||
return 0;
|
||||
|
||||
return new SNAP(&pload[0], pload.size() - 20);
|
||||
}
|
||||
|
||||
SNAP *SessionKeys::SessionKeys::decrypt_unicast(const Dot11Data &dot11, RawPDU &raw) const {
|
||||
return is_ccmp ?
|
||||
ccmp_decrypt_unicast(dot11, raw) :
|
||||
tkip_decrypt_unicast(dot11, raw);
|
||||
}
|
||||
|
||||
// supplicant_data
|
||||
|
||||
SupplicantData::SupplicantData(const std::string &psk, const std::string &ssid) {
|
||||
PKCS5_PBKDF2_HMAC_SHA1(
|
||||
psk.c_str(),
|
||||
psk.size(),
|
||||
(unsigned char *)ssid.c_str(),
|
||||
ssid.size(),
|
||||
4096,
|
||||
pmk_.size(),
|
||||
pmk_.begin()
|
||||
);
|
||||
}
|
||||
|
||||
const SupplicantData::pmk_type &SupplicantData::pmk() const {
|
||||
return pmk_;
|
||||
}
|
||||
} // namespace WPA2
|
||||
|
||||
void WPA2Decrypter::add_ap_data(const std::string &psk, const std::string &ssid) {
|
||||
pmks.insert(std::make_pair(ssid, WPA2::SupplicantData(psk, ssid)));
|
||||
}
|
||||
|
||||
void WPA2Decrypter::add_ap_data(const std::string &psk, const std::string &ssid,
|
||||
const address_type &addr)
|
||||
{
|
||||
add_ap_data(psk, ssid);
|
||||
add_access_point(ssid, addr);
|
||||
}
|
||||
|
||||
void WPA2Decrypter::add_access_point(const std::string &ssid, const address_type &addr) {
|
||||
pmks_map::const_iterator it = pmks.find(ssid);
|
||||
if(it == pmks.end())
|
||||
throw std::runtime_error("supplicant data not registered");
|
||||
aps.insert(std::make_pair(addr, it->second));
|
||||
}
|
||||
|
||||
void WPA2Decrypter::try_add_keys(const Dot11Data &dot11, const RSNHandshake &hs) {
|
||||
bssids_map::const_iterator it = find_ap(dot11);
|
||||
if(it != aps.end()) {
|
||||
addr_pair addr_p = extract_addr_pair(dot11);
|
||||
try {
|
||||
WPA2::SessionKeys session(hs, it->second.pmk());
|
||||
keys[addr_p] = session;
|
||||
}
|
||||
catch(WPA2::invalid_handshake&) { }
|
||||
}
|
||||
}
|
||||
|
||||
WPA2Decrypter::addr_pair WPA2Decrypter::extract_addr_pair(const Dot11Data &dot11) {
|
||||
if(dot11.from_ds() && !dot11.to_ds())
|
||||
return make_addr_pair(dot11.addr2(), dot11.addr3());
|
||||
else if(!dot11.from_ds() && dot11.to_ds())
|
||||
return make_addr_pair(dot11.addr1(), dot11.addr2());
|
||||
else
|
||||
return make_addr_pair(dot11.addr2(), dot11.addr3());
|
||||
}
|
||||
|
||||
WPA2Decrypter::addr_pair WPA2Decrypter::extract_addr_pair_dst(const Dot11Data &dot11) {
|
||||
if(dot11.from_ds() && !dot11.to_ds())
|
||||
return make_addr_pair(dot11.addr1(), dot11.addr2());
|
||||
else if(!dot11.from_ds() && dot11.to_ds())
|
||||
return make_addr_pair(dot11.addr1(), dot11.addr3());
|
||||
else
|
||||
return make_addr_pair(dot11.addr1(), dot11.addr3());
|
||||
}
|
||||
|
||||
WPA2Decrypter::bssids_map::const_iterator WPA2Decrypter::find_ap(const Dot11Data &dot11) {
|
||||
if(dot11.from_ds() && !dot11.to_ds())
|
||||
return aps.find(dot11.addr2());
|
||||
else if(!dot11.from_ds() && dot11.to_ds())
|
||||
return aps.find(dot11.addr1());
|
||||
else
|
||||
return aps.find(dot11.addr3());
|
||||
}
|
||||
|
||||
bool WPA2Decrypter::decrypt(PDU &pdu) {
|
||||
if(capturer.process_packet(pdu)) {
|
||||
try_add_keys(pdu.rfind_pdu<Dot11Data>(), capturer.handshakes().front());
|
||||
capturer.clear_handshakes();
|
||||
}
|
||||
else if(const Dot11Beacon *beacon = pdu.find_pdu<Dot11Beacon>()) {
|
||||
if(aps.count(beacon->addr3()) == 0) {
|
||||
try {
|
||||
std::string ssid = beacon->ssid();
|
||||
if(pmks.count(ssid)) {
|
||||
add_access_point(ssid, beacon->addr3());
|
||||
}
|
||||
}
|
||||
catch(option_not_found&) { }
|
||||
}
|
||||
}
|
||||
else {
|
||||
Dot11Data *data = pdu.find_pdu<Dot11Data>();
|
||||
RawPDU *raw = pdu.find_pdu<RawPDU>();
|
||||
if(data && raw && data->wep()) {
|
||||
// search for the tuple (bssid, src_addr)
|
||||
keys_map::const_iterator it = keys.find(extract_addr_pair(*data));
|
||||
|
||||
// search for the tuple (bssid, dst_addr) if the above didn't work
|
||||
if(it == keys.end())
|
||||
it = keys.find(extract_addr_pair_dst(*data));
|
||||
if(it != keys.end()) {
|
||||
SNAP *snap = it->second.decrypt_unicast(*data, *raw);
|
||||
if(snap) {
|
||||
data->inner_pdu(snap);
|
||||
data->wep(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} // namespace WPA2
|
||||
#endif // HAVE_WPA2_DECRYPTION
|
||||
} // namespace Crypto
|
||||
} // namespace Tins
|
||||
|
||||
73
src/dhcp.cpp
73
src/dhcp.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "endianness.h"
|
||||
#include "dhcp.h"
|
||||
#include "ethernetII.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
@@ -52,7 +53,7 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
total_sz -= BootP::header_size() - vend().size();
|
||||
uint8_t args[2] = {0};
|
||||
if(total_sz < sizeof(uint32_t) || *(uint32_t*)buffer != Endian::host_to_be<uint32_t>(0x63825363))
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
buffer += sizeof(uint32_t);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
while(total_sz) {
|
||||
@@ -64,22 +65,28 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
i = 2;
|
||||
}
|
||||
else if(!total_sz)
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
}
|
||||
if(total_sz < args[1])
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
add_option(dhcp_option((Options)args[0], args[1], buffer));
|
||||
throw malformed_packet();
|
||||
add_option(
|
||||
option((OptionTypes)args[0], args[1], buffer)
|
||||
);
|
||||
buffer += args[1];
|
||||
total_sz -= args[1];
|
||||
}
|
||||
}
|
||||
|
||||
void DHCP::add_option(const dhcp_option &option) {
|
||||
_options.push_back(option);
|
||||
_size += option.data_size() + (sizeof(uint8_t) << 1);
|
||||
void DHCP::add_option(const option &opt) {
|
||||
internal_add_option(opt);
|
||||
_options.push_back(opt);
|
||||
}
|
||||
|
||||
const DHCP::dhcp_option *DHCP::search_option(Options opt) const {
|
||||
void DHCP::internal_add_option(const option &opt) {
|
||||
_size += opt.data_size() + (sizeof(uint8_t) << 1);
|
||||
}
|
||||
|
||||
const DHCP::option *DHCP::search_option(OptionTypes opt) const {
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
if(it->option() == opt)
|
||||
return &(*it);
|
||||
@@ -89,11 +96,11 @@ const DHCP::dhcp_option *DHCP::search_option(Options opt) const {
|
||||
|
||||
void DHCP::type(Flags type) {
|
||||
uint8_t int_type = type;
|
||||
add_option(dhcp_option(DHCP_MESSAGE_TYPE, sizeof(uint8_t), &int_type));
|
||||
add_option(option(DHCP_MESSAGE_TYPE, sizeof(uint8_t), &int_type));
|
||||
}
|
||||
|
||||
void DHCP::end() {
|
||||
add_option(dhcp_option(DHCP_MESSAGE_TYPE));
|
||||
add_option(option(END));
|
||||
}
|
||||
|
||||
uint8_t DHCP::type() const {
|
||||
@@ -102,7 +109,7 @@ uint8_t DHCP::type() const {
|
||||
|
||||
void DHCP::server_identifier(ipaddress_type ip) {
|
||||
uint32_t ip_int = ip;
|
||||
add_option(dhcp_option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip_int));
|
||||
add_option(option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip_int));
|
||||
}
|
||||
|
||||
DHCP::ipaddress_type DHCP::server_identifier() const {
|
||||
@@ -111,7 +118,7 @@ DHCP::ipaddress_type DHCP::server_identifier() const {
|
||||
|
||||
void DHCP::lease_time(uint32_t time) {
|
||||
time = Endian::host_to_be(time);
|
||||
add_option(dhcp_option(DHCP_LEASE_TIME, sizeof(uint32_t), (const uint8_t*)&time));
|
||||
add_option(option(DHCP_LEASE_TIME, sizeof(uint32_t), (const uint8_t*)&time));
|
||||
}
|
||||
|
||||
uint32_t DHCP::lease_time() const {
|
||||
@@ -120,7 +127,7 @@ uint32_t DHCP::lease_time() const {
|
||||
|
||||
void DHCP::renewal_time(uint32_t time) {
|
||||
time = Endian::host_to_be(time);
|
||||
add_option(dhcp_option(DHCP_RENEWAL_TIME, sizeof(uint32_t), (const uint8_t*)&time));
|
||||
add_option(option(DHCP_RENEWAL_TIME, sizeof(uint32_t), (const uint8_t*)&time));
|
||||
}
|
||||
|
||||
uint32_t DHCP::renewal_time() const {
|
||||
@@ -129,7 +136,7 @@ uint32_t DHCP::renewal_time() const {
|
||||
|
||||
void DHCP::subnet_mask(ipaddress_type mask) {
|
||||
uint32_t mask_int = mask;
|
||||
add_option(dhcp_option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask_int));
|
||||
add_option(option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask_int));
|
||||
}
|
||||
|
||||
DHCP::ipaddress_type DHCP::subnet_mask() const {
|
||||
@@ -138,7 +145,7 @@ DHCP::ipaddress_type DHCP::subnet_mask() const {
|
||||
|
||||
void DHCP::routers(const list<ipaddress_type> &routers) {
|
||||
serialization_type buffer = serialize_list(routers);
|
||||
add_option(dhcp_option(ROUTERS, buffer.begin(), buffer.end()));
|
||||
add_option(option(ROUTERS, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
std::list<DHCP::ipaddress_type> DHCP::routers() const {
|
||||
@@ -147,7 +154,7 @@ std::list<DHCP::ipaddress_type> DHCP::routers() const {
|
||||
|
||||
void DHCP::domain_name_servers(const list<ipaddress_type> &dns) {
|
||||
serialization_type buffer = serialize_list(dns);
|
||||
add_option(dhcp_option(DOMAIN_NAME_SERVERS, buffer.begin(), buffer.end()));
|
||||
add_option(option(DOMAIN_NAME_SERVERS, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
std::list<DHCP::ipaddress_type> DHCP::domain_name_servers() const {
|
||||
@@ -156,7 +163,7 @@ std::list<DHCP::ipaddress_type> DHCP::domain_name_servers() const {
|
||||
|
||||
void DHCP::broadcast(ipaddress_type addr) {
|
||||
uint32_t int_addr = addr;
|
||||
add_option(dhcp_option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
|
||||
add_option(option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
|
||||
}
|
||||
|
||||
DHCP::ipaddress_type DHCP::broadcast() const {
|
||||
@@ -165,7 +172,7 @@ DHCP::ipaddress_type DHCP::broadcast() const {
|
||||
|
||||
void DHCP::requested_ip(ipaddress_type addr) {
|
||||
uint32_t int_addr = addr;
|
||||
add_option(dhcp_option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
|
||||
add_option(option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr));
|
||||
}
|
||||
|
||||
DHCP::ipaddress_type DHCP::requested_ip() const {
|
||||
@@ -173,7 +180,7 @@ DHCP::ipaddress_type DHCP::requested_ip() const {
|
||||
}
|
||||
|
||||
void DHCP::domain_name(const string &name) {
|
||||
add_option(dhcp_option(DOMAIN_NAME, name.size(), (const uint8_t*)name.c_str()));
|
||||
add_option(option(DOMAIN_NAME, name.size(), (const uint8_t*)name.c_str()));
|
||||
}
|
||||
|
||||
std::string DHCP::domain_name() const {
|
||||
@@ -182,7 +189,7 @@ std::string DHCP::domain_name() const {
|
||||
|
||||
void DHCP::rebind_time(uint32_t time) {
|
||||
time = Endian::host_to_be(time);
|
||||
add_option(dhcp_option(DHCP_REBINDING_TIME, sizeof(uint32_t), (uint8_t*)&time));
|
||||
add_option(option(DHCP_REBINDING_TIME, sizeof(uint32_t), (uint8_t*)&time));
|
||||
}
|
||||
|
||||
uint32_t DHCP::rebind_time() const {
|
||||
@@ -202,7 +209,9 @@ uint32_t DHCP::header_size() const {
|
||||
}
|
||||
|
||||
void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
if(_size) {
|
||||
vend_type &result(BootP::vend());
|
||||
result.resize(_size);
|
||||
@@ -211,7 +220,7 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
|
||||
*((uint32_t*)&result[0]) = Endian::host_to_be<uint32_t>(0x63825363);
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
*(ptr++) = it->option();
|
||||
*(ptr++) = it->data_size();
|
||||
*(ptr++) = it->length_field();
|
||||
std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), ptr);
|
||||
ptr += it->data_size();
|
||||
}
|
||||
@@ -219,12 +228,12 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
|
||||
BootP::write_serialization(buffer, total_sz, parent);
|
||||
}
|
||||
|
||||
std::list<DHCP::ipaddress_type> DHCP::generic_search(Options opt, type2type<std::list<ipaddress_type> >) const {
|
||||
const dhcp_option *option = search_option(opt);
|
||||
if(!option)
|
||||
std::list<DHCP::ipaddress_type> DHCP::generic_search(OptionTypes opt_type, type2type<std::list<ipaddress_type> >) const {
|
||||
const option *opt = search_option(opt_type);
|
||||
if(!opt)
|
||||
throw option_not_found();
|
||||
const uint32_t *ptr = (const uint32_t*)option->data_ptr();
|
||||
uint32_t len = option->data_size();
|
||||
const uint32_t *ptr = (const uint32_t*)opt->data_ptr();
|
||||
uint32_t len = opt->data_size();
|
||||
if((len % sizeof(uint32_t)) != 0)
|
||||
throw option_not_found();
|
||||
std::list<ipaddress_type> container;
|
||||
@@ -235,14 +244,14 @@ std::list<DHCP::ipaddress_type> DHCP::generic_search(Options opt, type2type<std:
|
||||
return container;
|
||||
}
|
||||
|
||||
std::string DHCP::generic_search(Options opt, type2type<std::string>) const {
|
||||
const dhcp_option *option = search_option(opt);
|
||||
if(!option)
|
||||
std::string DHCP::generic_search(OptionTypes opt_type, type2type<std::string>) const {
|
||||
const option *opt = search_option(opt_type);
|
||||
if(!opt)
|
||||
throw option_not_found();
|
||||
return string(option->data_ptr(), option->data_ptr() + option->data_size());
|
||||
return string(opt->data_ptr(), opt->data_ptr() + opt->data_size());
|
||||
}
|
||||
|
||||
DHCP::ipaddress_type DHCP::generic_search(Options opt, type2type<ipaddress_type>) const {
|
||||
DHCP::ipaddress_type DHCP::generic_search(OptionTypes opt, type2type<ipaddress_type>) const {
|
||||
return ipaddress_type(generic_search(opt, type2type<uint32_t>()));
|
||||
}
|
||||
}
|
||||
|
||||
113
src/dhcpv6.cpp
113
src/dhcpv6.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,10 +27,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream> //borrame
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "dhcpv6.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
DHCPv6::DHCPv6() : options_size() {
|
||||
@@ -40,21 +40,19 @@ DHCPv6::DHCPv6() : options_size() {
|
||||
DHCPv6::DHCPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: options_size()
|
||||
{
|
||||
const char *err_msg = "Not enough size for a DHCPv6 header",
|
||||
*opt_err_msg = "Not enough size for a DHCPv6 option";
|
||||
if(total_sz == 0)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
// Relay Agent/Server Messages
|
||||
bool is_relay_msg = (buffer[0] == 12 || buffer[0] == 13);
|
||||
uint32_t required_size = is_relay_msg ? 2 : 4;
|
||||
if(total_sz < required_size)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
std::copy(buffer, buffer + required_size, header_data);
|
||||
buffer += required_size;
|
||||
total_sz -= required_size;
|
||||
if(is_relay_message()) {
|
||||
if(total_sz < ipaddress_type::address_size * 2)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
link_addr = buffer;
|
||||
peer_addr = buffer + ipaddress_type::address_size;
|
||||
buffer += ipaddress_type::address_size * 2;
|
||||
@@ -63,28 +61,28 @@ DHCPv6::DHCPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
options_size = total_sz;
|
||||
while(total_sz) {
|
||||
if(total_sz < sizeof(uint16_t) * 2)
|
||||
throw std::runtime_error(opt_err_msg);
|
||||
throw malformed_packet();
|
||||
|
||||
const uint16_t option = Endian::be_to_host(*(const uint16_t*)buffer);
|
||||
const uint16_t opt = Endian::be_to_host(*(const uint16_t*)buffer);
|
||||
const uint16_t data_size = Endian::be_to_host(
|
||||
*(const uint16_t*)(buffer + sizeof(uint16_t))
|
||||
);
|
||||
if(total_sz - sizeof(uint16_t) * 2 < data_size)
|
||||
throw std::runtime_error(opt_err_msg);
|
||||
throw malformed_packet();
|
||||
buffer += sizeof(uint16_t) * 2;
|
||||
add_option(
|
||||
dhcpv6_option(option, buffer, buffer + data_size)
|
||||
option(opt, buffer, buffer + data_size)
|
||||
);
|
||||
buffer += data_size;
|
||||
total_sz -= sizeof(uint16_t) * 2 + data_size;
|
||||
}
|
||||
}
|
||||
|
||||
void DHCPv6::add_option(const dhcpv6_option &option) {
|
||||
options_.push_back(option);
|
||||
void DHCPv6::add_option(const option &opt) {
|
||||
options_.push_back(opt);
|
||||
}
|
||||
|
||||
const DHCPv6::dhcpv6_option *DHCPv6::search_option(Option id) const {
|
||||
const DHCPv6::option *DHCPv6::search_option(OptionTypes id) const {
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it) {
|
||||
if(it->option() == static_cast<uint16_t>(id))
|
||||
return &*it;
|
||||
@@ -92,12 +90,12 @@ const DHCPv6::dhcpv6_option *DHCPv6::search_option(Option id) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* DHCPv6::write_option(const dhcpv6_option &option, uint8_t* buffer) const {
|
||||
*(uint16_t*)buffer = Endian::host_to_be(option.option());
|
||||
*(uint16_t*)&buffer[sizeof(uint16_t)] = Endian::host_to_be(option.data_size());
|
||||
uint8_t* DHCPv6::write_option(const option &opt, uint8_t* buffer) const {
|
||||
*(uint16_t*)buffer = Endian::host_to_be(opt.option());
|
||||
*(uint16_t*)&buffer[sizeof(uint16_t)] = Endian::host_to_be<uint16_t>(opt.length_field());
|
||||
return std::copy(
|
||||
option.data_ptr(),
|
||||
option.data_ptr() + option.data_size(),
|
||||
opt.data_ptr(),
|
||||
opt.data_ptr() + opt.data_size(),
|
||||
buffer + sizeof(uint16_t) * 2
|
||||
);
|
||||
}
|
||||
@@ -133,6 +131,15 @@ uint32_t DHCPv6::header_size() const {
|
||||
return (is_relay_message() ? (2 + ipaddress_type::address_size * 2) : 4) + options_size;
|
||||
}
|
||||
|
||||
bool DHCPv6::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(!is_relay_message()) {
|
||||
if(total_sz < 4 || (ptr[0] == 12 || ptr[0] == 13))
|
||||
return false;
|
||||
return std::equal(header_data + 1, header_data + 4, ptr + 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DHCPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
const uint32_t required_size = is_relay_message() ? 2 : 4;
|
||||
buffer = std::copy(header_data, header_data + required_size, buffer);
|
||||
@@ -150,7 +157,7 @@ void DHCPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *
|
||||
// ********************************************************************
|
||||
|
||||
DHCPv6::ia_na_type DHCPv6::ia_na() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
IA_NA, sizeof(uint32_t) * 3
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t) * 3;
|
||||
@@ -164,7 +171,7 @@ DHCPv6::ia_na_type DHCPv6::ia_na() const {
|
||||
}
|
||||
|
||||
DHCPv6::ia_ta_type DHCPv6::ia_ta() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
IA_TA, sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t);
|
||||
@@ -176,7 +183,7 @@ DHCPv6::ia_ta_type DHCPv6::ia_ta() const {
|
||||
}
|
||||
|
||||
DHCPv6::ia_address_type DHCPv6::ia_address() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
IA_ADDR, sizeof(uint32_t) * 2 + ipaddress_type::address_size
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t) * 2 + ipaddress_type::address_size;
|
||||
@@ -190,7 +197,7 @@ DHCPv6::ia_address_type DHCPv6::ia_address() const {
|
||||
}
|
||||
|
||||
DHCPv6::option_request_type DHCPv6::option_request() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
OPTION_REQUEST, 2
|
||||
);
|
||||
const uint16_t *ptr = (const uint16_t*)opt->data_ptr(),
|
||||
@@ -198,21 +205,21 @@ DHCPv6::option_request_type DHCPv6::option_request() const {
|
||||
option_request_type output;
|
||||
while(ptr < end) {
|
||||
output.push_back(
|
||||
static_cast<Option>(Endian::be_to_host(*ptr++))
|
||||
static_cast<OptionTypes>(Endian::be_to_host(*ptr++))
|
||||
);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
uint8_t DHCPv6::preference() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
const option *opt = safe_search_option<std::not_equal_to>(
|
||||
PREFERENCE, 1
|
||||
);
|
||||
return *opt->data_ptr();
|
||||
}
|
||||
|
||||
uint16_t DHCPv6::elapsed_time() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
const option *opt = safe_search_option<std::not_equal_to>(
|
||||
ELAPSED_TIME, 2
|
||||
);
|
||||
return Endian::be_to_host(
|
||||
@@ -221,7 +228,7 @@ uint16_t DHCPv6::elapsed_time() const {
|
||||
}
|
||||
|
||||
DHCPv6::relay_msg_type DHCPv6::relay_message() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
RELAY_MSG, 1
|
||||
);
|
||||
return relay_msg_type(
|
||||
@@ -231,7 +238,7 @@ DHCPv6::relay_msg_type DHCPv6::relay_message() const {
|
||||
}
|
||||
|
||||
DHCPv6::authentication_type DHCPv6::authentication() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
AUTH, sizeof(uint8_t) * 3 + sizeof(uint64_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -248,14 +255,14 @@ DHCPv6::authentication_type DHCPv6::authentication() const {
|
||||
}
|
||||
|
||||
DHCPv6::ipaddress_type DHCPv6::server_unicast() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
const option *opt = safe_search_option<std::not_equal_to>(
|
||||
UNICAST, ipaddress_type::address_size
|
||||
);
|
||||
return ipaddress_type(opt->data_ptr());
|
||||
}
|
||||
|
||||
DHCPv6::status_code_type DHCPv6::status_code() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
STATUS_CODE, sizeof(uint16_t)
|
||||
);
|
||||
status_code_type output;
|
||||
@@ -272,7 +279,7 @@ bool DHCPv6::has_rapid_commit() const {
|
||||
}
|
||||
|
||||
DHCPv6::user_class_type DHCPv6::user_class() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
USER_CLASS, sizeof(uint16_t)
|
||||
);
|
||||
return option2class_option_data<user_class_type>(
|
||||
@@ -281,7 +288,7 @@ DHCPv6::user_class_type DHCPv6::user_class() const {
|
||||
}
|
||||
|
||||
DHCPv6::vendor_class_type DHCPv6::vendor_class() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
VENDOR_CLASS, sizeof(uint32_t)
|
||||
);
|
||||
typedef vendor_class_type::class_data_type data_type;
|
||||
@@ -298,7 +305,7 @@ DHCPv6::vendor_class_type DHCPv6::vendor_class() const {
|
||||
}
|
||||
|
||||
DHCPv6::vendor_info_type DHCPv6::vendor_info() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
VENDOR_OPTS, sizeof(uint32_t)
|
||||
);
|
||||
vendor_info_type output;
|
||||
@@ -313,7 +320,7 @@ DHCPv6::vendor_info_type DHCPv6::vendor_info() const {
|
||||
}
|
||||
|
||||
DHCPv6::interface_id_type DHCPv6::interface_id() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::equal_to>(
|
||||
const option *opt = safe_search_option<std::equal_to>(
|
||||
INTERFACE_ID, 0
|
||||
);
|
||||
return interface_id_type(
|
||||
@@ -333,7 +340,7 @@ bool DHCPv6::has_reconfigure_accept() const {
|
||||
}
|
||||
|
||||
DHCPv6::duid_type DHCPv6::client_id() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
CLIENTID, sizeof(uint16_t) + 1
|
||||
);
|
||||
return duid_type(
|
||||
@@ -346,7 +353,7 @@ DHCPv6::duid_type DHCPv6::client_id() const {
|
||||
}
|
||||
|
||||
DHCPv6::duid_type DHCPv6::server_id() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
SERVERID, sizeof(uint16_t) + 1
|
||||
);
|
||||
return duid_type(
|
||||
@@ -374,7 +381,7 @@ void DHCPv6::ia_na(const ia_na_type &value) {
|
||||
buffer.begin() + sizeof(uint32_t) * 3
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_NA, buffer.begin(), buffer.end())
|
||||
option(IA_NA, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -388,7 +395,7 @@ void DHCPv6::ia_ta(const ia_ta_type &value) {
|
||||
buffer.begin() + sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_TA, buffer.begin(), buffer.end())
|
||||
option(IA_TA, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -406,7 +413,7 @@ void DHCPv6::ia_address(const ia_address_type &value) {
|
||||
buffer.begin() + sizeof(uint32_t) * 2 + ipaddress_type::address_size
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_ADDR, buffer.begin(), buffer.end())
|
||||
option(IA_ADDR, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -418,26 +425,26 @@ void DHCPv6::option_request(const option_request_type &value) {
|
||||
for(iterator it = value.begin(); it != value.end(); ++it, index += 2)
|
||||
*(uint16_t*)&buffer[index] = Endian::host_to_be<uint16_t>(*it);
|
||||
add_option(
|
||||
dhcpv6_option(OPTION_REQUEST, buffer.begin(), buffer.end())
|
||||
option(OPTION_REQUEST, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::preference(uint8_t value) {
|
||||
add_option(
|
||||
dhcpv6_option(PREFERENCE, 1, &value)
|
||||
option(PREFERENCE, 1, &value)
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::elapsed_time(uint16_t value) {
|
||||
value = Endian::host_to_be(value);
|
||||
add_option(
|
||||
dhcpv6_option(ELAPSED_TIME, 2, (const uint8_t*)&value)
|
||||
option(ELAPSED_TIME, 2, (const uint8_t*)&value)
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::relay_message(const relay_msg_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(RELAY_MSG, value.begin(), value.end())
|
||||
option(RELAY_MSG, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -455,13 +462,13 @@ void DHCPv6::authentication(const authentication_type &value) {
|
||||
buffer.begin() + sizeof(uint8_t) * 3 + sizeof(uint64_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(AUTH, buffer.begin(), buffer.end())
|
||||
option(AUTH, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::server_unicast(const ipaddress_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(UNICAST, value.begin(), value.end())
|
||||
option(UNICAST, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -474,7 +481,7 @@ void DHCPv6::status_code(const status_code_type &value) {
|
||||
buffer.begin() + sizeof(uint16_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(STATUS_CODE, buffer.begin(), buffer.end())
|
||||
option(STATUS_CODE, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -490,7 +497,7 @@ void DHCPv6::user_class(const user_class_type &value) {
|
||||
std::vector<uint8_t> buffer;
|
||||
class_option_data2option(value.begin(), value.end(), buffer);
|
||||
add_option(
|
||||
dhcpv6_option(USER_CLASS, buffer.begin(), buffer.end())
|
||||
option(USER_CLASS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -506,7 +513,7 @@ void DHCPv6::vendor_class(const vendor_class_type &value) {
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(VENDOR_CLASS, buffer.begin(), buffer.end())
|
||||
option(VENDOR_CLASS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -519,19 +526,19 @@ void DHCPv6::vendor_info(const vendor_info_type &value) {
|
||||
buffer.begin() + sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(VENDOR_OPTS, buffer.begin(), buffer.end())
|
||||
option(VENDOR_OPTS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::interface_id(const interface_id_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(INTERFACE_ID, value.begin(), value.end())
|
||||
option(INTERFACE_ID, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::reconfigure_msg(uint8_t value) {
|
||||
add_option(
|
||||
dhcpv6_option(RECONF_MSG, 1, &value)
|
||||
option(RECONF_MSG, 1, &value)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -626,7 +633,7 @@ void DHCPv6::client_id(const duid_type &value) {
|
||||
buffer.begin() + sizeof(uint16_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(CLIENTID, buffer.begin(), buffer.end())
|
||||
option(CLIENTID, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -639,7 +646,7 @@ void DHCPv6::server_id(const duid_type &value) {
|
||||
buffer.begin() + sizeof(uint16_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(SERVERID, buffer.begin(), buffer.end())
|
||||
option(SERVERID, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
68
src/dns.cpp
68
src/dns.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "dns.h"
|
||||
#include "ip_address.h"
|
||||
#include "ipv6_address.h"
|
||||
#include "exceptions.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
@@ -47,7 +49,7 @@ DNS::DNS() : extra_size(0) {
|
||||
|
||||
DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
if(total_sz < sizeof(dnshdr))
|
||||
throw std::runtime_error("Not enough size for a DNS header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&dns, buffer, sizeof(dnshdr));
|
||||
const uint8_t *end(buffer + total_sz);
|
||||
uint16_t nquestions(questions_count());
|
||||
@@ -59,7 +61,7 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
ptr++;
|
||||
Query query;
|
||||
if((ptr + (sizeof(uint16_t) * 2)) >= end)
|
||||
throw std::runtime_error("Not enough size for a given query.");
|
||||
throw malformed_packet();
|
||||
query.dname(string(buffer, ptr));
|
||||
ptr++;
|
||||
const uint16_t *opt_ptr = reinterpret_cast<const uint16_t*>(ptr);
|
||||
@@ -73,6 +75,8 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
buffer = build_resource_list(ans, buffer, total_sz, answers_count());
|
||||
buffer = build_resource_list(arity, buffer, total_sz, authority_count());
|
||||
build_resource_list(addit, buffer, total_sz, additional_count());
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer, total_sz));
|
||||
}
|
||||
|
||||
const uint8_t *DNS::build_resource_list(ResourcesType &lst, const uint8_t *ptr, uint32_t &sz, uint16_t nrecs) {
|
||||
@@ -81,7 +85,7 @@ const uint8_t *DNS::build_resource_list(ResourcesType &lst, const uint8_t *ptr,
|
||||
for(uint16_t i(0); i < nrecs; ++i) {
|
||||
const uint8_t *this_opt_start(ptr);
|
||||
if(ptr + sizeof(uint16_t) > ptr_end)
|
||||
throw std::runtime_error("Not enough size for a given resource.");
|
||||
throw malformed_packet();
|
||||
lst.push_back(DNSResourceRecord(ptr, ptr_end - ptr));
|
||||
ptr += lst.back().size();
|
||||
extra_size += ptr - this_opt_start;
|
||||
@@ -220,9 +224,17 @@ DNSResourceRecord DNS::make_record(const std::string &name,
|
||||
const DNSResourceRecord::info &info, const uint8_t *ptr, uint32_t len)
|
||||
{
|
||||
string nm;
|
||||
std::basic_string<uint8_t> data;
|
||||
parse_domain_name(name, nm);
|
||||
uint16_t index = find_domain_name(nm);
|
||||
DNSResourceRecord res;
|
||||
if(info.type == MX) {
|
||||
data.push_back(0);
|
||||
data.push_back(0);
|
||||
data.insert(data.end(), ptr, ptr + len);
|
||||
ptr = &data[0];
|
||||
len = data.size();
|
||||
}
|
||||
if(index)
|
||||
res = make_offseted_record(Endian::host_to_be(index), ptr, len);
|
||||
else
|
||||
@@ -290,7 +302,9 @@ void DNS::unparse_domain_name(const std::string &dn, std::string &out) const {
|
||||
}
|
||||
|
||||
void DNS::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(dns) + extra_size);
|
||||
#endif
|
||||
std::memcpy(buffer, &dns, sizeof(dns));
|
||||
buffer += sizeof(dns);
|
||||
for(list<Query>::const_iterator it(queries_.begin()); it != queries_.end(); ++it) {
|
||||
@@ -386,7 +400,7 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) const
|
||||
// We need at least a suffix or a suffix index to compose
|
||||
// the domain name
|
||||
if(it == suffixes.end() && suff_it == suffix_indices.end())
|
||||
throw std::runtime_error("Malformed DNS packet");
|
||||
throw malformed_packet();
|
||||
bool first(true);
|
||||
do {
|
||||
if(it != suffixes.end()) {
|
||||
@@ -431,23 +445,36 @@ void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res)
|
||||
}
|
||||
ptr = it->data_ptr();
|
||||
sz = it->data_size();
|
||||
if(sz == 4)
|
||||
addr = IPv4Address(*(uint32_t*)ptr).to_string();
|
||||
else {
|
||||
if(Endian::be_to_host(it->information().type) == MX) {
|
||||
ptr += 2;
|
||||
sz -= 2;
|
||||
}
|
||||
if(Endian::be_to_host(it->information().type) == DNS::AAAA) {
|
||||
uint16_t record_type = Endian::be_to_host(it->information().type);
|
||||
// Skip the preference field if it's MX
|
||||
if(record_type == MX) {
|
||||
ptr += 2;
|
||||
sz -= 2;
|
||||
}
|
||||
switch(record_type) {
|
||||
case AAAA:
|
||||
if(sz != 16)
|
||||
throw std::runtime_error("Malformed IPv6 address");
|
||||
throw malformed_packet();
|
||||
addr = IPv6Address(ptr).to_string();
|
||||
}
|
||||
else
|
||||
break;
|
||||
case A:
|
||||
if(sz != 4)
|
||||
throw malformed_packet();
|
||||
addr = IPv4Address(*(uint32_t*)ptr).to_string();
|
||||
break;
|
||||
case NS:
|
||||
case CNAME:
|
||||
case DNAM:
|
||||
case PTR:
|
||||
case MX:
|
||||
compose_name(ptr, sz, addr);
|
||||
break;
|
||||
default:
|
||||
addr.assign(ptr, ptr + sz);
|
||||
break;
|
||||
}
|
||||
res.push_back(
|
||||
Resource(dname, addr, Endian::be_to_host(it->information().type),
|
||||
Resource(dname, addr, record_type,
|
||||
Endian::host_to_be(it->information().qclass),
|
||||
Endian::be_to_host(it->information().ttl)
|
||||
)
|
||||
@@ -476,4 +503,11 @@ DNS::resources_type DNS::answers() const {
|
||||
convert_resources(ans, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool DNS::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(dnshdr))
|
||||
return false;
|
||||
const dnshdr *hdr = (const dnshdr*)ptr;
|
||||
return hdr->id == dns.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Nasel
|
||||
* Copyright (c) 2012, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <typeinfo>
|
||||
#include "dns_record.h"
|
||||
#include "endianness.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
bool contains_dname(uint16_t type) {
|
||||
@@ -53,7 +54,7 @@ DNSResourceRecord::DNSResourceRecord(DNSRRImpl *impl,
|
||||
DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
const uint8_t *buffer_end = buffer + size;
|
||||
std::auto_ptr<DNSRRImpl> tmp_impl;
|
||||
Internals::smart_ptr<DNSRRImpl>::type tmp_impl;
|
||||
if((*buffer & 0xc0)) {
|
||||
uint16_t offset(*reinterpret_cast<const uint16_t*>(buffer));
|
||||
offset = Endian::be_to_host(offset) & 0x3fff;
|
||||
@@ -65,17 +66,17 @@ DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
while(str_end < buffer_end && *str_end)
|
||||
str_end++;
|
||||
if(str_end == buffer_end)
|
||||
throw std::runtime_error("Not enough size for a resource domain name.");
|
||||
throw malformed_packet();
|
||||
//str_end++;
|
||||
tmp_impl.reset(new NamedDNSRRImpl(buffer, str_end));
|
||||
buffer = ++str_end;
|
||||
}
|
||||
if(buffer + sizeof(info_) > buffer_end)
|
||||
throw std::runtime_error("Not enough size for a resource info.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&info_, buffer, sizeof(info_));
|
||||
buffer += sizeof(info_);
|
||||
if(buffer + sizeof(uint16_t) > buffer_end)
|
||||
throw std::runtime_error("Not enough size for resource data size.");
|
||||
throw malformed_packet();
|
||||
|
||||
// Store the option size.
|
||||
data.resize(
|
||||
@@ -83,7 +84,7 @@ DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
);
|
||||
buffer += sizeof(uint16_t);
|
||||
if(buffer + data.size() > buffer_end)
|
||||
throw std::runtime_error("Not enough size for resource data");
|
||||
throw malformed_packet();
|
||||
if(contains_dname(info_.type) || data.size() != sizeof(uint32_t))
|
||||
std::copy(buffer, buffer + data.size(), data.begin());
|
||||
else if(data.size() == sizeof(uint32_t))
|
||||
@@ -106,24 +107,6 @@ DNSResourceRecord& DNSResourceRecord::operator=(const DNSResourceRecord &rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
DNSResourceRecord::DNSResourceRecord(DNSResourceRecord &&rhs) noexcept
|
||||
: info_(rhs.info_), data(std::move(rhs.data)), impl(0) {
|
||||
std::swap(impl, rhs.impl);
|
||||
}
|
||||
|
||||
DNSResourceRecord& DNSResourceRecord::operator=(DNSResourceRecord &&rhs)
|
||||
noexcept
|
||||
{
|
||||
info_ = rhs.info_;
|
||||
data = std::move(rhs.data);
|
||||
delete impl;
|
||||
impl = 0;
|
||||
std::swap(impl, rhs.impl);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
DNSResourceRecord::~DNSResourceRecord() {
|
||||
delete impl;
|
||||
}
|
||||
|
||||
1574
src/dot11.cpp
1574
src/dot11.cpp
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user