diff --git a/ESPFirewall/lib/Firewall/docs/bib/online.bib b/ESPFirewall/lib/Firewall/docs/bib/online.bib index ac0e8f2..b388646 100644 --- a/ESPFirewall/lib/Firewall/docs/bib/online.bib +++ b/ESPFirewall/lib/Firewall/docs/bib/online.bib @@ -46,10 +46,10 @@ url = {https://www.nongnu.org/lwip/2_1_x/index.html} } -@online{lwip-hook, - author = {LwIP}, - title = {LWIP_HOOK_IP4_INPUT}, - urldate = {2022-07-25}, +@online{arduino-esp-idf, + author = {Espressif}, + title = {Arduino as an ESP-IDF component}, + urldate = {2022-07-27}, year = {2022}, - url = {https://www.nongnu.org/lwip/2_1_x/group__lwip__opts__hooks.html#ga9124237c28e2f18f3b28d5be09e9ccb6} + url = {https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/esp-idf_component.html} } diff --git a/ESPFirewall/lib/Firewall/docs/firewall/firewall.tex b/ESPFirewall/lib/Firewall/docs/firewall/firewall.tex index 0b3df8a..31d0057 100644 --- a/ESPFirewall/lib/Firewall/docs/firewall/firewall.tex +++ b/ESPFirewall/lib/Firewall/docs/firewall/firewall.tex @@ -28,15 +28,14 @@ After analyzing existing solutions following firewall parameters were implemente \begin{lstlisting} typedef enum firewall_targets : uint8_t { - TARGET_REJECT = 0, TARGET_DROP = 1, TARGET_ACCEPT = 2, } firewall_target_t; typedef enum firewall_protocols : uint8_t { - PROTOCOL_TCP = 0, - PROTOCOL_UDP = 1, + PROTOCOL_TCP = 6, + PROTOCOL_UDP = 17, PROTOCOL_ALL = 255, } firewall_protocol_t; @@ -45,25 +44,25 @@ After analyzing existing solutions following firewall parameters were implemente { uint8_t key; char ip[IPV4ADDRESS_LENGTH]; - uint32_t port_from; - uint32_t port_to; + 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 65565, therefore cannot be of type \verb|uint16_t| but \verb|uint32_t|. Target as well as protocol are enums for the available options. 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. +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. -\newpage - -\subsection{IwIP} +\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} -\subsubsection{Analysing} +\newpage + +\subsubsection{Analysing} \label{lwip_analysis} First step is to analyze the code to find out where the packets are getting handled. Looking in @@ -78,8 +77,8 @@ to consume all incoming packages. Simply placing a logger can quickly show that \begin{verbatim} if (ip4_addr4_16_val(iphdr->src) == 211) { - ESP_LOGI("PROTO", "%3" U16_F, (u16_t)IPH_PROTO(iphdr)); - ESP_LOGI("IP", "% " U16_F "% " U16_F "% " U16_F "% " U16_F, + 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), @@ -90,11 +89,10 @@ if (ip4_addr4_16_val(iphdr->src) == 211) 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) PROTO: 1 - I (x) IP: 10 93 0 211 + 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. +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 @@ -104,23 +102,87 @@ Sending a UDP or TCP package to the ESP (IP-Address: \verb|10.93.0.246|) can be Following output can be registered. \begin{verbatim} - I (x) PROTO: 6 - I (x) IP: 10 93 0 211 - I (x) PROTO: 17 - I (x) IP: 10 93 0 211 + 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 6 == "TCP" and 17 == "UDP". +Looking at the printed protocols this means evidentially: +$$ 1 \equiv "ICMP" $$ +$$ 6 \equiv "TCP" $$ +$$ 17 \equiv "UDP" $$ -\subsubsection{Using Hook} +\subsubsection{Arduino as an ESP-IDF component} -After learning the protocols that need to be filtered and looked out for, a hook needs to be registered in order to filter the packets based on our rules. +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. -To register a hook \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. +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. + \subsection{Benchmark} diff --git a/ESPFirewall/lib/Firewall/docs/firststeps/firststeps.tex b/ESPFirewall/lib/Firewall/docs/firststeps/firststeps.tex index 59c91ac..a123880 100644 --- a/ESPFirewall/lib/Firewall/docs/firststeps/firststeps.tex +++ b/ESPFirewall/lib/Firewall/docs/firststeps/firststeps.tex @@ -12,9 +12,11 @@ A dependency of PlatformIO is Python\footnote{\href{https://www.python.org/}{htt 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/}}. -\subsubsection{Configuration} +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}). -The configuration can be initialized with PIO Home or directly written into a \verb|plaftormio.ini| file. Following configuration will be used for simultaneous \verb|esp8266| and \verb|ESP32| usage: +\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} @@ -23,7 +25,7 @@ The configuration can be initialized with PIO Home or directly written into a \v [env:esp32] platform = espressif32 - board = esp32dev + board = az-delivery-devkit-v4 framework = arduino monitor_speed = 115200 @@ -34,7 +36,7 @@ The configuration can be initialized with PIO Home or directly written into a \v monitor_speed = 115200 \end{lstlisting} -\subsection{IDE} +\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/}}. @@ -42,6 +44,14 @@ Developing and writing code for this project will be done in Visual Studio Code\ \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. diff --git a/ESPFirewall/lib/Firewall/docs/images/pio.png b/ESPFirewall/lib/Firewall/docs/images/pio.png new file mode 100644 index 0000000..48f5aa5 Binary files /dev/null and b/ESPFirewall/lib/Firewall/docs/images/pio.png differ diff --git a/ESPFirewall/lib/Firewall/docs/main.tex b/ESPFirewall/lib/Firewall/docs/main.tex index f032eb6..305bec9 100644 --- a/ESPFirewall/lib/Firewall/docs/main.tex +++ b/ESPFirewall/lib/Firewall/docs/main.tex @@ -29,9 +29,13 @@ \lstdefinestyle{c++}{ language=C++, directivestyle={\color{codepurple}}, - emph={firewall_rule_t,uint8_t,uint32_t,firewall_protocol_t,firewall_target_t,fw,Firewall,API}, + 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}}, diff --git a/ESPFirewall/lib/Firewall/docs/storage/storage.tex b/ESPFirewall/lib/Firewall/docs/storage/storage.tex index fc68d22..1e418f3 100644 --- a/ESPFirewall/lib/Firewall/docs/storage/storage.tex +++ b/ESPFirewall/lib/Firewall/docs/storage/storage.tex @@ -29,4 +29,4 @@ To use the individual library with the firewall rules the firewall can be extend \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 8 bit for the current amount of rules to keep track how many rules need to be restored at power up. \ No newline at end of file +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. \ No newline at end of file