mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +01:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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>
|
||||
|
||||
40
CHANGES
40
CHANGES
@@ -1,3 +1,43 @@
|
||||
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.
|
||||
|
||||
4
Doxyfile
4
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.0
|
||||
|
||||
# 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
|
||||
|
||||
14
Makefile.am
14
Makefile.am
@@ -13,17 +13,20 @@ AM_CXXFLAGS = -Wall -pedantic -I@LIBTINS_INCLUDE_DIR@
|
||||
|
||||
libtins_la_SOURCES=src/arp.cpp \
|
||||
src/bootp.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 \
|
||||
@@ -49,17 +52,20 @@ libtins_includedir = $(includedir)/tins
|
||||
libtins_include_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/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 \
|
||||
@@ -90,4 +96,6 @@ 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
|
||||
|
||||
151
Makefile.in
151
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,24 @@ 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
|
||||
$(srcdir)/libtins.pc.in $(top_srcdir)/configure \
|
||||
$(top_srcdir)/include/config.h.in AUTHORS 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'`;
|
||||
@@ -83,12 +105,13 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
|
||||
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 \
|
||||
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo src/stp.lo \
|
||||
src/pppoe.lo src/crypto.lo src/dhcp.lo src/dhcpv6.lo \
|
||||
src/dns.lo src/dns_record.lo src/dot11.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/pdu.lo src/radiotap.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
|
||||
@@ -96,7 +119,7 @@ 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,6 +134,11 @@ 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)
|
||||
ETAGS = etags
|
||||
@@ -159,6 +187,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 +276,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 +295,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/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 \
|
||||
@@ -298,17 +334,20 @@ libtins_includedir = $(includedir)/tins
|
||||
libtins_include_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/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 \
|
||||
@@ -339,7 +378,9 @@ 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
|
||||
|
||||
all: all-am
|
||||
|
||||
@@ -379,11 +420,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 +446,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 +477,20 @@ 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/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)
|
||||
@@ -477,6 +537,10 @@ mostlyclean-compile:
|
||||
-rm -f src/dns_record.lo
|
||||
-rm -f src/dot11.$(OBJEXT)
|
||||
-rm -f src/dot11.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)
|
||||
@@ -485,8 +549,6 @@ mostlyclean-compile:
|
||||
-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 +571,8 @@ mostlyclean-compile:
|
||||
-rm -f src/packet_writer.lo
|
||||
-rm -f src/pdu.$(OBJEXT)
|
||||
-rm -f src/pdu.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 +585,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)
|
||||
@@ -541,11 +607,12 @@ distclean-compile:
|
||||
@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)/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,12 +624,14 @@ 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)/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@
|
||||
@@ -603,8 +672,11 @@ 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"; \
|
||||
@@ -621,8 +693,11 @@ uninstall-pkgconfigDATA:
|
||||
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
|
||||
install-libtins_includeHEADERS: $(libtins_include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libtins_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libtins_includedir)"
|
||||
@list='$(libtins_include_HEADERS)'; test -n "$(libtins_includedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(libtins_includedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libtins_includedir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
@@ -788,7 +863,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)
|
||||
@@ -901,7 +976,7 @@ distclean: distclean-am
|
||||
-rm -rf src/$(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
|
||||
|
||||
@@ -972,20 +1047,20 @@ 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 \
|
||||
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
|
||||
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-libtins_includeHEADERS \
|
||||
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
|
||||
|
||||
|
||||
# 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.0
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
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
|
||||
;;
|
||||
|
||||
33
configure.ac
33
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.0], [matias.fontanini@gmail.com], [libtins], [http://libtins.sourceforge.net])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CONFIG_HEADER(include/config.h)
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror])
|
||||
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,19 @@ AC_CHECK_HEADERS([pcap.h], [], [AC_MSG_ERROR([libpcap headers are missing!])])
|
||||
|
||||
CPPFLAGS=$old_cppflags
|
||||
|
||||
# Options
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
c++11,
|
||||
[ --enable-c++11 enable C++11 features],
|
||||
[AX_CXX_COMPILE_STDCXX_11(noext)]
|
||||
)
|
||||
|
||||
# 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:0:0])
|
||||
AC_CONFIG_FILES([Makefile libtins.pc])
|
||||
AC_OUTPUT
|
||||
|
||||
124
depcomp
124
depcomp
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2011-12-04.11; # UTC
|
||||
scriptversion=2012-03-27.16; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
|
||||
# 2011 Free Software Foundation, Inc.
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -28,7 +28,7 @@ scriptversion=2011-12-04.11; # UTC
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
@@ -40,8 +40,8 @@ as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
source Source file read by 'PROGRAMS ARGS'.
|
||||
object Object file output by 'PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputting dependencies.
|
||||
@@ -57,6 +57,12 @@ EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
@@ -102,6 +108,12 @@ if test "$depmode" = msvc7msys; then
|
||||
depmode=msvc7
|
||||
fi
|
||||
|
||||
if test "$depmode" = xlc; then
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
@@ -156,15 +168,14 @@ gcc)
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## This next piece of magic avoids the "deleted header file" problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
tr ' ' "$nl" < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the ':'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||
## to the object. Take care to not repeat it in the output.
|
||||
@@ -203,18 +214,15 @@ sgi)
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
tr "$nl" ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
@@ -226,10 +234,17 @@ sgi)
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
xlc)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
@@ -259,12 +274,11 @@ aix)
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Each line is of the form 'foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
# '$object: dependent.h' and one to simply 'dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
@@ -275,23 +289,26 @@ aix)
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
|
||||
# However on
|
||||
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# which is wrong. We want
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# and will wrap long lines using '\':
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
# tcc 0.9.26 (FIXME still under development at the moment of writing)
|
||||
# will emit a similar output, but also prepend the continuation lines
|
||||
# with horizontal tabulation characters.
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
@@ -300,15 +317,21 @@ icc)
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Each line is of the form 'foo.o: dependent.h',
|
||||
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
# '$object: dependent.h' and one to simply 'dependent.h:'.
|
||||
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
|
||||
< "$tmpdepfile" > "$depfile"
|
||||
sed '
|
||||
s/[ '"$tab"'][ '"$tab"']*/ /g
|
||||
s/^ *//
|
||||
s/ *\\*$//
|
||||
s/^[^:]*: *//
|
||||
/^$/d
|
||||
/:$/d
|
||||
s/$/ :/
|
||||
' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -344,7 +367,7 @@ hp2)
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
@@ -359,9 +382,9 @@ hp2)
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# dependencies in 'foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
@@ -407,8 +430,7 @@ tru64)
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
@@ -443,11 +465,11 @@ msvc7)
|
||||
p
|
||||
}' | $cygpath_u | sort -u | sed -n '
|
||||
s/ /\\ /g
|
||||
s/\(.*\)/ \1 \\/p
|
||||
s/\(.*\)/'"$tab"'\1 \\/p
|
||||
s/.\(.*\) \\/\1:/
|
||||
H
|
||||
$ {
|
||||
s/.*/ /
|
||||
s/.*/'"$tab"'/
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
@@ -478,7 +500,7 @@ dashmstdout)
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
@@ -498,15 +520,14 @@ dashmstdout)
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# Require at least two characters before searching for ':'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
tr ' ' "$nl" < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
@@ -562,8 +583,7 @@ makedepend)
|
||||
# makedepend may prepend the VPATH from the source file name to the object.
|
||||
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
@@ -583,7 +603,7 @@ cpp)
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
# Remove '-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
@@ -652,8 +672,8 @@ msvisualcpp)
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||
echo "$tab" >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -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";
|
||||
@@ -76,12 +72,12 @@ int do_arp_spoofing(NetworkInterface iface, IPv4Address gw, IPv4Address 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(gw_hw, info.hw_addr, gw_arp);
|
||||
EthernetII to_victim(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;
|
||||
|
||||
@@ -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>
|
||||
@@ -96,8 +97,8 @@ void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<
|
||||
// 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(info.hw_addr, info.hw_addr, ip.clone());
|
||||
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
|
||||
@@ -82,8 +82,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.
|
||||
*/
|
||||
@@ -230,34 +236,32 @@ namespace Tins {
|
||||
PDUType pdu_type() const { return PDU::ARP; }
|
||||
|
||||
/**
|
||||
* \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.
|
||||
* sent.
|
||||
*
|
||||
* \param iface string with the interface from where to send the ARP.
|
||||
* \param target IPv4Address with the target's IP.
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns a EthernetII containing the ARP Request.
|
||||
*/
|
||||
static EthernetII make_arp_request(const NetworkInterface& iface, ipaddress_type target,
|
||||
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.
|
||||
* sent.
|
||||
*
|
||||
* \param iface string with the interface from where to send the ARP.
|
||||
* \param target IPv4Address with the target's IP.
|
||||
* \param sender IPv4Address with the sender's IP.
|
||||
* \param hw_tgt uint8_t array of 6 bytes containing the target's hardware address.
|
||||
* \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address.
|
||||
* \return Returns an EthetnetII containing the ARP Replay.
|
||||
*/
|
||||
static EthernetII make_arp_reply(const NetworkInterface& iface, ipaddress_type target,
|
||||
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());
|
||||
|
||||
@@ -267,17 +271,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);
|
||||
|
||||
/** \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.
|
||||
@@ -293,6 +296,17 @@ 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
|
||||
|
||||
71
include/config.h.in
Normal file
71
include/config.h.in
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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 `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 <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
|
||||
|
||||
/* 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 */
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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,7 @@
|
||||
#include <string>
|
||||
#include "bootp.h"
|
||||
#include "pdu_option.h"
|
||||
#include "cxxstd.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
@@ -66,7 +67,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief DHCP options enum.
|
||||
*/
|
||||
enum Options {
|
||||
enum OptionTypes {
|
||||
PAD,
|
||||
SUBNET_MASK,
|
||||
TIME_OFFSET,
|
||||
@@ -142,12 +143,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,8 +159,12 @@ 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 contain 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.
|
||||
@@ -168,16 +173,30 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \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.
|
||||
@@ -401,17 +420,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);
|
||||
|
||||
|
||||
112
include/dhcpv6.h
112
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.
|
||||
*/
|
||||
@@ -851,9 +782,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 +795,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 +806,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 +829,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.
|
||||
@@ -566,6 +570,15 @@ namespace Tins {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
550
include/dot11.h
550
include/dot11.h
File diff suppressed because it is too large
Load Diff
209
include/dot1q.h
Normal file
209
include/dot1q.h
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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 {
|
||||
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 cfi field.
|
||||
* \return The stored cfi field value.
|
||||
*/
|
||||
small_uint<1> cfi() const {
|
||||
return _header.cfi;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the id field.
|
||||
* \return The stored 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 cfi field.
|
||||
* \param new_cfi The new cfi field value.
|
||||
*/
|
||||
void cfi(small_uint<1> new_cfi);
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
* \param new_id The new 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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
*
|
||||
@@ -157,24 +141,25 @@ namespace Tins {
|
||||
/**
|
||||
* \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 +168,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 +188,6 @@ namespace Tins {
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
ethhdr _eth;
|
||||
NetworkInterface _iface;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
129
include/exceptions.h
Normal file
129
include/exceptions.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TINS_EXCEPTIONS_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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -274,7 +279,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 +287,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
|
||||
|
||||
@@ -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
|
||||
@@ -57,6 +57,8 @@ namespace Internals {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
75
include/ip.h
75
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.
|
||||
@@ -380,13 +382,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 +409,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 +436,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 +563,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 +572,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 +580,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 +588,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 +618,18 @@ namespace Tins {
|
||||
/*The options start here. */
|
||||
} TINS_END_PACK;
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -90,22 +90,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.
|
||||
*/
|
||||
@@ -376,7 +379,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.
|
||||
@@ -91,18 +86,6 @@ public:
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* \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,
|
||||
@@ -75,7 +78,40 @@ namespace Tins {
|
||||
*
|
||||
* \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 +124,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 +133,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 +146,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();
|
||||
|
||||
/**
|
||||
* \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 +216,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 +253,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 +283,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 +296,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 +322,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 smartpointers.
|
||||
*/
|
||||
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
|
||||
|
||||
159
include/pdu.h
159
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,42 @@ namespace Tins {
|
||||
IPv6,
|
||||
ICMPv6,
|
||||
SLL,
|
||||
DHCPv6
|
||||
DHCPv6,
|
||||
DOT1Q,
|
||||
PPPOE,
|
||||
STP
|
||||
};
|
||||
|
||||
/** \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 +196,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 +225,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 +244,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 +290,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 +329,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 +351,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 +368,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 +392,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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
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;
|
||||
@@ -108,16 +107,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 +129,7 @@ namespace Tins {
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender &sender);
|
||||
void send(PacketSender &sender, const NetworkInterface &iface);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -292,6 +292,14 @@ namespace Tins {
|
||||
return (PresentFlags)*(uint32_t*)(&_radio.it_len + 1);
|
||||
}
|
||||
|
||||
/** \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.
|
||||
*
|
||||
@@ -357,13 +365,13 @@ namespace Tins {
|
||||
flags:1,
|
||||
tsft:1,
|
||||
reserved3:1,
|
||||
tx_attenuation:1,
|
||||
rx_flags:1,
|
||||
db_tx_attenuation:1,
|
||||
dbm_tx_attenuation:1,
|
||||
antenna:1,
|
||||
db_signal:1,
|
||||
db_noise:1,
|
||||
rx_flags:1,
|
||||
tx_attenuation:1,
|
||||
reserved2:5,
|
||||
channel_plus:1,
|
||||
reserved1:2,
|
||||
@@ -377,7 +385,6 @@ namespace Tins {
|
||||
|
||||
|
||||
radiotap_hdr _radio;
|
||||
NetworkInterface _iface;
|
||||
// present fields...
|
||||
uint64_t _tsft;
|
||||
uint32_t _channel_type;
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
@@ -42,8 +42,10 @@
|
||||
#include "packet.h"
|
||||
#include "loopback.h"
|
||||
#include "dot11.h"
|
||||
#include "dot3.h"
|
||||
#include "sll.h"
|
||||
#include "cxxstd.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
@@ -63,13 +65,25 @@ namespace Tins {
|
||||
* \brief Move constructor.
|
||||
* This constructor is available only in C++11.
|
||||
*/
|
||||
BaseSniffer(BaseSniffer &&rhs) noexcept;
|
||||
BaseSniffer(BaseSniffer &&rhs) noexcept
|
||||
{
|
||||
*this = std::move(rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Move assignment operator.
|
||||
* This opeartor is available only in C++11.
|
||||
*/
|
||||
BaseSniffer& operator=(BaseSniffer &&rhs) noexcept;
|
||||
BaseSniffer& operator=(BaseSniffer &&rhs) noexcept
|
||||
{
|
||||
handle = 0;
|
||||
mask = rhs.mask;
|
||||
iface_type = rhs.iface_type;
|
||||
actual_filter.bf_insns = 0;
|
||||
std::swap(handle, rhs.handle);
|
||||
std::swap(actual_filter, rhs.actual_filter);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -192,9 +206,25 @@ namespace Tins {
|
||||
: handle(_handle), c_handler(_handler), iface_type(if_type)
|
||||
{ }
|
||||
};
|
||||
|
||||
struct PCapLoopBreaker {
|
||||
bool &went_well;
|
||||
pcap_t *handle;
|
||||
|
||||
PCapLoopBreaker(bool &went_well, pcap_t *handle)
|
||||
: went_well(went_well), handle(handle) { }
|
||||
|
||||
~PCapLoopBreaker() {
|
||||
if(!went_well)
|
||||
pcap_breakloop(handle);
|
||||
}
|
||||
};
|
||||
|
||||
BaseSniffer(const BaseSniffer&);
|
||||
BaseSniffer &operator=(const BaseSniffer&);
|
||||
static bool is_dot3(const uint8_t *ptr, size_t sz) {
|
||||
return (sz >= 13 && ptr[12] < 8);
|
||||
}
|
||||
|
||||
template<class ConcretePDU, class Functor>
|
||||
static bool call_functor(LoopData<Functor> *data, const u_char *packet, const struct pcap_pkthdr *header);
|
||||
@@ -268,16 +298,22 @@ namespace Tins {
|
||||
|
||||
template<class Functor>
|
||||
void Tins::BaseSniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
|
||||
bool ret_val(true);
|
||||
LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args);
|
||||
PCapLoopBreaker _(ret_val, data->handle);
|
||||
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);
|
||||
Internals::smart_ptr<PDU>::type pdu;
|
||||
if(data->iface_type == DLT_EN10MB) {
|
||||
ret_val = is_dot3((const uint8_t*)packet, header->caplen) ?
|
||||
call_functor<Tins::Dot3>(data, packet, header) :
|
||||
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));
|
||||
Internals::smart_ptr<PDU>::type 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);
|
||||
@@ -287,12 +323,12 @@ namespace Tins {
|
||||
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&) {
|
||||
|
||||
catch(malformed_packet&) {
|
||||
ret_val = true;
|
||||
}
|
||||
catch(pdu_not_found&) {
|
||||
ret_val = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 proto_id field.
|
||||
* \return The stored proto_id field value.
|
||||
*/
|
||||
uint16_t proto_id() const {
|
||||
return Endian::be_to_host(_header.proto_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the proto_version field.
|
||||
* \return The stored proto_version field value.
|
||||
*/
|
||||
uint8_t proto_version() const {
|
||||
return _header.proto_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the bpdu_type field.
|
||||
* \return The stored bpdu_type field value.
|
||||
*/
|
||||
uint8_t bpdu_type() const {
|
||||
return _header.bpdu_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the bpdu_flags field.
|
||||
* \return The stored bpdu_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 msg_age field.
|
||||
* \return The stored msg_age field value.
|
||||
*/
|
||||
uint16_t msg_age() const {
|
||||
return Endian::be_to_host(_header.msg_age) / 256;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the max_age field.
|
||||
* \return The stored max_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 fwd_delay field.
|
||||
* \return The stored fwd_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 proto_id field.
|
||||
* \param new_proto_id The new proto_id field value.
|
||||
*/
|
||||
void proto_id(uint16_t new_proto_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the proto_version field.
|
||||
* \param new_proto_version The new proto_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 msg_age field.
|
||||
* \param new_msg_age The new msg_age field value.
|
||||
*/
|
||||
void msg_age(uint16_t new_msg_age);
|
||||
|
||||
/**
|
||||
* \brief Setter for the max_age field.
|
||||
* \param new_max_age The new max_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 fwd_delay field.
|
||||
* \param new_fwd_delay The new fwd_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
|
||||
@@ -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 {
|
||||
/**
|
||||
@@ -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.
|
||||
@@ -238,13 +246,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 +352,27 @@ 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 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 +383,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 +405,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 +453,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
|
||||
|
||||
@@ -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,7 @@
|
||||
#include "timestamp.h"
|
||||
#include "sll.h"
|
||||
#include "dhcpv6.h"
|
||||
#include "pppoe.h"
|
||||
#include "stp.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
|
||||
@@ -53,15 +53,20 @@ namespace Tins {
|
||||
*
|
||||
* Creates an instance of UDP. Destination and source port can
|
||||
* be provided, otherwise both 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])])
|
||||
52
src/arp.cpp
52
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,7 +60,7 @@ 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);
|
||||
if(total_sz)
|
||||
@@ -107,54 +108,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
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(DHCP_MESSAGE_TYPE));
|
||||
}
|
||||
|
||||
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())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
23
src/dns.cpp
23
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;
|
||||
@@ -290,7 +294,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 +392,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()) {
|
||||
@@ -476,4 +482,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;
|
||||
}
|
||||
|
||||
363
src/dot11.cpp
363
src/dot11.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
|
||||
@@ -33,9 +33,10 @@
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include "macros.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#if defined(BSD) || defined(__APPLE__)
|
||||
#if defined(__FreeBSD_kernel__) || defined(BSD) || defined(__APPLE__)
|
||||
#include <sys/types.h>
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
@@ -59,8 +60,8 @@ using std::runtime_error;
|
||||
namespace Tins {
|
||||
const Dot11::address_type Dot11::BROADCAST = "ff:ff:ff:ff:ff:ff";
|
||||
|
||||
Dot11::Dot11(const address_type &dst_hw_addr, PDU* child)
|
||||
: PDU(child), _options_size(0)
|
||||
Dot11::Dot11(const address_type &dst_hw_addr)
|
||||
: _options_size(0)
|
||||
{
|
||||
memset(&_header, 0, sizeof(ieee80211_header));
|
||||
addr1(dst_hw_addr);
|
||||
@@ -75,7 +76,7 @@ Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _options_size(0)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw runtime_error("Not enough size for an Dot11 header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
}
|
||||
|
||||
@@ -88,28 +89,32 @@ void Dot11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz) {
|
||||
buffer += 2;
|
||||
total_sz -= 2;
|
||||
if(length > total_sz) {
|
||||
throw std::runtime_error("Malformed option encountered");
|
||||
throw malformed_packet();
|
||||
}
|
||||
add_tagged_option((TaggedOption)opcode, length, buffer);
|
||||
add_tagged_option((OptionTypes)opcode, length, buffer);
|
||||
buffer += length;
|
||||
total_sz -= length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dot11::add_tagged_option(TaggedOption opt, uint8_t len, const uint8_t *val) {
|
||||
void Dot11::add_tagged_option(OptionTypes opt, uint8_t len, const uint8_t *val) {
|
||||
uint32_t opt_size = len + sizeof(uint8_t) * 2;
|
||||
_options.push_back(dot11_option((uint8_t)opt, len, val));
|
||||
_options.push_back(option((uint8_t)opt, len, val));
|
||||
_options_size += opt_size;
|
||||
}
|
||||
|
||||
void Dot11::add_tagged_option(const dot11_option &opt) {
|
||||
_options.push_back(opt);
|
||||
void Dot11::internal_add_option(const option &opt) {
|
||||
_options_size += opt.data_size() + sizeof(uint8_t) * 2;
|
||||
}
|
||||
|
||||
const Dot11::dot11_option *Dot11::search_option(TaggedOption opt) const {
|
||||
for(std::list<dot11_option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
|
||||
void Dot11::add_option(const option &opt) {
|
||||
internal_add_option(opt);
|
||||
_options.push_back(opt);
|
||||
}
|
||||
|
||||
const Dot11::option *Dot11::search_option(OptionTypes opt) const {
|
||||
for(std::list<option>::const_iterator it = _options.begin(); it != _options.end(); ++it)
|
||||
if(it->option() == (uint8_t)opt)
|
||||
return &(*it);
|
||||
return 0;
|
||||
@@ -163,21 +168,17 @@ void Dot11::addr1(const address_type &new_addr1) {
|
||||
std::copy(new_addr1.begin(), new_addr1.end(), _header.addr1);
|
||||
}
|
||||
|
||||
void Dot11::iface(const NetworkInterface &new_iface) {
|
||||
this->_iface = new_iface;
|
||||
}
|
||||
|
||||
uint32_t Dot11::header_size() const {
|
||||
uint32_t sz = sizeof(ieee80211_header) + _options_size;
|
||||
return sz;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void Dot11::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
void Dot11::send(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
throw invalid_interface();
|
||||
|
||||
#ifndef BSD
|
||||
#if !defined(BSD) && !defined(__FreeBSD_kernel__)
|
||||
sockaddr_ll addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
@@ -185,18 +186,19 @@ void Dot11::send(PacketSender &sender) {
|
||||
addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
|
||||
addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
|
||||
addr.sll_halen = 6;
|
||||
addr.sll_ifindex = _iface.id();
|
||||
addr.sll_ifindex = iface.id();
|
||||
memcpy(&(addr.sll_addr), _header.addr1, 6);
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
#else
|
||||
sender.send_l2(*this, 0, 0, _iface);
|
||||
sender.send_l2(*this, 0, 0, iface);
|
||||
#endif
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
assert(total_sz >= my_sz);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
memcpy(buffer, &_header, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -207,10 +209,12 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p
|
||||
|
||||
uint32_t child_len = write_fixed_parameters(buffer, total_sz - _options_size);
|
||||
buffer += child_len;
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= child_len + _options_size);
|
||||
for(std::list<dot11_option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
#endif
|
||||
for(std::list<option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
*(buffer++) = it->option();
|
||||
*(buffer++) = it->data_size();
|
||||
*(buffer++) = it->length_field();
|
||||
std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), buffer);
|
||||
buffer += it->data_size();
|
||||
}
|
||||
@@ -221,7 +225,7 @@ Dot11 *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
|
||||
// This should be sizeof(ieee80211_header::control), but gcc 4.2 complains
|
||||
if(total_sz < 2)
|
||||
throw runtime_error("Not enough size for a IEEE 802.11 header in the buffer.");
|
||||
throw malformed_packet();
|
||||
const ieee80211_header *hdr = (const ieee80211_header*)buffer;
|
||||
Dot11 *ret = 0;
|
||||
if(hdr->control.type == MANAGEMENT) {
|
||||
@@ -280,14 +284,14 @@ Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *buffer, uint32_t total
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
if(total_sz < sizeof(_ext_header))
|
||||
throw runtime_error("Not enough size for an Dot11ManagementFrame header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_ext_header, buffer, sizeof(_ext_header));
|
||||
total_sz -= sizeof(_ext_header);
|
||||
if(from_ds() && to_ds()) {
|
||||
if(total_sz >= _addr4.size())
|
||||
_addr4 = buffer + sizeof(_ext_header);
|
||||
else
|
||||
throw runtime_error("Not enough size for an Dot11ManagementFrame header in the buffer.");
|
||||
throw malformed_packet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,9 +370,9 @@ uint8_t *Dot11ManagementFrame::serialize_rates(const rates_type &rates) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::rates_type Dot11ManagementFrame::deserialize_rates(const dot11_option *option) {
|
||||
Dot11ManagementFrame::rates_type Dot11ManagementFrame::deserialize_rates(const option *opt) {
|
||||
rates_type output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
const uint8_t *ptr = opt->data_ptr(), *end = ptr + opt->data_size();
|
||||
while(ptr != end) {
|
||||
output.push_back(float(*(ptr++) & 0x7f) / 2);
|
||||
}
|
||||
@@ -598,52 +602,52 @@ void Dot11ManagementFrame::challenge_text(const std::string &text) {
|
||||
// Getters
|
||||
|
||||
RSNInformation Dot11ManagementFrame::rsn_information() {
|
||||
const Dot11::dot11_option *option = search_option(RSN);
|
||||
const Dot11::option *option = search_option(RSN);
|
||||
if(!option || option->data_size() < (sizeof(uint16_t) << 1) + sizeof(uint32_t))
|
||||
throw std::runtime_error("RSN information not set");
|
||||
throw option_not_found();
|
||||
return RSNInformation(option->data_ptr(), option->data_size());
|
||||
}
|
||||
|
||||
string Dot11ManagementFrame::ssid() const {
|
||||
const Dot11::dot11_option *option = search_option(SSID);
|
||||
const Dot11::option *option = search_option(SSID);
|
||||
if(!option || option->data_size() == 0)
|
||||
throw std::runtime_error("SSID not set");
|
||||
throw option_not_found();
|
||||
return string((const char*)option->data_ptr(), option->data_size());
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::rates_type Dot11ManagementFrame::supported_rates() const {
|
||||
const Dot11::dot11_option *option = search_option(SUPPORTED_RATES);
|
||||
const Dot11::option *option = search_option(SUPPORTED_RATES);
|
||||
if(!option || option->data_size() == 0)
|
||||
throw std::runtime_error("Supported rates not set");
|
||||
throw option_not_found();
|
||||
return deserialize_rates(option);
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::rates_type Dot11ManagementFrame::extended_supported_rates() const {
|
||||
const Dot11::dot11_option *option = search_option(EXT_SUPPORTED_RATES);
|
||||
const Dot11::option *option = search_option(EXT_SUPPORTED_RATES);
|
||||
if(!option || option->data_size() == 0)
|
||||
throw std::runtime_error("Extended supported rates not set");
|
||||
throw option_not_found();
|
||||
return deserialize_rates(option);
|
||||
}
|
||||
|
||||
uint8_t Dot11ManagementFrame::qos_capability() const {
|
||||
const Dot11::dot11_option *option = search_option(QOS_CAPABILITY);
|
||||
const Dot11::option *option = search_option(QOS_CAPABILITY);
|
||||
if(!option || option->data_size() != 1)
|
||||
throw std::runtime_error("QOS capability not set");
|
||||
throw option_not_found();
|
||||
return *option->data_ptr();
|
||||
}
|
||||
|
||||
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::power_capability() const {
|
||||
const Dot11::dot11_option *option = search_option(POWER_CAPABILITY);
|
||||
const Dot11::option *option = search_option(POWER_CAPABILITY);
|
||||
if(!option || option->data_size() != 2)
|
||||
throw std::runtime_error("Power capability not set");
|
||||
throw option_not_found();
|
||||
return std::make_pair(*option->data_ptr(), *(option->data_ptr() + 1));
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() const {
|
||||
const Dot11::dot11_option *option = search_option(SUPPORTED_CHANNELS);
|
||||
const Dot11::option *option = search_option(SUPPORTED_CHANNELS);
|
||||
// We need a multiple of two
|
||||
if(!option || ((option->data_size() & 0x1) == 1))
|
||||
throw std::runtime_error("Supported channels not set");
|
||||
throw option_not_found();
|
||||
channels_type output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
while(ptr != end) {
|
||||
@@ -654,9 +658,9 @@ Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() c
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_information() const {
|
||||
const Dot11::dot11_option *option = search_option(REQUEST_INFORMATION);
|
||||
const Dot11::option *option = search_option(REQUEST_INFORMATION);
|
||||
if(!option || option->data_size() == 0)
|
||||
throw std::runtime_error("Request information not set");
|
||||
throw option_not_found();
|
||||
request_info_type output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
output.assign(ptr, end);
|
||||
@@ -664,9 +668,9 @@ Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_informatio
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() const {
|
||||
const Dot11::dot11_option *option = search_option(FH_SET);
|
||||
const Dot11::option *option = search_option(FH_SET);
|
||||
if(!option || option->data_size() != sizeof(fh_params_set))
|
||||
throw std::runtime_error("FH parameters set not set");
|
||||
throw option_not_found();
|
||||
fh_params_set output = *reinterpret_cast<const fh_params_set*>(option->data_ptr());
|
||||
output.dwell_time = Endian::le_to_host(output.dwell_time);
|
||||
output.hop_set = output.hop_set;
|
||||
@@ -676,23 +680,23 @@ Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() con
|
||||
}
|
||||
|
||||
uint8_t Dot11ManagementFrame::ds_parameter_set() const {
|
||||
const Dot11::dot11_option *option = search_option(DS_SET);
|
||||
const Dot11::option *option = search_option(DS_SET);
|
||||
if(!option || option->data_size() != sizeof(uint8_t))
|
||||
throw std::runtime_error("DS parameters set not set");
|
||||
throw option_not_found();
|
||||
return *option->data_ptr();
|
||||
}
|
||||
|
||||
uint16_t Dot11ManagementFrame::ibss_parameter_set() const {
|
||||
const Dot11::dot11_option *option = search_option(IBSS_SET);
|
||||
const Dot11::option *option = search_option(IBSS_SET);
|
||||
if(!option || option->data_size() != sizeof(uint16_t))
|
||||
throw std::runtime_error("IBSS parameters set not set");
|
||||
throw option_not_found();
|
||||
return Endian::le_to_host(*reinterpret_cast<const uint16_t*>(option->data_ptr()));
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::ibss_dfs_params Dot11ManagementFrame::ibss_dfs() const {
|
||||
const Dot11::dot11_option *option = search_option(IBSS_DFS);
|
||||
const Dot11::option *option = search_option(IBSS_DFS);
|
||||
if(!option || option->data_size() < ibss_dfs_params::minimum_size)
|
||||
throw std::runtime_error("IBSS DFS set not set");
|
||||
throw option_not_found();
|
||||
ibss_dfs_params output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
output.dfs_owner = ptr;
|
||||
@@ -701,16 +705,16 @@ Dot11ManagementFrame::ibss_dfs_params Dot11ManagementFrame::ibss_dfs() const {
|
||||
while(ptr != end) {
|
||||
uint8_t first = *(ptr++);
|
||||
if(ptr == end)
|
||||
throw std::runtime_error("Malformed channel data");
|
||||
throw option_not_found();
|
||||
output.channel_map.push_back(std::make_pair(first, *(ptr++)));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::country_params Dot11ManagementFrame::country() const {
|
||||
const Dot11::dot11_option *option = search_option(COUNTRY);
|
||||
const Dot11::option *option = search_option(COUNTRY);
|
||||
if(!option || option->data_size() < country_params::minimum_size)
|
||||
throw std::runtime_error("Country option not set");
|
||||
throw option_not_found();
|
||||
country_params output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
std::copy(ptr, ptr + 3, std::back_inserter(output.country));
|
||||
@@ -721,23 +725,23 @@ Dot11ManagementFrame::country_params Dot11ManagementFrame::country() const {
|
||||
output.max_transmit_power.push_back(*(ptr++));
|
||||
}
|
||||
if(ptr != end)
|
||||
throw std::runtime_error("Malformed option");
|
||||
throw option_not_found();
|
||||
return output;
|
||||
}
|
||||
|
||||
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::fh_parameters() const {
|
||||
const Dot11::dot11_option *option = search_option(HOPPING_PATTERN_PARAMS);
|
||||
const Dot11::option *option = search_option(HOPPING_PATTERN_PARAMS);
|
||||
if(!option || option->data_size() != sizeof(uint8_t) * 2)
|
||||
throw std::runtime_error("FH parameters option not set");
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = option->data_ptr();
|
||||
uint8_t first = *(ptr++);
|
||||
return std::make_pair(first, *ptr);
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::fh_pattern_type Dot11ManagementFrame::fh_pattern_table() const {
|
||||
const Dot11::dot11_option *option = search_option(HOPPING_PATTERN_TABLE);
|
||||
const Dot11::option *option = search_option(HOPPING_PATTERN_TABLE);
|
||||
if(!option || option->data_size() < fh_pattern_type::minimum_size)
|
||||
throw std::runtime_error("FH pattern option not set");
|
||||
throw option_not_found();
|
||||
fh_pattern_type output;
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
|
||||
@@ -751,16 +755,16 @@ Dot11ManagementFrame::fh_pattern_type Dot11ManagementFrame::fh_pattern_table() c
|
||||
}
|
||||
|
||||
uint8_t Dot11ManagementFrame::power_constraint() const {
|
||||
const Dot11::dot11_option *option = search_option(POWER_CONSTRAINT);
|
||||
const Dot11::option *option = search_option(POWER_CONSTRAINT);
|
||||
if(!option || option->data_size() != 1)
|
||||
throw std::runtime_error("Power constraint option not set");
|
||||
throw option_not_found();
|
||||
return *option->data_ptr();
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::channel_switch_type Dot11ManagementFrame::channel_switch() const {
|
||||
const Dot11::dot11_option *option = search_option(CHANNEL_SWITCH);
|
||||
const Dot11::option *option = search_option(CHANNEL_SWITCH);
|
||||
if(!option || option->data_size() != sizeof(uint8_t) * 3)
|
||||
throw std::runtime_error("Channel switch option not set");
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = option->data_ptr();
|
||||
channel_switch_type output;
|
||||
output.switch_mode = *(ptr++);
|
||||
@@ -770,9 +774,9 @@ Dot11ManagementFrame::channel_switch_type Dot11ManagementFrame::channel_switch()
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::quiet_type Dot11ManagementFrame::quiet() const {
|
||||
const Dot11::dot11_option *option = search_option(QUIET);
|
||||
const Dot11::option *option = search_option(QUIET);
|
||||
if(!option || option->data_size() != (sizeof(uint8_t) * 2 + sizeof(uint16_t) * 2))
|
||||
throw std::runtime_error("Quiet option not set");
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = option->data_ptr();
|
||||
quiet_type output;
|
||||
|
||||
@@ -785,25 +789,25 @@ Dot11ManagementFrame::quiet_type Dot11ManagementFrame::quiet() const {
|
||||
}
|
||||
|
||||
std::pair<uint8_t, uint8_t> Dot11ManagementFrame::tpc_report() const {
|
||||
const Dot11::dot11_option *option = search_option(TPC_REPORT);
|
||||
const Dot11::option *option = search_option(TPC_REPORT);
|
||||
if(!option || option->data_size() != sizeof(uint8_t) * 2)
|
||||
throw std::runtime_error("TPC Report option not set");
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = option->data_ptr();
|
||||
uint8_t first = *(ptr++);
|
||||
return std::make_pair(first, *ptr);
|
||||
}
|
||||
|
||||
uint8_t Dot11ManagementFrame::erp_information() const {
|
||||
const Dot11::dot11_option *option = search_option(ERP_INFORMATION);
|
||||
const Dot11::option *option = search_option(ERP_INFORMATION);
|
||||
if(!option || option->data_size() != sizeof(uint8_t))
|
||||
throw std::runtime_error("ERP Information option not set");
|
||||
throw option_not_found();
|
||||
return *option->data_ptr();
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::bss_load_type Dot11ManagementFrame::bss_load() const {
|
||||
const Dot11::dot11_option *option = search_option(BSS_LOAD);
|
||||
const Dot11::option *option = search_option(BSS_LOAD);
|
||||
if(!option || option->data_size() != sizeof(uint8_t) + 2 * sizeof(uint16_t))
|
||||
throw std::runtime_error("BSS Load option not set");
|
||||
throw option_not_found();
|
||||
bss_load_type output;
|
||||
|
||||
const uint8_t *ptr = option->data_ptr();
|
||||
@@ -814,9 +818,9 @@ Dot11ManagementFrame::bss_load_type Dot11ManagementFrame::bss_load() const {
|
||||
}
|
||||
|
||||
Dot11ManagementFrame::tim_type Dot11ManagementFrame::tim() const {
|
||||
const Dot11::dot11_option *option = search_option(TIM);
|
||||
const Dot11::option *option = search_option(TIM);
|
||||
if(!option || option->data_size() < 4 * sizeof(uint8_t))
|
||||
throw std::runtime_error("TIM option not set");
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size();
|
||||
tim_type output;
|
||||
|
||||
@@ -829,9 +833,9 @@ Dot11ManagementFrame::tim_type Dot11ManagementFrame::tim() const {
|
||||
}
|
||||
|
||||
std::string Dot11ManagementFrame::challenge_text() const {
|
||||
const Dot11::dot11_option *option = search_option(CHALLENGE_TEXT);
|
||||
const Dot11::option *option = search_option(CHALLENGE_TEXT);
|
||||
if(!option || option->data_size() == 0)
|
||||
throw std::runtime_error("Challenge text option not set");
|
||||
throw option_not_found();
|
||||
return std::string(option->data_ptr(), option->data_ptr() + option->data_size());
|
||||
}
|
||||
|
||||
@@ -852,7 +856,7 @@ Dot11Beacon::Dot11Beacon(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for a IEEE 802.11 beacon header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -873,7 +877,9 @@ uint32_t Dot11Beacon::header_size() const {
|
||||
|
||||
uint32_t Dot11Beacon::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -894,7 +900,7 @@ Dot11Disassoc::Dot11Disassoc(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for a IEEE 802.11 disassociation header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -911,7 +917,9 @@ uint32_t Dot11Disassoc::header_size() const {
|
||||
|
||||
uint32_t Dot11Disassoc::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(DisassocBody);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -926,12 +934,14 @@ const address_type &src_hw_addr)
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
}
|
||||
|
||||
Dot11AssocRequest::Dot11AssocRequest(const uint8_t *buffer, uint32_t total_sz) : Dot11ManagementFrame(buffer, total_sz) {
|
||||
Dot11AssocRequest::Dot11AssocRequest(const uint8_t *buffer, uint32_t total_sz)
|
||||
: Dot11ManagementFrame(buffer, total_sz)
|
||||
{
|
||||
uint32_t sz = management_frame_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 association request header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -948,7 +958,9 @@ uint32_t Dot11AssocRequest::header_size() const {
|
||||
|
||||
uint32_t Dot11AssocRequest::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(AssocReqBody);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -970,7 +982,7 @@ Dot11AssocResponse::Dot11AssocResponse(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 association response header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -991,7 +1003,9 @@ uint32_t Dot11AssocResponse::header_size() const {
|
||||
|
||||
uint32_t Dot11AssocResponse::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(AssocRespBody);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1013,7 +1027,7 @@ Dot11ReAssocRequest::Dot11ReAssocRequest(const uint8_t *buffer, uint32_t total_s
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 reassociation request header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -1034,7 +1048,9 @@ uint32_t Dot11ReAssocRequest::header_size() const {
|
||||
|
||||
uint32_t Dot11ReAssocRequest::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1055,7 +1071,7 @@ Dot11ReAssocResponse::Dot11ReAssocResponse(const uint8_t *buffer, uint32_t total
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 reassociation response header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -1076,7 +1092,9 @@ uint32_t Dot11ReAssocResponse::header_size() const {
|
||||
|
||||
uint32_t Dot11ReAssocResponse::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1099,7 +1117,7 @@ Dot11Authentication::Dot11Authentication(const uint8_t *buffer, uint32_t total_s
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 authentication header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -1124,7 +1142,9 @@ uint32_t Dot11Authentication::header_size() const {
|
||||
|
||||
uint32_t Dot11Authentication::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1145,7 +1165,7 @@ Dot11Deauthentication::Dot11Deauthentication(const uint8_t *buffer, uint32_t tot
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for a IEEE 802.11 deauthentication header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -1162,7 +1182,9 @@ uint32_t Dot11Deauthentication::header_size() const {
|
||||
|
||||
uint32_t Dot11Deauthentication::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1202,7 +1224,7 @@ Dot11ProbeResponse::Dot11ProbeResponse(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 probe response header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
@@ -1223,7 +1245,9 @@ uint32_t Dot11ProbeResponse::header_size() const {
|
||||
|
||||
uint32_t Dot11ProbeResponse::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
@@ -1231,22 +1255,11 @@ uint32_t Dot11ProbeResponse::write_fixed_parameters(uint8_t *buffer, uint32_t to
|
||||
/* Dot11Data */
|
||||
|
||||
Dot11Data::Dot11Data(const uint8_t *buffer, uint32_t total_sz)
|
||||
: Dot11(buffer, total_sz) {
|
||||
uint32_t sz = Dot11::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_ext_header))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 data header in the buffer.");
|
||||
std::memcpy(&_ext_header, buffer, sizeof(_ext_header));
|
||||
buffer += sizeof(_ext_header);
|
||||
total_sz -= sizeof(_ext_header);
|
||||
if(from_ds() && to_ds()) {
|
||||
if(total_sz < _addr4.size())
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 data header in the buffer.");
|
||||
_addr4 = buffer;
|
||||
buffer += _addr4.size();
|
||||
total_sz -= _addr4.size();
|
||||
}
|
||||
: Dot11(buffer, total_sz)
|
||||
{
|
||||
const uint32_t offset = init(buffer, total_sz);
|
||||
buffer += offset;
|
||||
total_sz -= offset;
|
||||
if(total_sz) {
|
||||
// If the wep bit is on, then just use a RawPDU
|
||||
if(wep())
|
||||
@@ -1256,10 +1269,35 @@ Dot11Data::Dot11Data(const uint8_t *buffer, uint32_t total_sz)
|
||||
}
|
||||
}
|
||||
|
||||
Dot11Data::Dot11Data(const uint8_t *buffer, uint32_t total_sz, no_inner_pdu)
|
||||
: Dot11(buffer, total_sz)
|
||||
{
|
||||
init(buffer, total_sz);
|
||||
}
|
||||
|
||||
uint32_t Dot11Data::init(const uint8_t *buffer, uint32_t total_sz) {
|
||||
const uint8_t *start_ptr = buffer;
|
||||
uint32_t sz = Dot11::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_ext_header))
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_ext_header, buffer, sizeof(_ext_header));
|
||||
buffer += sizeof(_ext_header);
|
||||
total_sz -= sizeof(_ext_header);
|
||||
if(from_ds() && to_ds()) {
|
||||
if(total_sz < _addr4.size())
|
||||
throw malformed_packet();
|
||||
_addr4 = buffer;
|
||||
buffer += _addr4.size();
|
||||
total_sz -= _addr4.size();
|
||||
}
|
||||
return buffer - start_ptr;
|
||||
}
|
||||
|
||||
Dot11Data::Dot11Data(const address_type &dst_hw_addr,
|
||||
const address_type &src_hw_addr, PDU* child)
|
||||
: Dot11(dst_hw_addr, child)
|
||||
const address_type &src_hw_addr)
|
||||
: Dot11(dst_hw_addr)
|
||||
{
|
||||
type(Dot11::DATA);
|
||||
memset(&_ext_header, 0, sizeof(_ext_header));
|
||||
@@ -1316,8 +1354,8 @@ uint32_t Dot11Data::write_ext_header(uint8_t *buffer, uint32_t total_sz) {
|
||||
/* QoS data. */
|
||||
|
||||
Dot11QoSData::Dot11QoSData(const address_type &dst_hw_addr,
|
||||
const address_type &src_hw_addr, PDU* child)
|
||||
: Dot11Data(dst_hw_addr, src_hw_addr, child)
|
||||
const address_type &src_hw_addr)
|
||||
: Dot11Data(dst_hw_addr, src_hw_addr)
|
||||
{
|
||||
subtype(Dot11::QOS_DATA_DATA);
|
||||
_qos_control = 0;
|
||||
@@ -1325,13 +1363,12 @@ Dot11QoSData::Dot11QoSData(const address_type &dst_hw_addr,
|
||||
|
||||
Dot11QoSData::Dot11QoSData(const uint8_t *buffer, uint32_t total_sz)
|
||||
// Am I breaking something? :S
|
||||
//: Dot11Data(buffer, std::min(data_frame_size(), total_sz)) {
|
||||
: Dot11Data(buffer, total_sz) {
|
||||
: Dot11Data(buffer, total_sz, no_inner_pdu()) {
|
||||
uint32_t sz = data_frame_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(this->_qos_control))
|
||||
throw runtime_error("Not enough size for an IEEE 802.11 data header in the buffer.");
|
||||
if(total_sz < sizeof(_qos_control))
|
||||
throw malformed_packet();
|
||||
_qos_control = *(uint16_t*)buffer;
|
||||
total_sz -= sizeof(uint16_t);
|
||||
buffer += sizeof(uint16_t);
|
||||
@@ -1349,15 +1386,17 @@ uint32_t Dot11QoSData::header_size() const {
|
||||
|
||||
uint32_t Dot11QoSData::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_qos_control);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(sz <= total_sz);
|
||||
#endif
|
||||
*(uint16_t*)buffer = this->_qos_control;
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Dot11Control */
|
||||
|
||||
Dot11Control::Dot11Control(const address_type &dst_addr, PDU* child)
|
||||
: Dot11(dst_addr, child)
|
||||
Dot11Control::Dot11Control(const address_type &dst_addr)
|
||||
: Dot11(dst_addr)
|
||||
{
|
||||
type(CONTROL);
|
||||
}
|
||||
@@ -1370,8 +1409,8 @@ Dot11Control::Dot11Control(const uint8_t *buffer, uint32_t total_sz)
|
||||
/* Dot11ControlTA */
|
||||
|
||||
Dot11ControlTA::Dot11ControlTA(const address_type &dst_addr,
|
||||
const address_type &target_address, PDU* child)
|
||||
: Dot11Control(dst_addr, child)
|
||||
const address_type &target_address)
|
||||
: Dot11Control(dst_addr)
|
||||
{
|
||||
target_addr(target_address);
|
||||
}
|
||||
@@ -1390,7 +1429,9 @@ uint32_t Dot11ControlTA::header_size() const {
|
||||
}
|
||||
|
||||
uint32_t Dot11ControlTA::write_ext_header(uint8_t *buffer, uint32_t total_sz) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(_taddr));
|
||||
#endif
|
||||
//std::memcpy(buffer, _taddr, sizeof(_taddr));
|
||||
_taddr.copy(buffer);
|
||||
return sizeof(_taddr);
|
||||
@@ -1403,8 +1444,8 @@ void Dot11ControlTA::target_addr(const address_type &addr) {
|
||||
/* Dot11RTS */
|
||||
|
||||
Dot11RTS::Dot11RTS(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
subtype(RTS);
|
||||
}
|
||||
@@ -1417,8 +1458,8 @@ Dot11RTS::Dot11RTS(const uint8_t *buffer, uint32_t total_sz)
|
||||
/* Dot11PSPoll */
|
||||
|
||||
Dot11PSPoll::Dot11PSPoll(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
subtype(PS);
|
||||
}
|
||||
@@ -1431,8 +1472,8 @@ Dot11PSPoll::Dot11PSPoll(const uint8_t *buffer, uint32_t total_sz)
|
||||
/* Dot11CFEnd */
|
||||
|
||||
Dot11CFEnd::Dot11CFEnd(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
subtype(CF_END);
|
||||
}
|
||||
@@ -1445,8 +1486,8 @@ Dot11CFEnd::Dot11CFEnd(const uint8_t *buffer, uint32_t total_sz)
|
||||
/* Dot11EndCFAck */
|
||||
|
||||
Dot11EndCFAck::Dot11EndCFAck(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
subtype(CF_END_ACK);
|
||||
}
|
||||
@@ -1458,26 +1499,30 @@ Dot11EndCFAck::Dot11EndCFAck(const uint8_t *buffer, uint32_t total_sz)
|
||||
|
||||
/* Dot11Ack */
|
||||
|
||||
Dot11Ack::Dot11Ack(const address_type &dst_addr, PDU* child)
|
||||
: Dot11Control(dst_addr, child)
|
||||
Dot11Ack::Dot11Ack(const address_type &dst_addr)
|
||||
: Dot11Control(dst_addr)
|
||||
{
|
||||
subtype(ACK);
|
||||
}
|
||||
|
||||
Dot11Ack::Dot11Ack(const uint8_t *buffer, uint32_t total_sz) : Dot11Control(buffer, total_sz) {
|
||||
Dot11Ack::Dot11Ack(const uint8_t *buffer, uint32_t total_sz)
|
||||
: Dot11Control(buffer, total_sz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Dot11BlockAck */
|
||||
|
||||
Dot11BlockAckRequest::Dot11BlockAckRequest(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
init_block_ack();
|
||||
}
|
||||
|
||||
Dot11BlockAckRequest::Dot11BlockAckRequest(const uint8_t *buffer, uint32_t total_sz) : Dot11ControlTA(buffer, total_sz) {
|
||||
Dot11BlockAckRequest::Dot11BlockAckRequest(const uint8_t *buffer, uint32_t total_sz)
|
||||
: Dot11ControlTA(buffer, total_sz)
|
||||
{
|
||||
uint32_t padding = controlta_size();
|
||||
buffer += padding;
|
||||
total_sz -= padding;
|
||||
@@ -1503,18 +1548,28 @@ uint32_t Dot11BlockAckRequest::write_ext_header(uint8_t *buffer, uint32_t total_
|
||||
return parent_size + sizeof(_start_sequence) + sizeof(_bar_control);
|
||||
}
|
||||
|
||||
void Dot11BlockAckRequest::bar_control(uint16_t bar) {
|
||||
//std::memcpy(&_bar_control, &bar, sizeof(bar));
|
||||
_bar_control.tid = Endian::host_to_le(bar);
|
||||
void Dot11BlockAckRequest::bar_control(small_uint<4> bar) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_bar_control = bar | (_bar_control & 0xfff0);
|
||||
#else
|
||||
_bar_control = (bar << 8) | (_bar_control & 0xf0ff);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot11BlockAckRequest::start_sequence(uint16_t seq) {
|
||||
//std::memcpy(&_start_sequence, &seq, sizeof(seq));
|
||||
_start_sequence.seq = Endian::host_to_le(seq);
|
||||
void Dot11BlockAckRequest::start_sequence(small_uint<12> seq) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_start_sequence = (seq << 4) | (_start_sequence & 0xf);
|
||||
#else
|
||||
_start_sequence = Endian::host_to_le<uint16_t>(seq << 4) | (_start_sequence & 0xf00);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot11BlockAckRequest::fragment_number(uint8_t frag) {
|
||||
_start_sequence.frag = frag;
|
||||
void Dot11BlockAckRequest::fragment_number(small_uint<4> frag) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_start_sequence = frag | (_start_sequence & 0xfff0);
|
||||
#else
|
||||
_start_sequence = (frag << 8) | (_start_sequence & 0xf0ff);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t Dot11BlockAckRequest::header_size() const {
|
||||
@@ -1524,8 +1579,8 @@ uint32_t Dot11BlockAckRequest::header_size() const {
|
||||
/* Dot11BlockAck */
|
||||
|
||||
Dot11BlockAck::Dot11BlockAck(const address_type &dst_addr,
|
||||
const address_type &target_addr, PDU* child)
|
||||
: Dot11ControlTA(dst_addr, target_addr, child)
|
||||
const address_type &target_addr)
|
||||
: Dot11ControlTA(dst_addr, target_addr)
|
||||
{
|
||||
subtype(BLOCK_ACK);
|
||||
std::memset(_bitmap, 0, sizeof(_bitmap));
|
||||
@@ -1544,12 +1599,28 @@ Dot11BlockAck::Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz) : Dot11Co
|
||||
std::memcpy(&_bitmap, buffer, sizeof(_bitmap));
|
||||
}
|
||||
|
||||
void Dot11BlockAck::bar_control(uint16_t bar) {
|
||||
std::memcpy(&_bar_control, &bar, sizeof(bar));
|
||||
void Dot11BlockAck::bar_control(small_uint<4> bar) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_bar_control = bar | (_bar_control & 0xfff0);
|
||||
#else
|
||||
_bar_control = (bar << 8) | (_bar_control & 0xf0ff);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot11BlockAck::start_sequence(uint16_t seq) {
|
||||
std::memcpy(&_start_sequence, &seq, sizeof(seq));
|
||||
void Dot11BlockAck::start_sequence(small_uint<12> seq) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_start_sequence = (seq << 4) | (_start_sequence & 0xf);
|
||||
#else
|
||||
_start_sequence = Endian::host_to_le<uint16_t>(seq << 4) | (_start_sequence & 0xf00);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot11BlockAck::fragment_number(small_uint<4> frag) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_start_sequence = frag | (_start_sequence & 0xfff0);
|
||||
#else
|
||||
_start_sequence = (frag << 8) | (_start_sequence & 0xf0ff);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot11BlockAck::bitmap(const uint8_t *bit) {
|
||||
|
||||
144
src/dot1q.cpp
Normal file
144
src/dot1q.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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 <stdexcept>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "dot1q.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
Dot1Q::Dot1Q(small_uint<12> tag_id, bool append_pad)
|
||||
: _header(), _append_padding(append_pad)
|
||||
{
|
||||
id(tag_id);
|
||||
}
|
||||
|
||||
Dot1Q::Dot1Q(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _append_padding()
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
if(total_sz) {
|
||||
inner_pdu(
|
||||
Internals::pdu_from_flag(
|
||||
(Constants::Ethernet::e)payload_type(),
|
||||
buffer,
|
||||
total_sz
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void Dot1Q::priority(small_uint<3> new_priority) {
|
||||
_header.priority = new_priority;
|
||||
}
|
||||
|
||||
void Dot1Q::cfi(small_uint<1> new_cfi) {
|
||||
_header.cfi = new_cfi;
|
||||
}
|
||||
|
||||
void Dot1Q::id(small_uint<12> new_id) {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
_header.idL = new_id & 0xff;
|
||||
_header.idH = new_id >> 8;
|
||||
#else
|
||||
_header.id = new_id;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Dot1Q::payload_type(uint16_t new_type) {
|
||||
_header.type = Endian::host_to_be(new_type);
|
||||
}
|
||||
|
||||
uint32_t Dot1Q::header_size() const {
|
||||
return sizeof(_header);
|
||||
}
|
||||
|
||||
uint32_t Dot1Q::trailer_size() const {
|
||||
if(_append_padding) {
|
||||
uint32_t total_size = sizeof(_header);
|
||||
if(inner_pdu())
|
||||
total_size += inner_pdu()->size();
|
||||
return (total_size > 50) ? 0 : (50 - total_size);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
uint32_t trailer = trailer_size();
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(_header) + trailer);
|
||||
#endif
|
||||
if ((payload_type() == 0) && inner_pdu()) {
|
||||
Constants::Ethernet::e flag = Internals::pdu_flag_to_ether_type(
|
||||
inner_pdu()->pdu_type()
|
||||
);
|
||||
payload_type(static_cast<uint16_t>(flag));
|
||||
}
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
|
||||
buffer += sizeof(_header) + inner_pdu()->size();
|
||||
std::fill(buffer, buffer + trailer, 0);
|
||||
}
|
||||
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t Dot1Q::get_id(const dot1q_hdr *hdr) {
|
||||
return hdr->idL | (hdr->idH << 8);
|
||||
}
|
||||
#else
|
||||
uint16_t Dot1Q::get_id(const dot1q_hdr *hdr) {
|
||||
return hdr->id;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Dot1Q::append_padding(bool value) {
|
||||
_append_padding = value;
|
||||
}
|
||||
|
||||
bool Dot1Q::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(_header))
|
||||
return false;
|
||||
const dot1q_hdr *dot1q_ptr = (const dot1q_hdr*)ptr;
|
||||
if(get_id(dot1q_ptr) == get_id(&_header)) {
|
||||
ptr += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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,13 +27,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include "macros.h"
|
||||
#ifndef WIN32
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
@@ -41,30 +43,27 @@
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include "ieee802_3.h"
|
||||
#include "dot3.h"
|
||||
#include "packet_sender.h"
|
||||
#include "llc.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
const IEEE802_3::address_type IEEE802_3::BROADCAST("ff:ff:ff:ff:ff:ff");
|
||||
const Dot3::address_type Dot3::BROADCAST("ff:ff:ff:ff:ff:ff");
|
||||
|
||||
IEEE802_3::IEEE802_3(const NetworkInterface& iface,
|
||||
const address_type &dst_hw_addr, const address_type &src_hw_addr,
|
||||
PDU* child)
|
||||
: PDU(child)
|
||||
Dot3::Dot3(const address_type &dst_hw_addr, const address_type &src_hw_addr)
|
||||
{
|
||||
memset(&_eth, 0, sizeof(ethhdr));
|
||||
this->dst_addr(dst_hw_addr);
|
||||
this->src_addr(src_hw_addr);
|
||||
this->iface(iface);
|
||||
this->_eth.length = 0;
|
||||
|
||||
}
|
||||
|
||||
IEEE802_3::IEEE802_3(const uint8_t *buffer, uint32_t total_sz)
|
||||
Dot3::Dot3(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
buffer += sizeof(ethhdr);
|
||||
total_sz -= sizeof(ethhdr);
|
||||
@@ -72,32 +71,28 @@ IEEE802_3::IEEE802_3(const uint8_t *buffer, uint32_t total_sz)
|
||||
inner_pdu(new Tins::LLC(buffer, total_sz));
|
||||
}
|
||||
|
||||
void IEEE802_3::dst_addr(const address_type &new_dst_mac) {
|
||||
void Dot3::dst_addr(const address_type &new_dst_mac) {
|
||||
std::copy(new_dst_mac.begin(), new_dst_mac.end(), _eth.dst_mac);
|
||||
}
|
||||
|
||||
void IEEE802_3::src_addr(const address_type &new_src_mac) {
|
||||
void Dot3::src_addr(const address_type &new_src_mac) {
|
||||
std::copy(new_src_mac.begin(), new_src_mac.end(), _eth.src_mac);
|
||||
}
|
||||
|
||||
void IEEE802_3::iface(const NetworkInterface &new_iface) {
|
||||
_iface = new_iface;
|
||||
}
|
||||
|
||||
void IEEE802_3::length(uint16_t new_length) {
|
||||
void Dot3::length(uint16_t new_length) {
|
||||
this->_eth.length = Endian::host_to_be(new_length);
|
||||
}
|
||||
|
||||
uint32_t IEEE802_3::header_size() const {
|
||||
uint32_t Dot3::header_size() const {
|
||||
return sizeof(ethhdr);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void IEEE802_3::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
void Dot3::send(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
throw invalid_interface();
|
||||
|
||||
#ifndef BSD
|
||||
#if !defined(BSD) && !defined(__FreeBSD_kernel__)
|
||||
struct sockaddr_ll addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
@@ -105,30 +100,37 @@ void IEEE802_3::send(PacketSender &sender) {
|
||||
addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
|
||||
addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
|
||||
addr.sll_halen = address_type::address_size;
|
||||
addr.sll_ifindex = _iface.id();
|
||||
addr.sll_ifindex = iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, sizeof(_eth.dst_mac));
|
||||
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
#else
|
||||
sender.send_l2(*this, 0, 0, _iface);
|
||||
sender.send_l2(*this, 0, 0, iface);
|
||||
#endif
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
bool IEEE802_3::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
||||
bool Dot3::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
return false;
|
||||
ethhdr *eth_ptr = (ethhdr*)ptr;
|
||||
if(!memcmp(eth_ptr->dst_mac, _eth.src_mac, sizeof(_eth.src_mac))) {
|
||||
return true;
|
||||
const size_t addr_sz = address_type::address_size;
|
||||
const ethhdr *eth_ptr = (const ethhdr*)ptr;
|
||||
if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac)) {
|
||||
if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac) || dst_addr() == BROADCAST)
|
||||
{
|
||||
ptr += sizeof(ethhdr);
|
||||
total_sz -= sizeof(ethhdr);
|
||||
return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void IEEE802_3::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
void Dot3::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
bool set_length = _eth.length == 0;
|
||||
assert(total_sz >= my_sz);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
|
||||
if (set_length)
|
||||
_eth.length = Endian::host_to_be(size() - sizeof(_eth));
|
||||
@@ -140,36 +142,23 @@ void IEEE802_3::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
PDU *IEEE802_3::recv_response(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
#ifndef BSD
|
||||
PDU *Dot3::recv_response(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
throw invalid_interface();
|
||||
#if !defined(BSD) && !defined(__FreeBSD_kernel__)
|
||||
struct sockaddr_ll addr;
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
|
||||
addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
|
||||
addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_802_3);
|
||||
addr.sll_halen = address_type::address_size;
|
||||
addr.sll_ifindex = _iface.id();
|
||||
addr.sll_ifindex = iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, sizeof(_eth.dst_mac));
|
||||
|
||||
return sender.recv_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
#else
|
||||
return sender.recv_l2(*this, 0, 0, _iface);
|
||||
return sender.recv_l2(*this, 0, 0, iface);
|
||||
#endif
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
PDU *IEEE802_3::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(_eth))
|
||||
return 0;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sizeof(_eth)) {
|
||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(_eth), total_sz - sizeof(_eth))) == 0)
|
||||
return 0;
|
||||
}
|
||||
cloned = new IEEE802_3(ptr, std::min(total_sz, (uint32_t)sizeof(_eth)));
|
||||
cloned->inner_pdu(child);
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -28,12 +28,14 @@
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#include "eapol.h"
|
||||
#include "dot11.h"
|
||||
#include "rsn_information.h"
|
||||
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type)
|
||||
@@ -47,13 +49,13 @@ EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type)
|
||||
EAPOL::EAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
}
|
||||
|
||||
EAPOL *EAPOL::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(eapolhdr))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
const eapolhdr *ptr = (const eapolhdr*)buffer;
|
||||
switch(ptr->type) {
|
||||
case RC4:
|
||||
@@ -84,10 +86,9 @@ void EAPOL::type(uint8_t new_type) {
|
||||
}
|
||||
|
||||
void EAPOL::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
uint32_t sz = header_size();
|
||||
assert(total_sz >= sz);
|
||||
//if(!_header.length)
|
||||
// length(sz - sizeof(_header.version) - sizeof(_header.length) - sizeof(_header.type));
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
write_body(buffer + sizeof(_header), total_sz - sizeof(_header));
|
||||
}
|
||||
@@ -106,7 +107,7 @@ RC4EAPOL::RC4EAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sizeof(eapolhdr);
|
||||
total_sz -= sizeof(eapolhdr);
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -147,8 +148,9 @@ uint32_t RC4EAPOL::header_size() const {
|
||||
}
|
||||
|
||||
void RC4EAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(_header) + _key.size();
|
||||
assert(total_sz >= sz);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(_header) + _key.size());
|
||||
#endif
|
||||
if(_key.size())
|
||||
_header.key_length = Endian::host_to_be(_key.size());
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
@@ -171,7 +173,7 @@ RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sizeof(eapolhdr);
|
||||
total_sz -= sizeof(eapolhdr);
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -261,8 +263,9 @@ uint32_t RSNEAPOL::header_size() const {
|
||||
}
|
||||
|
||||
void RSNEAPOL::write_body(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = header_size() - sizeof(eapolhdr);
|
||||
assert(total_sz >= sz);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size() - sizeof(eapolhdr));
|
||||
#endif
|
||||
if(_key.size()) {
|
||||
if(!_header.key_t) {
|
||||
_header.key_length = Endian::host_to_be<uint16_t>(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
|
||||
@@ -27,13 +27,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include "macros.h"
|
||||
#ifndef WIN32
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
@@ -49,19 +51,17 @@
|
||||
#include "arp.h"
|
||||
#include "constants.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
const EthernetII::address_type EthernetII::BROADCAST("ff:ff:ff:ff:ff:ff");
|
||||
|
||||
EthernetII::EthernetII(const NetworkInterface& iface,
|
||||
const address_type &dst_hw_addr, const address_type &src_hw_addr,
|
||||
PDU* child)
|
||||
: PDU(child)
|
||||
EthernetII::EthernetII(const address_type &dst_hw_addr,
|
||||
const address_type &src_hw_addr)
|
||||
{
|
||||
memset(&_eth, 0, sizeof(ethhdr));
|
||||
dst_addr(dst_hw_addr);
|
||||
src_addr(src_hw_addr);
|
||||
this->iface(iface);
|
||||
_eth.payload_type = 0;
|
||||
|
||||
}
|
||||
@@ -69,7 +69,7 @@ EthernetII::EthernetII(const NetworkInterface& iface,
|
||||
EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
buffer += sizeof(ethhdr);
|
||||
total_sz -= sizeof(ethhdr);
|
||||
@@ -92,10 +92,6 @@ void EthernetII::src_addr(const address_type &new_src_addr) {
|
||||
new_src_addr.copy(_eth.src_mac);
|
||||
}
|
||||
|
||||
void EthernetII::iface(const NetworkInterface& new_iface) {
|
||||
_iface = new_iface;
|
||||
}
|
||||
|
||||
void EthernetII::payload_type(uint16_t new_payload_type) {
|
||||
this->_eth.payload_type = Endian::host_to_be(new_payload_type);
|
||||
}
|
||||
@@ -105,11 +101,11 @@ uint32_t EthernetII::header_size() const {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void EthernetII::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
void EthernetII::send(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
throw invalid_interface();
|
||||
|
||||
#ifndef BSD
|
||||
#if !defined(BSD) && !defined(__FreeBSD_kernel__)
|
||||
struct sockaddr_ll addr;
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
@@ -117,30 +113,35 @@ void EthernetII::send(PacketSender &sender) {
|
||||
addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
|
||||
addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
|
||||
addr.sll_halen = address_type::address_size;
|
||||
addr.sll_ifindex = _iface.id();
|
||||
addr.sll_ifindex = iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, address_type::address_size);
|
||||
|
||||
sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
#else
|
||||
sender.send_l2(*this, 0, 0, _iface);
|
||||
sender.send_l2(*this, 0, 0, iface);
|
||||
#endif
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
bool EthernetII::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
||||
bool EthernetII::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
return false;
|
||||
ethhdr *eth_ptr = (ethhdr*)ptr;
|
||||
if(!memcmp(eth_ptr->dst_mac, _eth.src_mac, address_type::address_size)) {
|
||||
// chequear broadcast en destino original...
|
||||
return (inner_pdu()) ? inner_pdu()->matches_response(ptr + sizeof(_eth), total_sz - sizeof(_eth)) : true;
|
||||
const size_t addr_sz = address_type::address_size;
|
||||
const ethhdr *eth_ptr = (const ethhdr*)ptr;
|
||||
if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac)) {
|
||||
if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac) || dst_addr() == BROADCAST ||
|
||||
(_eth.src_mac[0] == 0x33 && _eth.src_mac[1] == 0x33))
|
||||
{
|
||||
return (inner_pdu()) ? inner_pdu()->matches_response(ptr + sizeof(_eth), total_sz - sizeof(_eth)) : true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
assert(total_sz >= my_sz);
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
|
||||
/* Inner type defaults to IP */
|
||||
if ((_eth.payload_type == 0) && inner_pdu()) {
|
||||
@@ -153,34 +154,21 @@ void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
PDU *EthernetII::recv_response(PacketSender &sender) {
|
||||
#ifndef BSD
|
||||
PDU *EthernetII::recv_response(PacketSender &sender, const NetworkInterface &iface) {
|
||||
#if !defined(BSD) && !defined(__FreeBSD_kernel__)
|
||||
struct sockaddr_ll addr;
|
||||
memset(&addr, 0, sizeof(struct sockaddr_ll));
|
||||
|
||||
addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
|
||||
addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
|
||||
addr.sll_halen = address_type::address_size;
|
||||
addr.sll_ifindex = _iface.id();
|
||||
addr.sll_ifindex = iface.id();
|
||||
memcpy(&(addr.sll_addr), _eth.dst_mac, address_type::address_size);
|
||||
|
||||
return sender.recv_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
|
||||
#else
|
||||
return sender.recv_l2(*this, 0, 0, _iface);
|
||||
return sender.recv_l2(*this, 0, 0, iface);
|
||||
#endif
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
PDU *EthernetII::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(_eth))
|
||||
return 0;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sizeof(_eth)) {
|
||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(_eth), total_sz - sizeof(_eth))) == 0)
|
||||
return 0;
|
||||
}
|
||||
cloned = new EthernetII(ptr, std::min(total_sz, (uint32_t)sizeof(_eth)));
|
||||
cloned->inner_pdu(child);
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
|
||||
74
src/icmp.cpp
74
src/icmp.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
|
||||
@@ -29,7 +29,9 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
#define NOMINMAX
|
||||
#include <netinet/in.h>
|
||||
@@ -37,95 +39,97 @@
|
||||
#include "icmp.h"
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
Tins::ICMP::ICMP(Flags flag)
|
||||
namespace Tins {
|
||||
ICMP::ICMP(Flags flag)
|
||||
{
|
||||
std::memset(&_icmp, 0, sizeof(icmphdr));
|
||||
type(flag);
|
||||
}
|
||||
|
||||
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz)
|
||||
ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(icmphdr))
|
||||
throw std::runtime_error("Not enough size for an ICMP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_icmp, buffer, sizeof(icmphdr));
|
||||
total_sz -= sizeof(icmphdr);
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer + sizeof(icmphdr), total_sz));
|
||||
}
|
||||
|
||||
void Tins::ICMP::code(uint8_t new_code) {
|
||||
void ICMP::code(uint8_t new_code) {
|
||||
_icmp.code = new_code;
|
||||
}
|
||||
|
||||
void Tins::ICMP::type(Flags new_type) {
|
||||
void ICMP::type(Flags new_type) {
|
||||
_icmp.type = new_type;
|
||||
}
|
||||
|
||||
void Tins::ICMP::check(uint16_t new_check) {
|
||||
void ICMP::check(uint16_t new_check) {
|
||||
_icmp.check = Endian::host_to_be(new_check);
|
||||
}
|
||||
|
||||
void Tins::ICMP::id(uint16_t new_id) {
|
||||
void ICMP::id(uint16_t new_id) {
|
||||
_icmp.un.echo.id = Endian::host_to_be(new_id);
|
||||
}
|
||||
|
||||
void Tins::ICMP::sequence(uint16_t new_seq) {
|
||||
void ICMP::sequence(uint16_t new_seq) {
|
||||
_icmp.un.echo.sequence = Endian::host_to_be(new_seq);
|
||||
}
|
||||
|
||||
void Tins::ICMP::gateway(uint32_t new_gw) {
|
||||
void ICMP::gateway(uint32_t new_gw) {
|
||||
_icmp.un.gateway = Endian::host_to_be(new_gw);
|
||||
}
|
||||
|
||||
void Tins::ICMP::mtu(uint16_t new_mtu) {
|
||||
void ICMP::mtu(uint16_t new_mtu) {
|
||||
_icmp.un.frag.mtu = Endian::host_to_be(new_mtu);
|
||||
}
|
||||
|
||||
void Tins::ICMP::pointer(uint8_t new_pointer) {
|
||||
void ICMP::pointer(uint8_t new_pointer) {
|
||||
_icmp.un.pointer = new_pointer;
|
||||
}
|
||||
|
||||
uint32_t Tins::ICMP::header_size() const {
|
||||
uint32_t ICMP::header_size() const {
|
||||
return sizeof(icmphdr);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_echo_request(uint16_t id, uint16_t seq) {
|
||||
void ICMP::set_echo_request(uint16_t id, uint16_t seq) {
|
||||
type(ECHO_REQUEST);
|
||||
this->id(id);
|
||||
sequence(seq);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_echo_reply(uint16_t id, uint16_t seq) {
|
||||
void ICMP::set_echo_reply(uint16_t id, uint16_t seq) {
|
||||
type(ECHO_REPLY);
|
||||
this->id(id);
|
||||
sequence(seq);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_info_request(uint16_t id, uint16_t seq) {
|
||||
void ICMP::set_info_request(uint16_t id, uint16_t seq) {
|
||||
type(INFO_REQUEST);
|
||||
code(0);
|
||||
this->id(id);
|
||||
sequence(seq);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_info_reply(uint16_t id, uint16_t seq) {
|
||||
void ICMP::set_info_reply(uint16_t id, uint16_t seq) {
|
||||
type(INFO_REPLY);
|
||||
code(0);
|
||||
this->id(id);
|
||||
sequence(seq);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_dest_unreachable() {
|
||||
void ICMP::set_dest_unreachable() {
|
||||
type(DEST_UNREACHABLE);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_time_exceeded(bool ttl_exceeded) {
|
||||
void ICMP::set_time_exceeded(bool ttl_exceeded) {
|
||||
type(TIME_EXCEEDED);
|
||||
code((ttl_exceeded) ? 0 : 1);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_param_problem(bool set_pointer, uint8_t bad_octet) {
|
||||
void ICMP::set_param_problem(bool set_pointer, uint8_t bad_octet) {
|
||||
type(PARAM_PROBLEM);
|
||||
if(set_pointer) {
|
||||
code(0);
|
||||
@@ -135,18 +139,20 @@ void Tins::ICMP::set_param_problem(bool set_pointer, uint8_t bad_octet) {
|
||||
code(1);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_source_quench() {
|
||||
void ICMP::set_source_quench() {
|
||||
type(SOURCE_QUENCH);
|
||||
}
|
||||
|
||||
void Tins::ICMP::set_redirect(uint8_t icode, uint32_t address) {
|
||||
void ICMP::set_redirect(uint8_t icode, uint32_t address) {
|
||||
type(REDIRECT);
|
||||
code(icode);
|
||||
gateway(address);
|
||||
}
|
||||
|
||||
void Tins::ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(icmphdr));
|
||||
#endif
|
||||
if(!_icmp.check) {
|
||||
uint32_t checksum = Utils::do_checksum(buffer + sizeof(icmphdr), buffer + total_sz) +
|
||||
Utils::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr));
|
||||
@@ -158,25 +164,13 @@ void Tins::ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
|
||||
_icmp.check = 0;
|
||||
}
|
||||
|
||||
bool Tins::ICMP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
||||
bool ICMP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(icmphdr))
|
||||
return false;
|
||||
icmphdr *icmp_ptr = (icmphdr*)ptr;
|
||||
if(_icmp.type == ECHO_REQUEST) {
|
||||
return icmp_ptr->type == ECHO_REPLY && icmp_ptr->un.echo.id == _icmp.un.echo.id && icmp_ptr->un.echo.sequence == _icmp.un.echo.sequence;
|
||||
const icmphdr *icmp_ptr = (const icmphdr*)ptr;
|
||||
if(_icmp.type == ECHO_REQUEST && icmp_ptr->type == ECHO_REPLY) {
|
||||
return icmp_ptr->un.echo.id == _icmp.un.echo.id && icmp_ptr->un.echo.sequence == _icmp.un.echo.sequence;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::ICMP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(icmphdr))
|
||||
return 0;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sizeof(icmphdr)) {
|
||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(icmphdr), total_sz - sizeof(icmphdr))) == 0)
|
||||
return 0;
|
||||
}
|
||||
cloned = new ICMP(ptr, std::min(total_sz, (uint32_t)sizeof(_icmp)));
|
||||
cloned->inner_pdu(child);
|
||||
return cloned;
|
||||
}
|
||||
} // namespace Tins
|
||||
|
||||
140
src/icmpv6.cpp
140
src/icmpv6.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,13 +27,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include "icmpv6.h"
|
||||
#include "ipv6.h"
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "constants.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -48,27 +51,27 @@ ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _options_size(), reach_time(0), retrans_timer(0)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an ICMPv6 header");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
if(has_target_addr()) {
|
||||
if(total_sz < ipaddress_type::address_size)
|
||||
throw std::runtime_error("Not enough size for the target address");
|
||||
throw malformed_packet();
|
||||
target_addr(buffer);
|
||||
buffer += ipaddress_type::address_size;
|
||||
total_sz -= ipaddress_type::address_size;
|
||||
}
|
||||
if(has_dest_addr()) {
|
||||
if(total_sz < ipaddress_type::address_size)
|
||||
throw std::runtime_error("Not enough size for the destination address");
|
||||
throw malformed_packet();
|
||||
dest_addr(buffer);
|
||||
buffer += ipaddress_type::address_size;
|
||||
total_sz -= ipaddress_type::address_size;
|
||||
}
|
||||
if(type() == ROUTER_ADVERT) {
|
||||
if(total_sz < sizeof(uint32_t) * 2)
|
||||
throw std::runtime_error("Not enough size for router advert fields");
|
||||
throw malformed_packet();
|
||||
const uint32_t *ptr_32 = (const uint32_t*)buffer;
|
||||
reach_time = *ptr_32++;
|
||||
retrans_timer = *ptr_32++;
|
||||
@@ -85,9 +88,15 @@ ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
void ICMPv6::parse_options(const uint8_t *&buffer, uint32_t &total_sz) {
|
||||
while(total_sz > 0) {
|
||||
if(total_sz < 8 || (static_cast<uint32_t>(buffer[1]) * 8) > total_sz || buffer[1] < 1)
|
||||
throw std::runtime_error("Not enough size for options");
|
||||
throw malformed_packet();
|
||||
// size(option) = option_size - identifier_size - length_identifier_size
|
||||
add_option(icmpv6_option(buffer[0], static_cast<uint32_t>(buffer[1]) * 8 - sizeof(uint8_t) * 2, buffer + 2));
|
||||
add_option(
|
||||
option(
|
||||
buffer[0],
|
||||
static_cast<uint32_t>(buffer[1]) * 8 - sizeof(uint8_t) * 2,
|
||||
buffer + 2
|
||||
)
|
||||
);
|
||||
total_sz -= buffer[1] * 8;
|
||||
buffer += buffer[1] * 8;
|
||||
}
|
||||
@@ -174,6 +183,16 @@ uint32_t ICMPv6::header_size() const {
|
||||
(has_dest_addr() ? ipaddress_type::address_size : 0);
|
||||
}
|
||||
|
||||
bool ICMPv6::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(icmp6hdr))
|
||||
return false;
|
||||
const icmp6hdr *hdr_ptr = (const icmp6hdr*)ptr;
|
||||
if(type() == ECHO_REQUEST && hdr_ptr->type == ECHO_REPLY)
|
||||
return hdr_ptr->u_echo.identifier == _header.u_echo.identifier &&
|
||||
hdr_ptr->u_echo.sequence == _header.u_echo.sequence;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ICMPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
@@ -200,6 +219,7 @@ void ICMPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= it->data_size() + sizeof(uint8_t) * 2);
|
||||
// total_sz is only used if TINS_DEBUG is defined.
|
||||
total_sz -= it->data_size() + sizeof(uint8_t) * 2;
|
||||
#endif
|
||||
buffer = write_option(*it, buffer);
|
||||
@@ -226,18 +246,22 @@ bool ICMPv6::has_options() const {
|
||||
type() == ROUTER_ADVERT;
|
||||
}
|
||||
|
||||
void ICMPv6::add_option(const icmpv6_option &option) {
|
||||
void ICMPv6::add_option(const option &option) {
|
||||
internal_add_option(option);
|
||||
_options.push_back(option);
|
||||
}
|
||||
|
||||
void ICMPv6::internal_add_option(const option &option) {
|
||||
_options_size += option.data_size() + sizeof(uint8_t) * 2;
|
||||
}
|
||||
|
||||
uint8_t *ICMPv6::write_option(const icmpv6_option &opt, uint8_t *buffer) {
|
||||
uint8_t *ICMPv6::write_option(const option &opt, uint8_t *buffer) {
|
||||
*buffer++ = opt.option();
|
||||
*buffer++ = (opt.data_size() + sizeof(uint8_t) * 2) / 8;
|
||||
*buffer++ = (opt.length_field() + sizeof(uint8_t) * 2) / 8;
|
||||
return std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer);
|
||||
}
|
||||
|
||||
const ICMPv6::icmpv6_option *ICMPv6::search_option(Options id) const {
|
||||
const ICMPv6::option *ICMPv6::search_option(OptionTypes id) const {
|
||||
for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
if(it->option() == id)
|
||||
return &*it;
|
||||
@@ -250,11 +274,11 @@ const ICMPv6::icmpv6_option *ICMPv6::search_option(Options id) const {
|
||||
// ********************************************************************
|
||||
|
||||
void ICMPv6::source_link_layer_addr(const hwaddress_type &addr) {
|
||||
add_option(icmpv6_option(SOURCE_ADDRESS, addr.begin(), addr.end()));
|
||||
add_option(option(SOURCE_ADDRESS, addr.begin(), addr.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::target_link_layer_addr(const hwaddress_type &addr) {
|
||||
add_option(icmpv6_option(TARGET_ADDRESS, addr.begin(), addr.end()));
|
||||
add_option(option(TARGET_ADDRESS, addr.begin(), addr.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::prefix_info(prefix_info_type info) {
|
||||
@@ -266,7 +290,7 @@ void ICMPv6::prefix_info(prefix_info_type info) {
|
||||
*(uint32_t*)(buffer + 2 + sizeof(uint32_t) * 2) = 0;
|
||||
info.prefix.copy(buffer + 2 + sizeof(uint32_t) * 3);
|
||||
add_option(
|
||||
icmpv6_option(PREFIX_INFO, buffer, buffer + sizeof(buffer))
|
||||
option(PREFIX_INFO, buffer, buffer + sizeof(buffer))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -278,32 +302,32 @@ void ICMPv6::redirect_header(PDU::serialization_type data) {
|
||||
if(padding == 8)
|
||||
padding = 0;
|
||||
data.insert(data.end(), padding, 0);
|
||||
add_option(icmpv6_option(REDIRECT_HEADER, data.begin(), data.end()));
|
||||
add_option(option(REDIRECT_HEADER, data.begin(), data.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::mtu(uint32_t value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
*((uint32_t*)(buffer + sizeof(uint16_t))) = Endian::host_to_be(value);
|
||||
add_option(icmpv6_option(MTU, sizeof(buffer), buffer));
|
||||
add_option(option(MTU, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::shortcut_limit(uint8_t value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
buffer[0] = value;
|
||||
add_option(icmpv6_option(NBMA_SHORT_LIMIT, sizeof(buffer), buffer));
|
||||
add_option(option(NBMA_SHORT_LIMIT, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::new_advert_interval(uint32_t value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
*((uint32_t*)(buffer + sizeof(uint16_t))) = Endian::host_to_be(value);
|
||||
add_option(icmpv6_option(ADVERT_INTERVAL, sizeof(buffer), buffer));
|
||||
add_option(option(ADVERT_INTERVAL, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::new_home_agent_info(const new_ha_info_type &value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
*((uint16_t*)(buffer + sizeof(uint16_t))) = Endian::host_to_be(value.first);
|
||||
*((uint16_t*)(buffer + sizeof(uint16_t) * 2)) = Endian::host_to_be(value.second);
|
||||
add_option(icmpv6_option(HOME_AGENT_INFO, sizeof(buffer), buffer));
|
||||
add_option(option(HOME_AGENT_INFO, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::source_addr_list(const addr_list_type &value) {
|
||||
@@ -320,7 +344,7 @@ void ICMPv6::add_addr_list(uint8_t type, const addr_list_type &value) {
|
||||
buffer.insert(buffer.end(), 6, 0);
|
||||
for(addr_list_type::const_iterator it(value.begin()); it != value.end(); ++it)
|
||||
buffer.insert(buffer.end(), it->begin(), it->end());
|
||||
add_option(icmpv6_option(type, buffer.begin(), buffer.end()));
|
||||
add_option(option(type, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::rsa_signature(const rsa_sign_type &value) {
|
||||
@@ -334,18 +358,18 @@ void ICMPv6::rsa_signature(const rsa_sign_type &value) {
|
||||
buffer.insert(buffer.end(), value.key_hash, value.key_hash + sizeof(value.key_hash));
|
||||
buffer.insert(buffer.end(), value.signature.begin(), value.signature.end());
|
||||
buffer.insert(buffer.end(), padding, 0);
|
||||
add_option(icmpv6_option(RSA_SIGN, buffer.begin(), buffer.end()));
|
||||
add_option(option(RSA_SIGN, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::timestamp(uint64_t value) {
|
||||
std::vector<uint8_t> buffer(6 + sizeof(uint64_t));
|
||||
buffer.insert(buffer.begin(), 6, 0);
|
||||
*((uint64_t*)&buffer[6]) = Endian::host_to_be(value);
|
||||
add_option(icmpv6_option(TIMESTAMP, buffer.begin(), buffer.end()));
|
||||
add_option(option(TIMESTAMP, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::nonce(const nonce_type &value) {
|
||||
add_option(icmpv6_option(NONCE, value.begin(), value.end()));
|
||||
add_option(option(NONCE, value.begin(), value.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::ip_prefix(const ip_prefix_type &value) {
|
||||
@@ -356,7 +380,7 @@ void ICMPv6::ip_prefix(const ip_prefix_type &value) {
|
||||
// reserved
|
||||
buffer.insert(buffer.end(), sizeof(uint32_t), 0);
|
||||
buffer.insert(buffer.end(), value.address.begin(), value.address.end());
|
||||
add_option(icmpv6_option(IP_PREFIX, buffer.begin(), buffer.end()));
|
||||
add_option(option(IP_PREFIX, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::link_layer_addr(lladdr_type value) {
|
||||
@@ -365,14 +389,14 @@ void ICMPv6::link_layer_addr(lladdr_type value) {
|
||||
if(padding == 8)
|
||||
padding = 0;
|
||||
value.address.insert(value.address.end(), padding, 0);
|
||||
add_option(icmpv6_option(LINK_ADDRESS, value.address.begin(), value.address.end()));
|
||||
add_option(option(LINK_ADDRESS, value.address.begin(), value.address.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::naack(const naack_type &value) {
|
||||
uint8_t buffer[6];
|
||||
buffer[0] = value.first;
|
||||
buffer[1] = value.second;
|
||||
add_option(icmpv6_option(NAACK, buffer, buffer + sizeof(buffer)));
|
||||
add_option(option(NAACK, buffer, buffer + sizeof(buffer)));
|
||||
}
|
||||
|
||||
void ICMPv6::map(const map_type &value) {
|
||||
@@ -381,7 +405,7 @@ void ICMPv6::map(const map_type &value) {
|
||||
buffer[1] = value.r << 7;
|
||||
*(uint32_t*)(buffer + 2) = Endian::host_to_be(value.valid_lifetime);
|
||||
value.address.copy(buffer + 2 + sizeof(uint32_t));
|
||||
add_option(icmpv6_option(MAP, buffer, buffer + sizeof(buffer)));
|
||||
add_option(option(MAP, buffer, buffer + sizeof(buffer)));
|
||||
}
|
||||
|
||||
void ICMPv6::route_info(const route_info_type &value) {
|
||||
@@ -398,7 +422,7 @@ void ICMPv6::route_info(const route_info_type &value) {
|
||||
padding,
|
||||
0
|
||||
);
|
||||
add_option(icmpv6_option(ROUTE_INFO, buffer.begin(), buffer.end()));
|
||||
add_option(option(ROUTE_INFO, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::recursive_dns_servers(const recursive_dns_type &value) {
|
||||
@@ -412,7 +436,7 @@ void ICMPv6::recursive_dns_servers(const recursive_dns_type &value) {
|
||||
typedef recursive_dns_type::servers_type::const_iterator iterator;
|
||||
for(iterator it = value.servers.begin(); it != value.servers.end(); ++it)
|
||||
out = it->copy(out);
|
||||
add_option(icmpv6_option(RECURSIVE_DNS_SERV, buffer.begin(), buffer.end()));
|
||||
add_option(option(RECURSIVE_DNS_SERV, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::handover_key_request(const handover_key_req_type &value) {
|
||||
@@ -428,7 +452,7 @@ void ICMPv6::handover_key_request(const handover_key_req_type &value) {
|
||||
buffer.end(),
|
||||
0
|
||||
);
|
||||
add_option(icmpv6_option(HANDOVER_KEY_REQ, buffer.begin(), buffer.end()));
|
||||
add_option(option(HANDOVER_KEY_REQ, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::handover_key_reply(const handover_key_reply_type &value) {
|
||||
@@ -446,7 +470,7 @@ void ICMPv6::handover_key_reply(const handover_key_reply_type &value) {
|
||||
buffer.end(),
|
||||
0
|
||||
);
|
||||
add_option(icmpv6_option(HANDOVER_KEY_REPLY, buffer.begin(), buffer.end()));
|
||||
add_option(option(HANDOVER_KEY_REPLY, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::handover_assist_info(const handover_assist_info_type &value) {
|
||||
@@ -463,7 +487,7 @@ void ICMPv6::handover_assist_info(const handover_assist_info_type &value) {
|
||||
padding,
|
||||
0
|
||||
);
|
||||
add_option(icmpv6_option(HANDOVER_ASSIST_INFO, buffer.begin(), buffer.end()));
|
||||
add_option(option(HANDOVER_ASSIST_INFO, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::mobile_node_identifier(const mobile_node_id_type &value) {
|
||||
@@ -480,7 +504,7 @@ void ICMPv6::mobile_node_identifier(const mobile_node_id_type &value) {
|
||||
padding,
|
||||
0
|
||||
);
|
||||
add_option(icmpv6_option(MOBILE_NODE_ID, buffer.begin(), buffer.end()));
|
||||
add_option(option(MOBILE_NODE_ID, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::dns_search_list(const dns_search_list_type &value) {
|
||||
@@ -504,7 +528,7 @@ void ICMPv6::dns_search_list(const dns_search_list_type &value) {
|
||||
if(padding == 8)
|
||||
padding = 0;
|
||||
buffer.insert(buffer.end(), padding, 0);
|
||||
add_option(icmpv6_option(DNS_SEARCH_LIST, buffer.begin(), buffer.end()));
|
||||
add_option(option(DNS_SEARCH_LIST, buffer.begin(), buffer.end()));
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
@@ -512,21 +536,21 @@ void ICMPv6::dns_search_list(const dns_search_list_type &value) {
|
||||
// ********************************************************************
|
||||
|
||||
ICMPv6::hwaddress_type ICMPv6::source_link_layer_addr() const {
|
||||
const icmpv6_option *opt = search_option(SOURCE_ADDRESS);
|
||||
const option *opt = search_option(SOURCE_ADDRESS);
|
||||
if(!opt || opt->data_size() != hwaddress_type::address_size)
|
||||
throw option_not_found();
|
||||
return hwaddress_type(opt->data_ptr());
|
||||
}
|
||||
|
||||
ICMPv6::hwaddress_type ICMPv6::target_link_layer_addr() const {
|
||||
const icmpv6_option *opt = search_option(TARGET_ADDRESS);
|
||||
const option *opt = search_option(TARGET_ADDRESS);
|
||||
if(!opt || opt->data_size() != hwaddress_type::address_size)
|
||||
throw option_not_found();
|
||||
return hwaddress_type(opt->data_ptr());
|
||||
}
|
||||
|
||||
ICMPv6::prefix_info_type ICMPv6::prefix_info() const {
|
||||
const icmpv6_option *opt = search_option(PREFIX_INFO);
|
||||
const option *opt = search_option(PREFIX_INFO);
|
||||
if(!opt || opt->data_size() != 2 + sizeof(uint32_t) * 3 + ipaddress_type::address_size)
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -542,7 +566,7 @@ ICMPv6::prefix_info_type ICMPv6::prefix_info() const {
|
||||
}
|
||||
|
||||
PDU::serialization_type ICMPv6::redirect_header() const {
|
||||
const icmpv6_option *opt = search_option(REDIRECT_HEADER);
|
||||
const option *opt = search_option(REDIRECT_HEADER);
|
||||
if(!opt || opt->data_size() < 6)
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = opt->data_ptr() + 6;
|
||||
@@ -550,28 +574,28 @@ PDU::serialization_type ICMPv6::redirect_header() const {
|
||||
}
|
||||
|
||||
uint32_t ICMPv6::mtu() const {
|
||||
const icmpv6_option *opt = search_option(MTU);
|
||||
const option *opt = search_option(MTU);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return Endian::be_to_host(*(const uint32_t*)(opt->data_ptr() + sizeof(uint16_t)));
|
||||
}
|
||||
|
||||
uint8_t ICMPv6::shortcut_limit() const {
|
||||
const icmpv6_option *opt = search_option(NBMA_SHORT_LIMIT);
|
||||
const option *opt = search_option(NBMA_SHORT_LIMIT);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return *opt->data_ptr();
|
||||
}
|
||||
|
||||
uint32_t ICMPv6::new_advert_interval() const {
|
||||
const icmpv6_option *opt = search_option(ADVERT_INTERVAL);
|
||||
const option *opt = search_option(ADVERT_INTERVAL);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return Endian::be_to_host(*(const uint32_t*)(opt->data_ptr() + sizeof(uint16_t)));
|
||||
}
|
||||
|
||||
ICMPv6::new_ha_info_type ICMPv6::new_home_agent_info() const {
|
||||
const icmpv6_option *opt = search_option(HOME_AGENT_INFO);
|
||||
const option *opt = search_option(HOME_AGENT_INFO);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return std::make_pair(
|
||||
@@ -588,8 +612,8 @@ ICMPv6::addr_list_type ICMPv6::target_addr_list() const {
|
||||
return search_addr_list(T_ADDRESS_LIST);
|
||||
}
|
||||
|
||||
ICMPv6::addr_list_type ICMPv6::search_addr_list(Options type) const {
|
||||
const icmpv6_option *opt = search_option(type);
|
||||
ICMPv6::addr_list_type ICMPv6::search_addr_list(OptionTypes type) const {
|
||||
const option *opt = search_option(type);
|
||||
if(!opt || opt->data_size() < 6 + ipaddress_type::address_size)
|
||||
throw option_not_found();
|
||||
addr_list_type output;
|
||||
@@ -604,7 +628,7 @@ ICMPv6::addr_list_type ICMPv6::search_addr_list(Options type) const {
|
||||
}
|
||||
|
||||
ICMPv6::rsa_sign_type ICMPv6::rsa_signature() const {
|
||||
const icmpv6_option *opt = search_option(RSA_SIGN);
|
||||
const option *opt = search_option(RSA_SIGN);
|
||||
// 2 bytes reserved + at least 1 byte signature.
|
||||
// 16 == sizeof(rsa_sign_type::key_hash), removed the sizeof
|
||||
// expression since gcc 4.2 doesn't like it
|
||||
@@ -619,21 +643,21 @@ ICMPv6::rsa_sign_type ICMPv6::rsa_signature() const {
|
||||
}
|
||||
|
||||
uint64_t ICMPv6::timestamp() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
TIMESTAMP, 6 + sizeof(uint64_t)
|
||||
);
|
||||
return Endian::be_to_host(*(uint64_t*)(opt->data_ptr() + 6));
|
||||
}
|
||||
|
||||
ICMPv6::nonce_type ICMPv6::nonce() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::equal_to>(
|
||||
const option *opt = safe_search_option<std::equal_to>(
|
||||
NONCE, 0
|
||||
);
|
||||
return nonce_type(opt->data_ptr(), opt->data_ptr() + opt->data_size());
|
||||
}
|
||||
|
||||
ICMPv6::ip_prefix_type ICMPv6::ip_prefix() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
IP_PREFIX, 2
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -648,7 +672,7 @@ ICMPv6::ip_prefix_type ICMPv6::ip_prefix() const {
|
||||
|
||||
ICMPv6::lladdr_type ICMPv6::link_layer_addr() const {
|
||||
// at least the option_code and 1 byte from the link layer address
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
LINK_ADDRESS, 2
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -658,7 +682,7 @@ ICMPv6::lladdr_type ICMPv6::link_layer_addr() const {
|
||||
}
|
||||
|
||||
ICMPv6::naack_type ICMPv6::naack() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
const option *opt = safe_search_option<std::not_equal_to>(
|
||||
NAACK, 6
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -666,7 +690,7 @@ ICMPv6::naack_type ICMPv6::naack() const {
|
||||
}
|
||||
|
||||
ICMPv6::map_type ICMPv6::map() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
const option *opt = safe_search_option<std::not_equal_to>(
|
||||
MAP, 2 + sizeof(uint32_t) + ipaddress_type::address_size
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -681,7 +705,7 @@ ICMPv6::map_type ICMPv6::map() const {
|
||||
}
|
||||
|
||||
ICMPv6::route_info_type ICMPv6::route_info() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
ROUTE_INFO, 2 + sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
@@ -695,7 +719,7 @@ ICMPv6::route_info_type ICMPv6::route_info() const {
|
||||
}
|
||||
|
||||
ICMPv6::recursive_dns_type ICMPv6::recursive_dns_servers() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
RECURSIVE_DNS_SERV, 2 + sizeof(uint32_t) + ipaddress_type::address_size
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + 2, *end = opt->data_ptr() + opt->data_size();
|
||||
@@ -712,7 +736,7 @@ ICMPv6::recursive_dns_type ICMPv6::recursive_dns_servers() const {
|
||||
}
|
||||
|
||||
ICMPv6::handover_key_req_type ICMPv6::handover_key_request() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
HANDOVER_KEY_REQ, 2 + sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + 1, *end = opt->data_ptr() + opt->data_size();
|
||||
@@ -726,7 +750,7 @@ ICMPv6::handover_key_req_type ICMPv6::handover_key_request() const {
|
||||
}
|
||||
|
||||
ICMPv6::handover_key_reply_type ICMPv6::handover_key_reply() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
HANDOVER_KEY_REPLY, 2 + sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + 1, *end = opt->data_ptr() + opt->data_size();
|
||||
@@ -742,7 +766,7 @@ ICMPv6::handover_key_reply_type ICMPv6::handover_key_reply() const {
|
||||
}
|
||||
|
||||
ICMPv6::handover_assist_info_type ICMPv6::handover_assist_info() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
HANDOVER_ASSIST_INFO, 2
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr(), *end = ptr + opt->data_size();
|
||||
@@ -755,7 +779,7 @@ ICMPv6::handover_assist_info_type ICMPv6::handover_assist_info() const {
|
||||
}
|
||||
|
||||
ICMPv6::mobile_node_id_type ICMPv6::mobile_node_identifier() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
MOBILE_NODE_ID, 2
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr(), *end = ptr + opt->data_size();
|
||||
@@ -768,7 +792,7 @@ ICMPv6::mobile_node_id_type ICMPv6::mobile_node_identifier() const {
|
||||
}
|
||||
|
||||
ICMPv6::dns_search_list_type ICMPv6::dns_search_list() const {
|
||||
const icmpv6_option *opt = safe_search_option<std::less>(
|
||||
const option *opt = safe_search_option<std::less>(
|
||||
DNS_SEARCH_LIST, 2 + sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr(), *end = ptr + opt->data_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
|
||||
@@ -29,10 +29,16 @@
|
||||
|
||||
#include "internals.h"
|
||||
#include "ip.h"
|
||||
#include "ethernetII.h"
|
||||
#include "ieee802_3.h"
|
||||
#include "radiotap.h"
|
||||
#include "dot11.h"
|
||||
#include "ipv6.h"
|
||||
#include "arp.h"
|
||||
#include "eapol.h"
|
||||
#include "rawpdu.h"
|
||||
#include "dot1q.h"
|
||||
#include "pppoe.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@@ -71,13 +77,62 @@ Tins::PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
|
||||
return new Tins::IPv6(buffer, size);
|
||||
case Tins::Constants::Ethernet::ARP:
|
||||
return new Tins::ARP(buffer, size);
|
||||
case Tins::Constants::Ethernet::PPPOED:
|
||||
return new Tins::PPPoE(buffer, size);
|
||||
case Tins::Constants::Ethernet::EAPOL:
|
||||
return Tins::EAPOL::from_bytes(buffer, size);
|
||||
case Tins::Constants::Ethernet::VLAN:
|
||||
return new Tins::Dot1Q(buffer, size);
|
||||
default:
|
||||
return rawpdu_on_no_match ? new RawPDU(buffer, size) : 0;
|
||||
};
|
||||
}
|
||||
|
||||
Tins::PDU *pdu_from_flag(PDU::PDUType type, const uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
switch(type) {
|
||||
case Tins::PDU::ETHERNET_II:
|
||||
return new Tins::EthernetII(buffer, size);
|
||||
case Tins::PDU::IP:
|
||||
return new Tins::IP(buffer, size);
|
||||
case Tins::PDU::IPv6:
|
||||
return new Tins::IPv6(buffer, size);
|
||||
case Tins::PDU::ARP:
|
||||
return new Tins::ARP(buffer, size);
|
||||
case Tins::PDU::IEEE802_3:
|
||||
return new Tins::IEEE802_3(buffer, size);
|
||||
case Tins::PDU::RADIOTAP:
|
||||
return new Tins::RadioTap(buffer, size);
|
||||
case Tins::PDU::PPPOE:
|
||||
return new Tins::PPPoE(buffer, size);
|
||||
case Tins::PDU::DOT11:
|
||||
case Tins::PDU::DOT11_ACK:
|
||||
case Tins::PDU::DOT11_ASSOC_REQ:
|
||||
case Tins::PDU::DOT11_ASSOC_RESP:
|
||||
case Tins::PDU::DOT11_AUTH:
|
||||
case Tins::PDU::DOT11_BEACON:
|
||||
case Tins::PDU::DOT11_BLOCK_ACK:
|
||||
case Tins::PDU::DOT11_BLOCK_ACK_REQ:
|
||||
case Tins::PDU::DOT11_CF_END:
|
||||
case Tins::PDU::DOT11_DATA:
|
||||
case Tins::PDU::DOT11_CONTROL:
|
||||
case Tins::PDU::DOT11_DEAUTH:
|
||||
case Tins::PDU::DOT11_DIASSOC:
|
||||
case Tins::PDU::DOT11_END_CF_ACK:
|
||||
case Tins::PDU::DOT11_MANAGEMENT:
|
||||
case Tins::PDU::DOT11_PROBE_REQ:
|
||||
case Tins::PDU::DOT11_PROBE_RESP:
|
||||
case Tins::PDU::DOT11_PS_POLL:
|
||||
case Tins::PDU::DOT11_REASSOC_REQ:
|
||||
case Tins::PDU::DOT11_REASSOC_RESP:
|
||||
case Tins::PDU::DOT11_RTS:
|
||||
case Tins::PDU::DOT11_QOS_DATA:
|
||||
return Tins::Dot11::from_bytes(buffer, size);
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
|
||||
switch (flag) {
|
||||
case PDU::IP:
|
||||
@@ -86,6 +141,10 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
|
||||
return Constants::Ethernet::IPV6;
|
||||
case PDU::ARP:
|
||||
return Constants::Ethernet::ARP;
|
||||
case PDU::DOT1Q:
|
||||
return Constants::Ethernet::VLAN;
|
||||
case PDU::PPPOE:
|
||||
return Constants::Ethernet::PPPOED;
|
||||
default:
|
||||
return Constants::Ethernet::UNKNOWN;
|
||||
}
|
||||
|
||||
207
src/ip.cpp
207
src/ip.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
|
||||
@@ -29,7 +29,9 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#ifndef WIN32
|
||||
#include <netdb.h>
|
||||
@@ -48,6 +50,8 @@
|
||||
#include "utils.h"
|
||||
#include "packet_sender.h"
|
||||
#include "constants.h"
|
||||
#include "network_interface.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::list;
|
||||
|
||||
@@ -55,8 +59,7 @@ namespace Tins {
|
||||
|
||||
const uint8_t IP::DEFAULT_TTL = 128;
|
||||
|
||||
IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
|
||||
: PDU(child)
|
||||
IP::IP(address_type ip_dst, address_type ip_src)
|
||||
{
|
||||
init_ip_fields();
|
||||
this->dst_addr(ip_dst);
|
||||
@@ -65,18 +68,17 @@ IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
|
||||
|
||||
IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
const char *msg = "Not enough size for an IP header in the buffer.";
|
||||
if(total_sz < sizeof(iphdr))
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_ip, buffer, sizeof(iphdr));
|
||||
|
||||
/* Options... */
|
||||
/* Establish beginning and ending of the options */
|
||||
const uint8_t* ptr_buffer = buffer + sizeof(iphdr);
|
||||
if(total_sz < head_len() * sizeof(uint32_t))
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
if(head_len() * sizeof(uint32_t) < sizeof(iphdr))
|
||||
throw std::runtime_error("Malformed head len field");
|
||||
throw malformed_packet();
|
||||
buffer += head_len() * sizeof(uint32_t);
|
||||
|
||||
_options_size = 0;
|
||||
@@ -87,47 +89,28 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
option_identifier opt_type;
|
||||
memcpy(&opt_type, ptr_buffer, sizeof(uint8_t));
|
||||
ptr_buffer++;
|
||||
switch (opt_type.number) {
|
||||
if(opt_type.number > NOOP) {
|
||||
/* Multibyte options with length as second byte */
|
||||
case SEC:
|
||||
case LSSR:
|
||||
case TIMESTAMP:
|
||||
case EXTSEC:
|
||||
case RR:
|
||||
case SID:
|
||||
case SSRR:
|
||||
case MTUPROBE:
|
||||
case MTUREPLY:
|
||||
case EIP:
|
||||
case TR:
|
||||
case ADDEXT:
|
||||
case RTRALT:
|
||||
case SDB:
|
||||
case DPS:
|
||||
case UMP:
|
||||
case QS:
|
||||
if(ptr_buffer == buffer || *ptr_buffer == 0)
|
||||
throw std::runtime_error(msg);
|
||||
|
||||
{
|
||||
const uint8_t data_size = *ptr_buffer - 2;
|
||||
if(data_size > 0) {
|
||||
ptr_buffer++;
|
||||
if(buffer - ptr_buffer < data_size)
|
||||
throw std::runtime_error(msg);
|
||||
_ip_options.push_back(ip_option(opt_type, ptr_buffer, ptr_buffer + data_size));
|
||||
}
|
||||
else
|
||||
_ip_options.push_back(ip_option(opt_type));
|
||||
}
|
||||
if(ptr_buffer == buffer || *ptr_buffer == 0)
|
||||
throw malformed_packet();
|
||||
|
||||
ptr_buffer += _ip_options.back().data_size() + 1;
|
||||
break;
|
||||
default:
|
||||
_ip_options.push_back(ip_option(opt_type));
|
||||
break;
|
||||
const uint8_t data_size = *ptr_buffer - 2;
|
||||
if(data_size > 0) {
|
||||
ptr_buffer++;
|
||||
if(buffer - ptr_buffer < data_size)
|
||||
throw malformed_packet();
|
||||
_ip_options.push_back(option(opt_type, ptr_buffer, ptr_buffer + data_size));
|
||||
}
|
||||
else
|
||||
_ip_options.push_back(option(opt_type));
|
||||
|
||||
ptr_buffer += _ip_options.back().data_size() + 1;
|
||||
_options_size += _ip_options.back().data_size() + 2;
|
||||
}
|
||||
else {
|
||||
_ip_options.push_back(option(opt_type));
|
||||
_options_size++;
|
||||
}
|
||||
_options_size += _ip_options.back().data_size() + 2;
|
||||
}
|
||||
uint8_t padding = _options_size % 4;
|
||||
_padded_options_size = padding ? (_options_size - padding + 4) : _options_size;
|
||||
@@ -189,7 +172,7 @@ void IP::protocol(uint8_t new_protocol) {
|
||||
_ip.protocol = new_protocol;
|
||||
}
|
||||
|
||||
void IP::check(uint16_t new_check) {
|
||||
void IP::checksum(uint16_t new_check) {
|
||||
_ip.check = Endian::host_to_be(new_check);
|
||||
}
|
||||
|
||||
@@ -231,7 +214,7 @@ void IP::security(const security_type &data) {
|
||||
array[6] = ((value >> 16) & 0xff);
|
||||
|
||||
add_option(
|
||||
ip_option(
|
||||
option(
|
||||
130,
|
||||
sizeof(array),
|
||||
array
|
||||
@@ -242,7 +225,7 @@ void IP::security(const security_type &data) {
|
||||
void IP::stream_identifier(uint16_t stream_id) {
|
||||
stream_id = Endian::host_to_be(stream_id);
|
||||
add_option(
|
||||
ip_option(
|
||||
option(
|
||||
136,
|
||||
sizeof(uint16_t),
|
||||
(const uint8_t*)&stream_id
|
||||
@@ -264,7 +247,7 @@ void IP::add_route_option(option_identifier id, const generic_route_option_type
|
||||
opt_data[1 + i * 4 + 3] = (ip >> 24) & 0xff;
|
||||
}
|
||||
add_option(
|
||||
ip_option(
|
||||
option(
|
||||
id,
|
||||
opt_data.size(),
|
||||
&opt_data[0]
|
||||
@@ -273,7 +256,7 @@ void IP::add_route_option(option_identifier id, const generic_route_option_type
|
||||
}
|
||||
|
||||
IP::generic_route_option_type IP::search_route_option(option_identifier id) const {
|
||||
const ip_option *option = search_option(id);
|
||||
const option *option = search_option(id);
|
||||
if(!option || option->data_size() < 1 + sizeof(uint32_t) ||
|
||||
((option->data_size() - 1) % sizeof(uint32_t)) != 0)
|
||||
throw option_not_found();
|
||||
@@ -287,7 +270,7 @@ IP::generic_route_option_type IP::search_route_option(option_identifier id) cons
|
||||
}
|
||||
|
||||
IP::security_type IP::security() const {
|
||||
const ip_option *option = search_option(130);
|
||||
const option *option = search_option(130);
|
||||
if(!option || option->data_size() < 9)
|
||||
throw option_not_found();
|
||||
security_type output;
|
||||
@@ -303,35 +286,42 @@ IP::security_type IP::security() const {
|
||||
}
|
||||
|
||||
uint16_t IP::stream_identifier() const {
|
||||
const ip_option *option = search_option(136);
|
||||
const option *option = search_option(136);
|
||||
if(!option || option->data_size() != sizeof(uint16_t))
|
||||
throw option_not_found();
|
||||
return Endian::be_to_host(*(const uint16_t*)option->data_ptr());
|
||||
}
|
||||
|
||||
void IP::add_option(const ip_option &option) {
|
||||
_ip_options.push_back(option);
|
||||
_options_size += 1 + option.data_size();
|
||||
void IP::add_option(const option &opt) {
|
||||
internal_add_option(opt);
|
||||
_ip_options.push_back(opt);
|
||||
}
|
||||
|
||||
void IP::internal_add_option(const option &opt) {
|
||||
_options_size += 1 + opt.data_size();
|
||||
uint8_t padding = _options_size % 4;
|
||||
_padded_options_size = padding ? (_options_size - padding + 4) : _options_size;
|
||||
}
|
||||
|
||||
const IP::ip_option *IP::search_option(option_identifier id) const {
|
||||
for(std::list<ip_option>::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
|
||||
const IP::option *IP::search_option(option_identifier id) const {
|
||||
for(options_type::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
|
||||
if(it->option() == id)
|
||||
return &(*it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* IP::write_option(const ip_option &opt, uint8_t* buffer) {
|
||||
uint8_t* IP::write_option(const option &opt, uint8_t* buffer) {
|
||||
option_identifier opt_type = opt.option();
|
||||
memcpy(buffer, &opt_type, 1);
|
||||
if(*buffer <= 1)
|
||||
return ++buffer;
|
||||
buffer++;
|
||||
*(buffer++) = opt.data_size() + 2;
|
||||
std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer);
|
||||
buffer += opt.data_size();
|
||||
return buffer;
|
||||
*buffer = opt.length_field();
|
||||
if(opt.data_size() == opt.length_field())
|
||||
*buffer += 2;
|
||||
buffer++;
|
||||
return std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer);
|
||||
}
|
||||
|
||||
/* Virtual method overriding. */
|
||||
@@ -340,33 +330,54 @@ uint32_t IP::header_size() const {
|
||||
return sizeof(iphdr) + _padded_options_size;
|
||||
}
|
||||
|
||||
void IP::send(PacketSender& sender) {
|
||||
struct sockaddr_in link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IP_SOCKET;
|
||||
PacketSender::SocketType pdu_type_to_sender_type(PDU::PDUType type) {
|
||||
switch(type) {
|
||||
case PDU::TCP:
|
||||
return PacketSender::IP_TCP_SOCKET;
|
||||
case PDU::UDP:
|
||||
return PacketSender::IP_UDP_SOCKET;
|
||||
case PDU::ICMP:
|
||||
return PacketSender::ICMP_SOCKET;
|
||||
default:
|
||||
return PacketSender::IP_RAW_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
void IP::send(PacketSender& sender, const NetworkInterface &) {
|
||||
sockaddr_in link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IP_RAW_SOCKET;
|
||||
link_addr.sin_family = AF_INET;
|
||||
link_addr.sin_port = 0;
|
||||
link_addr.sin_addr.s_addr = _ip.daddr;
|
||||
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
|
||||
type = PacketSender::ICMP_SOCKET;
|
||||
if(inner_pdu())
|
||||
type = pdu_type_to_sender_type(inner_pdu()->pdu_type());
|
||||
|
||||
sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
|
||||
}
|
||||
|
||||
PDU *IP::recv_response(PacketSender &sender) {
|
||||
struct sockaddr_in link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IP_SOCKET;
|
||||
link_addr.sin_family = AF_INET;
|
||||
link_addr.sin_port = 0;
|
||||
link_addr.sin_addr.s_addr = _ip.daddr;
|
||||
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
|
||||
type = PacketSender::ICMP_SOCKET;
|
||||
PDU *IP::recv_response(PacketSender &sender, const NetworkInterface &) {
|
||||
sockaddr_in link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IP_RAW_SOCKET;
|
||||
std::memset(&link_addr, 0, sizeof(link_addr));
|
||||
if(inner_pdu())
|
||||
type = pdu_type_to_sender_type(inner_pdu()->pdu_type());
|
||||
|
||||
return sender.recv_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
|
||||
return sender.recv_l3(*this, 0, sizeof(link_addr), type);
|
||||
}
|
||||
|
||||
void IP::prepare_for_serialize(const PDU *parent) {
|
||||
if(!parent && _ip.saddr == 0) {
|
||||
NetworkInterface iface(dst_addr());
|
||||
src_addr(iface.addresses().ip_addr);
|
||||
}
|
||||
}
|
||||
|
||||
void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= my_sz);
|
||||
#endif
|
||||
checksum(0);
|
||||
if(inner_pdu()) {
|
||||
uint32_t new_flag;
|
||||
switch(inner_pdu()->pdu_type()) {
|
||||
@@ -390,7 +401,7 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
|
||||
//flag(new_flag);
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#if __FreeBSD__ || defined(__FreeBSD_kernel__)
|
||||
if(!parent)
|
||||
total_sz = Endian::host_to_be<uint16_t>(total_sz);
|
||||
#endif
|
||||
@@ -400,44 +411,30 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
|
||||
memcpy(buffer, &_ip, sizeof(_ip));
|
||||
|
||||
uint8_t* ptr_buffer = buffer + sizeof(_ip);
|
||||
for(list<ip_option>::iterator it = _ip_options.begin(); it != _ip_options.end(); ++it)
|
||||
for(options_type::const_iterator it = _ip_options.begin(); it != _ip_options.end(); ++it) {
|
||||
ptr_buffer = write_option(*it, ptr_buffer);
|
||||
}
|
||||
memset(buffer + sizeof(_ip) + _options_size, 0, _padded_options_size - _options_size);
|
||||
|
||||
if(parent && !_ip.check) {
|
||||
uint32_t checksum = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
((iphdr*)buffer)->check = Endian::host_to_be<uint16_t>(~checksum);
|
||||
this->check(0);
|
||||
if(parent) {
|
||||
uint32_t check = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size);
|
||||
while (check >> 16)
|
||||
check = (check & 0xffff) + (check >> 16);
|
||||
checksum(~check);
|
||||
((iphdr*)buffer)->check = _ip.check;
|
||||
}
|
||||
}
|
||||
|
||||
bool IP::matches_response(uint8_t *ptr, uint32_t total_sz) {
|
||||
bool IP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(iphdr))
|
||||
return false;
|
||||
iphdr *ip_ptr = (iphdr*)ptr;
|
||||
if(_ip.daddr == ip_ptr->saddr && _ip.saddr == ip_ptr->daddr) {
|
||||
uint32_t sz = _ip.ihl * sizeof(uint32_t);
|
||||
const iphdr *ip_ptr = (const iphdr*)ptr;
|
||||
// checks for broadcast addr
|
||||
if((_ip.saddr == ip_ptr->daddr && (_ip.daddr == ip_ptr->saddr || _ip.daddr == 0xffffffff)) ||
|
||||
(_ip.daddr == 0xffffffff && _ip.saddr == 0)) {
|
||||
uint32_t sz = std::min<uint32_t>(_ip.ihl * sizeof(uint32_t), total_sz);
|
||||
return inner_pdu() ? inner_pdu()->matches_response(ptr + sz, total_sz - sz) : true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PDU *IP::clone_packet(const uint8_t *ptr, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(iphdr))
|
||||
return 0;
|
||||
const iphdr *ip_ptr = (iphdr*)ptr;
|
||||
uint32_t sz = ip_ptr->ihl * sizeof(uint32_t);
|
||||
if(total_sz < sz)
|
||||
return 0;
|
||||
PDU *child = 0, *cloned;
|
||||
if(total_sz > sz) {
|
||||
if((child = PDU::clone_inner_pdu(ptr + sizeof(_ip), total_sz - sizeof(_ip))) == 0)
|
||||
return 0;
|
||||
}
|
||||
cloned = new IP(ptr, std::min(total_sz, (uint32_t)(Endian::be_to_host(ip_ptr->tot_len) * sizeof(uint32_t))));
|
||||
cloned->inner_pdu(child);
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
81
src/ipv6.cpp
81
src/ipv6.cpp
@@ -1,12 +1,43 @@
|
||||
/*
|
||||
* 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 <cstring>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <iostream> //borrame
|
||||
#include <algorithm>
|
||||
#include "ipv6.h"
|
||||
#include "constants.h"
|
||||
#include "packet_sender.h"
|
||||
@@ -16,6 +47,7 @@
|
||||
#include "icmp.h"
|
||||
#include "icmpv6.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -31,7 +63,7 @@ IPv6::IPv6(address_type ip_dst, address_type ip_src, PDU *child)
|
||||
IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: headers_size(0) {
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an IPv6 PDU");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -39,16 +71,16 @@ IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
while(total_sz) {
|
||||
if(is_extension_header(current_header)) {
|
||||
if(total_sz < 8)
|
||||
throw header_size_error();
|
||||
throw malformed_packet();
|
||||
// every ext header is at least 8 bytes long
|
||||
// minus one, from the next_header field.
|
||||
uint32_t size = static_cast<uint32_t>(buffer[1]) + 8;
|
||||
// -1 -> next header identifier
|
||||
if(total_sz < size)
|
||||
throw header_size_error();
|
||||
throw malformed_packet();
|
||||
// minus one, from the size field
|
||||
add_ext_header(
|
||||
ipv6_ext_header(buffer[0], size - sizeof(uint8_t)*2, buffer + 2)
|
||||
ext_header(buffer[0], size - sizeof(uint8_t)*2, buffer + 2)
|
||||
);
|
||||
current_header = buffer[0];
|
||||
buffer += size;
|
||||
@@ -132,8 +164,35 @@ uint32_t IPv6::header_size() const {
|
||||
return sizeof(_header) + headers_size;
|
||||
}
|
||||
|
||||
bool IPv6::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
if(total_sz < sizeof(ipv6_header))
|
||||
return false;
|
||||
const ipv6_header *hdr_ptr = (const ipv6_header*)ptr;
|
||||
// checks for ff02 multicast
|
||||
if(src_addr() == hdr_ptr->dst_addr &&
|
||||
(dst_addr() == hdr_ptr->src_addr || (_header.dst_addr[0] == 0xff && _header.dst_addr[1] == 0x02))) {
|
||||
// is this OK? there's no inner pdu, simple dst/src addr match should suffice
|
||||
if(!inner_pdu())
|
||||
return true;
|
||||
ptr += sizeof(ipv6_header);
|
||||
total_sz -= sizeof(ipv6_header);
|
||||
uint8_t current = hdr_ptr->next_header;
|
||||
// 8 == minimum header size
|
||||
while(total_sz > 8 && is_extension_header(current)) {
|
||||
if(static_cast<uint32_t>(ptr[1] + 1) * 8 > total_sz)
|
||||
return false;
|
||||
current = ptr[0];
|
||||
total_sz -= (ptr[1] + 1) * 8;
|
||||
ptr += (ptr[1] + 1) * 8;
|
||||
}
|
||||
if(!is_extension_header(current))
|
||||
return inner_pdu()->matches_response(ptr, total_sz);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void IPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef DEBUG
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
if(inner_pdu()) {
|
||||
@@ -169,7 +228,7 @@ void IPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
|
||||
}
|
||||
|
||||
#ifndef BSD
|
||||
void IPv6::send(PacketSender &sender) {
|
||||
void IPv6::send(PacketSender &sender, const NetworkInterface &) {
|
||||
struct sockaddr_in6 link_addr;
|
||||
PacketSender::SocketType type = PacketSender::IPV6_SOCKET;
|
||||
link_addr.sin6_family = AF_INET6;
|
||||
@@ -182,12 +241,12 @@ void IPv6::send(PacketSender &sender) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void IPv6::add_ext_header(const ipv6_ext_header &header) {
|
||||
void IPv6::add_ext_header(const ext_header &header) {
|
||||
ext_headers.push_back(header);
|
||||
headers_size += header.data_size() + sizeof(uint8_t) * 2;
|
||||
}
|
||||
|
||||
const IPv6::ipv6_ext_header *IPv6::search_header(ExtensionHeader id) const {
|
||||
const IPv6::ext_header *IPv6::search_header(ExtensionHeader id) const {
|
||||
uint8_t current_header = _header.next_header;
|
||||
headers_type::const_iterator it = ext_headers.begin();
|
||||
while(it != ext_headers.end() && current_header != id) {
|
||||
@@ -206,9 +265,9 @@ void IPv6::set_last_next_header(uint8_t value) {
|
||||
ext_headers.back().option(value);
|
||||
}
|
||||
|
||||
uint8_t *IPv6::write_header(const ipv6_ext_header &header, uint8_t *buffer) {
|
||||
uint8_t *IPv6::write_header(const ext_header &header, uint8_t *buffer) {
|
||||
*buffer++ = header.option();
|
||||
*buffer++ = (header.data_size() > 8) ? (header.data_size() - 8) : 0;
|
||||
*buffer++ = (header.length_field() > 8) ? (header.length_field() - 8) : 0;
|
||||
return std::copy(header.data_ptr(), header.data_ptr() + header.data_size(), buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,6 @@
|
||||
#include <mstcpip.h>
|
||||
#endif
|
||||
#include <limits>
|
||||
#include <iostream> // borrame
|
||||
#include <sstream>
|
||||
#include "ipv6_address.h"
|
||||
|
||||
|
||||
37
src/llc.cpp
37
src/llc.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
|
||||
@@ -29,11 +29,13 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
|
||||
#include "pdu.h"
|
||||
#endif
|
||||
#include "llc.h"
|
||||
#include "stp.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::list;
|
||||
|
||||
@@ -41,8 +43,8 @@ namespace Tins {
|
||||
const uint8_t LLC::GLOBAL_DSAP_ADDR = 0xFF;
|
||||
const uint8_t LLC::NULL_ADDR = 0x00;
|
||||
|
||||
LLC::LLC(PDU *child)
|
||||
: PDU(child), _type(LLC::INFORMATION)
|
||||
LLC::LLC()
|
||||
: _type(LLC::INFORMATION)
|
||||
{
|
||||
memset(&_header, 0, sizeof(llchdr));
|
||||
control_field_length = 2;
|
||||
@@ -50,8 +52,8 @@ LLC::LLC(PDU *child)
|
||||
information_field_length = 0;
|
||||
}
|
||||
|
||||
LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child)
|
||||
: PDU(child), _type(LLC::INFORMATION)
|
||||
LLC::LLC(uint8_t dsap, uint8_t ssap)
|
||||
: _type(LLC::INFORMATION)
|
||||
{
|
||||
_header.dsap = dsap;
|
||||
_header.ssap = ssap;
|
||||
@@ -63,14 +65,14 @@ LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child)
|
||||
LLC::LLC(const uint8_t *buffer, uint32_t total_sz) {
|
||||
// header + 1 info byte
|
||||
if(total_sz < sizeof(_header) + 1)
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
information_field_length = 0;
|
||||
if ((buffer[0] & 0x03) == LLC::UNNUMBERED) {
|
||||
if(total_sz < sizeof(un_control_field))
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
type(LLC::UNNUMBERED);
|
||||
std::memcpy(&control_field.unnumbered, buffer, sizeof(un_control_field));
|
||||
buffer += sizeof(un_control_field);
|
||||
@@ -79,15 +81,19 @@ LLC::LLC(const uint8_t *buffer, uint32_t total_sz) {
|
||||
}
|
||||
else {
|
||||
if(total_sz < sizeof(info_control_field))
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
type((Format)(buffer[0] & 0x03));
|
||||
control_field_length = 2;
|
||||
std::memcpy(&control_field.info, buffer, sizeof(info_control_field));
|
||||
buffer += 2;
|
||||
total_sz -= 2;
|
||||
}
|
||||
if(total_sz > 0)
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
if(total_sz > 0) {
|
||||
if(dsap() == 0x42 && ssap() == 0x42)
|
||||
inner_pdu(new Tins::STP(buffer, total_sz));
|
||||
else
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
}
|
||||
}
|
||||
|
||||
void LLC::group(bool value) {
|
||||
@@ -200,7 +206,13 @@ void LLC::clear_information_fields() {
|
||||
}
|
||||
|
||||
void LLC::write_serialization(uint8_t *buffer, uint32_t total_sz, const Tins::PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
#endif
|
||||
if(inner_pdu() && inner_pdu()->pdu_type() == PDU::STP) {
|
||||
dsap(0x42);
|
||||
ssap(0x42);
|
||||
}
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
switch (type()) {
|
||||
@@ -219,7 +231,6 @@ void LLC::write_serialization(uint8_t *buffer, uint32_t total_sz, const Tins::PD
|
||||
}
|
||||
|
||||
for (list<field_type>::const_iterator it = information_fields.begin(); it != information_fields.end(); it++) {
|
||||
//std::memcpy(buffer, it->second, it->first);
|
||||
std::copy(it->begin(), it->end(), buffer);
|
||||
buffer += it->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
|
||||
@@ -36,13 +36,16 @@
|
||||
#endif
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#ifdef TINS_DEBUG
|
||||
#include <cassert>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include "loopback.h"
|
||||
#include "packet_sender.h"
|
||||
#include "ip.h"
|
||||
#include "llc.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#if !defined(PF_LLC)
|
||||
// compilation fix, nasty but at least works on BSD
|
||||
@@ -54,18 +57,12 @@ Loopback::Loopback()
|
||||
: _family()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Loopback::Loopback(const NetworkInterface &iface, PDU *inner_pdu)
|
||||
: PDU(inner_pdu), _family(), _iface(iface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Loopback::Loopback(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_family))
|
||||
throw std::runtime_error("Not enough size for a loopback PDU");
|
||||
throw malformed_packet();
|
||||
_family = *reinterpret_cast<const uint32_t*>(buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
@@ -90,17 +87,15 @@ void Loopback::family(uint32_t family_id) {
|
||||
_family = family_id;
|
||||
}
|
||||
|
||||
void Loopback::iface(const NetworkInterface &new_iface) {
|
||||
_iface = new_iface;
|
||||
}
|
||||
|
||||
uint32_t Loopback::header_size() const {
|
||||
return sizeof(_family);
|
||||
}
|
||||
|
||||
void Loopback::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
|
||||
{
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(_family));
|
||||
#endif
|
||||
if(dynamic_cast<const Tins::IP*>(inner_pdu()))
|
||||
_family = PF_INET;
|
||||
else if(dynamic_cast<const Tins::LLC*>(inner_pdu()))
|
||||
@@ -108,11 +103,11 @@ void Loopback::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU
|
||||
*reinterpret_cast<uint32_t*>(buffer) = _family;
|
||||
}
|
||||
#ifdef BSD
|
||||
void Loopback::send(PacketSender &sender) {
|
||||
if(!_iface)
|
||||
throw std::runtime_error("Interface has not been set");
|
||||
void Loopback::send(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
throw invalid_interface();
|
||||
|
||||
sender.send_l2(*this, 0, 0, _iface);
|
||||
sender.send_l2(*this, 0, 0, iface);
|
||||
}
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
@@ -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,7 @@
|
||||
#include "macros.h"
|
||||
#ifndef WIN32
|
||||
#include <netinet/in.h>
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -64,7 +64,7 @@ struct InterfaceInfoCollector {
|
||||
bool operator() (const struct ifaddrs *addr) {
|
||||
using Tins::Endian::host_to_be;
|
||||
using Tins::IPv4Address;
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
const struct sockaddr_dl* addr_ptr = ((struct sockaddr_dl*)addr->ifa_addr);
|
||||
|
||||
if(addr->ifa_addr->sa_family == AF_LINK && addr_ptr->sdl_index == iface_id)
|
||||
@@ -138,7 +138,7 @@ NetworkInterface::NetworkInterface(IPv4Address ip) : iface_id(0) {
|
||||
typedef std::vector<Utils::RouteEntry> entries_type;
|
||||
|
||||
if(ip == "127.0.0.1")
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
iface_id = resolve_index("lo0");
|
||||
#else
|
||||
iface_id = resolve_index("lo");
|
||||
|
||||
@@ -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,7 +34,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -53,12 +53,18 @@
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "pdu.h"
|
||||
#include "macros.h"
|
||||
#include "network_interface.h"
|
||||
// PDUs required by PacketSender::send(PDU&, NetworkInterface)
|
||||
#include "ethernetII.h"
|
||||
#include "radiotap.h"
|
||||
#include "dot11.h"
|
||||
#include "radiotap.h"
|
||||
#include "ieee802_3.h"
|
||||
#include "internals.h"
|
||||
|
||||
|
||||
namespace Tins {
|
||||
@@ -76,15 +82,17 @@ const uint32_t PacketSender::DEFAULT_TIMEOUT = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
PacketSender::PacketSender(uint32_t recv_timeout, uint32_t usec)
|
||||
PacketSender::PacketSender(const NetworkInterface &iface, uint32_t recv_timeout,
|
||||
uint32_t usec)
|
||||
: _sockets(SOCKETS_END, INVALID_RAW_SOCKET),
|
||||
#if !defined(BSD) && !defined(WIN32)
|
||||
#if !defined(BSD) && !defined(WIN32) && !defined(__FreeBSD_kernel__)
|
||||
_ether_socket(INVALID_RAW_SOCKET),
|
||||
#endif
|
||||
_timeout(recv_timeout),
|
||||
_timeout_usec(usec)
|
||||
_timeout(recv_timeout), _timeout_usec(usec), default_iface(iface)
|
||||
{
|
||||
_types[IP_SOCKET] = IPPROTO_RAW;
|
||||
_types[IP_TCP_SOCKET] = IPPROTO_TCP;
|
||||
_types[IP_UDP_SOCKET] = IPPROTO_UDP;
|
||||
_types[IP_RAW_SOCKET] = IPPROTO_RAW;
|
||||
_types[IPV6_SOCKET] = IPPROTO_RAW;
|
||||
_types[ICMP_SOCKET] = IPPROTO_ICMP;
|
||||
}
|
||||
@@ -98,7 +106,7 @@ PacketSender::~PacketSender() {
|
||||
::closesocket(_sockets[i]);
|
||||
#endif
|
||||
}
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
for(BSDEtherSockets::iterator it = _ether_socket.begin(); it != _ether_socket.end(); ++it)
|
||||
::close(it->second);
|
||||
#elif !defined(WIN32)
|
||||
@@ -107,9 +115,17 @@ PacketSender::~PacketSender() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PacketSender::default_interface(const NetworkInterface &iface) {
|
||||
default_iface = iface;
|
||||
}
|
||||
|
||||
const NetworkInterface& PacketSender::default_interface() {
|
||||
return default_iface;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
bool PacketSender::ether_socket_initialized(const NetworkInterface& iface) const {
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
return _ether_socket.count(iface.id());
|
||||
#else
|
||||
return _ether_socket != INVALID_RAW_SOCKET;
|
||||
@@ -119,7 +135,7 @@ bool PacketSender::ether_socket_initialized(const NetworkInterface& iface) const
|
||||
int PacketSender::get_ether_socket(const NetworkInterface& iface) {
|
||||
if(!ether_socket_initialized(iface))
|
||||
open_l2_socket(iface);
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
return _ether_socket[iface.id()];
|
||||
#else
|
||||
return _ether_socket;
|
||||
@@ -127,7 +143,7 @@ int PacketSender::get_ether_socket(const NetworkInterface& iface) {
|
||||
}
|
||||
|
||||
void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
int sock = -1;
|
||||
// At some point, there should be an available device
|
||||
for (int i = 0; sock == -1;i++) {
|
||||
@@ -137,13 +153,13 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
sock = open(oss.str().c_str(), O_RDWR);
|
||||
}
|
||||
if(sock == -1)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface.name().c_str(), sizeof(ifr.ifr_name) - 1);
|
||||
if(ioctl(sock, BIOCSETIF, (caddr_t)&ifr) < 0) {
|
||||
::close(sock);
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
}
|
||||
_ether_socket[iface.id()] = sock;
|
||||
#else
|
||||
@@ -151,7 +167,7 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
_ether_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
|
||||
if (_ether_socket == -1)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -160,12 +176,12 @@ void PacketSender::open_l2_socket(const NetworkInterface& iface) {
|
||||
void PacketSender::open_l3_socket(SocketType type) {
|
||||
int socktype = find_type(type);
|
||||
if(socktype == -1)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(_sockets[type] == INVALID_RAW_SOCKET) {
|
||||
int sockfd;
|
||||
sockfd = socket((type == IPV6_SOCKET) ? AF_INET6 : AF_INET, SOCK_RAW, socktype);
|
||||
if (sockfd < 0)
|
||||
throw SocketOpenError(make_error_string());
|
||||
throw socket_open_error(make_error_string());
|
||||
|
||||
const int on = 1;
|
||||
#ifndef WIN32
|
||||
@@ -181,27 +197,27 @@ void PacketSender::open_l3_socket(SocketType type) {
|
||||
|
||||
void PacketSender::close_socket(SocketType type, const NetworkInterface &iface) {
|
||||
if(type == ETHER_SOCKET) {
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
BSDEtherSockets::iterator it = _ether_socket.find(iface.id());
|
||||
if(it == _ether_socket.end())
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(::close(it->second) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
_ether_socket.erase(it);
|
||||
#elif !defined(WIN32)
|
||||
if(_ether_socket == INVALID_RAW_SOCKET)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
if(::close(_ether_socket) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
_ether_socket = INVALID_RAW_SOCKET;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if(type >= SOCKETS_END || _sockets[type] == INVALID_RAW_SOCKET)
|
||||
throw InvalidSocketTypeError();
|
||||
throw invalid_socket_type();
|
||||
#ifndef WIN32
|
||||
if(close(_sockets[type]) == -1)
|
||||
throw SocketCloseError(make_error_string());
|
||||
throw socket_close_error(make_error_string());
|
||||
#else
|
||||
closesocket(_sockets[type]);
|
||||
#endif
|
||||
@@ -210,35 +226,62 @@ void PacketSender::close_socket(SocketType type, const NetworkInterface &iface)
|
||||
}
|
||||
|
||||
void PacketSender::send(PDU &pdu) {
|
||||
pdu.send(*this);
|
||||
pdu.send(*this, default_iface);
|
||||
}
|
||||
|
||||
void PacketSender::send(PDU &pdu, const NetworkInterface &iface) {
|
||||
PDU::PDUType type = pdu.pdu_type();
|
||||
switch(type) {
|
||||
case PDU::ETHERNET_II:
|
||||
send<Tins::EthernetII>(pdu, iface);
|
||||
break;
|
||||
case PDU::DOT11:
|
||||
send<Tins::Dot11>(pdu, iface);
|
||||
break;
|
||||
case PDU::RADIOTAP:
|
||||
send<Tins::RadioTap>(pdu, iface);
|
||||
break;
|
||||
case PDU::IEEE802_3:
|
||||
send<Tins::IEEE802_3>(pdu, iface);
|
||||
break;
|
||||
default:
|
||||
send(pdu);
|
||||
};
|
||||
}
|
||||
|
||||
PDU *PacketSender::send_recv(PDU &pdu) {
|
||||
return send_recv(pdu, NetworkInterface());
|
||||
}
|
||||
|
||||
PDU *PacketSender::send_recv(PDU &pdu, const NetworkInterface &iface) {
|
||||
try {
|
||||
pdu.send(*this);
|
||||
pdu.send(*this, iface);
|
||||
}
|
||||
catch(std::runtime_error&) {
|
||||
return 0;
|
||||
}
|
||||
return pdu.recv_response(*this);
|
||||
return pdu.recv_response(*this, iface);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void PacketSender::send_l2(PDU &pdu, struct sockaddr* link_addr,
|
||||
uint32_t len_addr, const NetworkInterface &iface) {
|
||||
uint32_t len_addr, const NetworkInterface &iface)
|
||||
{
|
||||
int sock = get_ether_socket(iface);
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
if(!buffer.empty()) {
|
||||
#ifdef BSD
|
||||
#if defined(BSD) || defined(__FreeBSD_kernel__)
|
||||
if(::write(sock, &buffer[0], buffer.size()) == -1)
|
||||
#else
|
||||
if(::sendto(sock, &buffer[0], buffer.size(), 0, link_addr, len_addr) == -1)
|
||||
#endif
|
||||
throw SocketWriteError(make_error_string());
|
||||
throw socket_write_error(make_error_string());
|
||||
}
|
||||
}
|
||||
|
||||
PDU *PacketSender::recv_l2(PDU &pdu, struct sockaddr *link_addr,
|
||||
uint32_t len_addr, const NetworkInterface &iface) {
|
||||
uint32_t len_addr, const NetworkInterface &iface)
|
||||
{
|
||||
int sock = get_ether_socket(iface);
|
||||
return recv_match_loop(sock, pdu, link_addr, len_addr);
|
||||
}
|
||||
@@ -254,7 +297,7 @@ void PacketSender::send_l3(PDU &pdu, struct sockaddr* link_addr, uint32_t len_ad
|
||||
int sock = _sockets[type];
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
if(sendto(sock, (const char*)&buffer[0], buffer.size(), 0, link_addr, len_addr) == -1)
|
||||
throw SocketWriteError(make_error_string());
|
||||
throw socket_write_error(make_error_string());
|
||||
}
|
||||
|
||||
PDU *PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_addr, uint32_t addrlen) {
|
||||
@@ -281,7 +324,7 @@ PDU *PacketSender::recv_match_loop(int sock, PDU &pdu, struct sockaddr* link_add
|
||||
#endif
|
||||
size = recvfrom(sock, (char*)buffer, 2048, 0, link_addr, &length);
|
||||
if(pdu.matches_response(buffer, size)) {
|
||||
return pdu.clone_packet(buffer, size);
|
||||
return Internals::pdu_from_flag(pdu.pdu_type(), buffer, size);
|
||||
}
|
||||
}
|
||||
struct timeval this_time, diff;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user