initial commit
This commit is contained in:
commit
5d74460e65
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
59
.vscode/settings.json
vendored
Normal file
59
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"algorithm": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"cerrno": "cpp",
|
||||
"climits": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"map": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"locale": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"cstdbool": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"freertos.h": "c"
|
||||
}
|
||||
}
|
39
include/README
Normal file
39
include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
165
lib/Freenove_WS2812_Lib_for_ESP32/LICENSE
Normal file
165
lib/Freenove_WS2812_Lib_for_ESP32/LICENSE
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) Freenove
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
82
lib/Freenove_WS2812_Lib_for_ESP32/README.md
Normal file
82
lib/Freenove_WS2812_Lib_for_ESP32/README.md
Normal file
@ -0,0 +1,82 @@
|
||||
# Freenove WS2812 Lib for ESP32
|
||||
|
||||
## Description
|
||||
This is an Arduino library for controlling ws2812b led on esp32.
|
||||
|
||||
Based on the example program "led_strip" in IDF-SDK. The source code repository is here:
|
||||
https://github.com/espressif/esp-idf/tree/master/examples/peripherals/rmt/led_strip
|
||||
|
||||
|
||||
## Examples:
|
||||
|
||||
Here are some simple examples.
|
||||
|
||||
### Show Rainbow
|
||||
This example make your strip show a flowing rainbow.
|
||||
```
|
||||
#include "Freenove_WS2812_Lib_for_ESP32.h"
|
||||
|
||||
#define LEDS_COUNT 8
|
||||
#define LEDS_PIN 2
|
||||
#define CHANNEL 0
|
||||
|
||||
Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL);
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int j = 0; j < 255; j += 2) {
|
||||
for (int i = 0; i < LEDS_COUNT; i++) {
|
||||
strip.setLedColorData(i, strip.Wheel((i * 256 / LEDS_COUNT + j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(2);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Usage
|
||||
```
|
||||
Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);
|
||||
```
|
||||
* Construction. Create a strip object.
|
||||
|
||||
```
|
||||
strip.begin()
|
||||
```
|
||||
Initialization data, ready for communication.
|
||||
```
|
||||
strip.setLedColorData(id, color);
|
||||
strip.setLedColorData(id, r, g, b);
|
||||
```
|
||||
* Send the color data of the specified LED to the controller.
|
||||
* Display color change after calling show function.
|
||||
* id: the index of led.
|
||||
* color: color value. egg, 0xFF0000 is RED color.
|
||||
* r,g,b: color value. 0-255.
|
||||
```
|
||||
strip.show();
|
||||
```
|
||||
* Immediately display the color data that has been sent.
|
||||
|
||||
|
||||
```
|
||||
strip.setLedColor(id, color);
|
||||
strip.setLedColor(id, r, g, b);
|
||||
```
|
||||
* Send color data and display it immediately.
|
||||
* It is equivalent to "strip.setLedColorData(id, color); strip.show();"
|
||||
* id: the index of led.
|
||||
* color: color value. egg, 0xFF0000 is RED color.
|
||||
* r,g,b: color value. 0-255.
|
||||
|
||||
```
|
||||
strip.Wheel(i)
|
||||
```
|
||||
* A simple color picker.
|
||||
* i: 0-255.
|
||||
<img src='extras/ColorWheel.jpg' width='100%'/>
|
||||
|
25
lib/Freenove_WS2812_Lib_for_ESP32/examples/RGBW/RGBW.ino
Normal file
25
lib/Freenove_WS2812_Lib_for_ESP32/examples/RGBW/RGBW.ino
Normal file
@ -0,0 +1,25 @@
|
||||
#include "Freenove_WS2812_Lib_for_ESP32.h"
|
||||
|
||||
#define LEDS_COUNT 8
|
||||
#define LEDS_PIN 2
|
||||
#define CHANNEL 0
|
||||
|
||||
Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);
|
||||
|
||||
u8 m_color[5][3] = { {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 255}, {0, 0, 0} };
|
||||
int delayval = 100;
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
strip.setBrightness(10);
|
||||
}
|
||||
void loop() {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
for (int i = 0; i < LEDS_COUNT; i++) {
|
||||
strip.setLedColorData(i, m_color[j][0], m_color[j][1], m_color[j][2]);
|
||||
strip.show();
|
||||
delay(delayval);
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
#include "Freenove_WS2812_Lib_for_ESP32.h"
|
||||
|
||||
#define LEDS_COUNT 8
|
||||
#define LEDS_PIN 2
|
||||
#define CHANNEL 0
|
||||
|
||||
Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB);
|
||||
|
||||
void setup() {
|
||||
strip.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int j = 0; j < 255; j += 2) {
|
||||
for (int i = 0; i < LEDS_COUNT; i++) {
|
||||
strip.setLedColorData(i, strip.Wheel((i * 256 / LEDS_COUNT + j) & 255));
|
||||
}
|
||||
strip.show();
|
||||
delay(5);
|
||||
}
|
||||
}
|
BIN
lib/Freenove_WS2812_Lib_for_ESP32/extras/ColorWheel.jpg
Normal file
BIN
lib/Freenove_WS2812_Lib_for_ESP32/extras/ColorWheel.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
30
lib/Freenove_WS2812_Lib_for_ESP32/keywords.txt
Normal file
30
lib/Freenove_WS2812_Lib_for_ESP32/keywords.txt
Normal file
@ -0,0 +1,30 @@
|
||||
#class (KEYWORD1)
|
||||
|
||||
|
||||
Freenove_ESP32_WS2812 KEYWORD1
|
||||
LED_TYPE KEYWORD1
|
||||
|
||||
#function and method (KEYWORD2)
|
||||
begin KEYWORD2
|
||||
setLedsCount KEYWORD2
|
||||
setLedType KEYWORD2
|
||||
setBrightness KEYWORD2
|
||||
setLedColorData KEYWORD2
|
||||
setLedColor KEYWORD2
|
||||
setAllLedsColorData KEYWORD2
|
||||
setAllLedsColor KEYWORD2
|
||||
show KEYWORD2
|
||||
|
||||
Wheel KEYWORD2
|
||||
hsv2rgb KEYWORD2
|
||||
|
||||
|
||||
#constant (LITERAL1)
|
||||
#none
|
||||
TYPE_RGB LITERAL1
|
||||
TYPE_RBG LITERAL1
|
||||
TYPE_GRB LITERAL1
|
||||
TYPE_GBR LITERAL1
|
||||
TYPE_BRG LITERAL1
|
||||
TYPE_BGR LITERAL1
|
||||
|
10
lib/Freenove_WS2812_Lib_for_ESP32/library.properties
Normal file
10
lib/Freenove_WS2812_Lib_for_ESP32/library.properties
Normal file
@ -0,0 +1,10 @@
|
||||
name=Freenove WS2812 Lib for ESP32
|
||||
version=1.0.4
|
||||
author=Freenove
|
||||
maintainer=Freenove <rd@freenove.com>
|
||||
sentence=An Arduino library for WS2812 led on ESP32.<br />
|
||||
paragraph=This is an Arduino library for controlling ws2812b led on esp32.
|
||||
category=Display
|
||||
url=https://github.com/Freenove/Freenove_WS2812_Lib_for_ESP32
|
||||
architectures=esp32
|
||||
includes=Freenove_WS2812_Lib_for_ESP32.h
|
@ -0,0 +1,179 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
/**
|
||||
* Brief A library for controlling ws2812 in esp32 platform.
|
||||
* Author SuhaylZhao
|
||||
* Company Freenove
|
||||
* Date 2020-07-31
|
||||
*/
|
||||
|
||||
|
||||
#include "Freenove_WS2812_Lib_for_ESP32.h"
|
||||
|
||||
|
||||
Freenove_ESP32_WS2812::Freenove_ESP32_WS2812(u16 n /*= 8*/, u8 pin_gpio /*= 2*/, u8 chn /*= 0*/, LED_TYPE t /*= TYPE_GRB*/)
|
||||
{
|
||||
ledCounts = n;
|
||||
pin = pin_gpio;
|
||||
rmt_chn = chn;
|
||||
br = 255;
|
||||
setLedType(t);
|
||||
}
|
||||
|
||||
bool Freenove_ESP32_WS2812::begin()
|
||||
{
|
||||
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, rmt_chn);
|
||||
rmt_config(&config);
|
||||
rmt_driver_install(config.channel, 0, 0);
|
||||
|
||||
strip_config = LED_STRIP_DEFAULT_CONFIG(ledCounts, (led_strip_dev_t)config.channel);
|
||||
|
||||
strip = led_strip_new_rmt_ws2812(&strip_config);
|
||||
if (!strip) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Freenove_ESP32_WS2812::setLedCount(u16 n)
|
||||
{
|
||||
ledCounts = n;
|
||||
begin();
|
||||
}
|
||||
|
||||
void Freenove_ESP32_WS2812::setLedType(LED_TYPE t)
|
||||
{
|
||||
rOffset = (t >> 4) & 0x03;
|
||||
gOffset = (t >> 2) & 0x03;
|
||||
bOffset = t & 0x03;
|
||||
}
|
||||
|
||||
void Freenove_ESP32_WS2812::setBrightness(u8 brightness)
|
||||
{
|
||||
br = constrain(brightness, 0, 255);
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setLedColorData(u16 index, u32 rgb)
|
||||
{
|
||||
return setLedColorData(index, rgb >> 16, rgb >> 8, rgb);
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setLedColorData(u16 index, u8 r, u8 g, u8 b)
|
||||
{
|
||||
u8 p[3];
|
||||
p[rOffset] = r * br / 255;
|
||||
p[gOffset] = g * br / 255;
|
||||
p[bOffset] = b * br / 255;
|
||||
return strip->set_pixel(strip, index, p[0], p[1], p[2]);
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setLedColor(u16 index, u32 rgb)
|
||||
{
|
||||
return setLedColor(index, rgb >> 16, rgb >> 8, rgb);
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setLedColor(u16 index, u8 r, u8 g, u8 b)
|
||||
{
|
||||
setLedColorData(index, r, g, b);
|
||||
return show();
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setAllLedsColorData(u32 rgb)
|
||||
{
|
||||
for (int i = 0; i < ledCounts; i++)
|
||||
{
|
||||
setLedColorData(i, rgb);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setAllLedsColorData(u8 r, u8 g, u8 b)
|
||||
{
|
||||
for (int i = 0; i < ledCounts; i++)
|
||||
{
|
||||
setLedColorData(i, r, g, b);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setAllLedsColor(u32 rgb)
|
||||
{
|
||||
setAllLedsColorData(rgb);
|
||||
show();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::setAllLedsColor(u8 r, u8 g, u8 b)
|
||||
{
|
||||
setAllLedsColorData(r, g, b);
|
||||
show();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Freenove_ESP32_WS2812::show()
|
||||
{
|
||||
return strip->refresh(strip, 100);
|
||||
}
|
||||
|
||||
uint32_t Freenove_ESP32_WS2812::Wheel(byte pos)
|
||||
{
|
||||
u32 WheelPos = pos % 0xff;
|
||||
if (WheelPos < 85) {
|
||||
return ((255 - WheelPos * 3) << 16) | ((WheelPos * 3) << 8);
|
||||
}
|
||||
if (WheelPos < 170) {
|
||||
WheelPos -= 85;
|
||||
return (((255 - WheelPos * 3) << 8) | (WheelPos * 3));
|
||||
}
|
||||
WheelPos -= 170;
|
||||
return ((WheelPos * 3) << 16 | (255 - WheelPos * 3));
|
||||
}
|
||||
|
||||
uint32_t Freenove_ESP32_WS2812::hsv2rgb(uint32_t h, uint32_t s, uint32_t v)
|
||||
{
|
||||
u8 r, g, b;
|
||||
h %= 360; // h -> [0,360]
|
||||
uint32_t rgb_max = v * 2.55f;
|
||||
uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;
|
||||
|
||||
uint32_t i = h / 60;
|
||||
uint32_t diff = h % 60;
|
||||
|
||||
// RGB adjustment amount by hue
|
||||
uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
r = rgb_max;
|
||||
g = rgb_min + rgb_adj;
|
||||
b = rgb_min;
|
||||
break;
|
||||
case 1:
|
||||
r = rgb_max - rgb_adj;
|
||||
g = rgb_max;
|
||||
b = rgb_min;
|
||||
break;
|
||||
case 2:
|
||||
r = rgb_min;
|
||||
g = rgb_max;
|
||||
b = rgb_min + rgb_adj;
|
||||
break;
|
||||
case 3:
|
||||
r = rgb_min;
|
||||
g = rgb_max - rgb_adj;
|
||||
b = rgb_max;
|
||||
break;
|
||||
case 4:
|
||||
r = rgb_min + rgb_adj;
|
||||
g = rgb_min;
|
||||
b = rgb_max;
|
||||
break;
|
||||
default:
|
||||
r = rgb_max;
|
||||
g = rgb_min;
|
||||
b = rgb_max - rgb_adj;
|
||||
break;
|
||||
}
|
||||
return (uint32_t)(r << 16 | g << 8 | b);
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
// Freenove_WS2812_Lib_for_ESP32.h
|
||||
/**
|
||||
* Brief A library for controlling ws2812 in esp32 platform.
|
||||
* Author SuhaylZhao
|
||||
* Company Freenove
|
||||
* Date 2020-07-31
|
||||
*/
|
||||
|
||||
#ifndef _FREENOVE_WS2812_LIB_FOR_ESP32_h
|
||||
#define _FREENOVE_WS2812_LIB_FOR_ESP32_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "driver/rmt.h"
|
||||
#include "led_strip.h"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned long u32;
|
||||
|
||||
enum LED_TYPE
|
||||
{ //R G B
|
||||
TYPE_RGB = 0x06, //00 01 10
|
||||
TYPE_RBG = 0x09, //00 10 01
|
||||
TYPE_GRB = 0x12, //01 00 10
|
||||
TYPE_GBR = 0x21, //10 00 01
|
||||
TYPE_BRG = 0x18, //01 10 00
|
||||
TYPE_BGR = 0x24 //10 01 00
|
||||
};
|
||||
|
||||
#define RMT_DEFAULT_CONFIG_TX(gpio, channel_id) \
|
||||
{ \
|
||||
.rmt_mode = RMT_MODE_TX, \
|
||||
.channel = (rmt_channel_t)channel_id, \
|
||||
.gpio_num = (gpio_num_t)gpio, \
|
||||
.clk_div = 2, \
|
||||
.mem_block_num = 1, \
|
||||
.flags = 0, \
|
||||
.tx_config = { \
|
||||
.carrier_freq_hz = 38000, \
|
||||
.carrier_level = RMT_CARRIER_LEVEL_HIGH, \
|
||||
.idle_level = RMT_IDLE_LEVEL_LOW, \
|
||||
.carrier_duty_percent = 33, \
|
||||
.carrier_en = false, \
|
||||
.loop_en = false, \
|
||||
.idle_output_en = true, \
|
||||
} \
|
||||
}
|
||||
|
||||
class Freenove_ESP32_WS2812
|
||||
{
|
||||
protected:
|
||||
|
||||
u16 ledCounts;
|
||||
u8 rmt_chn;
|
||||
u8 pin;
|
||||
u8 br;
|
||||
|
||||
u8 rOffset;
|
||||
u8 gOffset;
|
||||
u8 bOffset;
|
||||
|
||||
rmt_config_t config;
|
||||
led_strip_config_t strip_config;
|
||||
led_strip_t *strip;
|
||||
|
||||
public:
|
||||
Freenove_ESP32_WS2812(u16 n = 8, u8 pin_gpio = 2, u8 chn = 0, LED_TYPE t = TYPE_GRB);
|
||||
|
||||
bool begin();
|
||||
void setLedCount(u16 n);
|
||||
void setLedType(LED_TYPE t);
|
||||
void setBrightness(u8 brightness);
|
||||
|
||||
esp_err_t setLedColorData(u16 index, u32 rgb);
|
||||
esp_err_t setLedColorData(u16 index, u8 r, u8 g, u8 b);
|
||||
|
||||
esp_err_t setLedColor(u16 index, u32 rgb);
|
||||
esp_err_t setLedColor(u16 index, u8 r, u8 g, u8 b);
|
||||
|
||||
esp_err_t setAllLedsColorData(u32 rgb);
|
||||
esp_err_t setAllLedsColorData(u8 r, u8 g, u8 b);
|
||||
|
||||
esp_err_t setAllLedsColor(u32 rgb);
|
||||
esp_err_t setAllLedsColor(u8 r, u8 g, u8 b);
|
||||
|
||||
esp_err_t show();
|
||||
|
||||
uint32_t Wheel(byte pos);
|
||||
uint32_t hsv2rgb(uint32_t h, uint32_t s, uint32_t v);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
127
lib/Freenove_WS2812_Lib_for_ESP32/src/led_strip.h
Normal file
127
lib/Freenove_WS2812_Lib_for_ESP32/src/led_strip.h
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
/**
|
||||
* @brief LED Strip Type
|
||||
*
|
||||
*/
|
||||
typedef struct led_strip_s led_strip_t;
|
||||
|
||||
/**
|
||||
* @brief LED Strip Device Type
|
||||
*
|
||||
*/
|
||||
typedef void *led_strip_dev_t;
|
||||
|
||||
/**
|
||||
* @brief Declare of LED Strip Type
|
||||
*
|
||||
*/
|
||||
struct led_strip_s {
|
||||
/**
|
||||
* @brief Set RGB for a specific pixel
|
||||
*
|
||||
* @param strip: LED strip
|
||||
* @param index: index of pixel to set
|
||||
* @param red: red part of color
|
||||
* @param green: green part of color
|
||||
* @param blue: blue part of color
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Set RGB for a specific pixel successfully
|
||||
* - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters
|
||||
* - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred
|
||||
*/
|
||||
esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue);
|
||||
|
||||
/**
|
||||
* @brief Refresh memory colors to LEDs
|
||||
*
|
||||
* @param strip: LED strip
|
||||
* @param timeout_ms: timeout value for refreshing task
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Refresh successfully
|
||||
* - ESP_ERR_TIMEOUT: Refresh failed because of timeout
|
||||
* - ESP_FAIL: Refresh failed because some other error occurred
|
||||
*
|
||||
* @note:
|
||||
* After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip.
|
||||
*/
|
||||
esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Clear LED strip (turn off all LEDs)
|
||||
*
|
||||
* @param strip: LED strip
|
||||
* @param timeout_ms: timeout value for clearing task
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Clear LEDs successfully
|
||||
* - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout
|
||||
* - ESP_FAIL: Clear LEDs failed because some other error occurred
|
||||
*/
|
||||
esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Free LED strip resources
|
||||
*
|
||||
* @param strip: LED strip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Free resources successfully
|
||||
* - ESP_FAIL: Free resources failed because error occurred
|
||||
*/
|
||||
esp_err_t (*del)(led_strip_t *strip);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief LED Strip Configuration Type
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t max_leds; /*!< Maximum LEDs in a single strip */
|
||||
led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */
|
||||
} led_strip_config_t;
|
||||
|
||||
/**
|
||||
* @brief Default configuration for LED strip
|
||||
*
|
||||
*/
|
||||
#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \
|
||||
{ \
|
||||
.max_leds = number, \
|
||||
.dev = dev_hdl, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Install a new ws2812 driver (based on RMT peripheral)
|
||||
*
|
||||
* @param config: LED strip configuration
|
||||
* @return
|
||||
* LED strip instance or NULL
|
||||
*/
|
||||
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
183
lib/Freenove_WS2812_Lib_for_ESP32/src/led_strip_rmt_ws2812.c
Normal file
183
lib/Freenove_WS2812_Lib_for_ESP32/src/led_strip_rmt_ws2812.c
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "led_strip.h"
|
||||
#include "driver/rmt.h"
|
||||
|
||||
|
||||
static const char *TAG = "ws2812";
|
||||
#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
ret = ret_value; \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WS2812_T0H_NS (350)
|
||||
#define WS2812_T0L_NS (1000)
|
||||
#define WS2812_T1H_NS (1000)
|
||||
#define WS2812_T1L_NS (350)
|
||||
#define WS2812_RESET_US (280)
|
||||
|
||||
static uint32_t ws2812_t0h_ticks = 0;
|
||||
static uint32_t ws2812_t1h_ticks = 0;
|
||||
static uint32_t ws2812_t0l_ticks = 0;
|
||||
static uint32_t ws2812_t1l_ticks = 0;
|
||||
|
||||
typedef struct {
|
||||
led_strip_t parent;
|
||||
rmt_channel_t rmt_channel;
|
||||
uint32_t strip_len;
|
||||
uint8_t buffer[0];
|
||||
} ws2812_t;
|
||||
|
||||
/**
|
||||
* @brief Conver RGB data to RMT format.
|
||||
*
|
||||
* @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t)
|
||||
*
|
||||
* @param[in] src: source data, to converted to RMT format
|
||||
* @param[in] dest: place where to store the convert result
|
||||
* @param[in] src_size: size of source data
|
||||
* @param[in] wanted_num: number of RMT items that want to get
|
||||
* @param[out] translated_size: number of source data that got converted
|
||||
* @param[out] item_num: number of RMT items which are converted from source data
|
||||
*/
|
||||
static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size,
|
||||
size_t wanted_num, size_t *translated_size, size_t *item_num)
|
||||
{
|
||||
if (src == NULL || dest == NULL) {
|
||||
*translated_size = 0;
|
||||
*item_num = 0;
|
||||
return;
|
||||
}
|
||||
const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0
|
||||
const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1
|
||||
size_t size = 0;
|
||||
size_t num = 0;
|
||||
uint8_t *psrc = (uint8_t *)src;
|
||||
rmt_item32_t *pdest = dest;
|
||||
while (size < src_size && num < wanted_num) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// MSB first
|
||||
if (*psrc & (1 << (7 - i))) {
|
||||
pdest->val = bit1.val;
|
||||
} else {
|
||||
pdest->val = bit0.val;
|
||||
}
|
||||
num++;
|
||||
pdest++;
|
||||
}
|
||||
size++;
|
||||
psrc++;
|
||||
}
|
||||
*translated_size = size;
|
||||
*item_num = num;
|
||||
}
|
||||
|
||||
static esp_err_t ws2812_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||
STRIP_CHECK(index < ws2812->strip_len, "index out of the maximum number of leds", err, ESP_ERR_INVALID_ARG);
|
||||
uint32_t start = index * 3;
|
||||
// In thr order of RGB
|
||||
ws2812->buffer[start + 1] = green & 0xFF;
|
||||
ws2812->buffer[start + 0] = red & 0xFF;
|
||||
ws2812->buffer[start + 2] = blue & 0xFF;
|
||||
return ESP_OK;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t ws2812_refresh(led_strip_t *strip, uint32_t timeout_ms)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||
STRIP_CHECK(rmt_write_sample(ws2812->rmt_channel, ws2812->buffer, ws2812->strip_len * 3, true) == ESP_OK,
|
||||
"transmit RMT samples failed", err, ESP_FAIL);
|
||||
return rmt_wait_tx_done(ws2812->rmt_channel, pdMS_TO_TICKS(timeout_ms));
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t ws2812_clear(led_strip_t *strip, uint32_t timeout_ms)
|
||||
{
|
||||
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||
// Write zero to turn off all leds
|
||||
memset(ws2812->buffer, 0, ws2812->strip_len * 3);
|
||||
return ws2812_refresh(strip, timeout_ms);
|
||||
}
|
||||
|
||||
static esp_err_t ws2812_del(led_strip_t *strip)
|
||||
{
|
||||
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||
free(ws2812);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config)
|
||||
{
|
||||
led_strip_t *ret = NULL;
|
||||
STRIP_CHECK(config, "configuration can't be null", err, NULL);
|
||||
|
||||
// 24 bits per led
|
||||
uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3;
|
||||
ws2812_t *ws2812 = calloc(1, ws2812_size);
|
||||
STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL);
|
||||
|
||||
uint32_t counter_clk_hz = 0;
|
||||
|
||||
rmt_source_clk_t clk_t;
|
||||
uint8_t div_tt;
|
||||
rmt_get_source_clk((rmt_channel_t)config->dev, &clk_t);
|
||||
rmt_get_clk_div((rmt_channel_t)config->dev, &div_tt);
|
||||
if (clk_t == 1)
|
||||
{
|
||||
counter_clk_hz = 80000000 / div_tt;
|
||||
}
|
||||
|
||||
//STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK,
|
||||
// "get rmt counter clock failed", err, NULL);
|
||||
//counter_clk_hz = 40000000;
|
||||
// ns -> ticks
|
||||
float ratio = (float)counter_clk_hz / 1e9;
|
||||
ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS);
|
||||
ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS);
|
||||
ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS);
|
||||
ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS);
|
||||
|
||||
// set ws2812 to rmt adapter
|
||||
rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter);
|
||||
|
||||
ws2812->rmt_channel = (rmt_channel_t)config->dev;
|
||||
ws2812->strip_len = config->max_leds;
|
||||
|
||||
ws2812->parent.set_pixel = ws2812_set_pixel;
|
||||
ws2812->parent.refresh = ws2812_refresh;
|
||||
ws2812->parent.clear = ws2812_clear;
|
||||
ws2812->parent.del = ws2812_del;
|
||||
|
||||
return &ws2812->parent;
|
||||
err:
|
||||
return ret;
|
||||
}
|
46
lib/README
Normal file
46
lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
28
lib/libtins/.github/workflows/tests.yaml
vendored
Normal file
28
lib/libtins/.github/workflows/tests.yaml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
Ubuntu-Tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install libpcap
|
||||
run: sudo apt-get install -y libpcap-dev
|
||||
|
||||
- name: Initialize submodules
|
||||
run: git submodule init && git submodule update
|
||||
|
||||
- name: Initialize build system
|
||||
run: mkdir build && cd build && cmake ..
|
||||
|
||||
- name: Build tests
|
||||
run: cmake --build build --target tests
|
||||
|
||||
- name: Run tests
|
||||
run: ctest build
|
2
lib/libtins/.gitignore
vendored
Normal file
2
lib/libtins/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
build/**
|
||||
include/tins/config.h
|
4
lib/libtins/.gitmodules
vendored
Normal file
4
lib/libtins/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "googletest"]
|
||||
path = googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
ignore = dirty
|
27
lib/libtins/.travis.yml
Normal file
27
lib/libtins/.travis.yml
Normal file
@ -0,0 +1,27 @@
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libpcap-dev
|
||||
- libssl-dev
|
||||
- libboost-all-dev
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DLIBTINS_ENABLE_CXX11=1
|
||||
- make tests
|
||||
|
||||
script:
|
||||
- ctest -V
|
781
lib/libtins/CHANGES.md
Normal file
781
lib/libtins/CHANGES.md
Normal file
@ -0,0 +1,781 @@
|
||||
##### v4.4 - Thu Feb 17 14:41:59 UTC 2022
|
||||
|
||||
- Add RFC8335 extended echo types to `ICMP` and `ICMPv6` (#426)
|
||||
|
||||
- Handle loops in DNS name decompression (#444)
|
||||
|
||||
- Fix Windows' `interface` macro colliding with uses of that identifier in the code (#458)
|
||||
|
||||
- Sending IPv6 packets to a link-scope destination address now uses the right interface index (#448)
|
||||
|
||||
- Fix incorrect endian being used for ICMP's `gateway` and `address_mask` (#437)
|
||||
|
||||
- Socket in `PacketSender::open_l3_socket` is now closed if `setsockopt` fails (#433)
|
||||
|
||||
- Fix various incorrect doxygen documentation comments (#439).
|
||||
|
||||
- Fix infinite loop when querying the routing table in \*BSD (#427)
|
||||
|
||||
##### v4.3 - Fri Sep 18 03:08:33 UTC 2020
|
||||
|
||||
- Assign a PDUType to `Dot11ControlTA` (#420)
|
||||
|
||||
- Don't consider IPv6 ESP header a normal extension header (#374)
|
||||
|
||||
- Don't include non-existing headers when installed without libpcap (#382)
|
||||
|
||||
- Add `IPv6Address::is_local_unicast` (#369)
|
||||
|
||||
- Fix memory leak in `PacketWriter` (#343)
|
||||
|
||||
- Fix memory leaks in `OfflinePacketFilter` (#343)
|
||||
|
||||
- Fix detection of new TCP stream (#335)
|
||||
|
||||
- Introduce `TCP::has_flags` (#334)
|
||||
|
||||
- Fix padding calculations in RadioTapWriter (#333)
|
||||
|
||||
##### v4.2 - Fri Mar 8 04:15:13 UTC 2019
|
||||
|
||||
- Updated location of installed CMake files in unix systems (#331)
|
||||
|
||||
- Fix check to detect cross compilation (#330)
|
||||
|
||||
- Allow getting a PDU's advertised size and use it in `PacketWriter` (#324)
|
||||
|
||||
- Install DLLs in right directory (#326)
|
||||
|
||||
- Add missing Dot11 tagged option types (#305)
|
||||
|
||||
- Add support for DLT_RAW (#313)
|
||||
|
||||
- Fix potential invalid memory accesses when parsing RadioTap (#322)
|
||||
|
||||
##### v4.1 - Tue Dec 11 02:08:48 UTC 2018
|
||||
|
||||
- Fix serialization for QinQ (#316)
|
||||
|
||||
- Added base class access specifier for socket_close_error (#306)
|
||||
|
||||
- Rewrote hw_address_to_string to not require a stringstream (#299)
|
||||
|
||||
- Make RadioTapParser::skip_to_field check for end of buffer (#296)
|
||||
|
||||
- Ensure local include directory comes before system. (#293)
|
||||
|
||||
- Calculate IP option sizes properly (#288)
|
||||
|
||||
- Add parsing of well known IPv6 extension headers (#287)
|
||||
|
||||
- Add missing operators to address classes (#275)
|
||||
|
||||
- Add version macros in config.h
|
||||
|
||||
- Don't assume IPv6 uses ICMPv6 underneath
|
||||
|
||||
- Allow users to specify library install dir
|
||||
|
||||
- Use Sleep windows function passing milliseconds as parameter
|
||||
|
||||
- Implement IPv6::recv_response
|
||||
|
||||
- Don't use nullptr in non C++11 code
|
||||
|
||||
- Ignore (possibly malformed) options after EOL (#281)
|
||||
|
||||
- Don't include dot11.h in tins.h if it is not configured in the library (#277)
|
||||
|
||||
- Fix memory leak in PDU's move assignment operator
|
||||
|
||||
- Append padding to IPv6 options
|
||||
|
||||
##### v4.0 - Mon Dec 4 00:04:30 UTC 2017
|
||||
|
||||
- Add parent PDU to each PDU.
|
||||
|
||||
- Removed parent PDU parameter on `PDU::write_serialization`.
|
||||
|
||||
- Split `utils.h` into multiple files under the `utils` directory.
|
||||
|
||||
- Split `internals.h` into multiple files under the `detail` directory.
|
||||
|
||||
- Improve compilation times by removing useless include directives.
|
||||
|
||||
- Refactor `PDUOption` conversions so that heavy headers are not included in source file.
|
||||
|
||||
- Use `std::vector` instead of `std::list` in `TCP`, `IP`, `IPv6`, `DHCP`, `DHCPv6`, `DNS`, `LLC`, `Dot11` and `PPPoE`.
|
||||
|
||||
- Improve performance on `IP`, `IPv6` and `TCP` by compiting option sizes during serialization.
|
||||
|
||||
- Minor performance improvements in `DNS`.
|
||||
|
||||
- Fix `IPv6` next header handling. Now each one contains its own type and the next type is only set during serialization for ease of use.
|
||||
|
||||
- Refactor `RadioTap` parsing and serialization using a generic parser/writer.
|
||||
|
||||
- Add `BaseSniffer::set_pcap_sniffing_method` to specify whether `pcap_loop` or `pcap_dispatch` should be used when sniffing.
|
||||
|
||||
- Use `IFF_POINTOPOINT` on BSD when getting broadcast address for an interface.
|
||||
|
||||
- Added cipher and akm suites from 802.11-2016.
|
||||
|
||||
- Add IPv6 layer parsing on `Loopback` packets.
|
||||
|
||||
- Allow serializing `Loopback` on Windows.
|
||||
|
||||
- Use the right flag on `Loopback` for `IPv6`.
|
||||
|
||||
- Use the first fragment as a base when reassembling `IP` packets in `IPv4Reassembler`.
|
||||
|
||||
- Restructure CMake files removing useless `CMakeLists.txt` in `include` paths.
|
||||
|
||||
- Add getter/setter for "more data" field in `Dot11Base`.
|
||||
|
||||
- Implemented matching for ND protocol related ICMPv6 messages.
|
||||
|
||||
- Ensure TCP::OptionTypes has 8-bit range.
|
||||
|
||||
- Add header files into CMake sources so IDE can pick them up.
|
||||
|
||||
- Add MPLS "experimental" field.
|
||||
|
||||
- Fix dhcpv6::duid_type constructor from duid_ll.
|
||||
|
||||
##### v3.5 - Sat Apr 1 09:11:58 PDT 2017
|
||||
|
||||
- Added Utils::route6_entries
|
||||
|
||||
- Allow masking IPv4/6 and hardware addresses via `operator&`
|
||||
|
||||
- Add IPv4Address::from_prefix_length
|
||||
|
||||
- Move `stream_id` into a new file and rename it `StreamIdentifier`
|
||||
|
||||
- Allow disabling TCPIP classes
|
||||
|
||||
- Properly handle out of order SACKs on `AckTracker`
|
||||
|
||||
- Move TCP data tracking into a separate class
|
||||
|
||||
- Allow constructing `StreamIdentifier` from a `Stream`
|
||||
|
||||
- Allow configuring pcap timestamp precision
|
||||
|
||||
- Allow building libtins using MinGW
|
||||
|
||||
- Allow including libtins using `add_subdirectory` via CMake
|
||||
|
||||
- Allow setting customer user data to each TCP stream
|
||||
|
||||
- Allow skipping data forward in TCP streams
|
||||
|
||||
- Allow attaching to already existing TCP streams
|
||||
|
||||
- Fix: AddressRange masks first address as well
|
||||
|
||||
- Fix: Add TINS_API to `IPv4Address::operator<<`, `DataTracker` and `AckTracker`
|
||||
|
||||
- Fix: Don't always set `key_t` to 0 on `RSNEAPOL`
|
||||
|
||||
- Fix: Handle MLDv1 properly on ICMP
|
||||
|
||||
- Fix: Make Utils::resolve_hwaddress work on Windows
|
||||
|
||||
- Fix: Interface was sometimes considered down when it was up (BSD/Linux)
|
||||
|
||||
- Fix: Don't set `Dot1Q`'s payload type if next protocol type is unknown
|
||||
|
||||
- Fix: Use recvfrom on BSD/OSX when capturing layer 3 packets
|
||||
|
||||
- Fix: Make `Timestamp::current_time` work on Windows
|
||||
|
||||
- Fix: Forward `NetworkInterface` argument when calling `PacketSender::send_l2`
|
||||
|
||||
- Fix: `Timestamp` overflow issue
|
||||
|
||||
- Fix: boost's include directories variable incorrectly used on build system
|
||||
|
||||
- Fix: Configuring auto cleanup of `Stream`'s server data not working
|
||||
|
||||
- Fix: Set `EthernetII` payload type to `UNKNOWN` if there's no inner PDU
|
||||
|
||||
- Fix: Set payload type to 0 if there's no inner PDU in `IP`, `Dot1Q` and `IPv6`
|
||||
|
||||
- Fix: Buffer length check issues on `Dot11QosData`
|
||||
|
||||
- Fix: Use AF_INET6 flag when opening L3 IPv6 socket
|
||||
|
||||
- Fix: Check expecter size properly on `DNS::extract_metadata`
|
||||
|
||||
- Fix: several unused parameter warnings
|
||||
|
||||
- Fix: CCMP decryption issue when `Dot11QoSData` has a TID != 0
|
||||
|
||||
##### v3.4 - Wed Mar 9 20:24:54 PST 2016
|
||||
|
||||
- Check the secure bit on HandshakeCapturer to detect 2nd packet
|
||||
|
||||
- Add info members directly into NetworkInterface
|
||||
|
||||
- Add IPv6 addresses to NetworkInterface::Info
|
||||
|
||||
- Make *MemoryStream use size_t rather than uint32_t
|
||||
|
||||
- Add WPA2Decrypter callback interface
|
||||
|
||||
- Set MACOSX_RPATH to ON
|
||||
|
||||
- Don't fail configuration if openssl is missing
|
||||
|
||||
- Build layer 5 as RawPDU if IPv6 has fragment header
|
||||
|
||||
- Fix examples so they build on gcc 4.6
|
||||
|
||||
- Fix flag value for sniffer's immediate mode
|
||||
|
||||
- Fix IP fragment reassemble when packet has flags DF+MF
|
||||
|
||||
- Add extract_metadata to main PDU classes
|
||||
|
||||
- Fix examples to make them work on Windows
|
||||
|
||||
- Use timercmp/sub and std::chrono to subtract timevals on PacketSender
|
||||
|
||||
- Build examples against local libtins build
|
||||
|
||||
- Add uninstall target
|
||||
|
||||
- Prefix HAVE_ config.h macros with TINS_
|
||||
|
||||
- Use compiler intrinsics to swap bytes
|
||||
|
||||
- Use C++11 mode by default
|
||||
|
||||
- Add missing TINS_API to PDU classes.
|
||||
|
||||
- Extend/fix ICMPv6 enum values and unify naming
|
||||
|
||||
- Return an empty string for dot11 ssid, if ssid is present but empty
|
||||
|
||||
- Implement new TCP stream follower mechanism
|
||||
|
||||
- Use ExternalProject_Add rather than including the gtest directory
|
||||
|
||||
- Fix invalid endian on IP fragment offset on OSX
|
||||
|
||||
##### v3.3 - Sun Jan 31 21:06:04 PST 2016
|
||||
|
||||
- Add TCP connection close example
|
||||
|
||||
- Move implementations on utils.h to utils.cpp
|
||||
|
||||
- Add ICMPv6 Multicast Listener Query Messages support
|
||||
|
||||
- Add ICMPv6 Multicast Listener Report Message support
|
||||
|
||||
- Make DNS::Query and DNS::Resource lowercase and deprecate the old names
|
||||
|
||||
- Change DNS::query/resource::type to query_type and deprecate old name
|
||||
|
||||
- Add DNS Start Of Authority parsing and serialization
|
||||
|
||||
- Parse and serialize MX preference field correctly
|
||||
|
||||
- Add NetworkInterface::friendly_name to get Windows friendly names
|
||||
|
||||
- Mask 16 bits on random number generated on traceroute example
|
||||
|
||||
- Fix TCP sequence number addition/subtraction when wrapping around
|
||||
|
||||
- Use 802.1ad protocol flag when seralizing stacked Dot1Q
|
||||
|
||||
- Code cleanup and use same syntax on the entire project
|
||||
|
||||
- Correctly serialize PPPoE session packets
|
||||
|
||||
- Fix IPv6 extension headers parsing/serialization
|
||||
|
||||
- Include examples before src to avoid duplicate tins target issue
|
||||
|
||||
- Add MPLS PDU and hook it up with ICMP extensions
|
||||
|
||||
- Set UDP checksum to 0xffff if it's 0
|
||||
|
||||
- Don't define TINS_STATIC in config.h
|
||||
|
||||
- Fix invalid RSNEAPOL parsing issue
|
||||
|
||||
- Remove special clang on OSX case when building gtest
|
||||
|
||||
- Update pseudoheader_checksum signature
|
||||
|
||||
- Fix overall checksum calculation
|
||||
|
||||
- Set ICMP payload length without padding if no extensions are present
|
||||
|
||||
- Export classes on Windows shared lib builds
|
||||
|
||||
- Use google/googletest submodule and update to HEAD
|
||||
|
||||
- Remove unused cassert header inclusions
|
||||
|
||||
- Add input/output memory stream classes port PDU classes to use them
|
||||
|
||||
- Add extensions for ICMP/ICMPv6
|
||||
|
||||
- Fix RSNInformation issues on big endian architectures
|
||||
|
||||
- Add IP::fragment_offset and IP::flags
|
||||
|
||||
- Don't set Ethernet type if inner PDU type is unknown
|
||||
|
||||
- Don't run IP source address overwrite tests on OSX
|
||||
|
||||
- Always calculate IP/IPv6 checksum
|
||||
|
||||
- Fix invalid constant value on PPPoE
|
||||
|
||||
- Define default constructor for PKTAP
|
||||
|
||||
- Guard 802.11 parsing code on PPI around HAVE_DOT11
|
||||
|
||||
- Fix parsing of Dot11 packets encapsulated on PPI having FCS-at-end
|
||||
|
||||
- Fix DataLinkType typo on doxygen docs
|
||||
|
||||
- Update docs on sniff_loop handle persistency
|
||||
|
||||
- Use uint32_t for DNS resource TTL setter
|
||||
|
||||
- Erase streams when they're reassembed on IPv4Reassembler
|
||||
|
||||
- Make all exceptions derive from exception_base
|
||||
|
||||
- Add remove_option member to IP, TCP, Dot11, ICMPv6, DHCP and DHCPv6
|
||||
|
||||
- Allow HW addresses to be 00:00:00:00:00 on NetworkInterface::info
|
||||
|
||||
- Increment option size when adding a new DHCPv6 option
|
||||
|
||||
- Use NOMINMAX on examples
|
||||
|
||||
- Add metric field to RouteEntry
|
||||
|
||||
- Allow setting immediate mode on Sniffer
|
||||
|
||||
- Use one flags field for all flags on SnifferConfiguration
|
||||
|
||||
- Add ICMP responses example
|
||||
|
||||
- Add interfaces_info example
|
||||
|
||||
- Fix bug on SessionKeys::SessionKeys
|
||||
|
||||
- Fix compilation errors on android platform
|
||||
|
||||
- Fix example compilation on Windows
|
||||
|
||||
- Add PacketWriter::write overload that takes a Packet
|
||||
|
||||
- Use different IP addresses on IP tests depending on OS
|
||||
|
||||
- Allow retrieving keys on WPA2Decrypter
|
||||
|
||||
- Add NetworkInterface::is_up and NetworkInterface::info
|
||||
|
||||
- Add NetworkInterface::Info::is_up
|
||||
|
||||
- Fix compilation warnings on Windows x64
|
||||
|
||||
- Fix FindPCAP.cmake to find winpcap on x64
|
||||
|
||||
- Fix more tests warnings triggered on Windows
|
||||
|
||||
- Fix tests compilation warnings on Windows
|
||||
|
||||
- Fix error on VC triggered by pcap redefining the "inline" keyword
|
||||
|
||||
- Soften DNS parsing rules
|
||||
|
||||
- Replace WIN32 macro with _WIN32
|
||||
|
||||
- Fix IPv6Address::to_string on Windows
|
||||
|
||||
- Fix DNS issues triggered on VC
|
||||
|
||||
- Add google test as git submodule
|
||||
|
||||
- Perserve IP protocol when using RawPDU
|
||||
|
||||
- Use pcap_sendpacket by default to send packets on Windows
|
||||
|
||||
- Don't allow receiving l2 packets on windows
|
||||
|
||||
- Added RadioTap channel map type
|
||||
|
||||
- Made rsn_information() a const member function to make Dot11ManagementFrame
|
||||
immutable
|
||||
|
||||
- Ensure HAVE_CXX11 is checked when defining TINS_IS_CXX11
|
||||
|
||||
- Use one integer field for all flags on TCP
|
||||
|
||||
- Fix invalid DNS IPv4 address parsing on big endian arch
|
||||
|
||||
- Don't compile WPA2 test if LIBTINS_ENABLE_WPA2=0
|
||||
|
||||
- Add Dot11 radio measurement name corresponding to IEEE 802.11-2012
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.2 - Fri Mar 20 22:12:23 PST 2015
|
||||
|
||||
- Added include guard for config.h.
|
||||
|
||||
- The functor used on BaseSniffer::sniff_loop can now take a Packet.
|
||||
|
||||
- Added mcs, tx_flags, ext and data_retries options to RadioTap.
|
||||
|
||||
- Fixed big endian representation of RadioTap header.
|
||||
|
||||
- RadioTap's dbm_signal and dbm_noise are now signed.
|
||||
|
||||
- RadioTap now throws if an option is not present when getting
|
||||
its value.
|
||||
|
||||
- TKIP decryption now works correctly on packets from AP to STA.
|
||||
|
||||
- Added support for PKTAP header.
|
||||
|
||||
- Fixed endian issue on IPv4Address::ip_to_int on Windows.
|
||||
|
||||
- Fixed IP parsing when total length is 0 due to TCP segmentation offload.
|
||||
|
||||
- Re-added support for pkg-config.
|
||||
|
||||
- TCPStreamFollower now calls PDU::find_pdu instead of PDU::rfind_pdu.
|
||||
|
||||
- Fixed assertion throw caused by DNS parsing on Windows on debug mode.
|
||||
|
||||
- Added throw on BSD when trying to send_recv L3 packets.
|
||||
|
||||
- Added Loopback::matches_response.
|
||||
|
||||
- Removed obsolete autotools files.
|
||||
|
||||
- Fixed exception thrown when an interface didn't have an IP address
|
||||
on NetworkInterface.
|
||||
|
||||
- Added NetworkInterface::is_loopback.
|
||||
|
||||
- Moved all headers to the directory include/tins.
|
||||
|
||||
- Fixed compilation warning on TCPStramFollower due to signed to unsigned
|
||||
conversion on integral constant.
|
||||
|
||||
- BaseSniffer::get_pcap_handle is now public.
|
||||
|
||||
- PPPoE session packets are now parsed correctly.
|
||||
|
||||
- Fixed invalid Loopback protocol detection on FreeBSD/OSX.
|
||||
|
||||
- Fixed OSX IP packet sending issue.
|
||||
|
||||
- Added useful constructors to RawPDU.
|
||||
|
||||
- Fixed compilation errors on FreeBSD.
|
||||
|
||||
- Improved documentation on several classes.
|
||||
|
||||
- Fixed parsing bug when allocating IP over IP packets.
|
||||
|
||||
- Fixed Windows network interface naming.
|
||||
|
||||
- Utils::network_interface returns pcap compatible names on Windows.
|
||||
|
||||
- NetworkInterface::name now works on Windows.
|
||||
|
||||
- Added documentation generation through the build system.
|
||||
|
||||
- Added SnifferConfiguration class.
|
||||
|
||||
- Fixed bug on Dot3 serialization.
|
||||
|
||||
- Added OfflinePacketFilter class.
|
||||
|
||||
- Renamed NOEXCEPT macro to TINS_NOEXCEPT.
|
||||
|
||||
- Added DataLinkType class.
|
||||
|
||||
- IPv4Address now uses inet_pton when constructing from string.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.1 - Sun Aug 24 21:39:43 ART 2014
|
||||
|
||||
- Fixed ICMPv6 checksum error on serialization.
|
||||
|
||||
- Fixed empty domain name encoding on DNS.
|
||||
|
||||
- Changed the build system to CMake.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v3.0 - Thu Aug 7 21:39:09 ART 2014
|
||||
|
||||
- Timestamps can now be constructed from std::chrono::duration.
|
||||
|
||||
- Packets can now be constructed from a PDU pointer and take ownership
|
||||
of it.
|
||||
|
||||
- All protocols now set the next layer protocol flag, regardless if
|
||||
it was already set. This was not done in some protocols,
|
||||
like EthernetII, and as a consequence if the network layer protocol
|
||||
was replaced by other, the packet would be serialized incorrectly.
|
||||
|
||||
- Fixed invalid parsing of some unknown DNS records.
|
||||
|
||||
- Fixed unaligned memory accesses that were not supported under
|
||||
ARMv4 and ARMv5.
|
||||
|
||||
- Added BaseSniffer::set_extract_raw_pdus.
|
||||
|
||||
- Reduced minimum automake version to 1.11.
|
||||
|
||||
- Added Utils::to_string(PDU::PDUType).
|
||||
|
||||
- Fixed error compilations on Windows.
|
||||
|
||||
- Fixed ICMPv6 checksum calculation.
|
||||
|
||||
- Added method in IP and TCP to emplace an option (C++11 only).
|
||||
|
||||
- Added small option optimization to PDUOption.
|
||||
|
||||
- Fixed error compilation on RSNInformation.
|
||||
|
||||
- Renamed ICMP::check to ICMP::checksum.
|
||||
|
||||
- Added Sniffer support to set interface to promiscuous mode.
|
||||
|
||||
- TCPStreamFollower now handles overlapping fragments correctly.
|
||||
|
||||
- Fixed bugs in TCPStreamFollower which didn't allow it to follow
|
||||
stream correctly.
|
||||
|
||||
- TCPStreamFollower now doesn't clear its state after every call to
|
||||
TCPStreamFollower::follow_streams.
|
||||
|
||||
- Added IPv6 flag check to pdu_flag_to_ip_type.
|
||||
|
||||
- Added DHCP::hostname to extract the hostname options.
|
||||
|
||||
- Removed extra qualifier on SessionKeys::decrypt_unicast which
|
||||
produced compilation errors on some platforms.
|
||||
|
||||
- PacketSender::send now uses PDU::matches_flag to match specific
|
||||
PDU types.
|
||||
|
||||
- Removed 'no newline at end of file' warnings.
|
||||
|
||||
- Fixed bug when calling BIOCIMMEDIATE on *BSD.
|
||||
|
||||
- Fixed bug on PacketSender::send_recv which didn't work under *BSD.
|
||||
|
||||
- Fixed bug triggered by not including the string header.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v2.0 - Thu Jan 23 11:09:38 ART 2014
|
||||
|
||||
- DNSResourceRecord was removed. Now DNS records are added using
|
||||
DNS::Resource.
|
||||
|
||||
- tins.h now includes ppi.h.
|
||||
|
||||
- Done significant improvements in the speed of DNS parsing.
|
||||
|
||||
- Added PDUOption<>::to<> which converts a PDUOption to a specific type.
|
||||
|
||||
- Layer 3 packets sent using PacketSender::send_recv for which the
|
||||
answer is a different PDU type.
|
||||
|
||||
- ICMP::gateway now uses IPv4Address.
|
||||
|
||||
- Added support for ICMP address mask request/reply.
|
||||
|
||||
- Fixed bug in PacketSender when using send_recv and a layer 2 PDU. The
|
||||
interface in which the packet was sent was not the default_interface
|
||||
set when the sender was constructed.
|
||||
|
||||
- IP packets sent using PacketSender::send_recv now match ICMP
|
||||
responses.
|
||||
|
||||
- Added support for ICMP timestamp request/reply packets.
|
||||
ICMP::matches_response now works with these types of packets as well.
|
||||
|
||||
- Added support for reassembling of fragmented IP packets via the
|
||||
IPv4Reassembler class.
|
||||
|
||||
- Fragmented IP packet's inner_pdu PDUs are not decoded now.
|
||||
|
||||
- Added 1000ms as the default read timeout used when calling
|
||||
pcap_open_live. Added BaseSniffer::set_timeout to modify this parameter.
|
||||
|
||||
- Added the --disable-dot11 configure switch.
|
||||
|
||||
- Added support for IPSec.
|
||||
|
||||
- Fixed bug triggered when ifaddrs::ifa_addr was null in
|
||||
NetworkInterface::addresses.
|
||||
|
||||
- Added another overload of Utils::route_entries which returns the
|
||||
result either than storing it in a parameter.
|
||||
|
||||
- Added ARP monitor, WPS detector, DNS queries sniffer and DNS spoofer
|
||||
examples.
|
||||
|
||||
- Added another Sniffer constructor which doesn't expect the maximum
|
||||
capture size.
|
||||
|
||||
- Added tins_cast as a replacement for dynamic_cast on PDUs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v1.2 - Mon oct 7 23:33:49 ART 2013
|
||||
|
||||
- Added BaseSniffer::begin and BaseSniffer::end.
|
||||
|
||||
- BaseSniffer::next_packet uses pcap_loop instead of pcap_next, which
|
||||
doesn't work well on some linux distributions.
|
||||
|
||||
- Added PPI PDU class.
|
||||
|
||||
- Fixed a bug in EthernetII triggered when the size of the whole frame
|
||||
was lower than 60 bytes.
|
||||
|
||||
- Added AddressRange class and IPv4Address, IPv6Address and
|
||||
HWAddress<>::operator/.
|
||||
|
||||
- Added is_broadcast, is_multicast and is_unicast to IPv4, IPv6
|
||||
and HWAddress.
|
||||
|
||||
- Added is_private and is_loopback methods to IPv4 and IPv6 addresses.
|
||||
|
||||
- Done some optimizations on TCP's constructor from buffer.
|
||||
|
||||
- Added helper functions to Dot11Data to retrieve the source,
|
||||
destination and BSSID addresses.
|
||||
|
||||
- Fixed bugs in DNS triggered when parsing MX and unknown records.
|
||||
|
||||
- BaseSniffer::next_packet now iterates until a valid packet is found.
|
||||
|
||||
- TCP::get_flag is now const.
|
||||
|
||||
- The --disable-wpa2 now works as expected.
|
||||
|
||||
v1.1 - Wed Jun 5 09:03:37 ART 2013
|
||||
|
||||
- Implemented std::hash specialization for IPv4, IPv6 and HWAddress<>
|
||||
types.
|
||||
|
||||
- Added a RSNHandshakeCapturer class.
|
||||
|
||||
- Added WPA2Decrypter class.
|
||||
|
||||
- IEEE 802.11 frames are not parsed if the RadioTap FAILED_FCS flag
|
||||
is on.
|
||||
|
||||
- RadioTap now calculates its size everytime it's serialized.
|
||||
|
||||
- Splitted the dot11.h and dot11.cpp files into several files to
|
||||
speed up compilation times.
|
||||
|
||||
- Added HWAddress<>::is_broadcast and HWAddress::operator[].
|
||||
|
||||
- Fixed a bug triggered when parsing Dot11QoSData frames.
|
||||
|
||||
v1.0 - Tue Apr 23 20:40:57 ART 2013
|
||||
|
||||
- Link layer protocol PDUs now don't hold a NetworkInterface. This led
|
||||
to changes in their constructors.
|
||||
|
||||
- Removed the obsolete PDU* parameter taken by several classes'
|
||||
constructors.
|
||||
|
||||
- IP now sets the sender's address automatically when no link layer
|
||||
PDU is used.
|
||||
|
||||
- IP, TCP and UDP now calculate the checksum everytime they're
|
||||
serialized.
|
||||
|
||||
- Added PDU::rfind_pdu.
|
||||
|
||||
- Defined several exception types.
|
||||
|
||||
- Implemented matches_response on several protocols.
|
||||
|
||||
- PacketSender is now movable.
|
||||
|
||||
- Added an overload of add_option that takes an rvalue-reference in IP,
|
||||
TCP, DHCP, ICMPv6 and Dot11.
|
||||
|
||||
- Added support for GNU/kFreeBSD.
|
||||
|
||||
- Removed several deprecated methods, such as PDU::clone_packet.
|
||||
|
||||
- Added PacketSender::send(PDU&, NetworkInterface).
|
||||
|
||||
- Normalized the TLV options naming conventions in all of the classes
|
||||
that used them.
|
||||
|
||||
- Added support for Dot1Q, STP, PPPoE protocols.
|
||||
|
||||
- Made some important optimizations on PDUOption<>'s constructors.
|
||||
|
||||
- Added Utils::resolve_domain and Utils::resolve_domain6
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v0.3 - Thu Jan 31 16:47:27 ART 2013
|
||||
|
||||
- Added IPv6, ICMPv6 and DHCPv6 classes.
|
||||
|
||||
- Added support for Loopback interfaces and the Linux Crooked Capture
|
||||
pseudo protocol.
|
||||
|
||||
- Added support for IPv6 records in DNS.
|
||||
|
||||
- Added Packet/RefPacket class.
|
||||
|
||||
- Added support for FreeBSD, OSX and Windows.
|
||||
|
||||
- Added C++11 move semantics to several classes.
|
||||
|
||||
- Done a complete rewrite of the build system; it now uses libtool.
|
||||
|
||||
- Fixed several bugs in DNS.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v0.2 - Sat Oct 20 11:26:40 2012
|
||||
|
||||
- Added support for big endian architectures.
|
||||
|
||||
- Simplified several interfaces.
|
||||
|
||||
- Added IPv4Address and HWAddress class to simplify handling IP and hardware addresses.
|
||||
|
||||
- Added NetworkInterface class to abstract network interfaces.
|
||||
|
||||
- Added TCPStreamFollower class to follow TCP streams on the fly.
|
||||
|
||||
- Added WEPDecrypter class to decrypt WEP-encrypted 802.11 data frames on the fly.
|
||||
|
||||
- Added several new PDUs: Loopback, IEEE802_3, LLC, DNS.
|
||||
|
||||
- Added support for reading and writing pcap files.
|
||||
|
||||
- Moved to BSD-2 license.
|
361
lib/libtins/CMakeLists.txt
Normal file
361
lib/libtins/CMakeLists.txt
Normal file
@ -0,0 +1,361 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.1)
|
||||
PROJECT(libtins)
|
||||
|
||||
OPTION(LIBTINS_BUILD_EXAMPLES "Build examples" ON)
|
||||
OPTION(LIBTINS_BUILD_TESTS "Build tests" ON)
|
||||
|
||||
# Compile in release mode by default
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
MESSAGE(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
ELSE(NOT CMAKE_BUILD_TYPE)
|
||||
MESSAGE(STATUS "Using specified '${CMAKE_BUILD_TYPE}' build type.")
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Compilation flags.
|
||||
IF(MSVC)
|
||||
# Don't always use Wall, since VC's /Wall is ridiculously verbose.
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||
# Disable VC secure checks, since these are not really issues.
|
||||
ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS=1")
|
||||
ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS=1")
|
||||
ADD_DEFINITIONS("-DNOGDI=1")
|
||||
ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
ENDIF()
|
||||
|
||||
IF(APPLE)
|
||||
# This is set to ON as of policy CMP0042
|
||||
SET(CMAKE_MACOSX_RPATH ON)
|
||||
ENDIF()
|
||||
|
||||
# Build output checks
|
||||
OPTION(LIBTINS_BUILD_SHARED "Build libtins as a shared library." ON)
|
||||
IF(LIBTINS_BUILD_SHARED)
|
||||
MESSAGE(
|
||||
STATUS
|
||||
"Build will generate a shared library. "
|
||||
"Use LIBTINS_BUILD_SHARED=0 to perform a static build"
|
||||
)
|
||||
SET(LIBTINS_TYPE SHARED)
|
||||
ELSE(LIBTINS_BUILD_SHARED)
|
||||
MESSAGE(STATUS "Build will generate a static library.")
|
||||
SET(LIBTINS_TYPE STATIC)
|
||||
ADD_DEFINITIONS("-DTINS_STATIC=1")
|
||||
ENDIF(LIBTINS_BUILD_SHARED)
|
||||
|
||||
# The version number.
|
||||
SET(TINS_VERSION_MAJOR 4)
|
||||
SET(TINS_VERSION_MINOR 5)
|
||||
SET(TINS_VERSION_PATCH 0)
|
||||
SET(LIBTINS_VERSION "${TINS_VERSION_MAJOR}.${TINS_VERSION_MINOR}")
|
||||
|
||||
# Required Packages
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
# Allow disabling packet capture mechanism
|
||||
OPTION(LIBTINS_ENABLE_PCAP "Enable capturing packets via libpcap" ON)
|
||||
|
||||
# Look for libpcap
|
||||
IF(LIBTINS_ENABLE_PCAP)
|
||||
FIND_PACKAGE(PCAP REQUIRED)
|
||||
SET(TINS_HAVE_PCAP ON)
|
||||
ENDIF()
|
||||
|
||||
# Set some Windows specific flags
|
||||
IF(WIN32)
|
||||
# We need to link against these libs
|
||||
SET(LIBTINS_OS_LIBS Ws2_32.lib Iphlpapi.lib)
|
||||
|
||||
# Add the NOMINMAX macro to avoid Windows' min and max macros.
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
|
||||
# MinWG need some extra definitions to compile properly (WIN32 for PCAP and WIN32_WINNT version for ws2tcpip.h)
|
||||
IF(MINGW)
|
||||
ADD_DEFINITIONS(-DWIN32)
|
||||
MACRO(get_WIN32_WINNT version)
|
||||
IF (WIN32 AND CMAKE_SYSTEM_VERSION)
|
||||
SET(ver ${CMAKE_SYSTEM_VERSION})
|
||||
STRING(REPLACE "." "" ver ${ver})
|
||||
STRING(REGEX REPLACE "([0-9])" "0\\1" ver ${ver})
|
||||
SET(${version} "0x${ver}")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
get_WIN32_WINNT(ver)
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=${ver})
|
||||
ENDIF(MINGW)
|
||||
|
||||
ENDIF(WIN32)
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
|
||||
# *******************
|
||||
# Compilation options
|
||||
# *******************
|
||||
|
||||
# Always check for C++ features
|
||||
INCLUDE(CheckCXXFeatures)
|
||||
|
||||
IF(HAS_GCC_BUILTIN_SWAP)
|
||||
SET(TINS_HAVE_GCC_BUILTIN_SWAP ON)
|
||||
ENDIF()
|
||||
|
||||
# C++11 support
|
||||
OPTION(LIBTINS_ENABLE_CXX11 "Compile libtins with c++11 features" ON)
|
||||
IF(LIBTINS_ENABLE_CXX11)
|
||||
# We only use declval and decltype on gcc/clang as VC fails to build that code,
|
||||
# at least on VC2013
|
||||
IF(HAS_CXX11_RVALUE_REFERENCES AND HAS_CXX11_FUNCTIONAL AND HAS_CXX11_CHRONO AND
|
||||
HAS_CXX11_NOEXCEPT AND ((HAS_CXX11_DECLVAL AND HAS_CXX11_DECLTYPE) OR MSVC))
|
||||
SET(TINS_HAVE_CXX11 ON)
|
||||
MESSAGE(STATUS "Enabling C++11 features")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "The compiler doesn't support the necessary C++11 features. "
|
||||
"Disabling C++11 on this build")
|
||||
ENDIF()
|
||||
ELSE(LIBTINS_ENABLE_CXX11)
|
||||
MESSAGE(
|
||||
WARNING
|
||||
"Disabling C++11 features. Use LIBTINS_ENABLE_CXX11=1 to enable them. "
|
||||
"Unless you are using an old compiler, you should enable this option, "
|
||||
"as it increases the library's performance")
|
||||
ENDIF(LIBTINS_ENABLE_CXX11)
|
||||
|
||||
# IEEE 802.11 and WPA2 decryption support
|
||||
OPTION(LIBTINS_ENABLE_DOT11 "Compile libtins with IEEE 802.11 support" ON)
|
||||
OPTION(LIBTINS_ENABLE_WPA2 "Compile libtins with WPA2 decryption features (requires OpenSSL)" ON)
|
||||
IF(LIBTINS_ENABLE_DOT11)
|
||||
SET(TINS_HAVE_DOT11 ON)
|
||||
MESSAGE(STATUS "Enabling IEEE 802.11 support.")
|
||||
IF(LIBTINS_ENABLE_WPA2)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
IF(OPENSSL_FOUND)
|
||||
SET(TINS_HAVE_WPA2_DECRYPTION ON)
|
||||
MESSAGE(STATUS "Enabling WPA2 decryption support.")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling WPA2 decryption support since OpenSSL was not found")
|
||||
# Default this to empty strings
|
||||
SET(OPENSSL_INCLUDE_DIR "")
|
||||
SET(OPENSSL_LIBRARIES "")
|
||||
ENDIF()
|
||||
ELSE(LIBTINS_ENABLE_WPA2)
|
||||
MESSAGE(STATUS "Disabling WPA2 decryption support.")
|
||||
ENDIF(LIBTINS_ENABLE_WPA2)
|
||||
ENDIF(LIBTINS_ENABLE_DOT11)
|
||||
|
||||
# Optionally enable TCPIP classes (on by default)
|
||||
OPTION(LIBTINS_ENABLE_TCPIP "Enable TCPIP classes" ON)
|
||||
IF(LIBTINS_ENABLE_TCPIP AND TINS_HAVE_CXX11)
|
||||
SET(TINS_HAVE_TCPIP ON)
|
||||
MESSAGE(STATUS "Enabling TCPIP classes")
|
||||
ELSE()
|
||||
SET(TINS_HAVE_TCPIP OFF)
|
||||
MESSAGE(STATUS "Disabling TCPIP classes")
|
||||
ENDIF()
|
||||
|
||||
# Search for libboost
|
||||
FIND_PACKAGE(Boost)
|
||||
|
||||
# Optionally enable the ACK tracker (on by default)
|
||||
OPTION(LIBTINS_ENABLE_ACK_TRACKER "Enable TCP ACK tracking support" ON)
|
||||
IF(LIBTINS_ENABLE_ACK_TRACKER AND TINS_HAVE_CXX11)
|
||||
IF (Boost_FOUND)
|
||||
MESSAGE(STATUS "Enabling TCP ACK tracking support.")
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
SET(TINS_HAVE_ACK_TRACKER ON)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling ACK tracking support as boost.icl was not found")
|
||||
SET(TINS_HAVE_ACK_TRACKER OFF)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(TINS_HAVE_ACK_TRACKER OFF)
|
||||
MESSAGE(STATUS "Disabling ACK tracking support")
|
||||
ENDIF()
|
||||
|
||||
# Optionally enable the TCP stream custom data (on by default)
|
||||
OPTION(LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA "Enable TCP stream custom data support" ON)
|
||||
IF(LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA AND TINS_HAVE_CXX11)
|
||||
IF (Boost_FOUND)
|
||||
MESSAGE(STATUS "Enabling TCP stream custom data support.")
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA ON)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling TCP stream custom data support as boost.any was not found")
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA OFF)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(TINS_HAVE_TCP_STREAM_CUSTOM_DATA OFF)
|
||||
MESSAGE(STATUS "Disabling TCP stream custom data support")
|
||||
ENDIF()
|
||||
|
||||
OPTION(LIBTINS_ENABLE_WPA2_CALLBACKS "Enable WPA2 callback interface" ON)
|
||||
IF(LIBTINS_ENABLE_WPA2_CALLBACKS AND TINS_HAVE_WPA2_DECRYPTION AND TINS_HAVE_CXX11)
|
||||
SET(STATUS "Enabling WPA2 callback interface")
|
||||
SET(TINS_HAVE_WPA2_CALLBACKS ON)
|
||||
ENDIF()
|
||||
|
||||
# Use pcap_sendpacket to send l2 packets rather than raw sockets
|
||||
IF(WIN32)
|
||||
SET(USE_PCAP_SENDPACKET_DEFAULT ON)
|
||||
ELSE(WIN32)
|
||||
SET(USE_PCAP_SENDPACKET_DEFAULT OFF)
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(LIBTINS_USE_PCAP_SENDPACKET "Use pcap_sendpacket to send l2 packets"
|
||||
${USE_PCAP_SENDPACKET_DEFAULT})
|
||||
IF(LIBTINS_ENABLE_PCAP AND LIBTINS_USE_PCAP_SENDPACKET)
|
||||
SET(TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET ON)
|
||||
MESSAGE(STATUS "Using pcap_sendpacket to send l2 packets.")
|
||||
ENDIF()
|
||||
|
||||
# Add a target to generate API documentation using Doxygen
|
||||
FIND_PACKAGE(Doxygen QUIET)
|
||||
IF(DOXYGEN_FOUND)
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
@ONLY
|
||||
)
|
||||
ADD_CUSTOM_TARGET(
|
||||
docs
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
||||
)
|
||||
ENDIF(DOXYGEN_FOUND)
|
||||
|
||||
# Configuration file
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/include/tins/config.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/include/tins/config.h"
|
||||
)
|
||||
|
||||
IF (NOT CMAKE_INSTALL_LIBDIR)
|
||||
SET(CMAKE_INSTALL_LIBDIR lib)
|
||||
ENDIF()
|
||||
IF (NOT CMAKE_INSTALL_BINDIR)
|
||||
SET(CMAKE_INSTALL_BINDIR bin)
|
||||
ENDIF()
|
||||
# The library output directory
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
# Support for pkg-config
|
||||
SET(pkgconfig_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(pkgconfig_exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
SET(pkgconfig_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(pkgconfig_version ${LIBTINS_VERSION})
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libtins.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libtins.pc @ONLY)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libtins.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
|
||||
# Confiugure the uninstall script
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY
|
||||
)
|
||||
|
||||
# Add uninstall target
|
||||
ADD_CUSTOM_TARGET(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
# ******************
|
||||
# Add subdirectories
|
||||
# ******************
|
||||
ADD_SUBDIRECTORY(src)
|
||||
|
||||
IF(LIBTINS_BUILD_EXAMPLES)
|
||||
IF(LIBTINS_ENABLE_PCAP)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Not building examples as pcap support is disabled")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LIBTINS_BUILD_TESTS)
|
||||
# Only include googletest if the git submodule has been fetched
|
||||
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/googletest/CMakeLists.txt")
|
||||
# Enable tests and add the test directory
|
||||
MESSAGE(STATUS "Tests have been enabled")
|
||||
SET(GOOGLETEST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||
SET(GOOGLETEST_INCLUDE ${GOOGLETEST_ROOT}/googletest/include)
|
||||
SET(GOOGLETEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/googletest)
|
||||
SET(GOOGLETEST_LIBRARY ${GOOGLETEST_BINARY_DIR}/googletest)
|
||||
|
||||
ExternalProject_Add(
|
||||
googletest
|
||||
DOWNLOAD_COMMAND ""
|
||||
SOURCE_DIR ${GOOGLETEST_ROOT}
|
||||
BINARY_DIR ${GOOGLETEST_BINARY_DIR}
|
||||
CMAKE_CACHE_ARGS "-DBUILD_GTEST:bool=ON" "-DBUILD_GMOCK:bool=OFF"
|
||||
"-Dgtest_force_shared_crt:bool=ON"
|
||||
"-DCMAKE_CXX_COMPILER:path=${CMAKE_CXX_COMPILER}"
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
# Make sure we build googletest before anything else
|
||||
ADD_DEPENDENCIES(tins googletest)
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ELSE()
|
||||
FIND_PACKAGE(GTest QUIET)
|
||||
IF(${GTest_FOUND})
|
||||
ENABLE_TESTING()
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "googletest git submodule is absent. Run `git submodule init && git submodule update` to get it")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# **********************************
|
||||
# CMake project configuration export
|
||||
# **********************************
|
||||
|
||||
if(UNIX)
|
||||
set(CONF_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/libtins")
|
||||
else()
|
||||
set(CONF_CMAKE_INSTALL_DIR CMake)
|
||||
endif()
|
||||
|
||||
# Add all targets to the build-tree export set
|
||||
EXPORT(
|
||||
TARGETS tins
|
||||
FILE "${PROJECT_BINARY_DIR}/libtinsTargets.cmake"
|
||||
)
|
||||
|
||||
# Export the package for use from the build-tree
|
||||
# (this registers the build-tree with a global CMake-registry)
|
||||
EXPORT(PACKAGE libtins)
|
||||
|
||||
# Create the libtinsConfig.cmake and libtinsConfigVersion.cmake files
|
||||
# for the build tree
|
||||
SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
|
||||
CONFIGURE_FILE(
|
||||
cmake/libtinsConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfig.cmake" @ONLY
|
||||
)
|
||||
CONFIGURE_FILE(
|
||||
cmake/libtinsConfigVersion.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake" @ONLY
|
||||
)
|
||||
# Install the libtinsConfig.cmake and libtinsConfigVersion.cmake
|
||||
INSTALL(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfig.cmake"
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake"
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
# Install the export set for use with the install-tree
|
||||
INSTALL(
|
||||
EXPORT libtinsTargets
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
27
lib/libtins/CONTRIBUTING.md
Normal file
27
lib/libtins/CONTRIBUTING.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Contributing
|
||||
|
||||
Bug reports and enhancements to the library are really valued and appreciated!
|
||||
|
||||
# Bug reports
|
||||
|
||||
If you find a bug, please report it! Bugs on the library are taken seriously
|
||||
and a patch for them is usually pushed on the same day.
|
||||
|
||||
When reporting a bug, please make sure to indicate the platform (e.g. GNU/Linux, Windows, OSX)
|
||||
in which you came across the issue, as this is essential to finding the cause.
|
||||
|
||||
## Packet parsing bugs
|
||||
|
||||
If you find a bug related to packet parsing (e.g. a field on a packet contains an
|
||||
invalid value), please try to provide a pcap file that contains the packet that
|
||||
was incorrectly parsed. Doing this will make it very simple to find the issue, plus
|
||||
you will be asked to provide this file anyway, so this just makes things
|
||||
easier.
|
||||
|
||||
# Pull requests
|
||||
|
||||
Pull requests are very welcomed. When doing a pull request please:
|
||||
|
||||
* Notice that your code will be compiled and tests will be run automatically by the travis and
|
||||
appveyor CI tools. If your code has issues on any of the tested platforms (GNU/Linux, Windows
|
||||
and OSX), please fix it or otherwise the PR won't be merged.
|
25
lib/libtins/LICENSE
Normal file
25
lib/libtins/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2012-2017, Matias Fontanini
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
147
lib/libtins/README.md
Normal file
147
lib/libtins/README.md
Normal file
@ -0,0 +1,147 @@
|
||||
# libtins
|
||||
|
||||
[](https://travis-ci.org/mfontanini/libtins)
|
||||
[](https://ci.appveyor.com/project/mfontanini/libtins/branch/master)
|
||||
|
||||
libtins is a high-level, multiplatform C++ network packet sniffing and
|
||||
crafting library.
|
||||
|
||||
Its main purpose is to provide the C++ developer an easy, efficient,
|
||||
platform and endianess-independent way to create tools which need to
|
||||
send, receive and manipulate specially crafted packets.
|
||||
|
||||
In order to read tutorials, examples and checkout some benchmarks of the
|
||||
library, please visit:
|
||||
|
||||
http://libtins.github.io/
|
||||
|
||||
## Compiling ##
|
||||
|
||||
[libtins](http://libtins.github.io/) depends on
|
||||
[libpcap](http://www.tcpdump.org/) and
|
||||
[openssl](http://www.openssl.org/), although the latter is not necessary
|
||||
if some features of the library are disabled.
|
||||
|
||||
In order to compile, execute:
|
||||
|
||||
```Shell
|
||||
# Create the build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Configure the project. Add any relevant configuration flags
|
||||
cmake ../
|
||||
|
||||
# Compile!
|
||||
make
|
||||
```
|
||||
|
||||
### Static/shared build
|
||||
Note that by default, only the shared object is compiled. If you would
|
||||
like to generate a static library file, run:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_BUILD_SHARED=0
|
||||
```
|
||||
|
||||
The generated static/shared library files will be located in the
|
||||
_build/lib_ directory.
|
||||
|
||||
### C++11 support
|
||||
|
||||
libtins is noticeably faster if you enable _C++11_ support. Therefore,
|
||||
if your compiler supports this standard, then you should enable it.
|
||||
In order to do so, use the _LIBTINS_ENABLE_CXX11_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_CXX11=1
|
||||
```
|
||||
|
||||
### TCP ACK tracker
|
||||
|
||||
The TCP ACK tracker feature requires the boost.icl library (header only).
|
||||
This feature is enabled by default but will be disabled if the boost
|
||||
headers are not found. You can disable this feature by using:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_ACK_TRACKER=0
|
||||
```
|
||||
|
||||
If your boost installation is on some non-standard path, use
|
||||
the parameters shown on the
|
||||
[CMake FindBoost help](https://cmake.org/cmake/help/v3.0/module/FindBoost.html)
|
||||
|
||||
### WPA2 decryption
|
||||
|
||||
If you want to disable _WPA2_ decryption support, which will remove
|
||||
openssl as a dependency for compilation, use the
|
||||
_LIBTINS_ENABLE_WPA2_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_WPA2=0
|
||||
```
|
||||
|
||||
### IEEE 802.11 support
|
||||
|
||||
If you want to disable IEEE 802.11 support(this will also disable
|
||||
RadioTap and WPA2 decryption), which will reduce the size of the
|
||||
resulting library in around 20%, use the _LIBTINS_ENABLE_DOT11_ switch:
|
||||
|
||||
```Shell
|
||||
cmake ../ -DLIBTINS_ENABLE_DOT11=0
|
||||
```
|
||||
|
||||
## Installing ##
|
||||
|
||||
Once you're done, if you want to install the header files and the
|
||||
shared object, execute as root:
|
||||
|
||||
```Shell
|
||||
make install
|
||||
```
|
||||
|
||||
This will install the shared object typically in _/usr/local/lib_. Note
|
||||
that you might have to update ldconfig's cache before using it, so
|
||||
in order to invalidate it, you should run(as root):
|
||||
|
||||
```Shell
|
||||
ldconfig
|
||||
```
|
||||
|
||||
## Running tests ##
|
||||
|
||||
You may want to run the unit tests on your system so you make sure
|
||||
everything works. In order to do so, you need to follow these steps:
|
||||
|
||||
```Shell
|
||||
# This will fetch the googletest submodule, needed for tests
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Use any options you want
|
||||
cmake ..
|
||||
|
||||
# Compile tests
|
||||
make tests
|
||||
|
||||
# Run them
|
||||
make test
|
||||
```
|
||||
|
||||
If you find that any tests fail, please create an ticket in the
|
||||
issue tracker indicating the platform and architecture you're using.
|
||||
|
||||
## Examples ##
|
||||
|
||||
You might want to have a look at the examples located in the "examples"
|
||||
directory. The same samples can be found online at:
|
||||
|
||||
http://libtins.github.io/examples/
|
||||
|
||||
## Contributing ##
|
||||
|
||||
If you want to report a bug or make a pull request, please have a look at
|
||||
the [contributing](CONTRIBUTING.md) file before doing so.
|
4
lib/libtins/THANKS
Normal file
4
lib/libtins/THANKS
Normal file
@ -0,0 +1,4 @@
|
||||
We'd like to thank the following people, who have been of great help
|
||||
through the development of libtins:
|
||||
|
||||
- Raúl Benencia <rbenencia@gmail.com> - For creating the Debian package.
|
135
lib/libtins/cmake/Modules/CheckCXXFeatures.cmake
Normal file
135
lib/libtins/cmake/Modules/CheckCXXFeatures.cmake
Normal file
@ -0,0 +1,135 @@
|
||||
# - Check which parts of the C++11 standard the compiler supports
|
||||
#
|
||||
# When found it will set the following variables
|
||||
#
|
||||
# CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features
|
||||
#
|
||||
# HAS_CXX11_AUTO - auto keyword
|
||||
# HAS_CXX11_AUTO_RET_TYPE - function declaration with deduced return types
|
||||
# HAS_CXX11_CLASS_OVERRIDE - override and final keywords for classes and methods
|
||||
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
||||
# HAS_CXX11_CSTDINT_H - cstdint header
|
||||
# HAS_CXX11_DECLTYPE - decltype keyword
|
||||
# HAS_CXX11_DECLVAL - declval feature
|
||||
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
||||
# HAS_CXX11_INITIALIZER_LIST - initializer list
|
||||
# HAS_CXX11_LAMBDA - lambdas
|
||||
# HAS_CXX11_LIB_REGEX - regex library
|
||||
# HAS_CXX11_LONG_LONG - long long signed & unsigned types
|
||||
# HAS_CXX11_NULLPTR - nullptr
|
||||
# HAS_CXX11_RVALUE_REFERENCES - rvalue references
|
||||
# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members
|
||||
# HAS_CXX11_STATIC_ASSERT - static_assert()
|
||||
# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011,2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||
# Copyright 2012 Andreas Weis
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
#
|
||||
# Each feature may have up to 3 checks, every one of them in it's own file
|
||||
# FEATURE.cpp - example that must build and return 0 when run
|
||||
# FEATURE_fail.cpp - example that must build, but may not return 0 when run
|
||||
# FEATURE_fail_compile.cpp - example that must fail compilation
|
||||
#
|
||||
# The first one is mandatory, the latter 2 are optional and do not depend on
|
||||
# each other (i.e. only one may be present).
|
||||
#
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILER_LOADED)
|
||||
message(FATAL_ERROR "CheckCXX11Features modules only works if language CXX is enabled")
|
||||
endif ()
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
|
||||
#
|
||||
### Check for needed compiler flags
|
||||
#
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("-std=c++11" _HAS_CXX11_FLAG)
|
||||
if (NOT _HAS_CXX11_FLAG)
|
||||
check_cxx_compiler_flag("-std=c++0x" _HAS_CXX0X_FLAG)
|
||||
endif ()
|
||||
|
||||
if (_HAS_CXX11_FLAG)
|
||||
set(CXX11_COMPILER_FLAGS "-std=c++11")
|
||||
elseif (_HAS_CXX0X_FLAG)
|
||||
set(CXX11_COMPILER_FLAGS "-std=c++0x")
|
||||
endif ()
|
||||
|
||||
function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
||||
if (NOT DEFINED ${RESULT_VAR})
|
||||
set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${FEATURE_NAME}")
|
||||
|
||||
set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXXFeatures/cxx-test-${FEATURE_NAME})
|
||||
set(_LOG_NAME "\"${FEATURE_NAME}\"")
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}")
|
||||
|
||||
set(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
||||
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
||||
set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
else (CMAKE_CROSSCOMPILING)
|
||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
||||
"${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
else (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
endif (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
||||
"${_bindir}_fail" "${_SRCFILE_FAIL}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
else (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
endif (CMAKE_CROSSCOMPILING)
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (_TMP_RESULT)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
else (_TMP_RESULT)
|
||||
set(${RESULT_VAR} TRUE)
|
||||
endif (_TMP_RESULT)
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||
|
||||
if (${RESULT_VAR})
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}: works")
|
||||
else (${RESULT_VAR})
|
||||
message(STATUS "Checking C++ support for ${_LOG_NAME}: not supported")
|
||||
endif (${RESULT_VAR})
|
||||
set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++ support for ${_LOG_NAME}")
|
||||
endif (NOT DEFINED ${RESULT_VAR})
|
||||
endfunction(cxx11_check_feature)
|
||||
|
||||
cxx11_check_feature("decltype" HAS_CXX11_DECLTYPE)
|
||||
cxx11_check_feature("declval" HAS_CXX11_DECLVAL)
|
||||
cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST)
|
||||
cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES)
|
||||
cxx11_check_feature("functional" HAS_CXX11_FUNCTIONAL)
|
||||
cxx11_check_feature("chrono" HAS_CXX11_CHRONO)
|
||||
cxx11_check_feature("noexcept" HAS_CXX11_NOEXCEPT)
|
||||
cxx11_check_feature("builtin-swap" HAS_GCC_BUILTIN_SWAP)
|
@ -0,0 +1,8 @@
|
||||
int main(void)
|
||||
{
|
||||
if (!__func__)
|
||||
return 1;
|
||||
if (!(*__func__))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
12
lib/libtins/cmake/Modules/CheckCXXFeatures/cxx-test-auto.cpp
Normal file
12
lib/libtins/cmake/Modules/CheckCXXFeatures/cxx-test-auto.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
auto i = 5;
|
||||
auto f = 3.14159f;
|
||||
auto d = 3.14159;
|
||||
bool ret = (
|
||||
(sizeof(f) < sizeof(d)) &&
|
||||
(sizeof(i) == sizeof(int))
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
int main(void)
|
||||
{
|
||||
// must fail because there is no initializer
|
||||
auto i;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
auto foo(int i) -> int {
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo(1);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
int main() {
|
||||
uint16_t u16 = __builtin_bswap16(0x9812U);
|
||||
uint32_t u32 = __builtin_bswap32(0x9812ad81U);
|
||||
uint64_t u64 = __builtin_bswap64(0x9812ad81f61a890dU);
|
||||
return (u16 > 0 && u32 > 0 && u64 > 0) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
int main() {
|
||||
system_clock::time_point tp = system_clock::now();
|
||||
milliseconds ms = duration_cast<milliseconds>(tp.time_since_epoch());
|
||||
return (ms.count() > 0) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
class base {
|
||||
public:
|
||||
virtual int foo(int a)
|
||||
{ return 4 + a; }
|
||||
int bar(int a) final
|
||||
{ return a - 2; }
|
||||
};
|
||||
|
||||
class sub final : public base {
|
||||
public:
|
||||
virtual int foo(int a) override
|
||||
{ return 8 + 2 * a; };
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
base b;
|
||||
sub s;
|
||||
|
||||
return (b.foo(2) * 2 == s.foo(2)) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
class base {
|
||||
public:
|
||||
virtual int foo(int a)
|
||||
{ return 4 + a; }
|
||||
virtual int bar(int a) final
|
||||
{ return a - 2; }
|
||||
};
|
||||
|
||||
class sub final : public base {
|
||||
public:
|
||||
virtual int foo(int a) override
|
||||
{ return 8 + 2 * a; };
|
||||
virtual int bar(int a)
|
||||
{ return a; }
|
||||
};
|
||||
|
||||
class impossible : public sub { };
|
||||
|
||||
int main(void)
|
||||
{
|
||||
base b;
|
||||
sub s;
|
||||
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
constexpr int square(int x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
constexpr int the_answer()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int test_arr[square(3)];
|
||||
bool ret = (
|
||||
(square(the_answer()) == 1764) &&
|
||||
(sizeof(test_arr)/sizeof(test_arr[0]) == 9)
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include <cstdint>
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test =
|
||||
(sizeof(int8_t) == 1) &&
|
||||
(sizeof(int16_t) == 2) &&
|
||||
(sizeof(int32_t) == 4) &&
|
||||
(sizeof(int64_t) == 8);
|
||||
return test ? 0 : 1;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
bool check_size(int i)
|
||||
{
|
||||
return sizeof(int) == sizeof(decltype(i));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool ret = check_size(42);
|
||||
return ret ? 0 : 1;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
// Example code taken from http://en.cppreference.com/w/cpp/utility/declval
|
||||
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
struct Default { int foo() const { return 1; } };
|
||||
|
||||
struct NonDefault
|
||||
{
|
||||
NonDefault(const NonDefault&) { }
|
||||
int foo() const { return 1; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
decltype(Default().foo()) n1 = 1; // type of n1 is int
|
||||
decltype(std::declval<NonDefault>().foo()) n2 = n1; // type of n2 is int
|
||||
return (n1 == 1 && n2 == 1) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#include <functional>
|
||||
|
||||
int add(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::function<int(int, int)> func;
|
||||
func = std::bind(&add, std::placeholders::_1, std::placeholders::_2);
|
||||
return (func(2, 2) == 4) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#include <vector>
|
||||
|
||||
class seq {
|
||||
public:
|
||||
seq(std::initializer_list<int> list);
|
||||
|
||||
int length() const;
|
||||
private:
|
||||
std::vector<int> m_v;
|
||||
};
|
||||
|
||||
seq::seq(std::initializer_list<int> list)
|
||||
: m_v(list)
|
||||
{
|
||||
}
|
||||
|
||||
int seq::length() const
|
||||
{
|
||||
return m_v.size();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
seq a = {18, 20, 2, 0, 4, 7};
|
||||
|
||||
return (a.length() == 6) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
int main()
|
||||
{
|
||||
int ret = 0;
|
||||
return ([&ret]() -> int { return ret; })();
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
int main(void)
|
||||
{
|
||||
long long l;
|
||||
unsigned long long ul;
|
||||
|
||||
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
int foo() noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return foo();
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
int main(void)
|
||||
{
|
||||
void *v = nullptr;
|
||||
|
||||
return v ? 1 : 0;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
int main(void)
|
||||
{
|
||||
int i = nullptr;
|
||||
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
|
||||
int parse_line(std::string const& line)
|
||||
{
|
||||
std::string tmp;
|
||||
if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+//(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+//(-)?(\\d)+"), std::string("V"));
|
||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
||||
} else {
|
||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+"), std::string("V"));
|
||||
}
|
||||
return static_cast<int>(std::count(tmp.begin(), tmp.end(), 'V'));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
bool test = (parse_line("f 7/7/7 -3/3/-3 2/-2/2") == 3) &&
|
||||
(parse_line("f 7//7 3//-3 -2//2") == 3) &&
|
||||
(parse_line("f 7/7 3/-3 -2/2") == 3) &&
|
||||
(parse_line("f 7 3 -2") == 3);
|
||||
return test ? 0 : 1;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#include <cassert>
|
||||
|
||||
class rvmove {
|
||||
public:
|
||||
void *ptr;
|
||||
char *array;
|
||||
|
||||
rvmove()
|
||||
: ptr(0),
|
||||
array(new char[10])
|
||||
{
|
||||
ptr = this;
|
||||
}
|
||||
|
||||
rvmove(rvmove &&other)
|
||||
: ptr(other.ptr),
|
||||
array(other.array)
|
||||
{
|
||||
other.array = 0;
|
||||
other.ptr = 0;
|
||||
}
|
||||
|
||||
~rvmove()
|
||||
{
|
||||
assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0)));
|
||||
delete[] array;
|
||||
}
|
||||
|
||||
rvmove &operator=(rvmove &&other)
|
||||
{
|
||||
delete[] array;
|
||||
ptr = other.ptr;
|
||||
array = other.array;
|
||||
other.array = 0;
|
||||
other.ptr = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static rvmove create()
|
||||
{
|
||||
return rvmove();
|
||||
}
|
||||
private:
|
||||
rvmove(const rvmove &);
|
||||
rvmove &operator=(const rvmove &);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
rvmove mine;
|
||||
if (mine.ptr != &mine)
|
||||
return 1;
|
||||
mine = rvmove::create();
|
||||
if (mine.ptr == &mine)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
struct foo {
|
||||
char bar;
|
||||
int baz;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool ret = (
|
||||
(sizeof(foo::bar) == 1) &&
|
||||
(sizeof(foo::baz) >= sizeof(foo::bar)) &&
|
||||
(sizeof(foo) >= sizeof(foo::bar) + sizeof(foo::baz))
|
||||
);
|
||||
return ret ? 0 : 1;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
struct foo {
|
||||
int baz;
|
||||
double bar;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return (sizeof(foo::bar) == 4) ? 0 : 1;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
int main(void)
|
||||
{
|
||||
static_assert(0 < 1, "your ordering of integers is screwed");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
int main(void)
|
||||
{
|
||||
static_assert(1 < 0, "your ordering of integers is screwed");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
int Accumulate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
int Accumulate(T v, Ts... vs)
|
||||
{
|
||||
return v + Accumulate(vs...);
|
||||
}
|
||||
|
||||
template<int... Is>
|
||||
int CountElements()
|
||||
{
|
||||
return sizeof...(Is);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int acc = Accumulate(1, 2, 3, 4, -5);
|
||||
int count = CountElements<1,2,3,4,5>();
|
||||
return ((acc == 5) && (count == 5)) ? 0 : 1;
|
||||
}
|
85
lib/libtins/cmake/Modules/FindPCAP.cmake
Normal file
85
lib/libtins/cmake/Modules/FindPCAP.cmake
Normal file
@ -0,0 +1,85 @@
|
||||
# - Try to find libpcap include dirs and libraries
|
||||
#
|
||||
# Usage of this module as follows:
|
||||
#
|
||||
# find_package(PCAP)
|
||||
#
|
||||
# Variables used by this module, they can change the default behaviour and need
|
||||
# to be set before calling find_package:
|
||||
#
|
||||
# PCAP_ROOT_DIR Set this variable to the root installation of
|
||||
# libpcap if the module has problems finding the
|
||||
# proper installation path.
|
||||
#
|
||||
# Variables defined by this module:
|
||||
#
|
||||
# PCAP_FOUND System has libpcap, include and library dirs found
|
||||
# PCAP_INCLUDE_DIR The libpcap include directories.
|
||||
# PCAP_LIBRARY The libpcap library (possibly includes a thread
|
||||
# library e.g. required by pf_ring's libpcap)
|
||||
# HAVE_PF_RING If a found version of libpcap supports PF_RING
|
||||
# HAVE_PCAP_IMMEDIATE_MODE If the version of libpcap found supports immediate mode
|
||||
|
||||
find_path(PCAP_ROOT_DIR
|
||||
NAMES include/pcap.h
|
||||
)
|
||||
|
||||
find_path(PCAP_INCLUDE_DIR
|
||||
NAMES pcap.h
|
||||
HINTS ${PCAP_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
set (HINT_DIR ${PCAP_ROOT_DIR}/lib)
|
||||
|
||||
# On x64 windows, we should look also for the .lib at /lib/x64/
|
||||
# as this is the default path for the WinPcap developer's pack
|
||||
if (${CMAKE_SIZEOF_VOID_P} EQUAL 8 AND WIN32)
|
||||
set (HINT_DIR ${PCAP_ROOT_DIR}/lib/x64/ ${HINT_DIR})
|
||||
endif ()
|
||||
|
||||
find_library(PCAP_LIBRARY
|
||||
NAMES pcap wpcap
|
||||
HINTS ${HINT_DIR}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCAP DEFAULT_MSG
|
||||
PCAP_LIBRARY
|
||||
PCAP_INCLUDE_DIR
|
||||
)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||
check_cxx_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
# check if linking against libpcap also needs to link against a thread library
|
||||
if (NOT PCAP_LINKS_SOLO)
|
||||
find_package(Threads)
|
||||
if (THREADS_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||
check_cxx_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif (THREADS_FOUND)
|
||||
if (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||
list(REMOVE_DUPLICATES _tmp)
|
||||
set(PCAP_LIBRARY ${_tmp}
|
||||
CACHE STRING "Libraries needed to link against libpcap" FORCE)
|
||||
else (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
message(FATAL_ERROR "Couldn't determine how to link against libpcap")
|
||||
endif (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||
endif (NOT PCAP_LINKS_SOLO)
|
||||
|
||||
include(CheckFunctionExists)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||
check_function_exists(pcap_get_pfring_id HAVE_PF_RING)
|
||||
check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE)
|
||||
check_function_exists(pcap_set_tstamp_precision HAVE_PCAP_TIMESTAMP_PRECISION)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
mark_as_advanced(
|
||||
PCAP_ROOT_DIR
|
||||
PCAP_INCLUDE_DIR
|
||||
PCAP_LIBRARY
|
||||
)
|
53
lib/libtins/cmake/appveyor.yml
Normal file
53
lib/libtins/cmake/appveyor.yml
Normal file
@ -0,0 +1,53 @@
|
||||
version: 1.0.{build}
|
||||
configuration:
|
||||
- debug
|
||||
- release
|
||||
platform:
|
||||
- Win32
|
||||
- x64
|
||||
environment:
|
||||
matrix:
|
||||
- compiler: vs2013
|
||||
- compiler: vs2015
|
||||
BOOST_ROOT: C:/Libraries/boost
|
||||
clone_depth: 1
|
||||
install:
|
||||
- git clone https://github.com/mfontanini/winpcap-installer.git
|
||||
- cd winpcap-installer
|
||||
- winpcap-boundary-meter-4.1.3.exe /S
|
||||
- cd ..
|
||||
- appveyor DownloadFile http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip
|
||||
- 7z x .\WpdPack_4_1_2.zip -oc:\
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
before_build:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if "%compiler%"=="vs2013" (set VS_VERSION=12) else (set VS_VERSION=14)
|
||||
- set VS=Visual Studio %VS_VERSION%
|
||||
- if "%platform%"=="Win32" (set GENERATOR="%VS%" & set ARCH_BITS=32)
|
||||
- if "%platform%"=="x64" (set GENERATOR="%VS% Win64" & set ARCH_BITS=64)
|
||||
- set BOOST_LIBRARYDIR=C:\Libraries\boost\lib%ARCH_BITS%-msvc-%VS_VERSION%.0
|
||||
- cmake .. -G %GENERATOR% -DPCAP_ROOT_DIR=c:\WpdPack -DLIBTINS_BUILD_SHARED=0 -DLIBTINS_ENABLE_WPA2=0 -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DBoost_USE_STATIC_LIBS="ON"
|
||||
build:
|
||||
project: C:/projects/libtins/build/libtins.sln
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- mkdir install\libtins\include
|
||||
- mkdir install\libtins\lib
|
||||
- cd install\libtins
|
||||
- copy C:\projects\libtins\build\lib\%Configuration%\tins.lib lib
|
||||
- xcopy C:\projects\libtins\include include /s /e
|
||||
- del include\CMakeLists.txt
|
||||
- del include\tins\CMakeLists.txt
|
||||
- del include\tins\config.h.in
|
||||
- del include\tins\dot11\CMakeLists.txt
|
||||
- cd ..\
|
||||
- 7z a libtins-%compiler%-%platform%-%Configuration%.zip libtins
|
||||
test_script:
|
||||
- cd c:\projects\libtins\build
|
||||
- ctest -C %Configuration% -V
|
||||
deploy_script:
|
||||
- ps: Push-AppveyorArtifact "install\libtins-$env:Compiler-$env:Platform-$env:Configuration.zip"
|
||||
skip_commits:
|
||||
message: /Update documentation.*/
|
23
lib/libtins/cmake/cmake_uninstall.cmake.in
Normal file
23
lib/libtins/cmake/cmake_uninstall.cmake.in
Normal file
@ -0,0 +1,23 @@
|
||||
# Taken from https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
|
||||
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
16
lib/libtins/cmake/libtinsConfig.cmake.in
Normal file
16
lib/libtins/cmake/libtinsConfig.cmake.in
Normal file
@ -0,0 +1,16 @@
|
||||
# - Config file for the libtins package
|
||||
# It defines the following variables
|
||||
# LIBTINS_INCLUDE_DIRS - include directories for libtins
|
||||
# LIBTINS_LIBRARIES - libraries to link against
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(LIBTINS_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
set(LIBTINS_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
|
||||
|
||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||
if(NOT TARGET libtins AND NOT LIBTINS_BINARY_DIR)
|
||||
include("${LIBTINS_CMAKE_DIR}/libtinsTargets.cmake")
|
||||
endif()
|
||||
|
||||
# These are IMPORTED targets created by libtinsTargets.cmake
|
||||
set(LIBTINS_LIBRARIES tins)
|
11
lib/libtins/cmake/libtinsConfigVersion.cmake.in
Normal file
11
lib/libtins/cmake/libtinsConfigVersion.cmake.in
Normal file
@ -0,0 +1,11 @@
|
||||
set(PACKAGE_VERSION "@LIBTINS_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
1632
lib/libtins/docs/Doxyfile.in
Normal file
1632
lib/libtins/docs/Doxyfile.in
Normal file
File diff suppressed because it is too large
Load Diff
29
lib/libtins/docs/mainpage.dox
Normal file
29
lib/libtins/docs/mainpage.dox
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* \mainpage Documentation
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* <i>libtins</i> is a high-level, multiplatform <i>C++</i> network packet
|
||||
* sniffing and crafting library.
|
||||
*
|
||||
* Its main purpose is to provide the <i>C++</i> developer an easy, efficient,
|
||||
* platform and endianess-independent way to create tools which need to
|
||||
* send, receive and manipulate network packets.
|
||||
*
|
||||
* \section install_sec Installation
|
||||
*
|
||||
* Please visit the <a href="http://libtins.github.io/download/">downloads
|
||||
* section</a> in order to see the installation instructions.
|
||||
*
|
||||
* \section tutorials_sec Tutorials
|
||||
*
|
||||
* If you want to learn about how the library works, please visit the
|
||||
* <a href="http://libtins.github.io/tutorial/">tutorials</a> section.
|
||||
*
|
||||
* \section examples_sec Examples
|
||||
*
|
||||
* Make sure to visit the <a href="http://libtins.github.io/examples/">
|
||||
* examples</a> section to see some short but illustrative examples on how
|
||||
* to send and sniff packets using <i>libtins</i>.
|
||||
*
|
||||
*/
|
81
lib/libtins/examples/CMakeLists.txt
Normal file
81
lib/libtins/examples/CMakeLists.txt
Normal file
@ -0,0 +1,81 @@
|
||||
FIND_PACKAGE(Threads QUIET)
|
||||
FIND_PACKAGE(Boost COMPONENTS regex)
|
||||
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
${PCAP_INCLUDE_DIR}
|
||||
)
|
||||
LINK_LIBRARIES(tins)
|
||||
|
||||
IF(TINS_HAVE_CXX11)
|
||||
SET(LIBTINS_CXX11_EXAMPLES
|
||||
arpmonitor
|
||||
dns_queries
|
||||
dns_spoof
|
||||
dns_stats
|
||||
stream_dump
|
||||
icmp_responses
|
||||
interfaces_info
|
||||
tcp_connection_close
|
||||
traceroute
|
||||
wps_detect
|
||||
)
|
||||
IF(Boost_REGEX_FOUND)
|
||||
SET(LIBTINS_CXX11_EXAMPLES ${LIBTINS_CXX11_EXAMPLES} http_requests)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling HTTP requests example since boost.regex was not found")
|
||||
ENDIF()
|
||||
ELSE(TINS_HAVE_CXX11)
|
||||
MESSAGE(WARNING "Disabling some examples since C++11 support is disabled.")
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
|
||||
ADD_CUSTOM_TARGET(
|
||||
examples DEPENDS
|
||||
arpspoofing
|
||||
${LIBTINS_CXX11_EXAMPLES}
|
||||
beacon_display
|
||||
portscan
|
||||
route_table
|
||||
defragmenter
|
||||
)
|
||||
|
||||
# Make sure we first build libtins
|
||||
ADD_DEPENDENCIES(examples tins)
|
||||
|
||||
ADD_EXECUTABLE(arpspoofing EXCLUDE_FROM_ALL arpspoofing.cpp)
|
||||
ADD_EXECUTABLE(route_table EXCLUDE_FROM_ALL route_table.cpp)
|
||||
ADD_EXECUTABLE(defragmenter EXCLUDE_FROM_ALL defragmenter.cpp)
|
||||
IF(TINS_HAVE_CXX11)
|
||||
ADD_EXECUTABLE(arpmonitor EXCLUDE_FROM_ALL arpmonitor.cpp)
|
||||
ADD_EXECUTABLE(dns_queries EXCLUDE_FROM_ALL dns_queries.cpp)
|
||||
ADD_EXECUTABLE(dns_spoof EXCLUDE_FROM_ALL dns_spoof.cpp)
|
||||
ADD_EXECUTABLE(stream_dump EXCLUDE_FROM_ALL stream_dump.cpp)
|
||||
ADD_EXECUTABLE(icmp_responses EXCLUDE_FROM_ALL icmp_responses.cpp)
|
||||
ADD_EXECUTABLE(interfaces_info EXCLUDE_FROM_ALL interfaces_info.cpp)
|
||||
ADD_EXECUTABLE(tcp_connection_close EXCLUDE_FROM_ALL tcp_connection_close.cpp)
|
||||
ADD_EXECUTABLE(wps_detect EXCLUDE_FROM_ALL wps_detect.cpp)
|
||||
IF (Boost_REGEX_FOUND)
|
||||
ADD_EXECUTABLE(http_requests EXCLUDE_FROM_ALL http_requests.cpp)
|
||||
TARGET_LINK_LIBRARIES(http_requests ${Boost_LIBRARIES})
|
||||
ENDIF()
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
|
||||
ADD_EXECUTABLE(beacon_display EXCLUDE_FROM_ALL beacon_display.cpp)
|
||||
|
||||
if(THREADS_FOUND)
|
||||
IF(TINS_HAVE_CXX11)
|
||||
ADD_EXECUTABLE(traceroute EXCLUDE_FROM_ALL traceroute.cpp)
|
||||
ADD_EXECUTABLE(dns_stats EXCLUDE_FROM_ALL dns_stats.cpp)
|
||||
TARGET_LINK_LIBRARIES(traceroute ${CMAKE_THREAD_LIBS_INIT})
|
||||
TARGET_LINK_LIBRARIES(dns_stats ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(TINS_HAVE_CXX11)
|
||||
IF(WIN32)
|
||||
MESSAGE(WARNING "Disabling portscan example since it doesn't compile on Windows.")
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(portscan EXCLUDE_FROM_ALL portscan.cpp)
|
||||
TARGET_LINK_LIBRARIES(portscan ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Disabling portscan and traceroute examples since pthreads library was not found.")
|
||||
ENDIF()
|
107
lib/libtins/examples/arpmonitor.cpp
Normal file
107
lib/libtins/examples/arpmonitor.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::map;
|
||||
using std::bind;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class arp_monitor {
|
||||
public:
|
||||
void run(Sniffer& sniffer);
|
||||
private:
|
||||
bool callback(const PDU& pdu);
|
||||
|
||||
map<IPv4Address, HWAddress<6>> addresses;
|
||||
};
|
||||
|
||||
void arp_monitor::run(Sniffer& sniffer) {
|
||||
sniffer.sniff_loop(
|
||||
bind(
|
||||
&arp_monitor::callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bool arp_monitor::callback(const PDU& pdu) {
|
||||
// Retrieve the ARP layer
|
||||
const ARP& arp = pdu.rfind_pdu<ARP>();
|
||||
// Is it an ARP reply?
|
||||
if (arp.opcode() == ARP::REPLY) {
|
||||
// Let's check if there's already an entry for this address
|
||||
auto iter = addresses.find(arp.sender_ip_addr());
|
||||
if (iter == addresses.end()) {
|
||||
// We haven't seen this address. Save it.
|
||||
addresses.insert({ arp.sender_ip_addr(), arp.sender_hw_addr()});
|
||||
cout << "[INFO] " << arp.sender_ip_addr() << " is at "
|
||||
<< arp.sender_hw_addr() << std::endl;
|
||||
}
|
||||
else {
|
||||
// We've seen this address. If it's not the same HW address, inform it
|
||||
if (arp.sender_hw_addr() != iter->second) {
|
||||
cout << "[WARNING] " << arp.sender_ip_addr() << " is at "
|
||||
<< iter->second << " but also at " << arp.sender_hw_addr()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
arp_monitor monitor;
|
||||
// Sniffer configuration
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("arp");
|
||||
|
||||
try {
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// Only capture arp packets
|
||||
monitor.run(sniffer);
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
std::cerr << "Error: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
136
lib/libtins/examples/arpspoofing.cpp
Normal file
136
lib/libtins/examples/arpspoofing.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif // _WIN32
|
||||
#include <tins/arp.h>
|
||||
#include <tins/network_interface.h>
|
||||
#include <tins/utils.h>
|
||||
#include <tins/ethernetII.h>
|
||||
#include <tins/packet_sender.h>
|
||||
|
||||
using std::cout;
|
||||
using std::runtime_error;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
|
||||
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.
|
||||
gw_hw = Utils::resolve_hwaddr(iface, gw, sender);
|
||||
|
||||
// Resolves victim's hardware address.
|
||||
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";
|
||||
cout << " Using own hw address: " << info.hw_addr << "\n";
|
||||
|
||||
/* We tell the gateway that the victim is at out hw address,
|
||||
* and tell the victim that the gateway is at out hw address */
|
||||
ARP gw_arp(gw, victim, gw_hw, info.hw_addr),
|
||||
victim_arp(victim, gw, victim_hw, info.hw_addr);
|
||||
// We are "replying" ARP requests
|
||||
gw_arp.opcode(ARP::REPLY);
|
||||
victim_arp.opcode(ARP::REPLY);
|
||||
|
||||
/* The packet we'll send to the gateway and victim.
|
||||
* We include our hw address as the source address
|
||||
* in ethernet layer, to avoid possible packet dropping
|
||||
* performed by any routers. */
|
||||
EthernetII to_gw = EthernetII(gw_hw, info.hw_addr) / gw_arp;
|
||||
EthernetII to_victim = EthernetII(victim_hw, info.hw_addr) / victim_arp;
|
||||
while (true) {
|
||||
// Just send them once every 5 seconds.
|
||||
sender.send(to_gw, iface);
|
||||
sender.send(to_victim, iface);
|
||||
#ifdef _WIN32
|
||||
Sleep(5000);
|
||||
#else
|
||||
sleep(5);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " <<* argv << " <Gateway> <Victim>" << endl;
|
||||
return 1;
|
||||
}
|
||||
IPv4Address gw, victim;
|
||||
EthernetII::address_type own_hw;
|
||||
try {
|
||||
// Convert dotted-notation ip addresses to integer.
|
||||
gw = argv[1];
|
||||
victim = argv[2];
|
||||
}
|
||||
catch (...) {
|
||||
cout << "Invalid ip found...\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
NetworkInterface iface;
|
||||
NetworkInterface::Info info;
|
||||
try {
|
||||
// Get the interface which will be the gateway for our requests.
|
||||
iface = gw;
|
||||
// Lookup the interface id. This will be required while forging packets.
|
||||
// Find the interface hardware and ip address.
|
||||
info = iface.addresses();
|
||||
}
|
||||
catch (runtime_error& ex) {
|
||||
cout << ex.what() << endl;
|
||||
return 3;
|
||||
}
|
||||
try {
|
||||
do_arp_spoofing(iface, gw, victim, info);
|
||||
}
|
||||
catch (runtime_error& ex) {
|
||||
cout << "Runtime error: " << ex.what() << endl;
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
101
lib/libtins/examples/beacon_display.cpp
Normal file
101
lib/libtins/examples/beacon_display.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::set;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class BeaconSniffer {
|
||||
public:
|
||||
void run(const string& iface);
|
||||
private:
|
||||
typedef Dot11::address_type address_type;
|
||||
typedef set<address_type> ssids_type;
|
||||
|
||||
bool callback(PDU& pdu);
|
||||
|
||||
ssids_type ssids;
|
||||
};
|
||||
|
||||
void BeaconSniffer::run(const std::string& iface) {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("type mgt subtype beacon");
|
||||
config.set_rfmon(true);
|
||||
Sniffer sniffer(iface, config);
|
||||
sniffer.sniff_loop(make_sniffer_handler(this, &BeaconSniffer::callback));
|
||||
}
|
||||
|
||||
bool BeaconSniffer::callback(PDU& pdu) {
|
||||
// Get the Dot11 layer
|
||||
const Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
|
||||
// All beacons must have from_ds == to_ds == 0
|
||||
if (!beacon.from_ds() && !beacon.to_ds()) {
|
||||
// Get the AP address
|
||||
address_type addr = beacon.addr2();
|
||||
// Look it up in our set
|
||||
ssids_type::iterator it = ssids.find(addr);
|
||||
if (it == ssids.end()) {
|
||||
// First time we encounter this BSSID.
|
||||
try {
|
||||
/* If no ssid option is set, then Dot11::ssid will throw
|
||||
* a std::runtime_error.
|
||||
*/
|
||||
string ssid = beacon.ssid();
|
||||
// Save it so we don't show it again.
|
||||
ssids.insert(addr);
|
||||
// Display the tuple "address - ssid".
|
||||
cout << addr << " - " << ssid << endl;
|
||||
}
|
||||
catch (runtime_error&) {
|
||||
// No ssid, just ignore it.
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
string interface = argv[1];
|
||||
BeaconSniffer sniffer;
|
||||
sniffer.run(interface);
|
||||
}
|
118
lib/libtins/examples/defragmenter.cpp
Normal file
118
lib/libtins/examples/defragmenter.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "tins/ip.h"
|
||||
#include "tins/ip_reassembler.h"
|
||||
#include "tins/sniffer.h"
|
||||
#include "tins/packet_writer.h"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::exception;
|
||||
|
||||
using Tins::IPv4Reassembler;
|
||||
using Tins::IP;
|
||||
using Tins::Packet;
|
||||
using Tins::FileSniffer;
|
||||
using Tins::PacketWriter;
|
||||
using Tins::DataLinkType;
|
||||
|
||||
// This example reads packets from a pcap file and writes them to a new file.
|
||||
// If any IPv4 fragmented packets are found in the input file, then they will
|
||||
// be reassembled before writing them, so instead of the individual fragments
|
||||
// it will write the whole packet.
|
||||
|
||||
class Defragmenter {
|
||||
public:
|
||||
// Construct the sniffer and the packet writer using the sniffer's
|
||||
// data link type
|
||||
Defragmenter(const string& input_file, const string& output_file)
|
||||
: sniffer_(input_file),
|
||||
writer_(output_file, (PacketWriter::LinkType)sniffer_.link_type()),
|
||||
total_reassembled_(0) {
|
||||
|
||||
}
|
||||
|
||||
void run() {
|
||||
Packet packet;
|
||||
// Read packets and keep going until there's no more packets to read
|
||||
while (packet = sniffer_.next_packet()) {
|
||||
// Try to reassemble the packet
|
||||
IPv4Reassembler::PacketStatus status = reassembler_.process(*packet.pdu());
|
||||
|
||||
// If we did reassemble it, increase this counter
|
||||
if (status == IPv4Reassembler::REASSEMBLED) {
|
||||
total_reassembled_++;
|
||||
}
|
||||
|
||||
// Regardless, we'll write it into the output file unless it's fragmented
|
||||
// (and not yet reassembled)
|
||||
if (status != IPv4Reassembler::FRAGMENTED) {
|
||||
writer_.write(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t total_packets_reassembled() const {
|
||||
return total_reassembled_;
|
||||
}
|
||||
private:
|
||||
FileSniffer sniffer_;
|
||||
IPv4Reassembler reassembler_;
|
||||
PacketWriter writer_;
|
||||
uint64_t total_reassembled_;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " << argv[0] << " <input-file> <output-file>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
// Build the defragmented
|
||||
Defragmenter defragmenter(argv[1], argv[2]);
|
||||
cout << "Processing " << argv[1] << endl;
|
||||
cout << "Writing results to " << argv[2] << endl;
|
||||
|
||||
// Run!
|
||||
defragmenter.run();
|
||||
cout << "Done" << endl;
|
||||
cout << "Reassembled: " << defragmenter.total_packets_reassembled()
|
||||
<< " packet(s)" << endl;
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
|
68
lib/libtins/examples/dns_queries.cpp
Normal file
68
lib/libtins/examples/dns_queries.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
bool callback(const PDU& pdu) {
|
||||
// The packet probably looks like this:
|
||||
//
|
||||
// EthernetII / IP / UDP / RawPDU
|
||||
//
|
||||
// So we retrieve the RawPDU layer, and construct a
|
||||
// DNS PDU using its contents.
|
||||
DNS dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
|
||||
|
||||
// Retrieve the queries and print the domain name:
|
||||
for (const auto& query : dns.queries()) {
|
||||
cout << query.dname() << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
// Only capture udp packets sent to port 53
|
||||
config.set_filter("udp and dst port 53");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// Start the capture
|
||||
sniffer.sniff_loop(callback);
|
||||
}
|
107
lib/libtins/examples/dns_spoof.cpp
Normal file
107
lib/libtins/examples/dns_spoof.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
PacketSender sender;
|
||||
|
||||
bool callback(const PDU& pdu) {
|
||||
// The packet probably looks like this:
|
||||
//
|
||||
// EthernetII / IP / UDP / RawPDU
|
||||
//
|
||||
// So we retrieve each layer, and construct a
|
||||
// DNS PDU from the RawPDU layer contents.
|
||||
EthernetII eth = pdu.rfind_pdu<EthernetII>();
|
||||
IP ip = eth.rfind_pdu<IP>();
|
||||
UDP udp = ip.rfind_pdu<UDP>();
|
||||
DNS dns = udp.rfind_pdu<RawPDU>().to<DNS>();
|
||||
|
||||
// Is it a DNS query?
|
||||
if (dns.type() == DNS::QUERY) {
|
||||
// Let's see if there's any query for an "A" record.
|
||||
for (const auto& query : dns.queries()) {
|
||||
if (query.query_type() == DNS::A) {
|
||||
// Here's one! Let's add an answer.
|
||||
dns.add_answer(
|
||||
DNS::resource(
|
||||
query.dname(),
|
||||
"127.0.0.1",
|
||||
DNS::A,
|
||||
query.query_class(),
|
||||
// 777 is just a random TTL
|
||||
777
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// Have we added some answers?
|
||||
if (dns.answers_count() > 0) {
|
||||
// It's a response now
|
||||
dns.type(DNS::RESPONSE);
|
||||
// Recursion is available(just in case)
|
||||
dns.recursion_available(1);
|
||||
// Build our packet
|
||||
auto pkt = EthernetII(eth.src_addr(), eth.dst_addr()) /
|
||||
IP(ip.src_addr(), ip.dst_addr()) /
|
||||
UDP(udp.sport(), udp.dport()) /
|
||||
dns;
|
||||
// Send it!
|
||||
sender.send(pkt);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
cout << "Usage: " <<* argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
// Sniff on the provided interface in promiscuous mode
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
// Use immediate mode so we get the packets as fast as we can
|
||||
config.set_immediate_mode(true);
|
||||
// Only capture udp packets sent to port 53
|
||||
config.set_filter("udp and dst port 53");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
// All packets will be sent through the provided interface
|
||||
sender.default_interface(argv[1]);
|
||||
|
||||
// Start the capture
|
||||
sniffer.sniff_loop(callback);
|
||||
}
|
218
lib/libtins/examples/dns_stats.cpp
Normal file
218
lib/libtins/examples/dns_stats.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#endif // _WIN32
|
||||
|
||||
// Fix for gcc 4.6
|
||||
#define _GLIBCXX_USE_NANOSLEEP
|
||||
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::thread;
|
||||
using std::string;
|
||||
using std::bind;
|
||||
using std::map;
|
||||
using std::mutex;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::exception;
|
||||
using std::lock_guard;
|
||||
using std::tuple;
|
||||
using std::make_tuple;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::chrono::seconds;
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::system_clock;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// Holds the DNS response time statistics. The response time is
|
||||
// represented using the Duration template parameter.
|
||||
template<typename Duration>
|
||||
class statistics {
|
||||
public:
|
||||
typedef Duration duration_type;
|
||||
typedef lock_guard<mutex> locker_type;
|
||||
|
||||
struct information {
|
||||
duration_type average, worst;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
statistics()
|
||||
: m_duration(), m_worst(duration_type::min()), m_count() {
|
||||
|
||||
}
|
||||
|
||||
void add_response_time(const duration_type& duration) {
|
||||
locker_type _(m_lock);
|
||||
m_duration += duration;
|
||||
m_count++;
|
||||
m_worst = max(m_worst, duration);
|
||||
}
|
||||
|
||||
information get_information() const {
|
||||
locker_type _(m_lock);
|
||||
if(m_count == 0) {
|
||||
return { };
|
||||
}
|
||||
else {
|
||||
return { m_duration / m_count, m_worst, m_count };
|
||||
}
|
||||
};
|
||||
private:
|
||||
duration_type m_duration, m_worst;
|
||||
size_t m_count;
|
||||
mutable mutex m_lock;
|
||||
};
|
||||
|
||||
// Sniffs and tracks DNS queries. When a matching DNS response is found,
|
||||
// the response time is added to a statistics object.
|
||||
//
|
||||
// This class performs* no cleanup* on data associated with queries that
|
||||
// weren't answered.
|
||||
class dns_monitor {
|
||||
public:
|
||||
// The response times are measured in milliseconds
|
||||
typedef milliseconds duration_type;
|
||||
// The statistics type used.
|
||||
typedef statistics<duration_type> statistics_type;
|
||||
|
||||
void run(BaseSniffer& sniffer);
|
||||
const statistics_type& stats() const {
|
||||
return m_stats;
|
||||
}
|
||||
private:
|
||||
typedef tuple<IPv4Address, IPv4Address, uint16_t> packet_info;
|
||||
typedef system_clock clock_type;
|
||||
typedef clock_type::time_point time_point_type;
|
||||
|
||||
bool callback(const PDU& pdu);
|
||||
static packet_info make_packet_info(const PDU& pdu, const DNS& dns);
|
||||
|
||||
statistics_type m_stats;
|
||||
map<packet_info, time_point_type> m_packet_info;
|
||||
};
|
||||
|
||||
void dns_monitor::run(BaseSniffer& sniffer) {
|
||||
sniffer.sniff_loop(
|
||||
bind(
|
||||
&dns_monitor::callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bool dns_monitor::callback(const PDU& pdu) {
|
||||
auto now = clock_type::now();
|
||||
auto dns = pdu.rfind_pdu<RawPDU>().to<DNS>();
|
||||
auto info = make_packet_info(pdu, dns);
|
||||
// If it's a query, add the sniff time to our map.
|
||||
if (dns.type() == DNS::QUERY) {
|
||||
m_packet_info.insert(
|
||||
std::make_pair(info, now)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// It's a response, we need to find the query in our map.
|
||||
auto iter = m_packet_info.find(info);
|
||||
if (iter != m_packet_info.end()) {
|
||||
// We found the query, let's add the response time to the
|
||||
// statistics object.
|
||||
m_stats.add_response_time(
|
||||
duration_cast<duration_type>(now - iter->second)
|
||||
);
|
||||
// Forget about the query.
|
||||
m_packet_info.erase(iter);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// It is required that we can identify packets sent and received that
|
||||
// hold the same DNS id as belonging to the same query.
|
||||
//
|
||||
// This function retrieves a tuple (addr, addr, id) that will achieve it.
|
||||
auto dns_monitor::make_packet_info(const PDU& pdu, const DNS& dns) -> packet_info {
|
||||
const auto& ip = pdu.rfind_pdu<IP>();
|
||||
return make_tuple(
|
||||
// smallest address first
|
||||
min(ip.src_addr(), ip.dst_addr()),
|
||||
// largest address second
|
||||
max(ip.src_addr(), ip.dst_addr()),
|
||||
dns.id()
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
string iface;
|
||||
if (argc == 2) {
|
||||
// Use the provided interface
|
||||
iface = argv[1];
|
||||
}
|
||||
else {
|
||||
// Use the default interface
|
||||
iface = NetworkInterface::default_interface().name();
|
||||
}
|
||||
try {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("udp and port 53");
|
||||
Sniffer sniffer(iface, config);
|
||||
dns_monitor monitor;
|
||||
thread thread(
|
||||
[&]() {
|
||||
monitor.run(sniffer);
|
||||
}
|
||||
);
|
||||
while (true) {
|
||||
auto info = monitor.stats().get_information();
|
||||
cout << "\rAverage " << info.average.count()
|
||||
<< "ms. Worst: " << info.worst.count() << "ms. Count: "
|
||||
<< info.count << " ";
|
||||
cout.flush();
|
||||
sleep_for(seconds(1));
|
||||
}
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "[-] Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
147
lib/libtins/examples/http_requests.cpp
Normal file
147
lib/libtins/examples/http_requests.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <boost/regex.hpp>
|
||||
#include "tins/tcp_ip/stream_follower.h"
|
||||
#include "tins/sniffer.h"
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::exception;
|
||||
|
||||
using boost::regex;
|
||||
using boost::match_results;
|
||||
|
||||
using Tins::PDU;
|
||||
using Tins::Sniffer;
|
||||
using Tins::SnifferConfiguration;
|
||||
using Tins::TCPIP::Stream;
|
||||
using Tins::TCPIP::StreamFollower;
|
||||
|
||||
// This example captures and follows TCP streams seen on port 80. It will
|
||||
// wait until both the client and server send data and then apply a regex
|
||||
// to both payloads, extrating some information and printing it.
|
||||
|
||||
// Don't buffer more than 3kb of data in either request/response
|
||||
const size_t MAX_PAYLOAD = 3 * 1024;
|
||||
// The regex to be applied on the request. This will extract the HTTP
|
||||
// method being used, the request's path and the Host header value.
|
||||
regex request_regex("([\\w]+) ([^ ]+).+\r\nHost: ([\\d\\w\\.-]+)\r\n");
|
||||
// The regex to be applied on the response. This finds the response code.
|
||||
regex response_regex("HTTP/[^ ]+ ([\\d]+)");
|
||||
|
||||
void on_server_data(Stream& stream) {
|
||||
match_results<Stream::payload_type::const_iterator> client_match;
|
||||
match_results<Stream::payload_type::const_iterator> server_match;
|
||||
const Stream::payload_type& client_payload = stream.client_payload();
|
||||
const Stream::payload_type& server_payload = stream.server_payload();
|
||||
// Run the regexes on client/server payloads
|
||||
bool valid = regex_search(server_payload.begin(), server_payload.end(),
|
||||
server_match, response_regex) &&
|
||||
regex_search(client_payload.begin(), client_payload.end(),
|
||||
client_match, request_regex);
|
||||
// If we matched both the client and the server regexes
|
||||
if (valid) {
|
||||
// Extract all fields
|
||||
string method = string(client_match[1].first, client_match[1].second);
|
||||
string url = string(client_match[2].first, client_match[2].second);
|
||||
string host = string(client_match[3].first, client_match[3].second);
|
||||
string response_code = string(server_match[1].first, server_match[1].second);
|
||||
// Now print them
|
||||
cout << method << " http://" << host << url << " -> " << response_code << endl;
|
||||
|
||||
// Once we've seen the first request on this stream, ignore it
|
||||
stream.ignore_client_data();
|
||||
stream.ignore_server_data();
|
||||
}
|
||||
|
||||
// Just in case the server returns invalid data, stop at 3kb
|
||||
if (stream.server_payload().size() > MAX_PAYLOAD) {
|
||||
stream.ignore_server_data();
|
||||
}
|
||||
}
|
||||
|
||||
void on_client_data(Stream& stream) {
|
||||
// Don't hold more than 3kb of data from the client's flow
|
||||
if (stream.client_payload().size() > MAX_PAYLOAD) {
|
||||
stream.ignore_client_data();
|
||||
}
|
||||
}
|
||||
|
||||
void on_new_connection(Stream& stream) {
|
||||
stream.client_data_callback(&on_client_data);
|
||||
stream.server_data_callback(&on_server_data);
|
||||
// Don't automatically cleanup the stream's data, as we'll manage
|
||||
// the buffer ourselves and let it grow until we see a full request
|
||||
// and response
|
||||
stream.auto_cleanup_payloads(false);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " << argv[0] << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
// Construct the sniffer configuration object
|
||||
SnifferConfiguration config;
|
||||
// Get packets as quickly as possible
|
||||
config.set_immediate_mode(true);
|
||||
// Only capture TCP traffic sent from/to port 80
|
||||
config.set_filter("tcp port 80");
|
||||
// Construct the sniffer we'll use
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
cout << "Starting capture on interface " << argv[1] << endl;
|
||||
|
||||
// Now construct the stream follower
|
||||
StreamFollower follower;
|
||||
// We just need to specify the callback to be executed when a new
|
||||
// stream is captured. In this stream, you should define which callbacks
|
||||
// will be executed whenever new data is sent on that stream
|
||||
// (see on_new_connection)
|
||||
follower.new_stream_callback(&on_new_connection);
|
||||
// Now start capturing. Every time there's a new packet, call
|
||||
// follower.process_packet
|
||||
sniffer.sniff_loop([&](PDU& packet) {
|
||||
follower.process_packet(packet);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
140
lib/libtins/examples/icmp_responses.cpp
Normal file
140
lib/libtins/examples/icmp_responses.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::bind;
|
||||
using std::string;
|
||||
using std::runtime_error;
|
||||
using std::exception;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// This class captured packets on an interface, using the specified filter
|
||||
// and will respond with ICMP error packets whenever a packet is captured.
|
||||
// The response mechanism is pretty naive as it generates a packet which
|
||||
// has swapped HW and IP addresses (dst as src, src as dst).
|
||||
class ICMPResponder {
|
||||
public:
|
||||
// Use the given interface and ICMP type/code on responses
|
||||
ICMPResponder(string iface, int type, int code)
|
||||
: m_iface(iface), m_sender(iface), m_type(type), m_code(code) {
|
||||
|
||||
}
|
||||
|
||||
// Run using the given filter
|
||||
void run(const string& filter) {
|
||||
// Initialize the configuration
|
||||
SnifferConfiguration config;
|
||||
// Use promiscuous mode
|
||||
config.set_promisc_mode(true);
|
||||
// Use this packet filter
|
||||
config.set_filter(filter);
|
||||
// Use immediate mode (we don't want to buffer packets, we want the mright away).
|
||||
config.set_immediate_mode(true);
|
||||
|
||||
// Now create the Sniffer
|
||||
Sniffer sniffer(m_iface, config);
|
||||
if (sniffer.link_type() != DLT_EN10MB) {
|
||||
throw runtime_error("Ethernet interfaces only supported");
|
||||
}
|
||||
// Start the sniffing! For each packet, ICMPReponder::callback will be called
|
||||
sniffer.sniff_loop(bind(&ICMPResponder::callback, this, std::placeholders::_1));
|
||||
}
|
||||
private:
|
||||
// Extracts the payload to be used over the ICMP layer in the response.
|
||||
// This will be the entire IP header + 8 bytes of the next header.
|
||||
RawPDU extract_icmp_payload(IP& pdu) {
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
// Use whole IP + 8 bytes of next header.
|
||||
size_t end_index = pdu.header_size() + 8;
|
||||
return RawPDU(buffer.begin(), buffer.begin() + end_index);
|
||||
}
|
||||
|
||||
// Generates an ICMP response given a packet.
|
||||
EthernetII generate_response(PDU& pdu) {
|
||||
// Find Ethernet and IP headers.
|
||||
EthernetII& received_eth = pdu.rfind_pdu<EthernetII>();
|
||||
IP& received_ip = pdu.rfind_pdu<IP>();
|
||||
|
||||
// Create an Ethernet response, flipping the addresses
|
||||
EthernetII output(received_eth.src_addr(), received_eth.dst_addr());
|
||||
// Append an IP PDU, again flipping addresses.
|
||||
//output /= IP(received_ip.src_addr(), received_ip.dst_addr());
|
||||
output /= IP(received_ip.src_addr(), "8.8.8.8");
|
||||
|
||||
// Now generate the ICMP layer using the type and code provided.
|
||||
ICMP icmp;
|
||||
icmp.type(static_cast<ICMP::Flags>(m_type));
|
||||
icmp.code(m_code);
|
||||
// Append the ICMP layer to our packet
|
||||
output /= icmp;
|
||||
// Extract the payload to be used over ICMP.
|
||||
output /= extract_icmp_payload(received_ip);
|
||||
return output;
|
||||
}
|
||||
|
||||
// Packet capture callback
|
||||
bool callback(PDU& pdu) {
|
||||
// Generate a response for this packet
|
||||
EthernetII response = generate_response(pdu);
|
||||
// Send this packet!
|
||||
m_sender.send(response);
|
||||
return true;
|
||||
}
|
||||
|
||||
string m_iface;
|
||||
PacketSender m_sender;
|
||||
int m_type;
|
||||
int m_code;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const int type = 3;
|
||||
const int code = 0;
|
||||
if (argc < 3) {
|
||||
cout << "Usage: " << argv[0] << " <interface> <pcap_filter>" << endl;
|
||||
return 1;
|
||||
}
|
||||
string iface = argv[1];
|
||||
string filter = argv[2];
|
||||
try {
|
||||
ICMPResponder responder(iface, type, code);
|
||||
responder.run(filter);
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "Error: " << ex.what() << endl;
|
||||
}
|
||||
}
|
87
lib/libtins/examples/interfaces_info.cpp
Normal file
87
lib/libtins/examples/interfaces_info.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <tins/network_interface.h>
|
||||
|
||||
using std::cout;
|
||||
using std::wcout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
int main() {
|
||||
// Get all interfaces and iterate over them.
|
||||
for (const NetworkInterface& iface : NetworkInterface::all()) {
|
||||
// Get the name of this interface
|
||||
string name = iface.name();
|
||||
|
||||
// "stringify" the status of the interface
|
||||
string status = iface.is_up() ? "up" : "down";
|
||||
|
||||
// Get this interface's information (addresses).
|
||||
NetworkInterface::Info info = iface.info();
|
||||
|
||||
// Now print all of this info.
|
||||
cout << name;
|
||||
|
||||
#ifdef _WIN32
|
||||
// If this is running on Windows, also print the friendly name
|
||||
wcout << " (" << iface.friendly_name() << ")";
|
||||
#endif // _WIN32
|
||||
cout << ": " << endl;
|
||||
|
||||
string ipv6_string;
|
||||
if (info.ipv6_addrs.empty()) {
|
||||
ipv6_string = "(none)";
|
||||
}
|
||||
else {
|
||||
ostringstream oss;
|
||||
for (size_t i = 0; i < info.ipv6_addrs.size(); ++i) {
|
||||
const NetworkInterface::IPv6Prefix& prefix = info.ipv6_addrs[i];
|
||||
if (i > 0) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << prefix.address << "/" << prefix.prefix_length;
|
||||
}
|
||||
ipv6_string = oss.str();
|
||||
}
|
||||
cout << " HW address: " << info.hw_addr << endl
|
||||
<< " IP address: " << info.ip_addr << endl
|
||||
<< " IPv6 addresses: " << ipv6_string << endl
|
||||
<< " Netmask: " << info.netmask << endl
|
||||
<< " Broadcast: " << info.bcast_addr << endl
|
||||
<< " Iface index: " << iface.id() << endl
|
||||
<< " Status: " << "interface " << status << endl << endl;
|
||||
}
|
||||
}
|
195
lib/libtins/examples/portscan.cpp
Normal file
195
lib/libtins/examples/portscan.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <tins/ip.h>
|
||||
#include <tins/tcp.h>
|
||||
#include <tins/ip_address.h>
|
||||
#include <tins/ethernetII.h>
|
||||
#include <tins/network_interface.h>
|
||||
#include <tins/sniffer.h>
|
||||
#include <tins/utils.h>
|
||||
#include <tins/packet_sender.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
using std::setw;
|
||||
using std::string;
|
||||
using std::set;
|
||||
using std::runtime_error;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
typedef pair<Sniffer*, string> sniffer_data;
|
||||
|
||||
class Scanner {
|
||||
public:
|
||||
Scanner(const NetworkInterface& interface,
|
||||
const IPv4Address& address,
|
||||
const vector<string>& ports);
|
||||
|
||||
void run();
|
||||
private:
|
||||
void send_syns(const NetworkInterface& iface, IPv4Address dest_ip);
|
||||
bool callback(PDU& pdu);
|
||||
static void* thread_proc(void* param);
|
||||
void launch_sniffer();
|
||||
|
||||
NetworkInterface iface;
|
||||
IPv4Address host_to_scan;
|
||||
set<uint16_t> ports_to_scan;
|
||||
Sniffer sniffer;
|
||||
};
|
||||
|
||||
Scanner::Scanner(const NetworkInterface& interface,
|
||||
const IPv4Address& address,
|
||||
const vector<string>& ports)
|
||||
: iface(interface), host_to_scan(address), sniffer(interface.name()) {
|
||||
sniffer.set_filter(
|
||||
"tcp and ip src " + address.to_string() + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0"
|
||||
);
|
||||
for (size_t i = 0; i < ports.size(); ++i) {
|
||||
ports_to_scan.insert(atoi(ports[i].c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void* Scanner::thread_proc(void* param) {
|
||||
Scanner* data = (Scanner*)param;
|
||||
data->launch_sniffer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scanner::launch_sniffer() {
|
||||
sniffer.sniff_loop(make_sniffer_handler(this, &Scanner::callback));
|
||||
}
|
||||
|
||||
/* Our scan handler. This will receive SYNs and RSTs and inform us
|
||||
* the scanned port's status.
|
||||
*/
|
||||
bool Scanner::callback(PDU& pdu) {
|
||||
// Find the layers we want.
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
||||
// Check if the host that we're scanning sent this packet and
|
||||
// the source port is one of those that we scanned.
|
||||
if(ip.src_addr() == host_to_scan && ports_to_scan.count(tcp.sport()) == 1) {
|
||||
// Ok, it's a TCP PDU. Is RST flag on? Then port is closed.
|
||||
if(tcp.get_flag(TCP::RST)) {
|
||||
// This indicates we should stop sniffing.
|
||||
if(tcp.get_flag(TCP::SYN))
|
||||
return false;
|
||||
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
|
||||
}
|
||||
// Is SYN flag on? Then port is open!
|
||||
else if(tcp.has_flags(TCP::SYN | TCP::ACK)) {
|
||||
cout << "Port: " << setw(5) << tcp.sport() << " open\n";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scanner::run() {
|
||||
pthread_t thread;
|
||||
// Launch our sniff thread.
|
||||
pthread_create(&thread, 0, &Scanner::thread_proc, this);
|
||||
// Start sending SYNs to port.
|
||||
send_syns(iface, host_to_scan);
|
||||
|
||||
// Wait for our sniffer.
|
||||
void* dummy;
|
||||
pthread_join(thread, &dummy);
|
||||
}
|
||||
|
||||
// Send syns to the given ip address, using the destination ports provided.
|
||||
void Scanner::send_syns(const NetworkInterface& iface, IPv4Address dest_ip) {
|
||||
// Retrieve the addresses.
|
||||
NetworkInterface::Info info = iface.addresses();
|
||||
PacketSender sender;
|
||||
// Allocate the IP PDU
|
||||
IP ip = IP(dest_ip, info.ip_addr) / TCP();
|
||||
// Get the reference to the TCP PDU
|
||||
TCP& tcp = ip.rfind_pdu<TCP>();
|
||||
// Set the SYN flag on.
|
||||
tcp.set_flag(TCP::SYN, 1);
|
||||
// Just some random port.
|
||||
tcp.sport(1337);
|
||||
cout << "Sending SYNs..." << endl;
|
||||
for (set<uint16_t>::const_iterator it = ports_to_scan.begin(); it != ports_to_scan.end(); ++it) {
|
||||
// Set the new port and send the packet!
|
||||
tcp.dport(*it);
|
||||
sender.send(ip);
|
||||
}
|
||||
// Wait 1 second.
|
||||
sleep(1);
|
||||
/* Special packet to indicate that we're done. This will be sniffed
|
||||
* by our function, which will in turn return false.
|
||||
*/
|
||||
tcp.set_flag(TCP::RST, 1);
|
||||
tcp.sport(*ports_to_scan.begin());
|
||||
// Pretend we're the scanned host...
|
||||
ip.src_addr(dest_ip);
|
||||
// We use an ethernet pdu, otherwise the kernel will drop it.
|
||||
EthernetII eth = EthernetII(info.hw_addr, info.hw_addr) / ip;
|
||||
sender.send(eth, iface);
|
||||
}
|
||||
|
||||
void scan(int argc, char* argv[]) {
|
||||
IPv4Address ip(argv[1]);
|
||||
// Resolve the interface which will be our gateway
|
||||
NetworkInterface iface(ip);
|
||||
cout << "Sniffing on interface: " << iface.name() << endl;
|
||||
|
||||
// Consume arguments
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
Scanner scanner(iface, ip, vector<string>(argv, argv + (argc)));
|
||||
scanner.run();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 3) {
|
||||
cout << "Usage: " <<* argv << " <IPADDR> <port1> [port2] [port3]" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
scan(argc, argv);
|
||||
}
|
||||
catch(runtime_error& ex) {
|
||||
cout << "Error - " << ex.what() << endl;
|
||||
}
|
||||
}
|
69
lib/libtins/examples/route_table.cpp
Normal file
69
lib/libtins/examples/route_table.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::vector;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
int main() {
|
||||
vector<Utils::RouteEntry> v4_entries = Utils::route_entries();
|
||||
cout << "IPv4 route table entries: " << endl
|
||||
<< "========================= " << endl;
|
||||
for (size_t i = 0; i < v4_entries.size(); ++i) {
|
||||
cout << "Entry " << setw(2) << i << ": " << endl
|
||||
<< "Interface: " << v4_entries[i].interface << endl
|
||||
<< "Destination: " << v4_entries[i].destination << endl
|
||||
<< "Gateway: " << v4_entries[i].gateway << endl
|
||||
<< "Genmask: " << v4_entries[i].mask << endl
|
||||
<< "Metric: " << v4_entries[i].metric << endl << endl;
|
||||
}
|
||||
|
||||
vector<Utils::Route6Entry> v6_entries = Utils::route6_entries();
|
||||
if (!v6_entries.empty()) {
|
||||
cout << endl
|
||||
<< "IPv6 route table entries: " << endl
|
||||
<< "========================= " << endl;
|
||||
for (size_t i = 0; i < v6_entries.size(); ++i) {
|
||||
cout << "Entry " << setw(2) << i << ": " << endl
|
||||
<< "Interface: " << v6_entries[i].interface << endl
|
||||
<< "Destination: " << v6_entries[i].destination << endl
|
||||
<< "Gateway: " << v6_entries[i].gateway << endl
|
||||
<< "Genmask: " << v6_entries[i].mask << endl
|
||||
<< "Metric: " << v6_entries[i].metric << endl << endl;
|
||||
}
|
||||
}
|
||||
}
|
192
lib/libtins/examples/stream_dump.cpp
Normal file
192
lib/libtins/examples/stream_dump.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "tins/tcp_ip/stream_follower.h"
|
||||
#include "tins/sniffer.h"
|
||||
#include "tins/packet.h"
|
||||
#include "tins/ip_address.h"
|
||||
#include "tins/ipv6_address.h"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::bind;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::ostringstream;
|
||||
using std::exception;
|
||||
|
||||
using Tins::Sniffer;
|
||||
using Tins::SnifferConfiguration;
|
||||
using Tins::PDU;
|
||||
using Tins::TCPIP::StreamFollower;
|
||||
using Tins::TCPIP::Stream;
|
||||
|
||||
// This example takes an interface and a port as an argument and
|
||||
// it listens for TCP streams on the given interface and port.
|
||||
// It will reassemble TCP streams and show the traffic sent by
|
||||
// both the client and the server.
|
||||
|
||||
// Convert the client endpoint to a readable string
|
||||
string client_endpoint(const Stream& stream) {
|
||||
ostringstream output;
|
||||
// Use the IPv4 or IPv6 address depending on which protocol the
|
||||
// connection uses
|
||||
if (stream.is_v6()) {
|
||||
output << stream.client_addr_v6();
|
||||
}
|
||||
else {
|
||||
output << stream.client_addr_v4();
|
||||
}
|
||||
output << ":" << stream.client_port();
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Convert the server endpoint to a readable string
|
||||
string server_endpoint(const Stream& stream) {
|
||||
ostringstream output;
|
||||
if (stream.is_v6()) {
|
||||
output << stream.server_addr_v6();
|
||||
}
|
||||
else {
|
||||
output << stream.server_addr_v4();
|
||||
}
|
||||
output << ":" << stream.server_port();
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Concat both endpoints to get a readable stream identifier
|
||||
string stream_identifier(const Stream& stream) {
|
||||
ostringstream output;
|
||||
output << client_endpoint(stream) << " - " << server_endpoint(stream);
|
||||
return output.str();
|
||||
}
|
||||
|
||||
// Whenever there's new client data on the stream, this callback is executed.
|
||||
void on_client_data(Stream& stream) {
|
||||
// Construct a string out of the contents of the client's payload
|
||||
string data(stream.client_payload().begin(), stream.client_payload().end());
|
||||
|
||||
// Now print it, prepending some information about the stream
|
||||
cout << client_endpoint(stream) << " >> "
|
||||
<< server_endpoint(stream) << ": " << endl << data << endl;
|
||||
}
|
||||
|
||||
// Whenever there's new server data on the stream, this callback is executed.
|
||||
// This does the same thing as on_client_data
|
||||
void on_server_data(Stream& stream) {
|
||||
string data(stream.server_payload().begin(), stream.server_payload().end());
|
||||
cout << server_endpoint(stream) << " >> "
|
||||
<< client_endpoint(stream) << ": " << endl << data << endl;
|
||||
}
|
||||
|
||||
// When a connection is closed, this callback is executed.
|
||||
void on_connection_closed(Stream& stream) {
|
||||
cout << "[+] Connection closed: " << stream_identifier(stream) << endl;
|
||||
}
|
||||
|
||||
// When a new connection is captured, this callback will be executed.
|
||||
void on_new_connection(Stream& stream) {
|
||||
if (stream.is_partial_stream()) {
|
||||
// We found a partial stream. This means this connection/stream had
|
||||
// been established before we started capturing traffic.
|
||||
//
|
||||
// In this case, we need to allow for the stream to catch up, as we
|
||||
// may have just captured an out of order packet and if we keep waiting
|
||||
// for the holes to be filled, we may end up waiting forever.
|
||||
//
|
||||
// Calling enable_recovery_mode will skip out of order packets that
|
||||
// fall withing the range of the given window size.
|
||||
// See Stream::enable_recover_mode for more information
|
||||
cout << "[+] New connection " << stream_identifier(stream) << endl;
|
||||
|
||||
// Enable recovery mode using a window of 10kb
|
||||
stream.enable_recovery_mode(10 * 1024);
|
||||
}
|
||||
else {
|
||||
// Print some information about the new connection
|
||||
cout << "[+] New connection " << stream_identifier(stream) << endl;
|
||||
}
|
||||
|
||||
// Now configure the callbacks on it.
|
||||
// First, we want on_client_data to be called every time there's new client data
|
||||
stream.client_data_callback(&on_client_data);
|
||||
|
||||
// Same thing for server data, but calling on_server_data
|
||||
stream.server_data_callback(&on_server_data);
|
||||
|
||||
// When the connection is closed, call on_connection_closed
|
||||
stream.stream_closed_callback(&on_connection_closed);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
cout << "Usage: " << argv[0] << " <interface> <port>" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
// Construct the sniffer configuration object
|
||||
SnifferConfiguration config;
|
||||
|
||||
// Only capture TCP traffic sent from/to the given port
|
||||
config.set_filter("tcp port " + to_string(stoi(string(argv[2]))));
|
||||
|
||||
// Construct the sniffer we'll use
|
||||
Sniffer sniffer(argv[1], config);
|
||||
|
||||
cout << "Starting capture on interface " << argv[1] << endl;
|
||||
|
||||
// Now construct the stream follower
|
||||
StreamFollower follower;
|
||||
|
||||
// We just need to specify the callback to be executed when a new
|
||||
// stream is captured. In this stream, you should define which callbacks
|
||||
// will be executed whenever new data is sent on that stream
|
||||
// (see on_new_connection)
|
||||
follower.new_stream_callback(&on_new_connection);
|
||||
|
||||
// Allow following partial TCP streams (e.g. streams that were
|
||||
// open before the sniffer started running)
|
||||
follower.follow_partial_streams(true);
|
||||
|
||||
// Now start capturing. Every time there's a new packet, call
|
||||
// follower.process_packet
|
||||
sniffer.sniff_loop([&](PDU& packet) {
|
||||
follower.process_packet(packet);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cerr << "Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
107
lib/libtins/examples/tcp_connection_close.cpp
Normal file
107
lib/libtins/examples/tcp_connection_close.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::string;
|
||||
using std::bind;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::exception;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// This example will capture TCP packets and send packet that will reset
|
||||
// the connection when it captures a packet with the SYN and ACK flags on.
|
||||
class tcp_connection_closer {
|
||||
public:
|
||||
tcp_connection_closer() {
|
||||
|
||||
}
|
||||
|
||||
void run(const string& interface) {
|
||||
using std::placeholders::_1;
|
||||
// Make the PacketSender use this interface by default
|
||||
sender_.default_interface(interface);
|
||||
|
||||
// Create the sniffer configuration
|
||||
SnifferConfiguration config;
|
||||
config.set_filter("tcp");
|
||||
// We want to get the packets as fast as possible
|
||||
config.set_immediate_mode(true);
|
||||
// Create the sniffer and start the capture
|
||||
Sniffer sniffer(interface, config);
|
||||
sniffer.sniff_loop(bind(&tcp_connection_closer::callback, this, _1));
|
||||
}
|
||||
private:
|
||||
bool callback(const PDU& pdu) {
|
||||
const EthernetII& eth = pdu.rfind_pdu<EthernetII>();
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
||||
// We'll only close a connection when seeing a SYN|ACK
|
||||
if (tcp.has_flags(TCP::SYN | TCP::ACK)) {
|
||||
// Create an ethernet header flipping the addresses
|
||||
EthernetII packet(eth.src_addr(), eth.dst_addr());
|
||||
// Do the same for IP
|
||||
packet /= IP(ip.src_addr(), ip.dst_addr());
|
||||
// Flip TCP ports
|
||||
TCP response_tcp(tcp.sport(), tcp.dport());
|
||||
// Set RST|ACK flags
|
||||
response_tcp.flags(TCP::RST | TCP::ACK);
|
||||
// Use the right sequence and ack numbers
|
||||
response_tcp.seq(tcp.ack_seq());
|
||||
response_tcp.ack_seq(tcp.seq());
|
||||
// Add this PDU to the packet we'll send
|
||||
packet /= response_tcp;
|
||||
// Send it!
|
||||
sender_.send(packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PacketSender sender_;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Usage: " << *argv << " <interface>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
tcp_connection_closer closer;
|
||||
closer.run(argv[1]);
|
||||
}
|
||||
catch (exception& ex) {
|
||||
cout << "[-] Error: " << ex.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
211
lib/libtins/examples/traceroute.cpp
Normal file
211
lib/libtins/examples/traceroute.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#endif // _WIN32
|
||||
|
||||
// Fix for gcc 4.6
|
||||
#define _GLIBCXX_USE_NANOSLEEP
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <tins/tins.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::move;
|
||||
using std::map;
|
||||
using std::min;
|
||||
using std::setw;
|
||||
using std::atomic;
|
||||
using std::runtime_error;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::thread;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::lock_guard;
|
||||
using std::mutex;
|
||||
using std::random_device;
|
||||
using std::numeric_limits;
|
||||
using std::bind;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
class Traceroute {
|
||||
public:
|
||||
typedef std::map<uint16_t, IPv4Address> result_type;
|
||||
|
||||
Traceroute(NetworkInterface interface, IPv4Address address)
|
||||
: iface(interface), addr(address), lowest_dest_ttl(numeric_limits<int>::max()) {
|
||||
sequence = random_device()() & 0xffff;
|
||||
}
|
||||
|
||||
result_type trace() {
|
||||
SnifferConfiguration config;
|
||||
config.set_promisc_mode(false);
|
||||
// ICMPs that aren't sent from us.
|
||||
config.set_filter(
|
||||
"ip proto \\icmp and not src host " + iface.addresses().ip_addr.to_string());
|
||||
Sniffer sniffer(iface.name(), config);
|
||||
|
||||
PacketSender sender;
|
||||
// Create our handler
|
||||
auto handler = bind(
|
||||
&Traceroute::sniff_callback,
|
||||
this,
|
||||
std::placeholders::_1
|
||||
);
|
||||
// We're running
|
||||
running = true;
|
||||
// Start the sniff thread
|
||||
thread sniff_thread(
|
||||
[&]() {
|
||||
sniffer.sniff_loop(handler);
|
||||
}
|
||||
);
|
||||
send_packets(sender);
|
||||
sniff_thread.join();
|
||||
// If the final hop responded, add its address at the appropriate ttl
|
||||
if (lowest_dest_ttl != numeric_limits<int>::max()) {
|
||||
results[lowest_dest_ttl] = addr;
|
||||
}
|
||||
// Clear our results and return what we've found
|
||||
return move(results);
|
||||
}
|
||||
private:
|
||||
typedef map<uint16_t, size_t> ttl_map;
|
||||
|
||||
void send_packets(PacketSender& sender) {
|
||||
// ICMPs are icmp-requests by default
|
||||
IP ip = IP(addr, iface.addresses().ip_addr) / ICMP();
|
||||
ICMP& icmp = ip.rfind_pdu<ICMP>();
|
||||
icmp.sequence(sequence);
|
||||
// We'll find at most 20 hops.
|
||||
|
||||
for (auto i = 1; i <= 20; ++i) {
|
||||
// Set this ICMP id
|
||||
icmp.id(i);
|
||||
// Set the time-to-live option
|
||||
ip.ttl(i);
|
||||
|
||||
// Critical section
|
||||
{
|
||||
lock_guard<mutex> _(lock);
|
||||
ttls[i] = i;
|
||||
}
|
||||
|
||||
sender.send(ip);
|
||||
// Give it a little time
|
||||
sleep_for(milliseconds(100));
|
||||
}
|
||||
running = false;
|
||||
sender.send(ip);
|
||||
}
|
||||
|
||||
bool sniff_callback(PDU& pdu) {
|
||||
// Find IP and ICMP PDUs
|
||||
const IP& ip = pdu.rfind_pdu<IP>();
|
||||
const ICMP& icmp = pdu.rfind_pdu<ICMP>();
|
||||
// Check if this is an ICMP TTL exceeded error response
|
||||
if (icmp.type() == ICMP::TIME_EXCEEDED) {
|
||||
// Fetch the IP PDU attached to the ICMP response
|
||||
const IP inner_ip = pdu.rfind_pdu<RawPDU>().to<IP>();
|
||||
// Now get the ICMP layer
|
||||
const ICMP& inner_icmp = inner_ip.rfind_pdu<ICMP>();
|
||||
// Make sure this is one of our packets.
|
||||
if (inner_icmp.sequence() == sequence) {
|
||||
ttl_map::const_iterator iter;
|
||||
|
||||
// Critical section
|
||||
{
|
||||
std::lock_guard<std::mutex> _(lock);
|
||||
iter = ttls.find(inner_icmp.id());
|
||||
}
|
||||
|
||||
// It's an actual response
|
||||
if(iter != ttls.end()) {
|
||||
// Store it
|
||||
results[inner_icmp.id()] = ip.src_addr();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise, this could be the final hop making an echo response
|
||||
else if (icmp.type() == ICMP::ECHO_REPLY && icmp.sequence() == sequence &&
|
||||
ip.src_addr() == addr) {
|
||||
// Keep the lowest ttl seen for the destination.
|
||||
lowest_dest_ttl = min(lowest_dest_ttl, static_cast<int>(icmp.id()));
|
||||
}
|
||||
return running;
|
||||
}
|
||||
|
||||
NetworkInterface iface;
|
||||
IPv4Address addr;
|
||||
atomic<bool> running;
|
||||
ttl_map ttls;
|
||||
result_type results;
|
||||
mutex lock;
|
||||
uint16_t sequence;
|
||||
int lowest_dest_ttl;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc <= 1) {
|
||||
cout << "Usage: " <<* argv << " <ip_address>" << endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
IPv4Address addr = string(argv[1]);
|
||||
Traceroute tracer(addr, addr);
|
||||
auto results = tracer.trace();
|
||||
if (results.empty()) {
|
||||
cout << "No hops found" << endl;
|
||||
}
|
||||
else {
|
||||
cout << "Results: " << endl;
|
||||
for(const auto& entry : results) {
|
||||
cout << setw(2) << entry.first << " - " << entry.second << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (runtime_error& ex) {
|
||||
cout << "Error - " << ex.what() << endl;
|
||||
return 2;
|
||||
}
|
||||
}
|
78
lib/libtins/examples/wps_detect.cpp
Normal file
78
lib/libtins/examples/wps_detect.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/tins.h>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
// BSSIDs which we've already seen
|
||||
std::set<HWAddress<6>> addrs;
|
||||
// This will be the content of the OUI field in the vendor specific
|
||||
// tagged option if it's a WPS tag.
|
||||
const HWAddress<3> expected_oui("00:50:F2");
|
||||
|
||||
bool handler(const PDU& pdu) {
|
||||
const Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
|
||||
// Only process it once
|
||||
if(addrs.insert(beacon.addr3()).second) {
|
||||
// Iterate the tagged options
|
||||
for(const auto& opt : beacon.options()) {
|
||||
// Is this a vendor-specific tag?
|
||||
if(opt.option() == Dot11::VENDOR_SPECIFIC) {
|
||||
// Make sure there's enough size for the OUI + identifier
|
||||
if(opt.data_size() >= 4) {
|
||||
// Retrieve the OUI field
|
||||
HWAddress<3> addr = opt.data_ptr();
|
||||
// Are we interested in this OUI and is it a WPS tag?
|
||||
if(addr == expected_oui && opt.data_ptr()[3] == 0x04) {
|
||||
std::cout << "[+] Access point: " << beacon.ssid() << " uses WPS\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc != 2) {
|
||||
std::cout << "Usage: " <<* argv << " <DEVICE>\n";
|
||||
return 1;
|
||||
}
|
||||
// Only sniff beacons
|
||||
SnifferConfiguration config;
|
||||
config.set_snap_len(2000);
|
||||
config.set_promisc_mode(true);
|
||||
config.set_filter("wlan type mgt subtype beacon");
|
||||
Sniffer sniffer(argv[1], config);
|
||||
sniffer.sniff_loop(handler);
|
||||
}
|
338
lib/libtins/include/tins/address_range.h
Normal file
338
lib/libtins/include/tins/address_range.h
Normal file
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ADDRESS_RANGE
|
||||
#define TINS_ADDRESS_RANGE
|
||||
|
||||
#include <iterator>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/exceptions.h>
|
||||
#include <tins/detail/address_helpers.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief AddressRange iterator class.
|
||||
*/
|
||||
template<typename Address>
|
||||
class AddressRangeIterator {
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef const Address value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const Address* pointer;
|
||||
typedef const Address& reference;
|
||||
|
||||
struct end_iterator {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs an iterator.
|
||||
*
|
||||
* \param first The address held by this iterator.
|
||||
*/
|
||||
AddressRangeIterator(const value_type& address)
|
||||
: address_(address), reached_end_(false) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an iterator.
|
||||
*
|
||||
* \param first The address held by this iterator.
|
||||
*/
|
||||
AddressRangeIterator(const value_type& address, end_iterator)
|
||||
: address_(address) {
|
||||
reached_end_ = Internals::increment(address_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current address pointed by this iterator.
|
||||
*/
|
||||
const value_type& operator*() const {
|
||||
return address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the current address pointed by this iterator.
|
||||
*/
|
||||
const value_type* operator->() const {
|
||||
return& address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two iterators for equality.
|
||||
*
|
||||
* \param rhs The iterator with which to compare.
|
||||
*/
|
||||
bool operator==(const AddressRangeIterator& rhs) const {
|
||||
return reached_end_ == rhs.reached_end_ && address_ == rhs.address_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two iterators for inequality.
|
||||
*
|
||||
* \param rhs The iterator with which to compare.
|
||||
*/
|
||||
bool operator!=(const AddressRangeIterator& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments this iterator.
|
||||
*/
|
||||
AddressRangeIterator& operator++() {
|
||||
reached_end_ = Internals::increment(address_);
|
||||
return* this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments this iterator.
|
||||
*/
|
||||
AddressRangeIterator operator++(int) {
|
||||
AddressRangeIterator copy(*this);
|
||||
(*this)++;
|
||||
return copy;
|
||||
}
|
||||
private:
|
||||
Address address_;
|
||||
bool reached_end_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents a range of addresses.
|
||||
*
|
||||
* This class provides a begin()/end() interface which allows
|
||||
* iterating through every address stored in it.
|
||||
*
|
||||
* Note that when iterating a range that was created using
|
||||
* operator/(IPv4Address, int) and the analog for IPv6, the
|
||||
* network and broadcast addresses are discarded:
|
||||
*
|
||||
* \code
|
||||
* auto range = IPv4Address("192.168.5.0") / 24;
|
||||
* for(const auto& addr : range) {
|
||||
* // process 192.168.5.1-254, .0 and .255 are discarded
|
||||
* process(addr);
|
||||
* }
|
||||
*
|
||||
* // That's only valid for iteration, not for AddressRange<>::contains
|
||||
*
|
||||
* assert(range.contains("192.168.5.0")); // works
|
||||
* assert(range.contains("192.168.5.255")); // works
|
||||
* \endcode
|
||||
*
|
||||
* Ranges created using AddressRange(address_type, address_type)
|
||||
* will allow the iteration over the entire range:
|
||||
*
|
||||
* \code
|
||||
* AddressRange<IPv4Address> range("192.168.5.0", "192.168.5.255");
|
||||
* for(const auto& addr : range) {
|
||||
* // process 192.168.5.0-255, no addresses are discarded
|
||||
* process(addr);
|
||||
* }
|
||||
*
|
||||
* assert(range.contains("192.168.5.0")); // still valid
|
||||
* assert(range.contains("192.168.5.255")); // still valid
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
template<typename Address>
|
||||
class AddressRange {
|
||||
public:
|
||||
/**
|
||||
* The type of addresses stored in the range.
|
||||
*/
|
||||
typedef Address address_type;
|
||||
|
||||
/**
|
||||
* The iterator type.
|
||||
*/
|
||||
typedef AddressRangeIterator<address_type> const_iterator;
|
||||
|
||||
/**
|
||||
* \brief The iterator type.
|
||||
*
|
||||
* This is the same type as const_iterator, since the
|
||||
* addresses stored in this range are read only.
|
||||
*/
|
||||
typedef const_iterator iterator;
|
||||
|
||||
/**
|
||||
* \brief Constructs an address range from two addresses.
|
||||
*
|
||||
* The range will consist of the addresses [first, last].
|
||||
*
|
||||
* If only_hosts is true, then the network and broadcast addresses
|
||||
* will not be available when iterating the range.
|
||||
*
|
||||
* If last < first, an std::runtime_error exception is thrown.
|
||||
*
|
||||
* \param first The first address in the range.
|
||||
* \param last The last address(inclusive) in the range.
|
||||
* \param only_hosts Indicates whether only host addresses
|
||||
* should be accessed when using iterators.
|
||||
*/
|
||||
AddressRange(const address_type& first, const address_type& last, bool only_hosts = false)
|
||||
: first_(first), last_(last), only_hosts_(only_hosts){
|
||||
if (last_ < first_) {
|
||||
throw exception_base("Invalid address range");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates an address range from a base address
|
||||
* and a network mask.
|
||||
*
|
||||
* \param first The base address.
|
||||
* \param mask The network mask to be used.
|
||||
*/
|
||||
static AddressRange from_mask(const address_type& first, const address_type& mask) {
|
||||
return AddressRange<address_type>(
|
||||
first & mask,
|
||||
Internals::last_address_from_mask(first, mask),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicates whether an address is included in this range.
|
||||
* \param addr The address to test.
|
||||
* \return a bool indicating whether the address is in the range.
|
||||
*/
|
||||
bool contains(const address_type& addr) const {
|
||||
return (first_ < addr && addr < last_) || addr == first_ || addr == last_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns an interator to the beginning of this range.
|
||||
* \brief const_iterator pointing to the beginning of this range.
|
||||
*/
|
||||
const_iterator begin() const {
|
||||
address_type addr = first_;
|
||||
if (only_hosts_) {
|
||||
Internals::increment(addr);
|
||||
}
|
||||
return const_iterator(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns an interator to the end of this range.
|
||||
* \brief const_iterator pointing to the end of this range.
|
||||
*/
|
||||
const_iterator end() const {
|
||||
address_type addr = last_;
|
||||
if (only_hosts_) {
|
||||
Internals::decrement(addr);
|
||||
}
|
||||
return const_iterator(addr, typename const_iterator::end_iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicates whether this range is iterable.
|
||||
*
|
||||
* Iterable ranges are those for which there is at least one
|
||||
* address that could represent a host. For IPv4 ranges, a /31 or
|
||||
* /32 ranges does not contain any, therefore it's not iterable.
|
||||
* The same is true for /127 and /128 IPv6 ranges.
|
||||
*
|
||||
* If is_iterable returns false for a range, then iterating it
|
||||
* through the iterators returned by begin() and end() is
|
||||
* undefined.
|
||||
*
|
||||
* \return bool indicating whether this range is iterable.
|
||||
*/
|
||||
bool is_iterable() const {
|
||||
// Since first < last, it's iterable
|
||||
if (!only_hosts_) {
|
||||
return true;
|
||||
}
|
||||
// We need that distance(first, last) >= 4
|
||||
address_type addr(first_);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
// If there's overflow before the last iteration, we're done
|
||||
if (Internals::increment(addr) && i != 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If addr <= last, it's OK.
|
||||
return addr < last_ || addr == last_;
|
||||
}
|
||||
private:
|
||||
address_type first_, last_;
|
||||
bool only_hosts_;
|
||||
};
|
||||
|
||||
/**
|
||||
* An IPv4 address range.
|
||||
*/
|
||||
typedef AddressRange<IPv4Address> IPv4Range;
|
||||
|
||||
/**
|
||||
* An IPv6 address range.
|
||||
*/
|
||||
typedef AddressRange<IPv6Address> IPv6Range;
|
||||
|
||||
/**
|
||||
* \brief Constructs an AddressRange from a base address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
template<size_t n>
|
||||
AddressRange<HWAddress<n> > operator/(const HWAddress<n>& addr, int mask) {
|
||||
if (mask > 48) {
|
||||
throw std::logic_error("Prefix length cannot exceed 48");
|
||||
}
|
||||
HWAddress<n> last_addr;
|
||||
typename HWAddress<n>::iterator it = last_addr.begin();
|
||||
while (mask > 8) {
|
||||
*it = 0xff;
|
||||
++it;
|
||||
mask -= 8;
|
||||
}
|
||||
*it = 0xff << (8 - mask);
|
||||
return AddressRange<HWAddress<6> >::from_mask(addr, last_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constructs an IPv6Range from a base IPv6Address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
IPv6Range operator/(const IPv6Address& addr, int mask);
|
||||
|
||||
/**
|
||||
* \brief Constructs an IPv4Range from a base IPv4Address and a mask.
|
||||
* \param addr The range's first address.
|
||||
* \param mask The bit-length of the prefix.
|
||||
*/
|
||||
IPv4Range operator/(const IPv4Address& addr, int mask);
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_ADDRESS_RANGE
|
344
lib/libtins/include/tins/arp.h
Normal file
344
lib/libtins/include/tins/arp.h
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TINS_ARP_H
|
||||
#define TINS_ARP_H
|
||||
|
||||
#include <tins/macros.h>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/hw_address.h>
|
||||
#include <tins/ip_address.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
class NetworkInterface;
|
||||
class EthernetII;
|
||||
|
||||
/**
|
||||
* \class ARP
|
||||
* \brief Represents an ARP PDU.
|
||||
*
|
||||
*/
|
||||
class TINS_API ARP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the hardware address.
|
||||
*/
|
||||
typedef HWAddress<6> hwaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the IP address.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::ARP;
|
||||
|
||||
/**
|
||||
* \brief Enum which indicates the type of ARP packet.
|
||||
*/
|
||||
enum Flags {
|
||||
REQUEST = 0x0001,
|
||||
REPLY = 0x0002
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Extracts metadata for this protocol based on the buffer provided
|
||||
*
|
||||
* \param buffer Pointer to a buffer
|
||||
* \param total_sz Size of the buffer pointed by buffer
|
||||
*/
|
||||
static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Constructs an ARP object using the provided addresses.
|
||||
*
|
||||
* ARP requests and replies can be constructed easily using
|
||||
* ARP::make_arp_request/reply static member functions.
|
||||
*
|
||||
* \sa ARP::make_arp_request
|
||||
* \sa ARP::make_arp_reply
|
||||
*
|
||||
* \param target_ip The target IP address.
|
||||
* \param sender_ip The sender IP address.
|
||||
* \param target_hw The target hardware address.
|
||||
* \param sender_hw The sender hardware address.
|
||||
*/
|
||||
ARP(ipaddress_type target_ip = ipaddress_type(),
|
||||
ipaddress_type sender_ip = ipaddress_type(),
|
||||
const hwaddress_type& target_hw = hwaddress_type(),
|
||||
const hwaddress_type& sender_hw = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs an ARP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for an ARP header in the buffer,
|
||||
* a malformed_packet exception is thrown.
|
||||
*
|
||||
* If the buffer is bigger than the size of the ARP header,
|
||||
* then the extra data is stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
ARP(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
/**
|
||||
* \brief Getter for the sender's hardware address.
|
||||
*
|
||||
* \return The sender hardware address.
|
||||
*/
|
||||
hwaddress_type sender_hw_addr() const {
|
||||
return header_.sender_hw_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the sender's IP address.
|
||||
*
|
||||
* \return The sender IP address.
|
||||
*/
|
||||
ipaddress_type sender_ip_addr() const {
|
||||
return ipaddress_type(header_.sender_ip_address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's hardware address.
|
||||
*
|
||||
* \return The target hardware address.
|
||||
*/
|
||||
hwaddress_type target_hw_addr() const {
|
||||
return header_.target_hw_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the target's IP address.
|
||||
*
|
||||
* \return The target IP address.
|
||||
*/
|
||||
ipaddress_type target_ip_addr() const {
|
||||
return ipaddress_type(header_.target_ip_address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address format field.
|
||||
*
|
||||
* \return The hardware address format.
|
||||
*/
|
||||
uint16_t hw_addr_format() const {
|
||||
return Endian::be_to_host(header_.hw_address_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address format field.
|
||||
*
|
||||
* \return The protocol address format.
|
||||
*/
|
||||
uint16_t prot_addr_format() const {
|
||||
return Endian::be_to_host(header_.proto_address_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hardware address length field.
|
||||
*
|
||||
* \return The hardware address length.
|
||||
*/
|
||||
uint8_t hw_addr_length() const {
|
||||
return header_.hw_address_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol address length field.
|
||||
*
|
||||
* \return The protocol address length.
|
||||
*/
|
||||
uint8_t prot_addr_length() const {
|
||||
return header_.proto_address_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the ARP opcode field.
|
||||
*
|
||||
* \return The ARP opcode.
|
||||
*/
|
||||
uint16_t opcode() const {
|
||||
return Endian::be_to_host(header_.opcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the ARP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's hardware address.
|
||||
*
|
||||
* \param address The new sender hardware address.
|
||||
*/
|
||||
void sender_hw_addr(const hwaddress_type& address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sender's IP address.
|
||||
*
|
||||
* \param address The new sender IP address.
|
||||
*/
|
||||
void sender_ip_addr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's hardware address.
|
||||
*
|
||||
* \param address The new target hardware address.
|
||||
*/
|
||||
void target_hw_addr(const hwaddress_type& address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the target's IP address.
|
||||
*
|
||||
* \param address The new target IP address.
|
||||
*/
|
||||
void target_ip_addr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address format field.
|
||||
*
|
||||
* \param format The new hardware address format.
|
||||
*/
|
||||
void hw_addr_format(uint16_t format);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address format field.
|
||||
*
|
||||
* \param format The new protocol address format.
|
||||
*/
|
||||
void prot_addr_format(uint16_t format);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware address length field.
|
||||
*
|
||||
* \param length The new hardware address length.
|
||||
*/
|
||||
void hw_addr_length(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol address length field.
|
||||
*
|
||||
* \param length The new protocol address length.
|
||||
*/
|
||||
void prot_addr_length(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ARP opcode field.
|
||||
*
|
||||
* \param code Flag enum value of the ARP opcode to set.
|
||||
*/
|
||||
void opcode(Flags code);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Request within an EthernetII PDU.
|
||||
*
|
||||
* Creates an ARP Request PDU and embeds it inside an EthernetII
|
||||
* PDU.
|
||||
*
|
||||
* \param target The target's IP address.
|
||||
* \param sender The sender's IP address.
|
||||
* \param hw_snd The sender's hardware address.
|
||||
* \return EthernetII object containing the ARP Request.
|
||||
*/
|
||||
static EthernetII make_arp_request(ipaddress_type target,
|
||||
ipaddress_type sender,
|
||||
const hwaddress_type& hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Creates an ARP Reply within an EthernetII PDU.
|
||||
*
|
||||
* Creates an ARP Reply PDU and embeds it inside an EthernetII
|
||||
* PDU.
|
||||
*
|
||||
* \param target The target's IP address.
|
||||
* \param sender The sender's IP address.
|
||||
* \param hw_tgt The target's hardware address.
|
||||
* \param hw_snd The sender's hardware address.
|
||||
* \return EthernetII object containing the ARP Reply.
|
||||
*/
|
||||
static EthernetII make_arp_reply(ipaddress_type target,
|
||||
ipaddress_type sender,
|
||||
const hwaddress_type& hw_tgt = hwaddress_type(),
|
||||
const hwaddress_type& hw_snd = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
ARP* clone() const {
|
||||
return new ARP(*this);
|
||||
}
|
||||
private:
|
||||
TINS_BEGIN_PACK
|
||||
struct arp_header {
|
||||
uint16_t hw_address_format;
|
||||
uint16_t proto_address_format;
|
||||
uint8_t hw_address_length;
|
||||
uint8_t proto_address_length;
|
||||
uint16_t opcode;
|
||||
uint8_t sender_hw_address[hwaddress_type::address_size];
|
||||
uint32_t sender_ip_address;
|
||||
uint8_t target_hw_address[hwaddress_type::address_size];
|
||||
uint32_t target_ip_address;
|
||||
} TINS_END_PACK;
|
||||
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
arp_header header_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_ARP_H
|
363
lib/libtins/include/tins/bootp.h
Normal file
363
lib/libtins/include/tins/bootp.h
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_BOOTP_H
|
||||
#define TINS_BOOTP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/macros.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/ip_address.h>
|
||||
#include <tins/hw_address.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \class BootP
|
||||
* \brief Represents a BootP PDU
|
||||
*/
|
||||
class TINS_API BootP : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type of the IP addresses.
|
||||
*/
|
||||
typedef IPv4Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* The type of the chaddr field.
|
||||
*/
|
||||
typedef HWAddress<16> chaddr_type;
|
||||
|
||||
/**
|
||||
* The type of the vend field.
|
||||
*/
|
||||
typedef std::vector<uint8_t> vend_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::BOOTP;
|
||||
|
||||
/**
|
||||
* \brief Enum which contains the different opcodes BootP messages.
|
||||
*/
|
||||
enum OpCodes {
|
||||
BOOTREQUEST = 1,
|
||||
BOOTREPLY = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of BootP.
|
||||
*
|
||||
* This sets the size of the vend field to 64, as the BootP RFC
|
||||
* states.
|
||||
*/
|
||||
BootP();
|
||||
|
||||
/**
|
||||
* \brief Constructs a BootP object from a buffer .
|
||||
*
|
||||
* If there's not enough size for a BootP header, then a
|
||||
* malformed_packet exception is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \param vend_field_size The vend field size to allocate.
|
||||
* Subclasses might use 0 to provide their own interpretation of this field.
|
||||
*/
|
||||
BootP(const uint8_t* buffer, uint32_t total_sz, uint32_t vend_field_size = 64);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the opcode field.
|
||||
* \return The opcode field for this BootP PDU.
|
||||
*/
|
||||
uint8_t opcode() const { return bootp_.opcode; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the htype field.
|
||||
* \return The htype field for this BootP PDU.
|
||||
*/
|
||||
uint8_t htype() const { return bootp_.htype; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hlen field.
|
||||
* \return The hlen field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hlen() const { return bootp_.hlen; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the hops field.
|
||||
* \return The hops field for this BootP PDU.
|
||||
*/
|
||||
uint8_t hops() const { return bootp_.hops; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the xid field.
|
||||
* \return The xid field for this BootP PDU.
|
||||
*/
|
||||
uint32_t xid() const { return Endian::be_to_host(bootp_.xid); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the secs field.
|
||||
* \return The secs field for this BootP PDU.
|
||||
*/
|
||||
uint16_t secs() const { return Endian::be_to_host(bootp_.secs); }
|
||||
|
||||
/** \brief Getter for the padding field.
|
||||
* \return The padding field for this BootP PDU.
|
||||
*/
|
||||
uint16_t padding() const { return Endian::be_to_host(bootp_.padding); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the ciaddr field.
|
||||
* \return The ciaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type ciaddr() const { return ipaddress_type(bootp_.ciaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the yiaddr field.
|
||||
* \return The yiaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type yiaddr() const { return ipaddress_type(bootp_.yiaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the siaddr field.
|
||||
* \return The siaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type siaddr() const { return ipaddress_type(bootp_.siaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the giaddr field.
|
||||
* \return The giaddr field for this BootP PDU.
|
||||
*/
|
||||
ipaddress_type giaddr() const { return ipaddress_type(bootp_.giaddr); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the chaddr field.
|
||||
* \return The chddr field for this BootP PDU.
|
||||
*/
|
||||
chaddr_type chaddr() const { return bootp_.chaddr; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sname field.
|
||||
* \return The sname field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t* sname() const { return bootp_.sname; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the file field.
|
||||
* \return The file field for this BootP PDU.
|
||||
*/
|
||||
const uint8_t* file() const { return bootp_.file; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
const vend_type& vend() const { return vend_; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
* \param code The opcode to be set.
|
||||
*/
|
||||
void opcode(uint8_t code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hardware type field.
|
||||
* \param type The hardware type field value to be set.
|
||||
*/
|
||||
void htype(uint8_t type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hlen field.
|
||||
* \param length The hlen field value to be set.
|
||||
*/
|
||||
void hlen(uint8_t length);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hops field.
|
||||
* \param count The hops field value to be set.
|
||||
*/
|
||||
void hops(uint8_t count);
|
||||
|
||||
/**
|
||||
* \brief Setter for the xid field.
|
||||
* \param identifier The xid to be set.
|
||||
*/
|
||||
void xid(uint32_t identifier);
|
||||
|
||||
/**
|
||||
* \brief Setter for the secs field.
|
||||
* \param value The secs to be set.
|
||||
*/
|
||||
void secs(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the padding field.
|
||||
* \param value The padding to be set.
|
||||
*/
|
||||
void padding(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the ciaddr field.
|
||||
* \param address The ciaddr to be set.
|
||||
*/
|
||||
void ciaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the yiaddr field.
|
||||
* \param address The yiaddr to be set.
|
||||
*/
|
||||
void yiaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the siaddr field.
|
||||
* \param address The siaddr to be set.
|
||||
*/
|
||||
void siaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the giaddr field.
|
||||
* \param address The giaddr to be set.
|
||||
*/
|
||||
void giaddr(ipaddress_type address);
|
||||
|
||||
/**
|
||||
* \brief Setter for the chaddr field.
|
||||
* The new_chaddr pointer must be at least BOOTP::hlen() bytes long.
|
||||
* \param new_chaddr The chaddr to be set.
|
||||
*/
|
||||
template<size_t n>
|
||||
void chaddr(const HWAddress<n>& new_chaddr) {
|
||||
size_t copy_threshold = std::min(n, sizeof(bootp_.chaddr));
|
||||
for (size_t i = 0; i < copy_threshold; ++i) {
|
||||
if (i < copy_threshold) {
|
||||
bootp_.chaddr[i] = new_chaddr[i];
|
||||
}
|
||||
else {
|
||||
bootp_.chaddr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the sname field.
|
||||
* \param new_sname The sname to be set.
|
||||
*/
|
||||
void sname(const uint8_t* new_sname);
|
||||
|
||||
/**
|
||||
* \brief Setter for the file field.
|
||||
* \param new_file The file to be set.
|
||||
*/
|
||||
void file(const uint8_t* new_file);
|
||||
|
||||
/**
|
||||
* \brief Setter for the vend field.
|
||||
* \param newvend_ The vend to be set.
|
||||
*/
|
||||
void vend(const vend_type& newvend_);
|
||||
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* This returns true if the xid field is equal.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
BootP* clone() const {
|
||||
return new BootP(*this);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* \brief Getter for the vend field.
|
||||
*
|
||||
* This getter can be used by subclasses to avoid copying the
|
||||
* vend field around.
|
||||
*
|
||||
* \return The vend field for this BootP PDU.
|
||||
*/
|
||||
vend_type& vend() { return vend_; }
|
||||
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* Struct that represents the Bootp datagram.
|
||||
*/
|
||||
TINS_BEGIN_PACK
|
||||
struct bootp_header {
|
||||
uint8_t opcode;
|
||||
uint8_t htype;
|
||||
uint8_t hlen;
|
||||
uint8_t hops;
|
||||
uint32_t xid;
|
||||
uint16_t secs;
|
||||
uint16_t padding;
|
||||
uint32_t ciaddr;
|
||||
uint32_t yiaddr;
|
||||
uint32_t siaddr;
|
||||
uint32_t giaddr;
|
||||
uint8_t chaddr[16];
|
||||
uint8_t sname[64];
|
||||
uint8_t file[128];
|
||||
} TINS_END_PACK;
|
||||
|
||||
private:
|
||||
bootp_header bootp_;
|
||||
vend_type vend_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_BOOTP_H
|
39
lib/libtins/include/tins/config.h.in
Normal file
39
lib/libtins/include/tins/config.h.in
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef TINS_CONFIG_H
|
||||
#define TINS_CONFIG_H
|
||||
|
||||
/* Define if the compiler supports basic C++11 syntax */
|
||||
#cmakedefine TINS_HAVE_CXX11
|
||||
|
||||
/* Have IEEE 802.11 support */
|
||||
#cmakedefine TINS_HAVE_DOT11
|
||||
|
||||
/* Have WPA2 decryption library */
|
||||
#cmakedefine TINS_HAVE_WPA2_DECRYPTION
|
||||
|
||||
/* Use pcap_sendpacket to send l2 packets */
|
||||
#cmakedefine TINS_HAVE_PACKET_SENDER_PCAP_SENDPACKET
|
||||
|
||||
/* Have TCPIP classes */
|
||||
#cmakedefine TINS_HAVE_TCPIP
|
||||
|
||||
/* Have TCP ACK tracking */
|
||||
#cmakedefine TINS_HAVE_ACK_TRACKER
|
||||
|
||||
/* Have TCP stream custom data */
|
||||
#cmakedefine TINS_HAVE_TCP_STREAM_CUSTOM_DATA
|
||||
|
||||
/* Have GCC builtin swap */
|
||||
#cmakedefine TINS_HAVE_GCC_BUILTIN_SWAP
|
||||
|
||||
/* Have WPA2Decrypter callbacks */
|
||||
#cmakedefine TINS_HAVE_WPA2_CALLBACKS
|
||||
|
||||
/* Have libpcap */
|
||||
#cmakedefine TINS_HAVE_PCAP
|
||||
|
||||
/* Version macros */
|
||||
#define TINS_VERSION_MAJOR ${TINS_VERSION_MAJOR}
|
||||
#define TINS_VERSION_MINOR ${TINS_VERSION_MINOR}
|
||||
#define TINS_VERSION_PATCH ${TINS_VERSION_PATCH}
|
||||
|
||||
#endif // TINS_CONFIG_H
|
163
lib/libtins/include/tins/constants.h
Normal file
163
lib/libtins/include/tins/constants.h
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_CONSTANTS_H
|
||||
#define TINS_CONSTANTS_H
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Constants used in protocols.
|
||||
*/
|
||||
namespace Constants {
|
||||
/** \cond */
|
||||
struct IP {
|
||||
/** \endcond */
|
||||
enum e {
|
||||
PROTO_IP = 0, // Dummy protocol for TCP.
|
||||
PROTO_HOPOPTS = 0, // IPv6 Hop-by-Hop options.
|
||||
PROTO_ICMP = 1, // Internet Control Message Protocol.
|
||||
PROTO_IGMP = 2, // Internet Group Management Protocol.
|
||||
PROTO_IPIP = 4, // IPIP tunnels (older KA9Q tunnels use 94).
|
||||
PROTO_TCP = 6, // Transmission Control Protocol.
|
||||
PROTO_EGP = 8, // Exterior Gateway Protocol.
|
||||
PROTO_PUP = 12, // PUP protocol.
|
||||
PROTO_UDP = 17, // User Datagram Protocol.
|
||||
PROTO_IDP = 22, // XNS IDP protocol.
|
||||
PROTO_TP = 29, // SO Transport Protocol Class 4.
|
||||
PROTO_DCCP = 33, // Datagram Congestion Control Protocol.
|
||||
PROTO_IPV6 = 41, // IPv6 header.
|
||||
PROTO_ROUTING = 43, // IPv6 routing header.
|
||||
PROTO_FRAGMENT = 44, // IPv6 fragmentation header.
|
||||
PROTO_RSVP = 46, // Reservation Protocol.
|
||||
PROTO_GRE = 47, // General Routing Encapsulation.
|
||||
PROTO_ESP = 50, // encapsulating security payload.
|
||||
PROTO_AH = 51, // authentication header.
|
||||
PROTO_ICMPV6 = 58, // ICMPv6.
|
||||
PROTO_NONE = 59, // IPv6 no next header.
|
||||
PROTO_DSTOPTS = 60, // IPv6 destination options.
|
||||
PROTO_MTP = 92, // Multicast Transport Protocol.
|
||||
PROTO_ENCAP = 98, // Encapsulation Header.
|
||||
PROTO_PIM = 103, // Protocol Independent Multicast.
|
||||
PROTO_COMP = 108, // Compression Header Protocol.
|
||||
PROTO_SCTP = 132, // Stream Control Transmission Protocol.
|
||||
PROTO_UDPLITE = 136, // UDP-Lite protocol.
|
||||
PROTO_RAW = 255 // Raw IP packets.
|
||||
};
|
||||
};
|
||||
|
||||
struct Ethernet {
|
||||
enum e {
|
||||
UNKNOWN = 0,
|
||||
SPRITE = 0x0500, // Sprite
|
||||
IP = 0x0800, // IP
|
||||
ARP = 0x0806, // Address resolution
|
||||
MPLS = 0x8847, // MPLS
|
||||
REVARP = 0x8035, // Reverse ARP
|
||||
AT = 0x809B, // AppleTalk protocol
|
||||
AARP = 0x80F3, // AppleTalk ARP
|
||||
VLAN = 0x8100, // IEEE 802.1Q VLAN tagging
|
||||
QINQ = 0x88a8, // IEEE 802.1ad VLAN tagging
|
||||
OLD_QINQ = 0x9100, // IEEE 802.1ad VLAN tagging (old, deprecated, value)
|
||||
IPX = 0x8137, // IPX
|
||||
IPV6 = 0x86dd, // IP protocol version 6
|
||||
PPPOED = 0x8863, // PPPoE Discovery
|
||||
PPPOES = 0x8864, // PPPoE Session
|
||||
EAPOL = 0x888e, // EAPOL
|
||||
LOOPBACK = 0x9000 // used to test interfaces
|
||||
};
|
||||
};
|
||||
|
||||
struct ARP {
|
||||
enum e {
|
||||
NETROM = 0, // From KA9Q: NET/ROM pseudo.
|
||||
ETHER = 1, // Ethernet 10/100Mbps.
|
||||
EETHER = 2, // Experimental Ethernet.
|
||||
AX25 = 3, // AX.25 Level 2.
|
||||
PRONET = 4, // PROnet token ring.
|
||||
CHAOS = 5, // Chaosnet.
|
||||
IEEE802 = 6, // IEEE 802.2 Ethernet/TR/TB.
|
||||
ARCNET = 7, // ARCnet.
|
||||
APPLETLK = 8, // APPLEtalk.
|
||||
DLCI = 15, // Frame Relay DLCI.
|
||||
ATM = 19, // ATM.
|
||||
METRICOM = 23, // Metricom STRIP (new IANA id).
|
||||
IEEE1394 = 24, // IEEE 1394 IPv4 - RFC 2734.
|
||||
EUI64 = 27, // EUI-64.
|
||||
INFINIBAND = 32, // InfiniBand.
|
||||
SLIP = 256,
|
||||
CSLIP = 257,
|
||||
SLIP6 = 258,
|
||||
CSLIP6 = 259,
|
||||
RSRVD = 260, // Notional KISS type.
|
||||
ADAPT = 264,
|
||||
ROSE = 270,
|
||||
X25 = 271, // CCITT X.25.
|
||||
HWX25 = 272, // Boards with X.25 in firmware.
|
||||
PPP = 512,
|
||||
CISCO = 513, // Cisco HDLC.
|
||||
HDLC = CISCO,
|
||||
LAPB = 516, // LAPB.
|
||||
DDCMP = 517, // Digital's DDCMP.
|
||||
RAWHDLC = 518, // Raw HDLC.
|
||||
TUNNEL = 768, // IPIP tunnel.
|
||||
TUNNEL6 = 769, // IPIP6 tunnel.
|
||||
FRAD = 770, // Frame Relay Access Device.
|
||||
SKIP = 771, // SKIP vif.
|
||||
LOOPBACK = 772, // Loopback device.
|
||||
LOCALTLK = 773, // Localtalk device.
|
||||
FDDI = 774, // Fiber Distributed Data Interface.
|
||||
BIF = 775, // AP1000 BIF.
|
||||
SIT = 776, // sit0 device - IPv6-in-IPv4.
|
||||
IPDDP = 777, // IP-in-DDP tunnel.
|
||||
IPGRE = 778, // GRE over IP.
|
||||
PIMREG = 779, // PIMSM register interface.
|
||||
HIPPI = 780, // High Performance Parallel I'face.
|
||||
ASH = 781, // (Nexus Electronics) Ash.
|
||||
ECONET = 782, // Acorn Econet.
|
||||
IRDA = 783, // Linux-IrDA.
|
||||
FCPP = 784, // Point to point fibrechanel.
|
||||
FCAL = 785, // Fibrechanel arbitrated loop.
|
||||
FCPL = 786, // Fibrechanel public loop.
|
||||
FCFABRIC = 787, // Fibrechanel fabric.
|
||||
IEEE802_TR = 800, // Magic type ident for TR.
|
||||
IEEE80211 = 801, // IEEE 802.11.
|
||||
IEEE80211_PRISM = 802, // IEEE 802.11 + Prism2 header.
|
||||
IEEE80211_RADIOTAP = 803, // IEEE 802.11 + radiotap header.
|
||||
IEEE802154 = 804, // IEEE 802.15.4 header.
|
||||
IEEE802154_PHY = 805, // IEEE 802.15.4 PHY header.
|
||||
VOID_TYPE = 0xFFFF, // Void type, nothing is known.
|
||||
NONE = 0xFFFE // Zero header length.
|
||||
};
|
||||
};
|
||||
|
||||
} // Constants
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_CONSTANTS_H
|
536
lib/libtins/include/tins/crypto.h
Normal file
536
lib/libtins/include/tins/crypto.h
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_CRYPTO_H) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_CRYPTO_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||
#include <functional>
|
||||
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||
#include <tins/macros.h>
|
||||
#include <tins/handshake_capturer.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
class PDU;
|
||||
class Dot11;
|
||||
class Dot11Data;
|
||||
class SNAP;
|
||||
class RawPDU;
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||
namespace WPA2 {
|
||||
|
||||
/**
|
||||
* \brief Class that represents the keys used to decrypt a session.
|
||||
*/
|
||||
class TINS_API SessionKeys {
|
||||
public:
|
||||
/**
|
||||
* The size of the Pairwise Master Key.
|
||||
*/
|
||||
static const size_t PMK_SIZE;
|
||||
|
||||
/**
|
||||
* The size of the Pairwise Transient Key.
|
||||
*/
|
||||
static const size_t PTK_SIZE;
|
||||
|
||||
/**
|
||||
* The type used to hold the PTK (this has to be PTK_SIZE bytes long).
|
||||
*/
|
||||
typedef std::vector<uint8_t> ptk_type;
|
||||
|
||||
/**
|
||||
* The type used to hold the PMK (this has to be PMK_SIZE bytes long).
|
||||
*/
|
||||
typedef std::vector<uint8_t> pmk_type;
|
||||
|
||||
/**
|
||||
* Default constructs a SessionKeys object.
|
||||
*/
|
||||
SessionKeys();
|
||||
|
||||
/**
|
||||
* \brief Constructs an instance using the provided PTK and a flag
|
||||
* indicating whether it should use ccmp.
|
||||
*
|
||||
* \param ptk The PTK to use.
|
||||
* \param is_ccmp Indicates whether to use CCMP to decrypt this traffic.
|
||||
*/
|
||||
SessionKeys(const ptk_type& ptk, bool is_ccmp);
|
||||
|
||||
/**
|
||||
* \brief Constructs an instance using a handshake and a PMK.
|
||||
*
|
||||
* This will internally construct the PTK from the input parameters.
|
||||
*
|
||||
* \param hs The handshake to use.
|
||||
* \param pmk The PMK to use.
|
||||
*/
|
||||
SessionKeys(const RSNHandshake& hs, const pmk_type& pmk);
|
||||
|
||||
/**
|
||||
* \brief Decrypts a unicast packet.
|
||||
*
|
||||
* \param dot11 The encrypted packet to decrypt.
|
||||
* \param raw The raw layer on the packet to decrypt.
|
||||
* \return A SNAP layer containing the decrypted traffic or a null pointer
|
||||
* if decryption failed.
|
||||
*/
|
||||
SNAP* decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
|
||||
|
||||
/**
|
||||
* \brief Gets the PTK for this session keys.
|
||||
* \return The Pairwise Transcient Key.
|
||||
*/
|
||||
const ptk_type& get_ptk() const;
|
||||
|
||||
/**
|
||||
* \brief Indicates whether CCMP is used to decrypt packets
|
||||
* /return true iff CCMP is used.
|
||||
*/
|
||||
bool uses_ccmp() const;
|
||||
private:
|
||||
SNAP* ccmp_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
|
||||
SNAP* tkip_decrypt_unicast(const Dot11Data& dot11, RawPDU& raw) const;
|
||||
|
||||
ptk_type ptk_;
|
||||
bool is_ccmp_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents a WPA2 supplicant's data.
|
||||
*
|
||||
* Objects of this class can be given the pre-shared key and the SSID
|
||||
* of some access point, and this will generate the Pairwise Master Key
|
||||
* from those parameters.
|
||||
*/
|
||||
class TINS_API SupplicantData {
|
||||
public:
|
||||
/**
|
||||
* The type used to store the PMK.
|
||||
*/
|
||||
typedef SessionKeys::pmk_type pmk_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs a SupplicantData.
|
||||
* \param psk The pre-shared key.
|
||||
* \param ssid The access point's SSID.
|
||||
*/
|
||||
SupplicantData(const std::string& psk, const std::string& ssid);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PMK.
|
||||
* \return The generated PMK.
|
||||
*/
|
||||
const pmk_type& pmk() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the SSID
|
||||
* \return The access point's SSID
|
||||
*/
|
||||
const std::string& ssid() const;
|
||||
private:
|
||||
pmk_type pmk_;
|
||||
std::string ssid_;
|
||||
};
|
||||
|
||||
} // WPA2
|
||||
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||
|
||||
/**
|
||||
* \brief Decrypts WEP-encrypted traffic.
|
||||
*/
|
||||
class TINS_API WEPDecrypter {
|
||||
public:
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs a WEPDecrypter object.
|
||||
*/
|
||||
WEPDecrypter();
|
||||
|
||||
/**
|
||||
* \brief Adds a decryption password.
|
||||
*
|
||||
* \param addr The access point's BSSID.
|
||||
* \param password The password which will be used to decrypt
|
||||
* packets sent from and to the AP identifier by the BSSID addr.
|
||||
*/
|
||||
void add_password(const address_type& addr, const std::string& password);
|
||||
|
||||
/**
|
||||
* \brief Removes a decryption password
|
||||
*
|
||||
* \param addr The BSSID of the access point.
|
||||
*/
|
||||
void remove_password(const address_type& addr);
|
||||
|
||||
/**
|
||||
* \brief Decrypts the provided PDU.
|
||||
*
|
||||
* A Dot11Data PDU is looked up inside the provided PDU chain.
|
||||
* If no such PDU exists or there is no password associated
|
||||
* with the Dot11 packet's BSSID, then the PDU is left intact.
|
||||
*
|
||||
* Otherwise, the packet is decrypted using the given password.
|
||||
* If the CRC found after decrypting is invalid, false is
|
||||
* returned.
|
||||
*
|
||||
* \return false if no decryption was performed or decryption
|
||||
* failed, true otherwise.
|
||||
*/
|
||||
bool decrypt(PDU& pdu);
|
||||
private:
|
||||
typedef std::map<address_type, std::string> passwords_type;
|
||||
|
||||
PDU* decrypt(RawPDU& raw, const std::string& password);
|
||||
|
||||
passwords_type passwords_;
|
||||
std::vector<uint8_t> key_buffer_;
|
||||
};
|
||||
|
||||
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||
/**
|
||||
* \brief Decrypts WPA2-encrypted traffic.
|
||||
*
|
||||
* This class takes valid PSK and SSID tuples, captures client handshakes,
|
||||
* and decrypts their traffic afterwards.
|
||||
*/
|
||||
class TINS_API WPA2Decrypter {
|
||||
public:
|
||||
/*
|
||||
* \brief The type used to store Dot11 addresses.
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief Represents a pair of mac addresses.
|
||||
*
|
||||
* This is used to identify a host and the access point to which
|
||||
* it is connected. The first element in the pair will always de
|
||||
* lower or equal than the second one, so that given any host and
|
||||
* the access point it's connected to, we can uniquely identify
|
||||
* it with an address pair.
|
||||
*/
|
||||
typedef std::pair<address_type, address_type> addr_pair;
|
||||
|
||||
/**
|
||||
* \brief Maps an address pair to the session keys.
|
||||
*
|
||||
* This type associates an address pair (host, access point) with the
|
||||
* session keys, as generated using the packets seen on a handshake.
|
||||
*
|
||||
* \sa addr_pair
|
||||
*/
|
||||
typedef std::map<addr_pair, WPA2::SessionKeys> keys_map;
|
||||
|
||||
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||
|
||||
/**
|
||||
* \brief The type used to store the callback type used when a new access
|
||||
* point is found.
|
||||
*
|
||||
* The first argument to the function will be the access point's SSID and
|
||||
* the second one its BSSID.
|
||||
*/
|
||||
typedef std::function<void(const std::string&,
|
||||
const address_type&)> ap_found_callback_type;
|
||||
|
||||
/**
|
||||
* The type used to store the callback type used when a new handshake
|
||||
* is captured.
|
||||
*
|
||||
* The first argument to the function will be the access point's SSID and
|
||||
* the second one its BSSID. The third argument will be the client's hardware
|
||||
* address.
|
||||
*/
|
||||
typedef std::function<void(const std::string&,
|
||||
const address_type&,
|
||||
const address_type&)> handshake_captured_callback_type;
|
||||
|
||||
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||
|
||||
/**
|
||||
* \brief Adds an access points's information.
|
||||
*
|
||||
* This associates an SSID with a PSK, and allows the decryption of
|
||||
* any BSSIDs that broadcast the same SSID.
|
||||
*
|
||||
* The decrypter will inspect beacon frames, looking for SSID tags
|
||||
* that contain the given SSID.
|
||||
*
|
||||
* Note that using this overload, the decryption of data frames and
|
||||
* handshake capturing will be disabled until any access point
|
||||
* broadcasts the provided SSID(this shouldn't take long at all).
|
||||
* If this is not the desired behaviour, then you should check out
|
||||
* the ovther add_ap_data overload.
|
||||
*
|
||||
* \param psk The PSK associated with the SSID.
|
||||
* \param ssid The network's SSID.
|
||||
*/
|
||||
void add_ap_data(const std::string& psk, const std::string& ssid);
|
||||
|
||||
/**
|
||||
* \brief Adds a access points's information, including its BSSID.
|
||||
*
|
||||
* This overload can be used if the BSSID associated with this SSID is
|
||||
* known beforehand. The addr parameter indicates which specific BSSID
|
||||
* is associated to the SSID.
|
||||
*
|
||||
* Note that if any other access point broadcasts the provided SSID,
|
||||
* it will be taken into account as well.
|
||||
*
|
||||
* \param psk The PSK associated with this SSID.
|
||||
* \param ssid The network's SSID.
|
||||
* \param addr The access point's BSSID.
|
||||
*/
|
||||
void add_ap_data(const std::string& psk,
|
||||
const std::string& ssid,
|
||||
const address_type& addr);
|
||||
|
||||
/**
|
||||
* \brief Explicitly add decryption keys.
|
||||
*
|
||||
* This method associates a pair (host, access point) with the given decryption keys.
|
||||
* All encrypted packets sent between the given addresses will be decrypted using the
|
||||
* provided keys.
|
||||
*
|
||||
* This method shouldn't normally be required. The WPA2Decrypter will be waiting for
|
||||
* handshakes and will automatically extract the session keys, decrypting all
|
||||
* encrypted packets with them. You should only use this method if for some reason
|
||||
* you know the actual keys being used (because you checked and stored the keys_map
|
||||
* somewhere).
|
||||
*
|
||||
* The actual order of the addresses doesn't matter, this method will make sure
|
||||
* they're sorted.
|
||||
*
|
||||
* \param addresses The address pair (host, access point) to associate.
|
||||
* \param session_keys The keys to use when decrypting messages sent between the
|
||||
* given addresses.
|
||||
*/
|
||||
void add_decryption_keys(const addr_pair& addresses,
|
||||
const WPA2::SessionKeys& session_keys);
|
||||
|
||||
/**
|
||||
* \brief Decrypts the provided PDU.
|
||||
*
|
||||
* A Dot11Data PDU is looked up inside the provided PDU chain.
|
||||
* If no such PDU exists or no PSK was associated with the SSID
|
||||
* broadcasted by the Dot11 packet's BSSID, or no EAPOL handshake
|
||||
* was captured for the client involved in the communication,
|
||||
* then the PDU is left intact.
|
||||
*
|
||||
* Otherwise, the packet is decrypted using the generated PTK.
|
||||
* If the resulting MIC is invalid, then the packet is left intact.
|
||||
*
|
||||
* \return false if no decryption was performed, or the decryption
|
||||
* failed, true otherwise.
|
||||
*/
|
||||
bool decrypt(PDU& pdu);
|
||||
|
||||
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||
/**
|
||||
* \brief Sets the handshake captured callback
|
||||
*
|
||||
* This callback will be executed every time a new handshake is captured.
|
||||
*
|
||||
* \sa handshake_captured_callback_type
|
||||
* \param callback The new callback to be set
|
||||
*/
|
||||
void handshake_captured_callback(const handshake_captured_callback_type& callback);
|
||||
|
||||
/**
|
||||
* \brief Sets the access point found callback
|
||||
*
|
||||
* This callback will be executed every time a new access point is found, that's
|
||||
* advertising an SSID added when calling add_ap_data.
|
||||
*
|
||||
* \sa ap_found_callback_type
|
||||
* \param callback The new callback to be set
|
||||
*/
|
||||
void ap_found_callback(const ap_found_callback_type& callback);
|
||||
|
||||
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||
|
||||
/**
|
||||
* \brief Getter for the keys on this decrypter
|
||||
*
|
||||
* The returned map will be populated every time a new, complete, handshake
|
||||
* is captured.
|
||||
*
|
||||
* \return The WPA2Decrypter keys map.
|
||||
*/
|
||||
const keys_map& get_keys() const;
|
||||
private:
|
||||
typedef std::map<std::string, WPA2::SupplicantData> pmks_map;
|
||||
typedef std::map<address_type, WPA2::SupplicantData> bssids_map;
|
||||
|
||||
void try_add_keys(const Dot11Data& dot11, const RSNHandshake& hs);
|
||||
addr_pair make_addr_pair(const address_type& addr1, const address_type& addr2) {
|
||||
return (addr1 < addr2) ?
|
||||
std::make_pair(addr1, addr2) :
|
||||
std::make_pair(addr2, addr1);
|
||||
}
|
||||
addr_pair extract_addr_pair(const Dot11Data& dot11);
|
||||
addr_pair extract_addr_pair_dst(const Dot11Data& dot11);
|
||||
bssids_map::const_iterator find_ap(const Dot11Data& dot11);
|
||||
void add_access_point(const std::string& ssid, const address_type& addr);
|
||||
|
||||
RSNHandshakeCapturer capturer_;
|
||||
pmks_map pmks_;
|
||||
bssids_map aps_;
|
||||
keys_map keys_;
|
||||
#ifdef TINS_HAVE_WPA2_CALLBACKS
|
||||
handshake_captured_callback_type handshake_captured_callback_;
|
||||
ap_found_callback_type ap_found_callback_;
|
||||
#endif // TINS_HAVE_WPA2_CALLBACKS
|
||||
};
|
||||
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||
|
||||
/**
|
||||
* \brief Pluggable decrypter object which can be used to decrypt
|
||||
* data on sniffing sessions.
|
||||
*
|
||||
* This class holds a decrypter object and a functor, and implements
|
||||
* a suitable operator() to be used on BaseSniffer::sniff_loop, which
|
||||
* decrypts packets and forwards them to the given functor.
|
||||
*/
|
||||
template<typename Functor, typename Decrypter>
|
||||
class DecrypterProxy {
|
||||
public:
|
||||
/**
|
||||
* The type of the functor object.
|
||||
*/
|
||||
typedef Functor functor_type;
|
||||
|
||||
/**
|
||||
* The type of the decrypter object.
|
||||
*/
|
||||
typedef Decrypter decrypter_type;
|
||||
|
||||
/**
|
||||
* \brief Constructs an object from a functor and a decrypter.
|
||||
* \param func The functor to be used to forward decrypted
|
||||
* packets.
|
||||
* \param decrypter The decrypter which will be used to decrypt
|
||||
* packets
|
||||
*/
|
||||
DecrypterProxy(const functor_type& func,
|
||||
const decrypter_type& decr = decrypter_type());
|
||||
|
||||
/**
|
||||
* \brief Retrieves a reference to the decrypter object.
|
||||
*/
|
||||
decrypter_type& decrypter();
|
||||
|
||||
/**
|
||||
* \brief Retrieves a const reference to the decrypter object.
|
||||
*/
|
||||
const decrypter_type& decrypter() const;
|
||||
|
||||
/**
|
||||
* \brief The operator() which decrypts packets and forwards
|
||||
* them to the functor.
|
||||
*/
|
||||
bool operator() (PDU& pdu);
|
||||
private:
|
||||
Functor functor_;
|
||||
decrypter_type decrypter_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Wrapper function to create a DecrypterProxy using a
|
||||
* WEPDecrypter as the Decrypter template parameter.
|
||||
*
|
||||
* \param functor The functor to be forwarded to the DecrypterProxy
|
||||
* constructor.
|
||||
*/
|
||||
template<typename Functor>
|
||||
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor);
|
||||
|
||||
#ifdef TINS_HAVE_WPA2_DECRYPTION
|
||||
/**
|
||||
* \brief Wrapper function to create a DecrypterProxy using a
|
||||
* WPA2Decrypter as the Decrypter template parameter.
|
||||
*
|
||||
* \param functor The functor to be forwarded to the DecrypterProxy
|
||||
* constructor.
|
||||
*/
|
||||
template<typename Functor>
|
||||
DecrypterProxy<Functor, WPA2Decrypter> make_wpa2_decrypter_proxy(const Functor& functor) {
|
||||
return DecrypterProxy<Functor, WPA2Decrypter>(functor);
|
||||
}
|
||||
#endif // TINS_HAVE_WPA2_DECRYPTION
|
||||
|
||||
// Implementation section
|
||||
|
||||
// DecrypterProxy
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
DecrypterProxy<Functor, Decrypter>::DecrypterProxy(const functor_type& func,
|
||||
const decrypter_type& decr)
|
||||
: functor_(func), decrypter_(decr) {
|
||||
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
|
||||
DecrypterProxy<Functor, Decrypter>::decrypter() {
|
||||
return decrypter_;
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
const typename DecrypterProxy<Functor, Decrypter>::decrypter_type &
|
||||
DecrypterProxy<Functor, Decrypter>::decrypter() const {
|
||||
return decrypter_;
|
||||
}
|
||||
|
||||
template<typename Functor, typename Decrypter>
|
||||
bool DecrypterProxy<Functor, Decrypter>::operator() (PDU& pdu) {
|
||||
return decrypter_.decrypt(pdu) ? functor_(pdu) : true;
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
DecrypterProxy<Functor, WEPDecrypter> make_wep_decrypter_proxy(const Functor& functor) {
|
||||
return DecrypterProxy<Functor, WEPDecrypter>(functor);
|
||||
}
|
||||
|
||||
} // Crypto
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_CRYPTO_H
|
53
lib/libtins/include/tins/cxxstd.h
Normal file
53
lib/libtins/include/tins/cxxstd.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_CXXSTD_H
|
||||
#define TINS_CXXSTD_H
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
#define TINS_CXXSTD_GCC_FIX 1
|
||||
#else
|
||||
#define TINS_CXXSTD_GCC_FIX 0
|
||||
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||
|
||||
#if !defined(TINS_IS_CXX11) && defined(TINS_HAVE_CXX11)
|
||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1 || _MSC_VER >= 1800)
|
||||
#elif !defined(TINS_IS_CXX11)
|
||||
#define TINS_IS_CXX11 0
|
||||
#endif // TINS_IS_CXX11
|
||||
|
||||
namespace Tins{
|
||||
namespace Internals {
|
||||
template<class T> void unused(const T&) { }
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TINS_CXXSTD_H
|
83
lib/libtins/include/tins/data_link_type.h
Normal file
83
lib/libtins/include/tins/data_link_type.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DATA_LINK_TYPE_H
|
||||
#define TINS_DATA_LINK_TYPE_H
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
class EthernetII;
|
||||
class RadioTap;
|
||||
class Dot11;
|
||||
class Dot3;
|
||||
class SLL;
|
||||
class Loopback;
|
||||
class PPI;
|
||||
class IP;
|
||||
|
||||
/**
|
||||
* \struct DataLinkType
|
||||
* \brief Maps a libtins link layer PDU to a libpcap data link identifier.
|
||||
*
|
||||
* This is an empty class that should be instantiated with any object that
|
||||
* represents a link layer PDU (EthernetII, Dot11, RadioTap, etc):
|
||||
*
|
||||
* \code
|
||||
* // Instantiate it and pass it to PacketWriter's constructor.
|
||||
* PacketWriter writer("file.pcap", DataLinkType<RadioTap>());
|
||||
* \endcode
|
||||
*/
|
||||
template<typename T>
|
||||
struct DataLinkType;
|
||||
|
||||
#define TINS_MAKE_DATA_LINK_TYPE(tins_type, pcap_type) \
|
||||
template<> \
|
||||
struct DataLinkType<tins_type> { \
|
||||
static const int type = pcap_type; \
|
||||
int get_type() const { \
|
||||
return type; \
|
||||
} \
|
||||
};
|
||||
|
||||
TINS_MAKE_DATA_LINK_TYPE(EthernetII, DLT_EN10MB)
|
||||
TINS_MAKE_DATA_LINK_TYPE(Dot3, DLT_EN10MB)
|
||||
TINS_MAKE_DATA_LINK_TYPE(SLL, DLT_LINUX_SLL)
|
||||
TINS_MAKE_DATA_LINK_TYPE(Loopback, DLT_LOOP)
|
||||
TINS_MAKE_DATA_LINK_TYPE(PPI, DLT_PPI)
|
||||
TINS_MAKE_DATA_LINK_TYPE(Dot11, DLT_IEEE802_11)
|
||||
TINS_MAKE_DATA_LINK_TYPE(RadioTap, DLT_IEEE802_11_RADIO)
|
||||
TINS_MAKE_DATA_LINK_TYPE(IP, DLT_RAW)
|
||||
|
||||
#undef TINS_MAKE_DATA_LINK_TYPE
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_DATA_LINK_TYPE_H
|
106
lib/libtins/include/tins/detail/address_helpers.h
Normal file
106
lib/libtins/include/tins/detail/address_helpers.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ADDRESS_HELPERS_H
|
||||
#define TINS_ADDRESS_HELPERS_H
|
||||
|
||||
#include <tins/hw_address.h>
|
||||
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
namespace Tins {
|
||||
|
||||
class IPv4Address;
|
||||
class IPv6Address;
|
||||
|
||||
namespace Internals {
|
||||
|
||||
template<typename T>
|
||||
bool increment_buffer(T& addr) {
|
||||
typename T::iterator it = addr.end() - 1;
|
||||
while (it >= addr.begin() && *it == 0xff) {
|
||||
*it = 0;
|
||||
--it;
|
||||
}
|
||||
// reached end
|
||||
if (it < addr.begin()) {
|
||||
return true;
|
||||
}
|
||||
(*it)++;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool decrement_buffer(T& addr) {
|
||||
typename T::iterator it = addr.end() - 1;
|
||||
while (it >= addr.begin() && *it == 0) {
|
||||
*it = 0xff;
|
||||
--it;
|
||||
}
|
||||
// reached end
|
||||
if (it < addr.begin()) {
|
||||
return true;
|
||||
}
|
||||
(*it)--;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool increment(IPv4Address& addr);
|
||||
bool increment(IPv6Address& addr);
|
||||
bool decrement(IPv4Address& addr);
|
||||
bool decrement(IPv6Address& addr);
|
||||
template<size_t n>
|
||||
bool increment(HWAddress<n>& addr) {
|
||||
return increment_buffer(addr);
|
||||
}
|
||||
template<size_t n>
|
||||
bool decrement(HWAddress<n>& addr) {
|
||||
return decrement_buffer(addr);
|
||||
}
|
||||
|
||||
IPv4Address last_address_from_mask(IPv4Address addr, IPv4Address mask);
|
||||
IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address& mask);
|
||||
template<size_t n>
|
||||
HWAddress<n> last_address_from_mask(HWAddress<n> addr, const HWAddress<n>& mask) {
|
||||
typename HWAddress<n>::iterator addr_iter = addr.begin();
|
||||
for (typename HWAddress<n>::const_iterator it = mask.begin(); it != mask.end(); ++it, ++addr_iter) {
|
||||
*addr_iter = *addr_iter | ~*it;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
} // Internals
|
||||
} // Tins
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
#endif // TINS_ADDRESS_HELPERS_H
|
61
lib/libtins/include/tins/detail/icmp_extension_helpers.h
Normal file
61
lib/libtins/include/tins/detail/icmp_extension_helpers.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_ICMP_EXTENSION_HELPERS_H
|
||||
#define TINS_ICMP_EXTENSION_HELPERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
namespace Tins {
|
||||
|
||||
class PDU;
|
||||
class ICMPExtensionsStructure;
|
||||
|
||||
namespace Memory {
|
||||
class InputMemoryStream;
|
||||
} // Memory
|
||||
|
||||
namespace Internals {
|
||||
|
||||
uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_alignment);
|
||||
void try_parse_icmp_extensions(Memory::InputMemoryStream& stream, uint32_t payload_length,
|
||||
ICMPExtensionsStructure& extensions);
|
||||
|
||||
|
||||
} // Internals
|
||||
} // Tins
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
#endif // TINS_ICMP_EXTENSION_HELPERS_H
|
70
lib/libtins/include/tins/detail/pdu_helpers.h
Normal file
70
lib/libtins/include/tins/detail/pdu_helpers.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_PDU_HELPERS_H
|
||||
#define TINS_PDU_HELPERS_H
|
||||
|
||||
#include <tins/constants.h>
|
||||
#include <tins/config.h>
|
||||
#include <tins/pdu.h>
|
||||
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
|
||||
namespace Tins {
|
||||
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(Constants::IP::e flag, const uint8_t* buffer,
|
||||
uint32_t size, bool rawpdu_on_no_match = true);
|
||||
#ifdef TINS_HAVE_PCAP
|
||||
PDU* pdu_from_dlt_flag(int flag, const uint8_t* buffer,
|
||||
uint32_t size, bool rawpdu_on_no_match = true);
|
||||
#endif // TINS_HAVE_PCAP
|
||||
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);
|
||||
PDU::PDUType ether_type_to_pdu_flag(Constants::Ethernet::e flag);
|
||||
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
|
||||
PDU::PDUType ip_type_to_pdu_flag(Constants::IP::e flag);
|
||||
|
||||
inline bool is_dot3(const uint8_t* ptr, size_t sz) {
|
||||
return (sz >= 13 && ptr[12] < 8);
|
||||
}
|
||||
|
||||
} // Internals
|
||||
} // Tins
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
#endif // TINS_PDU_HELPERS_H
|
49
lib/libtins/include/tins/detail/sequence_number_helpers.h
Normal file
49
lib/libtins/include/tins/detail/sequence_number_helpers.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_SEQUENCE_NUMBER_HELPERS_H
|
||||
#define TINS_SEQUENCE_NUMBER_HELPERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
namespace Tins {
|
||||
namespace Internals {
|
||||
|
||||
// Compares sequence numbers as defined by RFC 1982.
|
||||
int seq_compare(uint32_t seq1, uint32_t seq2);
|
||||
|
||||
} // namespace Internals
|
||||
} // namespace Tins
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
#endif // TINS_SEQUENCE_NUMBER_HELPERS_H
|
51
lib/libtins/include/tins/detail/smart_ptr.h
Normal file
51
lib/libtins/include/tins/detail/smart_ptr.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_SMART_PTR_H
|
||||
#define TINS_SMART_PTR_H
|
||||
|
||||
#include <memory>
|
||||
#include <tins/cxxstd.h>
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
} // Internals
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_SMART_PTR_H
|
127
lib/libtins/include/tins/detail/type_traits.h
Normal file
127
lib/libtins/include/tins/detail/type_traits.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_TYPE_TRAITS_H
|
||||
#define TINS_TYPE_TRAITS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <tins/cxxstd.h>
|
||||
#if TINS_IS_CXX11
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace Tins {
|
||||
namespace Internals {
|
||||
/**
|
||||
* \cond
|
||||
*/
|
||||
|
||||
template<bool, typename T = void>
|
||||
struct enable_if {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct enable_if<false, T> {
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_to_type {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_unsigned_integral {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_unsigned_integral<uint8_t> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_unsigned_integral<uint16_t> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_unsigned_integral<uint32_t> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_unsigned_integral<uint64_t> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#if TINS_IS_CXX11 && !defined(_MSC_VER)
|
||||
|
||||
// Template metaprogramming trait to determine if a functor can accept another parameter as an argument
|
||||
template <typename T, typename P, typename=void>
|
||||
struct accepts_type : std::false_type { };
|
||||
|
||||
template <typename T, typename P>
|
||||
struct accepts_type<T, P,
|
||||
typename std::enable_if<
|
||||
std::is_same< decltype( std::declval<T>()(std::declval<P>()) ), bool>::value
|
||||
>::type
|
||||
> : std::true_type { };
|
||||
|
||||
// use enable_if to invoke the Packet&& version of the sniff_loop handler if possible - otherwise fail to old behavior
|
||||
template <typename Functor, typename Packet>
|
||||
bool invoke_loop_cb(Functor& f, Packet& p,
|
||||
typename std::enable_if<accepts_type<Functor, Packet>::value, bool>::type* = 0) {
|
||||
return f(std::move(p));
|
||||
}
|
||||
|
||||
template <typename Functor, typename Packet>
|
||||
bool invoke_loop_cb(Functor& f, Packet& p,
|
||||
typename std::enable_if<!accepts_type<Functor, Packet>::value && accepts_type<Functor, Packet&>::value, bool>::type* = 0) {
|
||||
return f(p);
|
||||
}
|
||||
|
||||
template <typename Functor, typename Packet>
|
||||
bool invoke_loop_cb(Functor& f, Packet& p,
|
||||
typename std::enable_if<!accepts_type<Functor, Packet>::value && !accepts_type<Functor, Packet&>::value, bool>::type* = 0) {
|
||||
return f(*p.pdu());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \endcond
|
||||
*/
|
||||
|
||||
} // Internals
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_TYPE_TRAITS_H
|
532
lib/libtins/include/tins/dhcp.h
Normal file
532
lib/libtins/include/tins/dhcp.h
Normal file
@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DHCP_H
|
||||
#define TINS_DHCP_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <tins/bootp.h>
|
||||
#include <tins/macros.h>
|
||||
#include <tins/pdu_option.h>
|
||||
#include <tins/cxxstd.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \class DHCP
|
||||
* \brief Represents the DHCP PDU.
|
||||
*
|
||||
* This class represents a DHCP PDU. It contains helpers methods
|
||||
* which make it easy to set/get specific option values.
|
||||
*
|
||||
* Note that when adding options, the "End" option is not added
|
||||
* automatically, so you will have to add it yourself.
|
||||
*
|
||||
* Options can be retrieved easily from DHCP PDUs:
|
||||
*
|
||||
* \code
|
||||
* // Sniff a packet from somewhere
|
||||
* DHCP dhcp = get_dhcp_from_somewhere();
|
||||
*
|
||||
* // This retrieves the Domain Name Servers option and converts
|
||||
* // it to a std::vector<IPv4Address>. Note that if this option
|
||||
* // is not present, an option_not_found exception is thrown.
|
||||
* for(const auto& address : dhcp.domain_name_servers()) {
|
||||
* // address is an ip
|
||||
* }
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
class TINS_API DHCP : public BootP {
|
||||
public:
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DHCP;
|
||||
|
||||
/**
|
||||
* DHCP flags.
|
||||
*/
|
||||
enum Flags {
|
||||
DISCOVER = 1,
|
||||
OFFER = 2,
|
||||
REQUEST = 3,
|
||||
DECLINE = 4,
|
||||
ACK = 5,
|
||||
NAK = 6,
|
||||
RELEASE = 7,
|
||||
INFORM = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DHCP options enum.
|
||||
*/
|
||||
enum OptionTypes {
|
||||
PAD,
|
||||
SUBNET_MASK,
|
||||
TIME_OFFSET,
|
||||
ROUTERS,
|
||||
TIME_SERVERS,
|
||||
NAME_SERVERS,
|
||||
DOMAIN_NAME_SERVERS,
|
||||
LOG_SERVERS,
|
||||
COOKIE_SERVERS,
|
||||
LPR_SERVERS,
|
||||
IMPRESS_SERVERS,
|
||||
RESOURCE_LOCATION_SERVERS,
|
||||
HOST_NAME,
|
||||
BOOT_SIZE,
|
||||
MERIT_DUMP,
|
||||
DOMAIN_NAME,
|
||||
SWAP_SERVER,
|
||||
ROOT_PATH,
|
||||
EXTENSIONS_PATH,
|
||||
IP_FORWARDING,
|
||||
NON_LOCAL_SOURCE_ROUTING,
|
||||
POLICY_FILTER,
|
||||
MAX_DGRAM_REASSEMBLY,
|
||||
DEFAULT_IP_TTL,
|
||||
PATH_MTU_AGING_TIMEOUT,
|
||||
PATH_MTU_PLATEAU_TABLE,
|
||||
INTERFACE_MTU,
|
||||
ALL_SUBNETS_LOCAL,
|
||||
BROADCAST_ADDRESS,
|
||||
PERFORM_MASK_DISCOVERY,
|
||||
MASK_SUPPLIER,
|
||||
ROUTER_DISCOVERY,
|
||||
ROUTER_SOLICITATION_ADDRESS,
|
||||
STATIC_ROUTES,
|
||||
TRAILER_ENCAPSULATION,
|
||||
ARP_CACHE_TIMEOUT,
|
||||
IEEE802_3_ENCAPSULATION,
|
||||
DEFAULT_TCP_TTL,
|
||||
TCP_KEEPALIVE_INTERVAL,
|
||||
TCP_KEEPALIVE_GARBAGE,
|
||||
NIS_DOMAIN,
|
||||
NIS_SERVERS,
|
||||
NTP_SERVERS,
|
||||
VENDOR_ENCAPSULATED_OPTIONS,
|
||||
NETBIOS_NAME_SERVERS,
|
||||
NETBIOS_DD_SERVER,
|
||||
NETBIOS_NODE_TYPE,
|
||||
NETBIOS_SCOPE,
|
||||
FONT_SERVERS,
|
||||
X_DISPLAY_MANAGER,
|
||||
DHCP_REQUESTED_ADDRESS,
|
||||
DHCP_LEASE_TIME,
|
||||
DHCP_OPTION_OVERLOAD,
|
||||
DHCP_MESSAGE_TYPE,
|
||||
DHCP_SERVER_IDENTIFIER,
|
||||
DHCP_PARAMETER_REQUEST_LIST,
|
||||
DHCP_MESSAGE,
|
||||
DHCP_MAX_MESSAGE_SIZE,
|
||||
DHCP_RENEWAL_TIME,
|
||||
DHCP_REBINDING_TIME,
|
||||
VENDOR_CLASS_IDENTIFIER,
|
||||
DHCP_CLIENT_IDENTIFIER,
|
||||
NWIP_DOMAIN_NAME,
|
||||
NWIP_SUBOPTIONS,
|
||||
USER_CLASS = 77,
|
||||
FQDN = 81,
|
||||
DHCP_AGENT_OPTIONS = 82,
|
||||
SUBNET_SELECTION = 118,
|
||||
AUTHENTICATE = 210,
|
||||
END = 255
|
||||
};
|
||||
|
||||
/**
|
||||
* The DHCP option type.
|
||||
*/
|
||||
typedef PDUOption<uint8_t, DHCP> option;
|
||||
|
||||
/**
|
||||
* The type used to store the DHCP options.
|
||||
*/
|
||||
typedef std::vector<option> options_type;
|
||||
|
||||
/**
|
||||
* \brief Extracts metadata for this protocol based on the buffer provided
|
||||
*
|
||||
* \param buffer Pointer to a buffer
|
||||
* \param total_sz Size of the buffer pointed by buffer
|
||||
*/
|
||||
static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of DHCP.
|
||||
*
|
||||
* This sets the hwtype and hlen fields to match the ethernet
|
||||
* type and length.
|
||||
*/
|
||||
DHCP();
|
||||
|
||||
/**
|
||||
* \brief Constructs a DHCP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a BootP header, or any of
|
||||
* the TLV options contains an invalid size field, then a
|
||||
* malformed_packet exception is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
DHCP(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Adds a new option to this DHCP PDU.
|
||||
* \param opt The option to be added.
|
||||
*/
|
||||
void add_option(const option& opt);
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
/**
|
||||
* \brief Adds a new option to this 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 Removes a DHCP option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \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 option* search_option(OptionTypes opt) const;
|
||||
|
||||
/**
|
||||
* \brief Adds a type option to the option list.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param type The type of this DHCP PDU.
|
||||
*/
|
||||
void type(Flags type);
|
||||
|
||||
/**
|
||||
* \brief Adds an end option to the option list.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* The END option is not added automatically. You should explicitly
|
||||
* add it at the end of the DHCP options for the PDU to be
|
||||
* standard-compliant.
|
||||
*/
|
||||
void end();
|
||||
|
||||
/**
|
||||
* \brief Adds a server identifier option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param ip The server's IP address.
|
||||
*/
|
||||
void server_identifier(ipaddress_type ip);
|
||||
|
||||
/**
|
||||
* \brief Adds an IP address lease time option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param time The lease time.
|
||||
*/
|
||||
void lease_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a lease renewal time option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param time The lease renew time.
|
||||
*/
|
||||
void renewal_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a rebind time option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param time The lease rebind time.
|
||||
*/
|
||||
void rebind_time(uint32_t time);
|
||||
|
||||
/**
|
||||
* \brief Adds a subnet mask option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param mask The subnet mask.
|
||||
*/
|
||||
void subnet_mask(ipaddress_type mask);
|
||||
|
||||
/**
|
||||
* \brief Adds a routers option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param routers A list of ip addresses.
|
||||
*/
|
||||
void routers(const std::vector<ipaddress_type>& routers);
|
||||
|
||||
/**
|
||||
* \brief Adds a domain name servers option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param dns A list of ip addresses.
|
||||
*/
|
||||
void domain_name_servers(const std::vector<ipaddress_type>& dns);
|
||||
|
||||
/**
|
||||
* \brief Adds a broadcast address option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param addr The broadcast address.
|
||||
*/
|
||||
void broadcast(ipaddress_type addr);
|
||||
|
||||
/**
|
||||
* \brief Adds a requested address option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param addr The requested address.
|
||||
*/
|
||||
void requested_ip(ipaddress_type addr);
|
||||
|
||||
/**
|
||||
* \brief Adds a domain name option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param name The domain name.
|
||||
*/
|
||||
void domain_name(const std::string& name);
|
||||
|
||||
/**
|
||||
* \brief Adds a hostname option.
|
||||
*
|
||||
* The new option is appended at the end of the list.
|
||||
*
|
||||
* \param name The hostname.
|
||||
*/
|
||||
void hostname(const std::string& name);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Searchs for a type option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint8_t containing the type option.
|
||||
*/
|
||||
uint8_t type() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a server identifier option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the server identifier.
|
||||
*/
|
||||
ipaddress_type server_identifier() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a lease time option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the lease time.
|
||||
*/
|
||||
uint32_t lease_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a lease renewal time option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the renewal time.
|
||||
*/
|
||||
uint32_t renewal_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a rebind time option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return uint32_t Containing the rebind time.
|
||||
*/
|
||||
uint32_t rebind_time() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a subnet mask option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the subnet mask.
|
||||
*/
|
||||
ipaddress_type subnet_mask() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a routers option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::vector<ipaddress_type> Containing the routers
|
||||
* option data.
|
||||
*/
|
||||
std::vector<ipaddress_type> routers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a dns option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return The list of DNS servers provided.
|
||||
*/
|
||||
std::vector<ipaddress_type> domain_name_servers() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a broadcast option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the broadcast address.
|
||||
*/
|
||||
ipaddress_type broadcast() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a requested option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return ipaddress_type Containing the requested IP address.
|
||||
*/
|
||||
ipaddress_type requested_ip() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a domain name option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::string Containing the domain name.
|
||||
*/
|
||||
std::string domain_name() const;
|
||||
|
||||
/**
|
||||
* \brief Searchs for a hostname option.
|
||||
*
|
||||
* If the option is not found, an option_not_found exception
|
||||
* is thrown.
|
||||
*
|
||||
* \return std::string Containing the hostname.
|
||||
*/
|
||||
std::string hostname() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the options list.
|
||||
* \return The option list.
|
||||
*/
|
||||
const options_type options() const { return options_; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return pdu_flag; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the header size.
|
||||
* \return Returns the BOOTP header size.
|
||||
* \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
DHCP* clone() const {
|
||||
return new DHCP(*this);
|
||||
}
|
||||
private:
|
||||
static const uint32_t MAX_DHCP_SIZE;
|
||||
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
template <typename T>
|
||||
T search_and_convert(OptionTypes opt) const {
|
||||
const option* option = search_option(opt);
|
||||
if (!option) {
|
||||
throw option_not_found();
|
||||
}
|
||||
return option->to<T>();
|
||||
}
|
||||
|
||||
void internal_add_option(const option& opt);
|
||||
serialization_type serialize_list(const std::vector<ipaddress_type>& ip_list);
|
||||
options_type::const_iterator search_option_iterator(OptionTypes opt) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes opt);
|
||||
|
||||
options_type options_;
|
||||
uint32_t size_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_DHCP_H
|
923
lib/libtins/include/tins/dhcpv6.h
Normal file
923
lib/libtins/include/tins/dhcpv6.h
Normal file
@ -0,0 +1,923 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TINS_DHCPV6_H
|
||||
#define TINS_DHCPV6_H
|
||||
|
||||
#include <cstring>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/macros.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/small_uint.h>
|
||||
#include <tins/ipv6_address.h>
|
||||
#include <tins/pdu_option.h>
|
||||
|
||||
namespace Tins {
|
||||
namespace Memory {
|
||||
|
||||
class OutputMemoryStream;
|
||||
|
||||
} // Memory
|
||||
|
||||
/**
|
||||
* \class DHCPv6
|
||||
* \brief Represents a DHCPv6 PDU.
|
||||
*/
|
||||
class TINS_API DHCPv6 : public PDU {
|
||||
public:
|
||||
/**
|
||||
* Represents a DHCPv6 option.
|
||||
*/
|
||||
typedef PDUOption<uint16_t, DHCPv6> option;
|
||||
|
||||
/**
|
||||
* The message types.
|
||||
*/
|
||||
enum MessageType {
|
||||
SOLICIT = 1,
|
||||
ADVERTISE,
|
||||
REQUEST,
|
||||
CONFIRM,
|
||||
RENEW,
|
||||
REBIND,
|
||||
REPLY,
|
||||
RELEASE,
|
||||
DECLINE,
|
||||
RECONFIGURE,
|
||||
INFO_REQUEST,
|
||||
RELAY_FORWARD,
|
||||
RELAY_REPLY,
|
||||
LEASE_QUERY,
|
||||
LEASE_QUERY_REPLY,
|
||||
LEASE_QUERY_DONE,
|
||||
LEASE_QUERY_DATA
|
||||
};
|
||||
|
||||
/**
|
||||
* The DHCPv6 options.
|
||||
*/
|
||||
enum OptionTypes {
|
||||
CLIENTID = 1,
|
||||
SERVERID,
|
||||
IA_NA,
|
||||
IA_TA,
|
||||
IA_ADDR,
|
||||
OPTION_REQUEST,
|
||||
PREFERENCE,
|
||||
ELAPSED_TIME,
|
||||
RELAY_MSG,
|
||||
AUTH = 11,
|
||||
UNICAST,
|
||||
STATUS_CODE,
|
||||
RAPID_COMMIT,
|
||||
USER_CLASS,
|
||||
VENDOR_CLASS,
|
||||
VENDOR_OPTS,
|
||||
INTERFACE_ID,
|
||||
RECONF_MSG,
|
||||
RECONF_ACCEPT,
|
||||
SIP_SERVER_D,
|
||||
SIP_SERVER_A,
|
||||
DNS_SERVERS,
|
||||
DOMAIN_LIST,
|
||||
IA_PD,
|
||||
IAPREFIX,
|
||||
NIS_SERVERS,
|
||||
NISP_SERVERS,
|
||||
NIS_DOMAIN_NAME,
|
||||
NISP_DOMAIN_NAME,
|
||||
SNTP_SERVERS,
|
||||
INFORMATION_REFRESH_TIME,
|
||||
BCMCS_SERVER_D,
|
||||
BCMCS_SERVER_A,
|
||||
GEOCONF_CIVIC = 36,
|
||||
REMOTE_ID,
|
||||
SUBSCRIBER_ID,
|
||||
CLIENT_FQDN,
|
||||
PANA_AGENT,
|
||||
NEW_POSIX_TIMEZONE,
|
||||
NEW_TZDB_TIMEZONE,
|
||||
ERO,
|
||||
LQ_QUERY,
|
||||
CLIENT_DATA,
|
||||
CLT_TIME,
|
||||
LQ_RELAY_DATA,
|
||||
LQ_CLIENT_LINK,
|
||||
MIP6_HNIDF,
|
||||
MIP6_VDINF,
|
||||
V6_LOST,
|
||||
CAPWAP_AC_V6,
|
||||
RELAY_ID,
|
||||
NTP_SERVER,
|
||||
V6_ACCESS_DOMAIN,
|
||||
SIP_UA_CS_LIST,
|
||||
BOOTFILE_URL,
|
||||
BOOTFILE_PARAM,
|
||||
CLIENT_ARCH_TYPE,
|
||||
NII,
|
||||
GEOLOCATION,
|
||||
AFTR_NAME,
|
||||
ERP_LOCAL_DOMAIN_NAME,
|
||||
RSOO,
|
||||
PD_EXCLUDE,
|
||||
VSS,
|
||||
MIP6_IDINF,
|
||||
MIP6_UDINF,
|
||||
MIP6_HNP,
|
||||
MIP6_HAA,
|
||||
MIP6_HAF,
|
||||
RDNSS_SELECTION,
|
||||
KRB_PRINCIPAL_NAME,
|
||||
KRB_REALM_NAME,
|
||||
KRB_DEFAULT_REALM_NAME,
|
||||
KRB_KDC
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the DHCPv6 options.
|
||||
*/
|
||||
typedef std::vector<option> options_type;
|
||||
|
||||
/**
|
||||
* The type used to store IP addresses.
|
||||
*/
|
||||
typedef IPv6Address ipaddress_type;
|
||||
|
||||
/**
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DHCPv6;
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*/
|
||||
struct ia_na_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
uint32_t id, t1, t2;
|
||||
options_type options;
|
||||
|
||||
ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), t1(t1), t2(t2), options(options) {}
|
||||
|
||||
static ia_na_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*/
|
||||
struct ia_ta_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
uint32_t id;
|
||||
options_type options;
|
||||
|
||||
ia_ta_type(uint32_t id = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), options(options) {}
|
||||
|
||||
static ia_ta_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association Address option.
|
||||
*/
|
||||
struct ia_address_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
ipaddress_type address;
|
||||
uint32_t preferred_lifetime, valid_lifetime;
|
||||
options_type options;
|
||||
|
||||
ia_address_type(ipaddress_type address = ipaddress_type(),
|
||||
uint32_t preferred_lifetime = 0, uint32_t valid_lifetime = 0,
|
||||
const options_type& options = options_type())
|
||||
: address(address), preferred_lifetime(preferred_lifetime),
|
||||
valid_lifetime(valid_lifetime), options(options) {}
|
||||
|
||||
static ia_address_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Authentication option.
|
||||
*/
|
||||
struct authentication_type {
|
||||
typedef std::vector<uint8_t> auth_info_type;
|
||||
|
||||
uint8_t protocol, algorithm, rdm;
|
||||
uint64_t replay_detection;
|
||||
auth_info_type auth_info;
|
||||
|
||||
authentication_type(uint8_t protocol = 0, uint8_t algorithm = 0,
|
||||
uint8_t rdm = 0, uint64_t replay_detection = 0,
|
||||
const auth_info_type& auth_info = auth_info_type())
|
||||
: protocol(protocol), algorithm(algorithm), rdm(rdm),
|
||||
replay_detection(replay_detection), auth_info(auth_info) {}
|
||||
|
||||
static authentication_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Status Code option.
|
||||
*/
|
||||
struct status_code_type {
|
||||
uint16_t code;
|
||||
std::string message;
|
||||
|
||||
status_code_type(uint16_t code = 0, const std::string& message = "")
|
||||
: code(code), message(message) { }
|
||||
|
||||
static status_code_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Vendor-specific Information option.
|
||||
*/
|
||||
struct vendor_info_type {
|
||||
typedef std::vector<uint8_t> data_type;
|
||||
|
||||
uint32_t enterprise_number;
|
||||
data_type data;
|
||||
|
||||
vendor_info_type(uint32_t enterprise_number = 0,
|
||||
const data_type& data = data_type())
|
||||
: enterprise_number(enterprise_number), data(data) { }
|
||||
|
||||
static vendor_info_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The type used to store the User Class option's user class data.
|
||||
*/
|
||||
typedef std::vector<uint8_t> class_option_data_type;
|
||||
|
||||
/**
|
||||
* The type used to store the User Class option.
|
||||
*/
|
||||
//typedef std::vector<class_option_data_type> user_class_type;
|
||||
struct user_class_type {
|
||||
typedef std::vector<class_option_data_type> data_type;
|
||||
data_type data;
|
||||
|
||||
user_class_type(const data_type& data = data_type())
|
||||
: data(data) { }
|
||||
|
||||
static user_class_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Vendor Class option.
|
||||
*/
|
||||
struct vendor_class_type {
|
||||
typedef std::vector<class_option_data_type> class_data_type;
|
||||
|
||||
uint32_t enterprise_number;
|
||||
class_data_type vendor_class_data;
|
||||
|
||||
vendor_class_type(uint32_t enterprise_number = 0,
|
||||
const class_data_type& vendor_class_data = class_data_type())
|
||||
: enterprise_number(enterprise_number),
|
||||
vendor_class_data(vendor_class_data) { }
|
||||
|
||||
static vendor_class_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to represent DUIDs Based on Link-layer Address Plus
|
||||
* Time.
|
||||
*/
|
||||
struct duid_llt {
|
||||
static const uint16_t duid_id = 1;
|
||||
typedef std::vector<uint8_t> lladdress_type;
|
||||
|
||||
uint16_t hw_type;
|
||||
uint32_t time;
|
||||
lladdress_type lladdress;
|
||||
|
||||
duid_llt(uint16_t hw_type = 0, uint32_t time = 0,
|
||||
const lladdress_type& lladdress = lladdress_type())
|
||||
: hw_type(hw_type), time(time), lladdress(lladdress) {}
|
||||
|
||||
PDU::serialization_type serialize() const;
|
||||
|
||||
static duid_llt from_bytes(const uint8_t* buffer, uint32_t total_sz);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to represent DUIDs Based on Enterprise Number
|
||||
*/
|
||||
struct duid_en {
|
||||
static const uint16_t duid_id = 2;
|
||||
typedef std::vector<uint8_t> identifier_type;
|
||||
|
||||
uint32_t enterprise_number;
|
||||
identifier_type identifier;
|
||||
|
||||
duid_en(uint32_t enterprise_number = 0,
|
||||
const identifier_type& identifier = identifier_type())
|
||||
: enterprise_number(enterprise_number), identifier(identifier) {}
|
||||
|
||||
PDU::serialization_type serialize() const;
|
||||
|
||||
static duid_en from_bytes(const uint8_t* buffer, uint32_t total_sz);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to represent DUIDs Based on Link-layer Address.
|
||||
*/
|
||||
struct duid_ll {
|
||||
static const uint16_t duid_id = 3;
|
||||
typedef std::vector<uint8_t> lladdress_type;
|
||||
|
||||
uint16_t hw_type;
|
||||
lladdress_type lladdress;
|
||||
|
||||
duid_ll(uint16_t hw_type = 0,
|
||||
const lladdress_type& lladdress = lladdress_type())
|
||||
: hw_type(hw_type), lladdress(lladdress) {}
|
||||
|
||||
PDU::serialization_type serialize() const;
|
||||
|
||||
static duid_ll from_bytes(const uint8_t* buffer, uint32_t total_sz);
|
||||
};
|
||||
|
||||
/**
|
||||
* Type type used to represent DUIDs. This will be stored as the
|
||||
* value for the Client/Server Identifier options.
|
||||
*/
|
||||
struct duid_type {
|
||||
typedef PDU::serialization_type data_type;
|
||||
|
||||
uint16_t id;
|
||||
data_type data;
|
||||
|
||||
duid_type(uint16_t id = 0, const data_type& data = data_type())
|
||||
: id(id), data(data) {}
|
||||
|
||||
duid_type(const duid_llt& identifier)
|
||||
: id(duid_llt::duid_id), data(identifier.serialize()) {}
|
||||
|
||||
duid_type(const duid_en& identifier)
|
||||
: id(duid_en::duid_id), data(identifier.serialize()) {}
|
||||
|
||||
duid_type(const duid_ll& identifier)
|
||||
: id(duid_ll::duid_id), data(identifier.serialize()) {}
|
||||
|
||||
static duid_type from_option(const option& opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Option Request option.
|
||||
*/
|
||||
typedef std::vector<uint16_t> option_request_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Relay Message option.
|
||||
*/
|
||||
typedef std::vector<uint8_t> relay_msg_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Interface-ID option.
|
||||
*/
|
||||
typedef std::vector<uint8_t> interface_id_type;
|
||||
|
||||
/**
|
||||
* \brief Extracts metadata for this protocol based on the buffer provided
|
||||
*
|
||||
* \param buffer Pointer to a buffer
|
||||
* \param total_sz Size of the buffer pointed by buffer
|
||||
*/
|
||||
static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
DHCPv6();
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
DHCPv6(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
// Getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the message type field.
|
||||
*
|
||||
* \return The stored message type field.
|
||||
*/
|
||||
MessageType msg_type() const {
|
||||
return static_cast<MessageType>(header_data_[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hop count field.
|
||||
*
|
||||
* \return The stored hop count field.
|
||||
*/
|
||||
uint8_t hop_count() const {
|
||||
return header_data_[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the transaction id field.
|
||||
*
|
||||
* \return The stored transaction id field.
|
||||
*/
|
||||
small_uint<24> transaction_id() const {
|
||||
return (header_data_[1] << 16) | (header_data_[2] << 8) | header_data_[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the peer address field.
|
||||
*
|
||||
* \return The stored peer address field.
|
||||
*/
|
||||
const ipaddress_type& peer_address() const {
|
||||
return peer_addr_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the link address field.
|
||||
*
|
||||
* \return The stored link address field.
|
||||
*/
|
||||
const ipaddress_type& link_address() const {
|
||||
return link_addr_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the DHCPv6 options.
|
||||
*
|
||||
* \return The stored options.
|
||||
*/
|
||||
const options_type& options() const {
|
||||
return options_;
|
||||
}
|
||||
|
||||
// Setters
|
||||
/**
|
||||
* \brief Setter for the message type field.
|
||||
*
|
||||
* \param type The new message type.
|
||||
*/
|
||||
void msg_type(MessageType type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hop count field.
|
||||
*
|
||||
* \param count The new hop count.
|
||||
*/
|
||||
void hop_count(uint8_t count);
|
||||
|
||||
/**
|
||||
* \brief Setter for the transaction id field.
|
||||
*
|
||||
* \param id The new transaction id.
|
||||
*/
|
||||
void transaction_id(small_uint<24> id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the peer address field.
|
||||
*
|
||||
* \param count The new peer address.
|
||||
*/
|
||||
void peer_address(const ipaddress_type& addr);
|
||||
|
||||
/**
|
||||
* \brief Setter for the link address field.
|
||||
*
|
||||
* \param count The new link address.
|
||||
*/
|
||||
void link_address(const ipaddress_type& addr);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_na_type ia_na() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_ta_type ia_ta() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association Address option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_address_type ia_address() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Option Request option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
option_request_type option_request() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Preference option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint8_t preference() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Elapsed Time option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint16_t elapsed_time() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Relay Message option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
relay_msg_type relay_message() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Authentication option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
authentication_type authentication() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Server Unicast option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ipaddress_type server_unicast() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Server Unicast option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
status_code_type status_code() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Rapid Commit option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
bool has_rapid_commit() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the User Class option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
user_class_type user_class() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor Class option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
vendor_class_type vendor_class() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor-specific Information option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
vendor_info_type vendor_info() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Interface ID option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
interface_id_type interface_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Reconfigure Message option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint8_t reconfigure_msg() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Reconfigure Accept option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
bool has_reconfigure_accept() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Client Identifier option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
duid_type client_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Server Identifier option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
duid_type server_id() const;
|
||||
|
||||
// Option setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* \param value The new IA_NA option data.
|
||||
*/
|
||||
void ia_na(const ia_na_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* \param value The new IA_TA option data.
|
||||
*/
|
||||
void ia_ta(const ia_ta_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association Address option.
|
||||
*
|
||||
* \param value The new IA Address option data.
|
||||
*/
|
||||
void ia_address(const ia_address_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association Address option.
|
||||
*
|
||||
* \param value The new Option Request option data.
|
||||
*/
|
||||
void option_request(const option_request_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Preference option.
|
||||
*
|
||||
* \param value The new Preference option data.
|
||||
*/
|
||||
void preference(uint8_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Elapsed Time option.
|
||||
*
|
||||
* \param value The new Elapsed Time option data.
|
||||
*/
|
||||
void elapsed_time(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Relay Message option.
|
||||
*
|
||||
* \param value The new Relay Message option data.
|
||||
*/
|
||||
void relay_message(const relay_msg_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Authentication option.
|
||||
*
|
||||
* \param value The new Authentication option data.
|
||||
*/
|
||||
void authentication(const authentication_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Server Unicast option.
|
||||
*
|
||||
* \param value The new Server Unicast option data.
|
||||
*/
|
||||
void server_unicast(const ipaddress_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Status Code option.
|
||||
*
|
||||
* \param value The new Status Code option data.
|
||||
*/
|
||||
void status_code(const status_code_type& value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Rapid Commit option.
|
||||
*/
|
||||
void rapid_commit();
|
||||
|
||||
/**
|
||||
* \brief Setter for the User Class option.
|
||||
*
|
||||
* \param value The new User Class option data.
|
||||
*/
|
||||
void user_class(const user_class_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Vendor Class option.
|
||||
*
|
||||
* \param value The new Vendor Class option data.
|
||||
*/
|
||||
void vendor_class(const vendor_class_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Vendor-specific Information option.
|
||||
*
|
||||
* \param value The new Vendor-specific Information option data.
|
||||
*/
|
||||
void vendor_info(const vendor_info_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Interface ID option.
|
||||
*
|
||||
* \param value The new Interface ID option data.
|
||||
*/
|
||||
void interface_id(const interface_id_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Reconfigure Message option.
|
||||
*
|
||||
* \param value The new Reconfigure Message option data.
|
||||
*/
|
||||
void reconfigure_msg(uint8_t value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Reconfigure Accept option.
|
||||
*/
|
||||
void reconfigure_accept();
|
||||
|
||||
/**
|
||||
* \brief Setter for the Client Identifier option.
|
||||
*
|
||||
* \param value The new Client Identifier option data.
|
||||
*/
|
||||
void client_id(const duid_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Server Identifier option.
|
||||
*
|
||||
* \param value The new Server Identifier option data.
|
||||
*/
|
||||
void server_id(const duid_type& value);
|
||||
|
||||
// Other stuff
|
||||
|
||||
/**
|
||||
* Indicates whether this is a relay agent/server message
|
||||
*/
|
||||
bool is_relay_message() const;
|
||||
|
||||
/**
|
||||
* \brief Adds a DHCPv6 option.
|
||||
*
|
||||
* The option is added after the last option in the option
|
||||
* fields.
|
||||
*
|
||||
* \param opt The option to be added
|
||||
*/
|
||||
void add_option(const option& opt);
|
||||
|
||||
/**
|
||||
* \brief Removes a DHCPv6 option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Searchs for an option that matchs the given type.
|
||||
*
|
||||
* If the option is not found, a null pointer is returned.
|
||||
* Deleting the returned pointer will result in <b>undefined
|
||||
* behaviour</b>.
|
||||
*
|
||||
* \param type The option identifier to be searched.
|
||||
*/
|
||||
const option* search_option(OptionTypes type) const;
|
||||
|
||||
// PDU stuff
|
||||
|
||||
/**
|
||||
* \brief Returns the header size.
|
||||
*
|
||||
* This method overrides PDU::header_size. \sa PDU::header_size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* \sa PDU::matches_response
|
||||
* \param ptr The pointer to the buffer.
|
||||
* \param total_sz The size of the buffer.
|
||||
*/
|
||||
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
DHCPv6* clone() const {
|
||||
return new DHCPv6(*this);
|
||||
}
|
||||
private:
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
void write_option(const option& option, Memory::OutputMemoryStream& stream) const;
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
template <template <typename> class Functor>
|
||||
const option* safe_search_option(OptionTypes opt, uint32_t size) const {
|
||||
const option* option = search_option(opt);
|
||||
if (!option || Functor<uint32_t>()(option->data_size(), size)) {
|
||||
throw option_not_found();
|
||||
}
|
||||
return option;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T search_and_convert(OptionTypes opt) const {
|
||||
const option* option = search_option(opt);
|
||||
if (!option) {
|
||||
throw option_not_found();
|
||||
}
|
||||
return option->to<T>();
|
||||
}
|
||||
|
||||
uint8_t header_data_[4];
|
||||
uint32_t options_size_;
|
||||
ipaddress_type link_addr_, peer_addr_;
|
||||
options_type options_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_DHCPV6_H
|
1059
lib/libtins/include/tins/dns.h
Normal file
1059
lib/libtins/include/tins/dns.h
Normal file
File diff suppressed because it is too large
Load Diff
44
lib/libtins/include/tins/dot11.h
Normal file
44
lib/libtins/include/tins/dot11.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT_11) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_DOT_11
|
||||
|
||||
#include <tins/dot11/dot11_base.h>
|
||||
#include <tins/dot11/dot11_data.h>
|
||||
#include <tins/dot11/dot11_mgmt.h>
|
||||
#include <tins/dot11/dot11_beacon.h>
|
||||
#include <tins/dot11/dot11_assoc.h>
|
||||
#include <tins/dot11/dot11_auth.h>
|
||||
#include <tins/dot11/dot11_probe.h>
|
||||
#include <tins/dot11/dot11_control.h>
|
||||
|
||||
#endif // TINS_DOT_11
|
666
lib/libtins/include/tins/dot11/dot11_assoc.h
Normal file
666
lib/libtins/include/tins/dot11/dot11_assoc.h
Normal file
@ -0,0 +1,666 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT11_DOT11_ASSOC_H) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_DOT11_DOT11_ASSOC_H
|
||||
|
||||
#include <tins/dot11/dot11_mgmt.h>
|
||||
#include <tins/macros.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Class representing a Disassociation frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11Disassoc : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_DIASSOC;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Disassociation.
|
||||
*
|
||||
* Constructs a 802.11 Disassociation taking the destination
|
||||
* and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11Disassoc(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Disassoc object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Disassoc(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the reason code field.
|
||||
*
|
||||
* \return The stored reason code.
|
||||
*/
|
||||
uint16_t reason_code() const {
|
||||
return Endian::le_to_host(body_.reason_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the reason code field.
|
||||
*
|
||||
* \param new_reason_code The reason code to be set.
|
||||
*/
|
||||
void reason_code(uint16_t new_reason_code);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11Disassoc* clone() const {
|
||||
return new Dot11Disassoc(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_disassoc_body {
|
||||
uint16_t reason_code;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_disassoc_body body_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class representing an Association Request frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11AssocRequest : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_ASSOC_REQ;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Association Request.
|
||||
*
|
||||
* Constructs a 802.11 Association Request taking the
|
||||
* destination and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11AssocRequest(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11AssocRequest object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11AssocRequest(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A constant refereence to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
const capability_information& capabilities() const {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A refereence to the stored Capabilities Information
|
||||
* field.
|
||||
*/
|
||||
capability_information& capabilities() {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the listen interval field.
|
||||
*
|
||||
* \return The stored listen interval field.
|
||||
*/
|
||||
uint16_t listen_interval() const {
|
||||
return Endian::le_to_host(body_.listen_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the listen interval field.
|
||||
*
|
||||
* \param new_listen_interval The listen interval to be set.
|
||||
*/
|
||||
void listen_interval(uint16_t new_listen_interval);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11AssocRequest* clone() const {
|
||||
return new Dot11AssocRequest(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_assoc_request_body {
|
||||
capability_information capability;
|
||||
uint16_t listen_interval;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_assoc_request_body body_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class representing an Association Response frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11AssocResponse : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_ASSOC_RESP;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Association Response.
|
||||
*
|
||||
* Constructors a 802.11 Association Response taking destination
|
||||
* and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11AssocResponse(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a Dot11AssocResponse object
|
||||
* from a buffer and adds all identifiable PDUs found in the
|
||||
* buffer as children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11AssocResponse(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information field.
|
||||
*
|
||||
* \return A constant reference to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
const capability_information& capabilities() const {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information field.
|
||||
*
|
||||
* \return A reference to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
capability_information& capabilities() {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the status code field.
|
||||
*
|
||||
* \return The stored status code.
|
||||
*/
|
||||
uint16_t status_code() const {
|
||||
return Endian::le_to_host(body_.status_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the AID field.
|
||||
*
|
||||
* \return The stored AID field.
|
||||
*/
|
||||
uint16_t aid() const {
|
||||
return Endian::le_to_host(body_.aid);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the status code.
|
||||
*
|
||||
* \param new_status_code The status code to be set.
|
||||
*/
|
||||
void status_code(uint16_t new_status_code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the AID field.
|
||||
*
|
||||
* \param new_aid The AID value to be set.
|
||||
*/
|
||||
void aid(uint16_t new_aid);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11AssocResponse* clone() const {
|
||||
return new Dot11AssocResponse(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_assoc_response_body {
|
||||
capability_information capability;
|
||||
uint16_t status_code;
|
||||
uint16_t aid;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_assoc_response_body body_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class representing an ReAssociation Request frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11ReAssocRequest : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_REASSOC_REQ;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 ReAssociation Request.
|
||||
*
|
||||
* Constructors a 802.11 Association Request taking the destination
|
||||
* and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11ReAssocRequest(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11AssocRequest object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as
|
||||
* children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11ReAssocRequest(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A constant reference to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
const capability_information& capabilities() const {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A reference to the stored Capabilities Information
|
||||
* field.
|
||||
*/
|
||||
capability_information& capabilities() {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the listen interval field.
|
||||
*
|
||||
* \return The stored listen interval.
|
||||
*/
|
||||
uint16_t listen_interval() const {
|
||||
return Endian::le_to_host(body_.listen_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the current ap field.
|
||||
*
|
||||
* \return The current ap.
|
||||
*/
|
||||
address_type current_ap() const {
|
||||
return body_.current_ap;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the listen interval field.
|
||||
*
|
||||
* \param new_listen_interval The listen interval to be set.
|
||||
*/
|
||||
void listen_interval(uint16_t new_listen_interval);
|
||||
|
||||
/**
|
||||
* \brief Setter for the current ap.
|
||||
*
|
||||
* \param new_current_ap The address of the current ap.
|
||||
*/
|
||||
void current_ap(const address_type& new_current_ap);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11ReAssocRequest* clone() const {
|
||||
return new Dot11ReAssocRequest(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_reassoc_request_body {
|
||||
capability_information capability;
|
||||
uint16_t listen_interval;
|
||||
uint8_t current_ap[address_type::address_size];
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_reassoc_request_body body_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IEEE 802.11 ReAssociation Response frame.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11ReAssocResponse : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_REASSOC_RESP;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Association Response.
|
||||
*
|
||||
* Constructs a 802.11 ReAssociation Response taking the
|
||||
* destination and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11ReAssocResponse(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11ReAssocResponse object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11ReAssocResponse(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A constant reference to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
const capability_information& capabilities() const {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A reference to the stored Capabilities Information
|
||||
* field.
|
||||
*/
|
||||
capability_information& capabilities() {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the status code field.
|
||||
*
|
||||
* \return The stored status code.
|
||||
*/
|
||||
uint16_t status_code() const {
|
||||
return Endian::le_to_host(body_.status_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the AID field.
|
||||
*
|
||||
* \return The stored AID field value.
|
||||
*/
|
||||
uint16_t aid() const {
|
||||
return Endian::le_to_host(body_.aid);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the status code field.
|
||||
*
|
||||
* \param new_status_code The status code to be set.
|
||||
*/
|
||||
void status_code(uint16_t new_status_code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the AID field.
|
||||
*
|
||||
* \param new_aid The AID to be set.
|
||||
*/
|
||||
void aid(uint16_t new_aid);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11ReAssocResponse* clone() const {
|
||||
return new Dot11ReAssocResponse(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_reassoc_response_body {
|
||||
capability_information capability;
|
||||
uint16_t status_code;
|
||||
uint16_t aid;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_reassoc_response_body body_;
|
||||
};
|
||||
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_DOT11_DOT11_ASSOC_H
|
271
lib/libtins/include/tins/dot11/dot11_auth.h
Normal file
271
lib/libtins/include/tins/dot11/dot11_auth.h
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT11_DOT11_AUTH_H) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_DOT11_DOT11_AUTH_H
|
||||
|
||||
#include <tins/dot11/dot11_mgmt.h>
|
||||
#include <tins/macros.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief IEEE 802.11 Authentication Request frame.
|
||||
*/
|
||||
class TINS_API Dot11Authentication : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_AUTH;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Authentication.
|
||||
*
|
||||
* Constructs a 802.11 Dot11Authentication taking the
|
||||
* destination and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11Authentication(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Authentication object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Authentication(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Authetication Algorithm Number field.
|
||||
*
|
||||
* \return The stored authentication algorithm number.
|
||||
*/
|
||||
uint16_t auth_algorithm() const {
|
||||
return Endian::le_to_host(body_.auth_algorithm); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the Authetication Sequence Number field.
|
||||
*
|
||||
* \return The stored authentication sequence number.
|
||||
*/
|
||||
uint16_t auth_seq_number() const {
|
||||
return Endian::le_to_host(body_.auth_seq_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the status code field.
|
||||
*
|
||||
* \return The stored status code.
|
||||
*/
|
||||
uint16_t status_code() const {
|
||||
return Endian::le_to_host(body_.status_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the Authetication Algorithm Number field.
|
||||
*
|
||||
* \param new_auth_algorithm The Authetication Algorithm Number
|
||||
* to be set.
|
||||
*/
|
||||
void auth_algorithm(uint16_t new_auth_algorithm);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Authetication Sequence Number field.
|
||||
*
|
||||
* \param new_auth_seq_number The Authetication Sequence Number
|
||||
* to be set.
|
||||
*/
|
||||
void auth_seq_number(uint16_t new_auth_seq_number);
|
||||
|
||||
/**
|
||||
* \brief Setter for the status code field.
|
||||
*
|
||||
* \param new_status_code The status code to be set.
|
||||
*/
|
||||
void status_code(uint16_t new_status_code);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11Authentication* clone() const {
|
||||
return new Dot11Authentication(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_auth_body {
|
||||
uint16_t auth_algorithm;
|
||||
uint16_t auth_seq_number;
|
||||
uint16_t status_code;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_auth_body body_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IEEE 802.11 Deauthentication frame.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11Deauthentication : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_DEAUTH;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Deauthentication.
|
||||
*
|
||||
* Constructs a 802.11 Deauthentication taking the
|
||||
* destination and source hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11Deauthentication(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Deauthentication object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Deauthentication(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the reason code field.
|
||||
*
|
||||
* \return The reason code to be set.
|
||||
*/
|
||||
uint16_t reason_code() const {
|
||||
return Endian::le_to_host(body_.reason_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the reason code field.
|
||||
*
|
||||
* \param new_reason_code The reason code to be set.
|
||||
*/
|
||||
void reason_code(uint16_t new_reason_code);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11Deauthentication* clone() const {
|
||||
return new Dot11Deauthentication(*this);
|
||||
}
|
||||
private:
|
||||
struct dot11_deauth_body {
|
||||
uint16_t reason_code;
|
||||
};
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_deauth_body body_;
|
||||
};
|
||||
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_DOT11_DOT11_AUTH_H
|
723
lib/libtins/include/tins/dot11/dot11_base.h
Normal file
723
lib/libtins/include/tins/dot11/dot11_base.h
Normal file
@ -0,0 +1,723 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT11_DOT11_H) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_DOT11_DOT11_H
|
||||
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/pdu_option.h>
|
||||
#include <tins/small_uint.h>
|
||||
#include <tins/hw_address.h>
|
||||
#include <tins/endianness.h>
|
||||
#include <tins/cxxstd.h>
|
||||
#include <tins/macros.h>
|
||||
|
||||
namespace Tins {
|
||||
namespace Memory {
|
||||
class InputMemoryStream;
|
||||
class OutputMemoryStream;
|
||||
} // Memory
|
||||
|
||||
class RSNInformation;
|
||||
|
||||
/**
|
||||
* \brief Class representing an 802.11 frame.
|
||||
*/
|
||||
class TINS_API Dot11 : public PDU {
|
||||
public:
|
||||
/**
|
||||
* The type used to store hardware addresses.
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief IEEE 802.11 options struct.
|
||||
*/
|
||||
typedef PDUOption<uint8_t, Dot11> option;
|
||||
|
||||
/**
|
||||
* The type used to store tagged options.
|
||||
*/
|
||||
typedef std::vector<option> options_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11;
|
||||
|
||||
/**
|
||||
* \brief Broadcast hardware address.
|
||||
*/
|
||||
static const address_type BROADCAST;
|
||||
|
||||
/**
|
||||
* The endianness used by Dot11.
|
||||
*/
|
||||
static const endian_type endianness = LE;
|
||||
|
||||
/**
|
||||
* \brief Enum for the different types of 802.11 frames.
|
||||
*
|
||||
*/
|
||||
enum Types {
|
||||
MANAGEMENT = 0,
|
||||
CONTROL = 1,
|
||||
DATA = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum for the different types of tagged options.
|
||||
*/
|
||||
enum OptionTypes {
|
||||
SSID,
|
||||
SUPPORTED_RATES,
|
||||
FH_SET,
|
||||
DS_SET,
|
||||
CF_SET,
|
||||
TIM,
|
||||
IBSS_SET,
|
||||
COUNTRY,
|
||||
HOPPING_PATTERN_PARAMS,
|
||||
HOPPING_PATTERN_TABLE,
|
||||
REQUEST_INFORMATION,
|
||||
BSS_LOAD,
|
||||
EDCA,
|
||||
TSPEC,
|
||||
TCLAS,
|
||||
SCHEDULE,
|
||||
CHALLENGE_TEXT,
|
||||
POWER_CONSTRAINT = 32,
|
||||
POWER_CAPABILITY,
|
||||
TPC_REQUEST,
|
||||
TPC_REPORT,
|
||||
SUPPORTED_CHANNELS,
|
||||
CHANNEL_SWITCH,
|
||||
MEASUREMENT_REQUEST,
|
||||
MEASUREMENT_REPORT,
|
||||
QUIET,
|
||||
IBSS_DFS,
|
||||
ERP_INFORMATION,
|
||||
TS_DELAY,
|
||||
TCLAS_PROCESSING,
|
||||
HT_CAPABILITY,
|
||||
QOS_CAPABILITY,
|
||||
RSN = 48,
|
||||
EXT_SUPPORTED_RATES = 50,
|
||||
AP_CHANNEL_REPORT,
|
||||
NEIGHBOR_REPORT,
|
||||
RCPI,
|
||||
MOBILITY_DOMAIN_MDE,
|
||||
FAST_BSS_TRANSITION_FTE,
|
||||
TIMEOUT_INTERVAL,
|
||||
RIC_DATA_RDE,
|
||||
DSE_REG_LOC,
|
||||
SUPPORTED_OP_CLASSES,
|
||||
EXT_CH_SWITCH_ANNOUNCEMENT,
|
||||
HT_OPERATION,
|
||||
SEC_CH_OFFSET,
|
||||
BSS_AVG_ACCESS_DELAY,
|
||||
ANTENNA,
|
||||
RSNI,
|
||||
MEASUREMENT_PILOT_TRANSMISSION,
|
||||
BSS_AVAIL_ADMISSION_CAPACITY,
|
||||
BSS_AC_ACCESS_DELAY,
|
||||
TIME_ADVERTISEMENT,
|
||||
RM_ENABLED_CAP,
|
||||
MULTIPLE_BSSID,
|
||||
BSS_2040_COEX,
|
||||
BSS_2040_INTOLERANT_CH_REPORT,
|
||||
OVERLAPPING_BSS_SCAN_PARAM,
|
||||
RIC_DESCRIPTOR,
|
||||
MGMT_MIC,
|
||||
EVENT_REQ = 78,
|
||||
EVENT_REPORT,
|
||||
DIAG_REQ,
|
||||
DIAG_REPORT,
|
||||
LOCATION_PARAMS,
|
||||
NONTRANSMITTED_BSSID_CAP,
|
||||
SSID_LIST,
|
||||
MULTIPLE_BSSID_INDEX,
|
||||
FMS_DESCRIPTOR,
|
||||
FMS_REQ,
|
||||
FMS_RESP,
|
||||
QOS_TRAFFIC_CAP,
|
||||
BSS_MAX_IDLE_PERIOD,
|
||||
TFS_REQ,
|
||||
TFS_RESP,
|
||||
WNM_SLEEP_MODE,
|
||||
TIM_BROADCAST_REQ,
|
||||
TIM_BROADCAST_RESP,
|
||||
COLLOCATED_INTERFERENCE_REPORT,
|
||||
CH_USAGE,
|
||||
TIME_ZONE,
|
||||
DMS_REQ,
|
||||
DMS_RESP,
|
||||
LINK_ID,
|
||||
WAKEUP_SCHEDULE,
|
||||
CH_SWITCH_TIMING,
|
||||
PTI_CONTROL,
|
||||
TPU_BUFFER_STATUS,
|
||||
INTERWORKING,
|
||||
ADVERTISEMENT_PROTOCOL,
|
||||
EXPEDITED_BANDWIDTH_REQ,
|
||||
QOS_MAP,
|
||||
ROAMING_CONSORTIUM,
|
||||
EMERG_ALERT_ID,
|
||||
MESH_CONFIG,
|
||||
MESH_ID,
|
||||
MESH_LINK_METRIC_REPORT,
|
||||
CONGESTION_NOTIFICATION,
|
||||
MESH_PEERING_MGMT,
|
||||
MESH_CH_SWITCH_PARAMS,
|
||||
MESH_AWAKE_WINDOW,
|
||||
BEACON_TIMING,
|
||||
MCCAOP_SETUP_REQ,
|
||||
MCCAOP_SETUP_REPLY,
|
||||
MCCAOP_ADVERTISEMENT,
|
||||
MCCAOP_TEARDOWN,
|
||||
GANN,
|
||||
RANN,
|
||||
EXT_CAP,
|
||||
PREQ = 130,
|
||||
PREP,
|
||||
PERR,
|
||||
PXU = 137,
|
||||
PXUC,
|
||||
AUTH_MESH_PEER_EX,
|
||||
MIC,
|
||||
DEST_URI,
|
||||
UAPSD_COEX,
|
||||
DMG_WAKEUP_SCHEDULE,
|
||||
EXT_SCHEDULE,
|
||||
STA_AVAIL,
|
||||
DMG_TSPEC,
|
||||
NEXT_DMG_ATI,
|
||||
DMG_CAP,
|
||||
DMG_OP = 151,
|
||||
DMG_BSS_PARAM_CHG,
|
||||
DMG_BEAM_REFINEMENT,
|
||||
CH_MEASUREMENT_FEEDBACK,
|
||||
AWAKE_WINDOW = 157,
|
||||
MULTIBAND,
|
||||
ADDBA_ESXT,
|
||||
NEXTPCP_LIST,
|
||||
PCP_HANDOVER,
|
||||
DMG_LINK_MARGIN,
|
||||
SWITCHING_STREAM,
|
||||
SESSION_TRANSITION,
|
||||
DYNAMIC_TONE_PAIRING_REPORT,
|
||||
CLUSTER_REPORT,
|
||||
RELAY_CAP,
|
||||
RELAY_TRANSFER_PARAM_SET,
|
||||
BEAMLINK_MAINTENANCE,
|
||||
MULTIPLE_MAC_SUBLAYERS,
|
||||
UPID,
|
||||
DMG_LINK_ADAPTATION_ACK,
|
||||
MCCAOP_ADV_OVERVIEW = 174,
|
||||
QUIET_PERIOD_REQ,
|
||||
QUIET_PERIOD_RESP = 177,
|
||||
QMF_POLICY = 181,
|
||||
ECAPC_POLICY = 182,
|
||||
CLUSTER_TIME_OFFSET,
|
||||
INTRA_ACCESS_CAT_PRIORITY,
|
||||
SCS_DESCRIPTOR,
|
||||
QLOAD_REPORT,
|
||||
HCCA_TXOP_UPDATE_COUNT,
|
||||
HIGHER_LAYER_STREAM_ID,
|
||||
GCR_GROUP_ADDR,
|
||||
ANTENNA_SECTOR_ID_PATTERN,
|
||||
VHT_CAP,
|
||||
VHT_OP,
|
||||
EXT_BSS_LOAD,
|
||||
WIDE_BANDWIDTH_CH_SWITCH,
|
||||
TRANSMIT_POWER_ENVELOPE,
|
||||
CH_SWITCH_WRAPPER,
|
||||
AID,
|
||||
QUIET_CHANNEL,
|
||||
OP_MODE_NOTIFY,
|
||||
UPSIM,
|
||||
REDUCED_NEIGHBOR_REPORT,
|
||||
TVHT_OP,
|
||||
DEV_LOC = 204,
|
||||
WHITE_SPACE_MAP,
|
||||
FINE_TUNING_MEASUREMENT_PARAMS,
|
||||
VENDOR_SPECIFIC = 221
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum for the different subtypes of 802.11 management frames.
|
||||
*
|
||||
*/
|
||||
enum ManagementSubtypes {
|
||||
ASSOC_REQ = 0,
|
||||
ASSOC_RESP = 1,
|
||||
REASSOC_REQ = 2,
|
||||
REASSOC_RESP = 3,
|
||||
PROBE_REQ = 4,
|
||||
PROBE_RESP = 5,
|
||||
BEACON = 8,
|
||||
ATIM = 9,
|
||||
DISASSOC = 10,
|
||||
AUTH = 11,
|
||||
DEAUTH = 12
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum for the different subtypes of 802.11 control frames.
|
||||
*
|
||||
*/
|
||||
enum ControlSubtypes {
|
||||
BLOCK_ACK_REQ = 8,
|
||||
BLOCK_ACK = 9,
|
||||
PS = 10,
|
||||
RTS = 11,
|
||||
CTS = 12,
|
||||
ACK = 13,
|
||||
CF_END = 14,
|
||||
CF_END_ACK = 15
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum fro the different subtypes of 802.11 data frames.
|
||||
*
|
||||
*/
|
||||
enum DataSubtypes {
|
||||
DATA_DATA = 0,
|
||||
DATA_CF_ACK = 1,
|
||||
DATA_CF_POLL = 2,
|
||||
DATA_CF_ACK_POLL = 3,
|
||||
DATA_NULL = 4,
|
||||
CF_ACK = 5,
|
||||
CF_POLL = 6,
|
||||
CF_ACK_POLL = 7,
|
||||
QOS_DATA_DATA = 8,
|
||||
QOS_DATA_CF_ACK = 9,
|
||||
QOS_DATA_CF_POLL = 10,
|
||||
QOS_DATA_CF_ACK_POLL = 11,
|
||||
QOS_DATA_NULL = 12
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructs an 802.11 PDU.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
*/
|
||||
Dot11(const address_type& dst_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs 802.11 PDU from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a 802.11 header in the
|
||||
* buffer, a malformed_packet exception is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol version field.
|
||||
*
|
||||
* \return The stored protocol version field.
|
||||
*/
|
||||
small_uint<2> protocol() const {
|
||||
return header_.control.protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Type field.
|
||||
*
|
||||
* \return The stored Type field.
|
||||
*/
|
||||
small_uint<2> type() const {
|
||||
return header_.control.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Subtype field.
|
||||
*
|
||||
* \return The stored Subtype field.
|
||||
*/
|
||||
small_uint<4> subtype() const {
|
||||
return header_.control.subtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the To-DS field.
|
||||
*
|
||||
* \return The stored To-DS field.
|
||||
*/
|
||||
small_uint<1> to_ds() const {
|
||||
return header_.control.to_ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the From-DS field.
|
||||
*
|
||||
* \return The stored From-DS field.
|
||||
*/
|
||||
small_uint<1> from_ds() const {
|
||||
return header_.control.from_ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the More-Frag field.
|
||||
*
|
||||
* \return The stored More-Frag field.
|
||||
*/
|
||||
small_uint<1> more_frag() const {
|
||||
return header_.control.more_frag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Retry field.
|
||||
*
|
||||
* \return The stored Retry field.
|
||||
*/
|
||||
small_uint<1> retry() const {
|
||||
return header_.control.retry;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Power-Management field.
|
||||
*
|
||||
* \return The stored Power-Management field.
|
||||
*/
|
||||
small_uint<1> power_mgmt() const {
|
||||
return header_.control.power_mgmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the More Data field.
|
||||
*
|
||||
* \return The stored More Data field.
|
||||
*/
|
||||
small_uint<1> more_data() const {
|
||||
return header_.control.more_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the WEP field.
|
||||
*
|
||||
* \return The stored WEP field.
|
||||
*/
|
||||
small_uint<1> wep() const {
|
||||
return header_.control.wep;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Order field.
|
||||
*
|
||||
* \return The stored Order field.
|
||||
*/
|
||||
small_uint<1> order() const {
|
||||
return header_.control.order;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Duration-ID field.
|
||||
*
|
||||
* \return The stored Duration-ID field.
|
||||
*/
|
||||
uint16_t duration_id() const {
|
||||
return Endian::le_to_host(header_.duration_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the first address.
|
||||
*
|
||||
* \return The stored first address.
|
||||
*/
|
||||
address_type addr1() const {
|
||||
return header_.addr1;
|
||||
}
|
||||
|
||||
// Setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the protocol version field.
|
||||
*
|
||||
* \param new_proto The new protocol version field value.
|
||||
*/
|
||||
void protocol(small_uint<2> new_proto);
|
||||
|
||||
/**
|
||||
* \brief Setter for the type field.
|
||||
*
|
||||
* \param new_type The new type field value.
|
||||
*/
|
||||
void type(small_uint<2> new_type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the subtype field.
|
||||
*
|
||||
* \param new_subtype The new subtype field value.
|
||||
*/
|
||||
void subtype(small_uint<4> new_subtype);
|
||||
|
||||
/**
|
||||
* \brief Setter for the To-DS field.
|
||||
*
|
||||
* \param new_value The new To-DS field value.
|
||||
*/
|
||||
void to_ds(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the From-DS field.
|
||||
*
|
||||
* \param new_value The new From-DS field value.
|
||||
*/
|
||||
void from_ds(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the More-Frag field.
|
||||
*
|
||||
* \param new_value The new More-Frag field value.
|
||||
*/
|
||||
void more_frag(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Retry field.
|
||||
*
|
||||
* \param new_value The new Retry field value.
|
||||
*/
|
||||
void retry(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Power-Management field.
|
||||
*
|
||||
* \param new_value The new Power-Management field value.
|
||||
*/
|
||||
void power_mgmt(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the More Data field.
|
||||
*
|
||||
* \param new_value The new More Data field value.
|
||||
*/
|
||||
void more_data(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the WEP field.
|
||||
*
|
||||
* \param new_value The new WEP field value.
|
||||
*/
|
||||
void wep(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Order field.
|
||||
*
|
||||
* \param new_value The new Order field value.
|
||||
*/
|
||||
void order(small_uint<1> new_value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Duration-ID field.
|
||||
*
|
||||
* \param new_duration_id The new Duration-ID field value.
|
||||
*/
|
||||
void duration_id(uint16_t new_duration_id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the first address.
|
||||
*
|
||||
* \param new_addr1 The new first address.
|
||||
*/
|
||||
void addr1(const address_type& new_addr1);
|
||||
|
||||
/* Virtual methods */
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
void send(PacketSender& sender, const NetworkInterface& iface);
|
||||
#endif // _WIN32
|
||||
|
||||
/**
|
||||
* \brief Adds a new option to this Dot11 PDU.
|
||||
* \param opt The option to be added.
|
||||
*/
|
||||
void add_option(const option& opt);
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
/**
|
||||
* \brief Adds a new option to this Dot11 PDU.
|
||||
*
|
||||
* The option is move-constructed
|
||||
*
|
||||
* \param opt The option to be added.
|
||||
*/
|
||||
void add_option(option &&opt) {
|
||||
internal_add_option(opt);
|
||||
options_.push_back(std::move(opt));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Removes a Dot11 option.
|
||||
*
|
||||
* If there are multiple options of the given type, only the first one
|
||||
* will be removed.
|
||||
*
|
||||
* \param type The type of the option to be removed.
|
||||
* \return true if the option was removed, false otherwise.
|
||||
*/
|
||||
bool remove_option(OptionTypes type);
|
||||
|
||||
/**
|
||||
* \brief Looks up a tagged option in the option list.
|
||||
*
|
||||
* The returned pointer <b>must not</b> be free'd.
|
||||
*
|
||||
* \param type The option identifier.
|
||||
* \return The option found, or 0 if no such option has been set.
|
||||
*/
|
||||
const option* search_option(OptionTypes type) const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11* clone() const {
|
||||
return new Dot11(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the option list.
|
||||
*
|
||||
* \return The options list.
|
||||
*/
|
||||
const options_type& options() const {
|
||||
return options_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates an Dot11 PDU from a buffer.
|
||||
*
|
||||
* This can be used somehow as a "virtual constructor". This
|
||||
* method instantiates the appropriate subclass of Dot11 from the
|
||||
* given buffer.
|
||||
*
|
||||
* The allocated class' type will be figured out from the
|
||||
* information provided in the buffer.
|
||||
*
|
||||
* \param buffer The buffer from which to take the PDU data.
|
||||
* \param total_sz The total size of the buffer.
|
||||
* \return The allocated Dot11 PDU.
|
||||
*/
|
||||
static Dot11* from_bytes(const uint8_t* buffer, uint32_t total_sz);
|
||||
protected:
|
||||
virtual void write_ext_header(Memory::OutputMemoryStream& stream);
|
||||
virtual void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
void parse_tagged_parameters(Memory::InputMemoryStream& stream);
|
||||
void add_tagged_option(OptionTypes opt, uint8_t len, const uint8_t* val);
|
||||
protected:
|
||||
/**
|
||||
* Struct that represents the 802.11 header
|
||||
*/
|
||||
TINS_BEGIN_PACK
|
||||
struct dot11_header {
|
||||
TINS_BEGIN_PACK
|
||||
struct {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
uint16_t protocol:2,
|
||||
type:2,
|
||||
subtype:4,
|
||||
to_ds:1,
|
||||
from_ds:1,
|
||||
more_frag:1,
|
||||
retry:1,
|
||||
power_mgmt:1,
|
||||
more_data:1,
|
||||
wep:1,
|
||||
order:1;
|
||||
#elif TINS_IS_BIG_ENDIAN
|
||||
uint16_t subtype:4,
|
||||
type:2,
|
||||
protocol:2,
|
||||
order:1,
|
||||
wep:1,
|
||||
more_data:1,
|
||||
power_mgmt:1,
|
||||
retry:1,
|
||||
more_frag:1,
|
||||
from_ds:1,
|
||||
to_ds:1;
|
||||
#endif
|
||||
} TINS_END_PACK control;
|
||||
uint16_t duration_id;
|
||||
uint8_t addr1[address_type::address_size];
|
||||
|
||||
} TINS_END_PACK;
|
||||
private:
|
||||
Dot11(const dot11_header* header_ptr);
|
||||
|
||||
void internal_add_option(const option& opt);
|
||||
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
||||
options_type::const_iterator search_option_iterator(OptionTypes type) const;
|
||||
options_type::iterator search_option_iterator(OptionTypes type);
|
||||
|
||||
|
||||
dot11_header header_;
|
||||
uint32_t options_size_;
|
||||
options_type options_;
|
||||
};
|
||||
|
||||
} // Tins
|
||||
|
||||
#endif // TINS_DOT11_DOT11_H
|
179
lib/libtins/include/tins/dot11/dot11_beacon.h
Normal file
179
lib/libtins/include/tins/dot11/dot11_beacon.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT11_DOT11_BEACON_H) && defined(TINS_HAVE_DOT11)
|
||||
#define TINS_DOT11_DOT11_BEACON_H
|
||||
|
||||
#include <tins/dot11/dot11_mgmt.h>
|
||||
#include <tins/macros.h>
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Represents an IEEE 802.11 Beacon.
|
||||
*
|
||||
*/
|
||||
class TINS_API Dot11Beacon : public Dot11ManagementFrame {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_BEACON;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Beacon.
|
||||
*
|
||||
* Constructs a 802.11 Beacon taking destination and source
|
||||
* hardware address.
|
||||
*
|
||||
* \param dst_hw_addr The destination hardware address.
|
||||
* \param src_hw_addr The source hardware address.
|
||||
*/
|
||||
Dot11Beacon(const address_type& dst_hw_addr = address_type(),
|
||||
const address_type& src_hw_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Beacon object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of this
|
||||
* one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Beacon(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the timestamp field.
|
||||
*
|
||||
* \return The stored timestamp value.
|
||||
*/
|
||||
uint64_t timestamp() const {
|
||||
return Endian::le_to_host(body_.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the interval field.
|
||||
*
|
||||
* \return The stored interval value.
|
||||
*/
|
||||
uint16_t interval() const {
|
||||
return Endian::le_to_host(body_.interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information structure.
|
||||
*
|
||||
* \return A constant refereence to the stored Capabilities
|
||||
* Information field.
|
||||
*/
|
||||
const capability_information& capabilities() const {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return A refereence to the stored Capabilities Information
|
||||
* field.
|
||||
*/
|
||||
capability_information& capabilities() {
|
||||
return body_.capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the timestamp field.
|
||||
*
|
||||
* \param new_timestamp The timestamp to be set.
|
||||
*/
|
||||
void timestamp(uint64_t new_timestamp);
|
||||
|
||||
/**
|
||||
* \brief Setter for the interval field.
|
||||
*
|
||||
* \param new_interval The interval to be set.
|
||||
*/
|
||||
void interval(uint16_t new_interval);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11Beacon* clone() const {
|
||||
return new Dot11Beacon(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
private:
|
||||
TINS_BEGIN_PACK
|
||||
struct dot11_beacon_body {
|
||||
uint64_t timestamp;
|
||||
uint16_t interval;
|
||||
capability_information capability;
|
||||
} TINS_END_PACK;
|
||||
|
||||
void write_fixed_parameters(Memory::OutputMemoryStream& stream);
|
||||
|
||||
dot11_beacon_body body_;
|
||||
};
|
||||
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_DOT11_DOT11_BEACON_H
|
782
lib/libtins/include/tins/dot11/dot11_control.h
Normal file
782
lib/libtins/include/tins/dot11/dot11_control.h
Normal file
@ -0,0 +1,782 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Matias Fontanini
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tins/config.h>
|
||||
|
||||
#if !defined(TINS_DOT11_DOT11_CONTROL_H) && defined(TINS_HAVE_DOT11)
|
||||
|
||||
#define TINS_DOT11_DOT11_CONTROL_H
|
||||
|
||||
#include <tins/dot11/dot11_base.h>
|
||||
#include <tins/macros.h>
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Represents an IEEE 802.11 control frame.
|
||||
*/
|
||||
class TINS_API Dot11Control : public Dot11 {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 control frame PDU
|
||||
*
|
||||
* Constructs a 802.11 Control PDU taking the destination and
|
||||
* source hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
*/
|
||||
Dot11Control(const address_type& dst_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Control object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Control(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class that represents an abstraction of the 802.11 control frames
|
||||
* that contain a target address.
|
||||
*/
|
||||
class TINS_API Dot11ControlTA : public Dot11Control {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL_TA;
|
||||
|
||||
/**
|
||||
* \brief Getter for the target address field.
|
||||
*/
|
||||
address_type target_addr() const {
|
||||
return taddr_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the target address field.
|
||||
* \param addr The new target address.
|
||||
*/
|
||||
void target_addr(const address_type& addr);
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11::matches_flag(flag);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 control frame TA PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11ControlTA(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11ControlTA object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11ControlTA(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
protected:
|
||||
/**
|
||||
* \brief Getter for the control ta additional fields size.
|
||||
*/
|
||||
uint32_t controlta_size() const {
|
||||
return static_cast<uint32_t>(taddr_.size() + sizeof(dot11_header));
|
||||
}
|
||||
|
||||
void write_ext_header(Memory::OutputMemoryStream& stream);
|
||||
private:
|
||||
|
||||
address_type taddr_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IEEE 802.11 RTS frame.
|
||||
*/
|
||||
class TINS_API Dot11RTS : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_RTS;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 RTS frame PDU
|
||||
*
|
||||
* Constructs a 802.11 RTS PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11RTS(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11RTS object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11RTS(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11RTS* clone() const {
|
||||
return new Dot11RTS(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
class TINS_API Dot11PSPoll : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_PS_POLL;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 PS-Poll frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11PSPoll(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11PSPoll object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11PSPoll(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11PSPoll* clone() const {
|
||||
return new Dot11PSPoll(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
class TINS_API Dot11CFEnd : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_CF_END;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 CF-End frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11CFEnd(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11CFEnd object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of this
|
||||
* one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11CFEnd(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11CFEnd* clone() const {
|
||||
return new Dot11CFEnd(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
class TINS_API Dot11EndCFAck : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_END_CF_ACK;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 End-CF-Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11EndCFAck(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11EndCFAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11EndCFAck(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11EndCFAck* clone() const {
|
||||
return new Dot11EndCFAck(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
class TINS_API Dot11Ack : public Dot11Control {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_ACK;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
*/
|
||||
Dot11Ack(const address_type& dst_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Ack frame object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Ack(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11Ack* clone() const {
|
||||
return new Dot11Ack(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class that represents an 802.11 Block Ack Request PDU.
|
||||
*/
|
||||
class TINS_API Dot11BlockAckRequest : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_BLOCK_ACK_REQ;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Block Ack request frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11BlockAckRequest(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11BlockAckRequest object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11BlockAckRequest(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/* Getter */
|
||||
|
||||
/**
|
||||
* \brief Getter for the bar control field.
|
||||
* \return The stored bar control field.
|
||||
*/
|
||||
small_uint<4> bar_control() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return bar_control_ & 0xf;
|
||||
#else
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the start sequence field.
|
||||
* \return The stored start sequence.
|
||||
*/
|
||||
small_uint<12> start_sequence() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
#else
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment number field.
|
||||
* \return The stored fragment number field.
|
||||
*/
|
||||
small_uint<4> fragment_number() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return start_sequence_ & 0xf;
|
||||
#else
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return The header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/* Setter */
|
||||
|
||||
/**
|
||||
* \brief Setter for the bar control field.
|
||||
* \param bar The bar control field to be set.
|
||||
*/
|
||||
void bar_control(small_uint<4> bar);
|
||||
|
||||
/**
|
||||
* \brief Setter for the start sequence field.
|
||||
* \param bar The start sequence field to be set.
|
||||
*/
|
||||
void start_sequence(small_uint<12> seq);
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment number field.
|
||||
* \param frag The fragment number field to be set.
|
||||
*/
|
||||
void fragment_number(small_uint<4> frag);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11BlockAckRequest* clone() const {
|
||||
return new Dot11BlockAckRequest(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
protected:
|
||||
void write_ext_header(Memory::OutputMemoryStream& stream);
|
||||
private:
|
||||
uint16_t bar_control_;
|
||||
uint16_t start_sequence_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class that represents an 802.11 block ack frame.
|
||||
*/
|
||||
class TINS_API Dot11BlockAck : public Dot11ControlTA {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_BLOCK_ACK;
|
||||
|
||||
/**
|
||||
* The size of the bitmap field.
|
||||
*/
|
||||
static const size_t bitmap_size = 8;
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Block Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11BlockAck(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11BlockAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11BlockAck(const uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* \brief Getter for the bar control field.
|
||||
* \return The stored bar control field.
|
||||
*/
|
||||
small_uint<4> bar_control() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return bar_control_ & 0xf;
|
||||
#else
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the start sequence field.
|
||||
* \return The stored start sequence.
|
||||
*/
|
||||
small_uint<12> start_sequence() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
#else
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment number field.
|
||||
* \return The stored fragment number field.
|
||||
*/
|
||||
small_uint<4> fragment_number() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return start_sequence_ & 0xf;
|
||||
#else
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
* \brief Setter for the bar control field.
|
||||
* \param bar The bar control field to be set.
|
||||
*/
|
||||
void bar_control(small_uint<4> bar);
|
||||
|
||||
/**
|
||||
* \brief Setter for the start sequence field.
|
||||
* \param bar The start sequence field to be set.
|
||||
*/
|
||||
void start_sequence(small_uint<12> seq);
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment number field.
|
||||
* \param frag The fragment number field to be set.
|
||||
*/
|
||||
void fragment_number(small_uint<4> frag);
|
||||
|
||||
/**
|
||||
* \brief Getter for the bitmap field.
|
||||
*
|
||||
* The returned pointer <b>must not</b> be free'd.
|
||||
*
|
||||
* \return The bitmap field.
|
||||
*/
|
||||
const uint8_t* bitmap() const {
|
||||
return bitmap_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Setter for the bitmap field.
|
||||
* \param bit The new bitmap field to be set.
|
||||
*/
|
||||
void bitmap(const uint8_t* bit);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const {
|
||||
return pdu_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check whether this PDU matches the specified flag.
|
||||
* \param flag The flag to match
|
||||
* \sa PDU::matches_flag
|
||||
*/
|
||||
bool matches_flag(PDUType flag) const {
|
||||
return flag == pdu_flag || Dot11Control::matches_flag(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone
|
||||
*/
|
||||
Dot11BlockAck* clone() const {
|
||||
return new Dot11BlockAck(*this);
|
||||
}
|
||||
private:
|
||||
void write_ext_header(Memory::OutputMemoryStream& stream);
|
||||
|
||||
uint16_t bar_control_, start_sequence_;
|
||||
uint8_t bitmap_[bitmap_size];
|
||||
};
|
||||
|
||||
} // namespace Tins
|
||||
|
||||
#endif // TINS_DOT11_DOT11_CONTROL_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user