Add latex documentation

This commit is contained in:
Florian Hoss 2022-07-29 14:22:31 +02:00
parent 0f6d7868d2
commit bef08d0838
14 changed files with 2575 additions and 0 deletions

368
documentation/.gitignore vendored Normal file
View file

@ -0,0 +1,368 @@
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
.*.lb
## Intermediate documents:
*.dvi
*.xdv
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
# *.pdf
## Generated if empty string is given at "Please type another file name for output:"
*.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Build tool directories for auxiliary files
# latexrun
latex.out/
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# changes
*.soc
# comment
*.cut
# cprotect
*.cpt
# elsarticle (documentclass of Elsevier journals)
*.spl
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
*.lzo
*.lzs
*.slg
*.slo
*.sls
# uncomment this for glossaries-extra (will ignore makeindex's style files!)
# *.ist
# gnuplot
*.gnuplot
*.table
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.glog
*.gtex
# htlatex
*.4ct
*.4tc
*.idv
*.lg
*.trc
*.xref
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files
# *.tikz
*-tikzDictionary
# listings
*.lol
# luatexja-ruby
*.ltjruby
# makeidx
*.idx
*.ilg
*.ind
# minitoc
*.maf
*.mlf
*.mlt
*.mtc[0-9]*
*.slf[0-9]*
*.slt[0-9]*
*.stc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# newpax
*.newpax
# nomencl
*.nlg
*.nlo
*.nls
# pax
*.pax
# pdfpcnotes
*.pdfpc
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# svg
svg-inkscape/
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# tcolorbox
*.listing
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# titletoc
*.ptc
# todonotes
*.tdo
# vhistory
*.hst
*.ver
# easy-todo
*.lod
# xcolor
*.xcp
# xmpincl
*.xmpi
# xindy
*.xdy
# xypic precompiled matrices and outlines
*.xyc
*.xyd
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# LyX
*.lyx~
# Kile
*.backup
# gummi
.*.swp
# KBibTeX
*~[0-9]*
# TeXnicCenter
*.tps
# auto folder when using emacs and auctex
./auto/*
*.el
# expex forward references with \gathertags
*-tags.tex
# standalone packages
*.sta
# Makeindex log files
*.lpz
# xwatermark package
*.xwm
# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
# Uncomment the next line to have this generated file ignored.
#*Notes.bib
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*

174
documentation/api/api.tex Normal file
View file

@ -0,0 +1,174 @@
\section{API}
\subsection{REST Endpoints} \label{api}
Managing the firewall rules can be done over a REST API\footnote{\href{https://www.ibm.com/cloud/learn/rest-apis}{What is a REST API}}. Available routes are the following and can be retrieved by visiting the API (e.g. \verb|http://10.93.0.224:8080/api|) of the device.
\lstset{style=json}
\begin{lstlisting}
[
{
"endpoint": "http://10.93.0.246:8080/api/firewall/rules",
"description": "Get all Firewall Rules",
"method": "GET"
},
{
"endpoint": "http://10.93.0.246:8080/api/firewall/rules/<key>",
"description": "Get Firewall Rule by key",
"method": "GET"
},
{
"endpoint": "http://10.93.0.246:8080/api/firewall/rules",
"description": "Create Firewall Rule",
"method": "POST"
},
{
"endpoint": "http://10.93.0.246:8080/api/firewall/rules/<key>",
"description": "Update Firewall Rule by key",
"method": "PUT"
},
{
"endpoint": "http://10.93.0.246:8080/api/firewall/rules/<key>",
"description": "Delete Firewall Rule by key",
"method": "DELETE"
}
]
\end{lstlisting}
\newpage
\subsection{Get rules}
\begin{verbatim}
curl -u username:password http://10.93.0.246:8080/api/firewall/rules
\end{verbatim}
\lstset{style=json}
\begin{lstlisting}
// HTTP/1.1 200 OK
// Content-Type: application/json; charset=utf-8
// Content-Length: 109
[
{
"key": "1",
"ip": "10.93.0.211",
"port_from": "8080",
"port_to": "8080",
"protocol": "TCP",
"target": "ACCEPT"
}
]
\end{lstlisting}
\subsection{Get rule}
\begin{verbatim}
curl -u username:password http://10.93.0.246:8080/api/firewall/rules/1
\end{verbatim}
\lstset{style=json}
\begin{lstlisting}
// HTTP/1.1 200 OK
// Content-Type: application/json; charset=utf-8
// Content-Length: 107
{
"key": "1",
"ip": "10.93.0.211",
"port_from": "8080",
"port_to": "8080",
"protocol": "TCP",
"target": "ACCEPT"
}
\end{lstlisting}
\subsection{Create rule}
\begin{verbatim}
curl -X POST -u username:password \
http://10.93.0.246:8080/api/firewall/rules
?ip=10.93.0.200&port_from=10&port_to=50&protocol=UDP&target=ACCEPT
\end{verbatim}
\lstset{style=json}
\begin{lstlisting}
// HTTP/1.1 201 Created
// Content-Type: application/json; charset=utf-8
// Content-Length: 104
{
"key": "2",
"ip": "10.93.0.200",
"port_from": "10",
"port_to": "50",
"protocol": "UDP",
"target": "ACCEPT"
}
\end{lstlisting}
Available protocols are \verb|TCP, UDP & ALL|
Available targets are \verb|ACCEPT & DROP|
\subsection{Update rule}
\begin{verbatim}
curl -X PUT -u username:password \
http://10.93.0.246:8080/api/firewall/rules/2
?ip=10.93.0.100&port_from=20&port_to=100&protocol=ALL&target=DROP
\end{verbatim}
\lstset{style=json}
\begin{lstlisting}
// HTTP/1.1 200 OK
// Content-Type: application/json; charset=utf-8
// Content-Length: 103
{
"key": "2",
"ip": "10.93.0.100",
"port_from": "20",
"port_to": "100",
"protocol": "ALL",
"target": "DROP"
}
\end{lstlisting}
Available protocols are \verb|TCP, UDP & ALL|
Available targets are \verb|ACCEPT & DROP|
\subsection{Delete rule}
\begin{verbatim}
curl -X DELETE -u username:password \
http://10.93.0.246:8080/api/firewall/rules/2
\end{verbatim}
\lstset{style=json}
\begin{lstlisting}
// HTTP/1.1 200 OK
// Content-Type: application/json; charset=utf-8
// Content-Length: 36
{
"message": "firewall rule deleted"
}
\end{lstlisting}
\subsection{HTTPS} \label{https}
To connect to the ESP over HTTPS (Hypertext Transfer Protocol Secure) the Webserver can be setup to use certificates that need to be included in the constructor as seen in section \ref{authentication}. This only works for the esp8266 with the Arduino library but can be added as an external library (\verb|esp32_https_server_combat|\footnote{\href{https://github.com/fhessel/esp32_https_server_compat}{https://github.com/fhessel/esp32\_https\_server\_compat}}) for the esp32 if needed.
\newpage
\subsection{Authentication} \label{authentication}
To authenticate the API uses basic auth. Communication should therefore be encrypted to protect the process from eavesdropping. Another solution would be to setup the rules in a private network and setup the esp without the API enabled. Therefore the rules will still apply, but cannot be changed over the network. Example certificates for the esp8266 are included in the repository and encryption can be added to the esp32 as described in section \ref{https}. Setting the username and password is done via the constructor of the api class. To create the api class to setup the firewall rules a firewall class instance is needed.
\lstset{style=c++}
\begin{lstlisting}
#include "Firewall.hpp"
#include "API.hpp"
firewall = new fw::Firewall();
firewallApi = new fw::API(firewall, cert, key, username, password);
\end{lstlisting}
After this all endpoints shown in section \ref{api} will be protected.

View file

@ -0,0 +1,9 @@
@book{example-book,
title = {{Example Book}},
author = {Lastname, Surname},
isbn = {123456789},
address = {Germany},
publisher = {Goverment},
year = {2019},
edition = {Second}
}

View file

@ -0,0 +1,55 @@
@online{pio-install,
author = {PlatformIO},
title = {Installation},
urldate = {2022-03-24},
year = {2022},
url = {https://docs.platformio.org/en/latest//core/installation.html}
}
@online{pio-about,
author = {PlatformIO},
title = {What is PlatformIO},
urldate = {2022-03-24},
year = {2022},
url = {https://docs.platformio.org/en/latest//what-is-platformio.html}
}
@online{vscode-about,
author = {{Visual Studio Code}},
title = {Getting Started},
urldate = {2022-03-24},
year = {2022},
url = {https://docs.platformio.org/en/latest//what-is-platformio.html}
}
@online{eeprom-doc,
author = {Arduino},
title = {EEPROM Library},
urldate = {2022-07-19},
year = {2022},
url = {https://docs.arduino.cc/learn/built-in-libraries/eeprom}
}
@online{espressif-wifi,
author = {Espressif},
title = {Wi-Fi Driver},
urldate = {2022-07-20},
year = {2022},
url = {https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-driver}
}
@online{lwip,
author = {LwIP},
title = {LwIP},
urldate = {2022-07-25},
year = {2022},
url = {https://www.nongnu.org/lwip/2_1_x/index.html}
}
@online{arduino-esp-idf,
author = {Espressif},
title = {Arduino as an ESP-IDF component},
urldate = {2022-07-27},
year = {2022},
url = {https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/esp-idf_component.html}
}

View file

@ -0,0 +1,265 @@
\section{Firewall}
\subsection{Software Firewall}
A software firewall is inspecting data that goes in and out of the device. It has to be installed on each device in the network. Therefore, can only protect one device at a time. Looking at already existing solutions for linux and other operating systems, rules and settings can be identified that need to be implemented for this firewall.
\subsection{UFW (Uncomplicated Firewall)}
To see how a firewall works, UFW was analyzed. A look at the table provides following information:
\begin{figure}[H]
\begin{center}
\includegraphics[width=0.6\textwidth]{ufw}
\caption{UFW}
\label{fig:UFW}
\end{center}
\end{figure}
A destination port on the device, the action of the firewall and the IP-Address from where the request originated can be setup. Also the protocol that the rule applies to, can be chosen with TCP or UDP.
\newpage
\subsection{Parameter}
After analyzing existing solutions following firewall parameters were implemented:
\lstset{style=c++}
\begin{lstlisting}
typedef enum firewall_targets : uint8_t
{
TARGET_DROP = 1,
TARGET_ACCEPT = 2,
} firewall_target_t;
typedef enum firewall_protocols : uint8_t
{
PROTOCOL_TCP = 6,
PROTOCOL_UDP = 17,
PROTOCOL_ALL = 255,
} firewall_protocol_t;
static const uint8_t IPV4ADDRESS_LENGTH = 16;
typedef struct firewall_rules
{
uint8_t key;
char ip[IPV4ADDRESS_LENGTH];
uint16_t port_from;
uint16_t port_to;
firewall_protocol_t protocol;
firewall_target_t target;
struct firewall_rules *next;
} firewall_rule_t;
\end{lstlisting}
A port can be a maximum of 65535, and was chosen because LwIP (Section \ref{lwip}) uses it for the ports in the respective header. Target as well as protocol are enums for the available options. LwIP uses the same specified values for their protocols (Section \ref{lwip_analysis}). To block a range of ports, there is a \verb|port_from| and \verb|port_to|. The firewall will store all the rules as linked list to dynamically add and remove rules.
\subsection{IwIP} \label{lwip}
lwIP is a small independent implementation of the TCP/IP protocol suite and is used in the esp-core for network communication. This is the place the firewall need to check for the incoming traffic in order to drop, reject or pass packets based on the rules.
\cite[cf.][]{lwip}
\newpage
\subsubsection{Analysing} \label{lwip_analysis}
First step is to analyze the code to find out where the packets are getting handled. Looking in
\verb|~/.platformio/packages/framework-espidf/components/lwip/lwip/src/core/ipv4|
there is a function:
\verb|err_t ip4_input(struct pbuf *p, struct netif *inp)|
to consume all incoming packages. Simply placing a logger can quickly show that this is the place to put the firewall filter.
\begin{verbatim}
if (ip4_addr4_16_val(iphdr->src) == 211)
{
ESP_LOGI("HOOK", "%3" U16_F, "% " U16_F "% " U16_F "% " U16_F "% " U16_F,
(u16_t)IPH_PROTO(iphdr)
ip4_addr1_16_val(iphdr->src),
ip4_addr2_16_val(iphdr->src),
ip4_addr3_16_val(iphdr->src),
ip4_addr4_16_val(iphdr->src));
}
\end{verbatim}
Following output can be seen when sending a ping from the machine with IP-Address \verb|10.93.0.211| to the esp. ICMP is therefore marked with protocol 1.
\begin{verbatim}
I (x) HOOK: 1 10 93 0 211
\end{verbatim}
Sending a UDP or TCP package to the ESP (IP-Address: \verb|10.93.0.246|) can be done by executing the python code in the repository, or simply executing an nmap\footnote{\href{https://nmap.org/}{https://nmap.org/}} scan with UDP and TCP.
\begin{verbatim}
python3 tester.py -i 10.93.0.246 -p 80 -t TCP
python3 tester.py -i 10.93.0.246 -p 22 -t UPD
\end{verbatim}
Following output can be registered.
\begin{verbatim}
I (x) HOOK: 6 10 93 0 211
I (x) HOOK: 17 10 93 0 211
\end{verbatim}
Looking at the printed protocols this means evidentially how protocols are identified in LwIP:
$$ "ICMP" \equiv 1 $$
$$ "TCP" \equiv 6 $$
$$ "UDP" \equiv 17 $$
\subsubsection{Arduino as an ESP-IDF component}
LwIP needs to be recompiled to register hooks (Section \ref{sec:hooks}). Therefore the following steps are performed to compile our code with Arduino as an ESP-IDF component on an ESP32.
After initializing an empty ESP-IDF project with PlatformIO the \verb|platformio.ini| file would look like this:
\begin{verbatim}
[platformio]
default_envs = esp32
[env:esp32]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf
monitor_speed = 115200
\end{verbatim}
Following commands need to be executed inside a fresh ESP-IDF project folder, in order to add Arduino into the setup:
\lstset{style=shell}
\begin{lstlisting}
mkdir -p components && \
cd components && \
git clone https://github.com/espressif/arduino-esp32.git arduino && \
cd arduino && \
git submodule update --init --recursive && \
cd ../..
\end{lstlisting}
After successful cloning of the git repository, some changes need to be written into the ESP-IDF config file with the help of \verb|menuconfig|:
\begin{verbatim}
platformio run --target menuconfig --environment esp32
\end{verbatim}
Navigating to the section Arduino Configuration, usage of setup() and loop() functions can be turned on with the option ``Autostart Arduino setup and loop on boot''.
After these steps Arduino code can be written and executed like expected, but with the advantages of compiling the whole esp32-core with the specified settings and hooks.
\cite[][]{arduino-esp-idf}
\newpage
\subsubsection{Using a Hook} \label{sec:hooks}
After learning the protocols, a hook needs to be registered in order to filter the packets based on our rules. To register the hook that suits our project, \verb|LWIP_HOOK_IP4_INPUT| needs to be set as \verb|build_flag| in the \verb|platformio.ini| file to overwrite it in LwIP. This is an easy way of testing if it works as expected, but should be written in a function for any other use-case.
\begin{verbatim}
build_flags =
'-DLWIP_HOOK_IP4_INPUT(pbuf, input_netif)=({ESP_LOGI("HOOK","TEST");0;})'
\end{verbatim}
\cite[cf.][]{lwip}
After the successful test of the logging hook, an implementation of a function is needed in order to integrate it with the firewall API written to change and create rules.
In order to register a function LwIP needs to know where the prototypes are declared. Therefore, in the \verb|platformio.ini| file, the \verb|build_flags| need to be adjusted.
\begin{verbatim}
build_flags =
'-Iinclude'
'-DESP_IDF_LWIP_HOOK_FILENAME="lwip_hooks.h"'
\end{verbatim}
The file \verb|lwip_hooks.h| has the necessary information for LwIP to know how the function will be called.
\lstset{style=c++}
\begin{lstlisting}
int lwip_hook_ip4_input(struct pbuf *pbuf, struct netif *input_netif);
#define LWIP_HOOK_IP4_INPUT lwip_hook_ip4_input
\end{lstlisting}
After specifying the prototype the function can be placed in the main.cpp file to be compiled and run.
\newpage
\subsection{Benchmark}
To test the performance of the firewall with rules and without rules, as well as many rules, the time is stopped at the beginning and the end of the hook.
\subsubsection{Code}
\lstset{style=c++}
\begin{lstlisting}
void print_time_taken(struct timeval start,
fw::firewall_target_t target)
{
struct timeval stop;
gettimeofday(&stop, NULL);
u32_t time_taken = (stop.tv_sec - start.tv_sec) * 1000000 +
stop.tv_usec - start.tv_usec;
Serial.println(time_taken);
}
int lwip_hook_ip4_input(struct pbuf *pbuf, struct netif *input_netif)
{
// Firewall is not setup yet
if (firewall != NULL)
{
struct timeval start;
gettimeofday(&start, NULL);
if (firewall->is_packet_allowed(pbuf))
{
print_time_taken(start, fw::TARGET_ACCEPT);
return 0;
}
else
{
print_time_taken(start, fw::TARGET_DROP);
pbuf_free(pbuf);
return 1;
}
}
return 0;
}
\end{lstlisting}
\newpage
\subsubsection{Result}
The results in milliseconds are copied into a spreadsheet to create an chart with the measured processing time of a packet in the hook. The tests were done with 1,5,10 and 15 rules. As the linear trendlines indicate, the amount of rules are heavily responsible for a longer processing time.
\begin{figure}[H]
\begin{center}
\includegraphics[width=\textwidth]{chart}
\caption{Benchmark graph}
\label{fig:Benchmark graph}
\end{center}
\end{figure}
Without any rule, the processing of the included hook takes between 23 to 24 milliseconds. No comparison or preparing of the packet is necessary.
With a single rule, the processing time already increases rapidly. The amount of time it takes for the packet to be prepared, comparing it to the rules and releasing it, is already between 67 and 99 milliseconds.
\begin{figure}[H]
\begin{center}
\begin{tabular}{|l|l|l|l|l|l|}
\hline
& 0 rule & 1 rule & 5 rules & 10 rules & 15 rules \\
\hline
\textbf{Average} & 23,81 ms & 74,94 ms & 78,81 ms & 87,07 ms & 94,63 ms \\
\textbf{Minimum} & 23 ms & 67 ms & 72 ms & 77 ms & 85 ms \\
\textbf{Maximum} & 24 ms & 99 ms & 98 ms & 115 ms & 124 ms \\
\hline
\end{tabular}
\end{center}
\caption{Benchmark table}
\label{fig:Benchmark table}
\end{figure}
$$ 0\ rule\ \textcolor{red}{\leftarrow 51,13 ms \rightarrow}\ 1\ rule\ \textcolor{teal}{\leftarrow 3,87 ms \rightarrow}\ 5\ rules\ \textcolor{orange}{\leftarrow 8,26 ms \rightarrow}\ 10\ rules\ \textcolor{orange}{\leftarrow 7,56 ms \rightarrow}\ 15\ rules $$

View file

@ -0,0 +1,57 @@
\section{PlatformIO}
There are several ways to compile and upload code to a micro-controller. The first tests where written and compiled in the Arduino IDE\footnote{\href{https://www.arduino.cc/en/software}{https://www.arduino.cc/en/software}}. Because references and cross-platform developing was not easy with this approach, developing in this project will be done with the help of PlatformIO.
``PlatformIO is a must-have tool for professional embedded systems engineers who develop solutions on more than one specific platform. In addition, by having a decentralized architecture, PlatformIO offers both new and existing developers a quick integration path for developing commercial-ready products, and reduces the overall time-to-market. [...] The build system structure automatically tags software dependencies and applies them using a modular hierarchy that takes away the usual complexity and pain. Developers no longer have to manually find and assemble an environment of tool-chains, compilers, and library dependencies to develop applications for a specific target. With PlatformIO, clicking the compile button will bring in all necessary dependencies automatically.''
\cite[cf.][]{pio-about}
\subsubsection{Install}
A dependency of PlatformIO is Python\footnote{\href{https://www.python.org/}{https://www.python.org/}}. To install the latest version of python, follow the installation instructions on their \href{https://www.python.org/}{website}.
PlatformIO can now simply installed by downloading a script called ``get-platformio.py'' and executing it. On Apple MacOS\footnote{\href{https://en.wikipedia.org/wiki/MacOS}{https://en.wikipedia.org/wiki/MacOS}} it can simply be installed with the help of Homebrew Packages Manager\footnote{\href{https://brew.sh/}{https://brew.sh/}}.
It is integrated into Visual Studio Code (Section \ref{sec:vsc}) and can be used with the official Plugin\footnote{\href{https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide}{https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide}} (Abbildung \ref{fig:PlatformIO in VSC}).
\subsubsection{Example configuration}
The configuration can be initialized with PIO Home or directly written into a \verb|plaftormio.ini| file. Following configuration can be used for simultaneous \verb|esp8266| and \verb|ESP32| usage:
\lstset{style=platform-io}
\begin{lstlisting}
[platformio]
default_envs = esp8266
[env:esp32]
platform = espressif32
board = az-delivery-devkit-v4
framework = arduino
monitor_speed = 115200
[env:esp8266]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200
\end{lstlisting}
\subsection{IDE} \label{sec:vsc}
Developing and writing code for this project will be done in Visual Studio Code\footnote{\href{https://code.visualstudio.com/}{https://code.visualstudio.com/}}.
``Visual Studio Code is a lightweight but powerful source code editor which runs on your desktop and is available for Windows, macOS and Linux. It comes with built-in support for JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other languages (such as C++, C\#, Java, Python, PHP, Go) and runtimes (such as .NET and Unity).''
\cite[][]{vscode-about}
\begin{figure}[H]
\begin{center}
\includegraphics[width=0.3\textwidth]{pio}
\caption{PlatformIO in VSC}
\label{fig:PlatformIO in VSC}
\end{center}
\end{figure}
\subsection{Documentation}
Documentation is written in \LaTeX and will be added to the library as source-code only.

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

131
documentation/main.tex Normal file
View file

@ -0,0 +1,131 @@
\documentclass[
a4paper,
oneside,
parskip=half,
listof=entryprefix,
listof=totoc,
index=totoc,
bibliography=totoc
]{scrartcl}
\usepackage{silence}
\WarningFilter{biblatex}{File 'british-iso.lbx'}
\WarningFilter{biblatex}{'\mainlang'}
\usepackage[utf8]{inputenc}
\usepackage[british]{babel}
\usepackage[T1]{fontenc}
\usepackage{pdfpages,graphicx,subcaption,lastpage}
\graphicspath{ {./images} }
\usepackage{geometry}
\geometry{a4paper, top=2.5cm, left=2.5cm, right=2.5cm, bottom=2.5cm}
\usepackage{float,listings,xcolor,csquotes,microtype,scrlayer-scrpage,etoolbox}
\usepackage[official]{eurosym}
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\lstdefinestyle{c++}{
language=C++,
directivestyle={\color{codepurple}},
emph={firewall_rule_t,uint8_t,uint16_t,firewall_protocol_t,firewall_target_t,fw,Firewall,API},
emphstyle={\color{codegreen}},
}
\lstdefinestyle{shell}{
emph={cd,mkdir,git},
emphstyle={\color{codepurple}},
}
\lstdefinestyle{platform-io}{
emph={platformio,esp32,esp8266,arduino},
emphstyle={\color{codegreen}},
}
\definecolor{delim}{RGB}{20,105,176}
\definecolor{numb}{RGB}{106, 109, 32}
\definecolor{string}{rgb}{0.64,0.08,0.08}
\lstdefinestyle{json}{
rulecolor=\color{black},
showspaces=false,
showtabs=false,
breaklines=true,
postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{gray}\hookrightarrow\space}},
breakatwhitespace=true,
basicstyle=\ttfamily\small,
upquote=true,
morestring=[b]",
stringstyle=\color{string},
literate=
*{0}{{{\color{numb}0}}}{1}
{1}{{{\color{numb}1}}}{1}
{2}{{{\color{numb}2}}}{1}
{3}{{{\color{numb}3}}}{1}
{4}{{{\color{numb}4}}}{1}
{5}{{{\color{numb}5}}}{1}
{6}{{{\color{numb}6}}}{1}
{7}{{{\color{numb}7}}}{1}
{8}{{{\color{numb}8}}}{1}
{9}{{{\color{numb}9}}}{1}
{\{}{{{\color{delim}{\{}}}}{1}
{\}}{{{\color{delim}{\}}}}}{1}
{[}{{{\color{delim}{[}}}}{1}
{]}{{{\color{delim}{]}}}}{1},
}
\setuptoc{toc}{totoc}
\usepackage[
backend=biber,
urldate=long,
style=iso-authoryear,
natbib=true,
useauthor=true,
mincitenames=1,
maxcitenames=3
]{biblatex}
\addbibresource{bib/online.bib}
\addbibresource{bib/book.bib}
\DeclareNameAlias{default}{family-given/given-family}
\renewcommand*{\finalnamedelim}{\addspace{}und\space}
\AtEveryCite{
\renewcommand*{\multinamedelim}{,\space}
\renewcommand*{\nameyeardelim}{\space}
}
\AtBeginBibliography{
\renewcommand*{\multinamedelim}{,\space}
}
\AfterTOCHead[lof]{\appto\autodot{:}}
\definecolor{must-have-brown}{RGB}{51, 22, 18}
\definecolor{should-have-red}{RGB}{229, 24, 31}
\definecolor{could-have-orange}{RGB}{246, 121, 28}
\definecolor{wont-have-blue}{RGB}{32, 169, 215}
\newcommand{\morequirement}[1]{\paragraph{#1}\hfill\textbf{\textcolor{must-have-brown}{must-have}}\\}
\newcommand{\srequirement}[1]{\paragraph{#1}\hfill\textbf{\textcolor{should-have-red}{should-have}}\\}
\newcommand{\corequirement}[1]{\paragraph{#1}\hfill\textbf{\textcolor{could-have-orange}{could-have}}\\}
\newcommand{\wrequirement}[1]{\paragraph{#1}\hfill\textbf{\textcolor{wont-have-blue}{won't-have}}\\}
\ihead{IoT Firewall - ESP8266/ESP32}
\chead{}
\ohead{Florian Hoss}
\ofoot{Page~\thepage{}/\pageref{LastPage}}
\cfoot{}
\title{IoT Firewall - ESP8266/ESP32}
\usepackage[breaklinks,colorlinks,linkcolor=black,citecolor=black,filecolor=black,urlcolor=black]{hyperref}
\begin{document}
\include{titlepage/titlepage}
\tableofcontents
\newpage
\listoffigures
\include{firststeps/firststeps}
\include{storage/storage}
\include{firewall/firewall}
\include{api/api}
\printbibliography[title=Bibliography]
\end{document}

View file

@ -0,0 +1,32 @@
\section{Storage}
To store the firewall rules there will be a class to handle storing and retrieving of the currently active rules. For each board there is a library available that will handle most of the work.
\subsection{esp8266}
A library called EEPROM can be used to access the memory that will be kept when the board is powered off. With this library we can easily write and read from this area.
``The supported micro-controllers on the various Arduino [...] boards have different amounts of EEPROM: [...] The Arduino [...] boards have an emulated EEPROM space of 1024 bytes.''
\cite[][]{eeprom-doc}
\subsection{esp32}
To save and retrieve data on the esp32, the Preferences.h\footnote{\href{https://github.com/espressif/arduino-esp32/blob/master/libraries/Preferences/src/Preferences.h}{preferences.h on github}} library will be used. It is a replacement for the deprecated EEPROM library that is used with the esp8266.
\subsection{Storage class}
To use the individual library with the firewall rules the firewall can be extended with the storage class. Following protected methods will be available to store and retrieve firewall rules:
\lstset{style=c++}
\begin{lstlisting}
uint8_t retrieve_amount_of_rules();
void store_amount_of_rules(const uint8_t new_amount);
firewall_rule_t *retrieve_firewall_rule(const uint8_t key);
void store_all_firewall_rules(firewall_rule_t *rule_head);
void store_firewall_rule(firewall_rule_t *rule_ptr);
\end{lstlisting}
\subsection{Space Allocation}
Each rule will get exactly the space it needs (\verb|firewall_rule_t|). Therefore a maximum of rules of \textbf{15} is specified in the constructor of the class. At the lowest storage space, there will be an 8 bit class variable for the current amount of rules, to keep track how many rules need to be restored at power up.

View file

@ -0,0 +1,30 @@
\newcommand{\HRule}[2]{\noindent\rule[#1]{\linewidth}{#2}}
\newcommand{\vlinespace}[1]{\vspace*{#1\baselineskip}}
\newcommand{\titleemph}[1]{\textbf{#1}}
\begin{titlepage}
\sffamily
\hfill
\includegraphics[width=5cm]{hs-esslingen}
\HRule{13pt}{1pt}
\centering
\Large
\vlinespace{5}\\
Student research project\\
\huge
\textbf{IoT Firewall\\for ESP8266/ESP32}\\
\Large
\vlinespace{5}
Software Engineering course\\
of the Faculty of Information Technology\\
in the 6th semester\\
\vlinespace{6}
\huge
\textbf{Florian Hoss}\\
\Large
\vfill
\raggedright{}
\HRule{13pt}{1pt} \\
\titleemph{Git:} \href{https://github.com/flohoss/esp8266\_firewall\_api}{https://github.com/flohoss/esp8266\_firewall\_api} \\
\titleemph{Git:} \href{https://github.com/flohoss/esp32\_firewall\_api}{https://github.com/flohoss/esp32\_firewall\_api} \\
\titleemph{Professor:} Prof. Dr. rer. nat. Tobias Heer
\end{titlepage}

54
tester.py Normal file
View file

@ -0,0 +1,54 @@
import socket
import sys
import argparse
message = "test"
def main(argv):
parser = argparse.ArgumentParser(
description='Send socket message to ip and port with protocol.')
parser.add_argument('-i', '--ip',
default='localhost',
dest='ip',
help='Provide destination ip. Defaults to localhost',
type=str
)
parser.add_argument('-p', '--port',
default=80,
dest='port',
help='Provide destination port. Defaults to 80',
type=int
)
parser.add_argument('-t', '--type', choices=['UDP', 'TCP'],
default='UDP',
dest='proto',
help='Provide protocol. Defaults to UDP',
type=str
)
args = parser.parse_args()
print(f'Sending message to {args.ip}:{args.port} width {args.proto}')
if args.proto == 'TCP':
sock = socket.socket()
try:
sock.connect((args.ip, args.port))
sock.send(message.encode())
print("Message sent.")
sock.close()
except:
print("Cannot send message...")
else:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
sock.sendto(message.encode('utf-8'), (args.ip, args.port))
print("Message sent.")
sock.close()
except:
print("Cannot send message...")
if __name__ == "__main__":
main(sys.argv[1:])