Post

Research checkpoint #07: more tests for the Raspberry, checking its sniffing performance

Research checkpoint #07: more tests for the Raspberry, checking its sniffing performance

During these last weeks, I kept testing the Raspberry Pi to verify its performance as I started in the last post, but this time conducting experiments with the python libraries cited in post 04, which are capable of sniffing the network traffic and manipulating this data. Here, I report the results and bring a brief discussion about them, I think it will be useful to revisit all of these findings to explore them in more depth!

Tests

The tests were conducted using the scripts available here, which implements network traffic sniffers using the Pyshark, Scapy and Pypcap python libraries, this last one being also accompanied with the dpkt library, which is capable of extracting information from the packets. The test flow is very simple, aimed to measure the Raspberry Pi performance dealing with live traffic using these different libraries:

  • Run the python script and wait 10 seconds;
  • Start a transmission of packets in the network to simulate live traffic during 10 seconds;
  • After the artificial traffic finished, wait more 30 seconds and end the test, collecting the results1.

All of the flow above is implemented in the bash script available in the repository cited before. Each of the tests were conducted five times with the same environment and the metrics exhibited below were based on these executions, usually taking the mean value of the numbers observed. To register each metric, I used:

  • To measure the CPU use, the psutil python library, that is capable to retrieve informations about the system performance, like the percentage of CPU used by a process. Its operation is similar to the ps command in Linux: the cpu_percent method returns a float representing the CPU utilization as a percentage for a process since its last call using the total CPU time consumed, so this value can be bigger than 100.0 if the process is running multiple threads in different cores.

  • To measure the memory use, the resource python module, which is capable of measuring the maximum resident set size used by the process in KBytes, in the same way described in the last post.

  • The “number of packets counted” is an information calculated by the python scripts: their job is to count how many network traffic packets were sniffed and how many of them are TCP packets. This last information was collected only to perform a minimal packet parsing, using the libraries also to extract some content of the data, not being reported below as it doesn’t aggregate much information.

  • The “iperf3 flow data” field reports the parameters for the transmission of packets used by the iperf3 app, which is the one used to simulate live traffic. More information about its use below.

  • For the “total time”, the time command, just to be sure that the workflow defined above was being followed.

As commented above, the application used to generate network traffic is iperf3, which is a tool that can transmit packets in the client-server model allowing adjusting of many parameters. The scenarios executed were:

  • Transmission of TCP packets in the localhost, with the Raspberry being the client and the server at the same time;
  • Transmission of UDP packets at the bitrate of 1Mb/sec, 2Mb/sec, 3Mb/sec, 4Mb/sec, 5Mb/sec and 10Mb/sec in the localhost;
  • Transmission of UDP packets without bitrate limit defined in the localhost;
  • All the scenarios above but with the Raspberry being a client and my personal notebook being the server, on a private network without internet access.

The machines specs used in the tests are:

  • Raspberry Pi Model 3 B
    • Quad Core 1.2GHz Broadcom BCM2837 64bit CPU
    • 1GB RAM
    • Debian GNU/Linux 12 (bookworm) OS
    • 100 Mbit/s network interface card (Fast Ethernet)
  • Acer Aspire 3 A315-41-R4RB
    • AMD Ryzen 5 2500U 2.0GHz 64bit CPU
    • 12GB DDR4 2667 MHz RAM
    • Fedora Linux 41 (Silverblue) OS
    • 1000 Mbits/s network interface card (Gigabit Ethernet)

For each of the tests described above, I tested the tree libraries cited, the results of each one are reported below.

Pyshark

TestUse of CPU (mean)Peak of memory use (max)N. of packets counted (mean)iperf3 flow dataTotal time (mean)
Localhost TCP80.22%36412 KB2583.53 Gbits/sec, 4.11 GBytes53.351s
Localhost UDP 1Mb/sec22.18%30696 KB108.81.02 Mbits/sec, 1.22 MBytes in 39 packets53.129s
Localhost UDP 2Mb/sec41.3%30892 KB147.62.02 Mbits/sec, 2.41 MBytes in 77 packets53.151s
Localhost UDP 3Mb/sec60.5%30696 KB185.23.01 Mbits/sec, 3.59 MBytes in 115 packets53.173s
Localhost UDP 4Mb/sec79.22%30928 KB223.24.01 Mbits/sec, 4.78 MBytes in 153 packets53.287s
Localhost UDP 5Mb/sec80.3%30744 KB214.45.01 Mbits/sec, 5.97 MBytes in 191 packets53.481s
Localhost UDP 10Mb/sec80.74%30884 KB214.810.00 Mbits/sec, 11.9 MBytes in 382 packets53.447s
Localhost UDP without limit81.04%30996 KB211.67.21 Gbits/sec, 8.4 GBytes in 275246 packets53.399s
Remote server TCP79.92%28064 KB1550.694.64 Mbits/sec, 113 MBytes53.380s
Remote server UDP 1Mb/sec41.2%27904 KB8981 Mbits/sec, 1.19 MBytes in 864 packets53.217s
Remote server UDP 2Mb/sec78.82%27776 KB1716.82.00 Mbits/sec, 2.38 MBytes in 1727 packets53.339s
Remote server UDP 3Mb/sec79%27904 KB17253.00 Mbits/sec, 3.58 MBytes in 2590 packets53.379s
Remote server UDP 4Mb/sec78.78%27904 KB1714.84.00 Mbits/sec, 4.77 MBytes in 3453 packets53.354s
Remote server UDP 5Mb/sec78.88%27904 KB1717.45.00 Mbits/sec, 5.96 MBytes in 4316 packets53.346s
Remote server UDP 10Mb/sec78.94%27904 KB1711.410.0 Mbits/sec, 11.9 MBytes in 8632 packets53.378s
Remote server UDP without limit79.3%27904 KB1681.895.7 Mbits/sec, 114 MBytes in 82620 packets53.357s

The first thing to notice above is the intense use of CPU, that were a way greater than any of the other Python libraries. And this intensive use wasn’t converted in better results: in the localhost scenario, we see that the library starts to struggle with 10 Mbits of bitrate, not taking in account all of the packets and its even worse with the remote server, failing already with 2 Mbits of bitrate. This give us some hints: the library is not suited to handle big volumes of traffic data, performing a little better with a smaller volume of bigger packets (as in the localhost scenario). However, its also worth to notice that apparently it also keeps a buffer of the unprocessed packets, as the data keeps being processed after the live flow ended, however the time given wasn’t sufficient to handle of the traffic.

Scapy

TestUse of CPU (mean)Peak of memory use (max)N. of packets counted (mean)iperf3 flow dataTotal time (mean)
Localhost TCP20.1%76552 KB1568.83.61 Gbits/sec, 4,21 GBytes54.401s
Localhost UDP 1Mb/sec1.14%73228 KB136.41.02 Mbits/sec, 1.22 MBytes in 39 packets54.398s
Localhost UDP 2Mb/sec1.64%73480 KB217.62.02 Mbits/sec, 2.41 MBytes in 77 packets54.412s
Localhost UDP 3Mb/sec2.26%74120 KB293.63.01 Mbits/sec, 3.59 MBytes in 115 packets54.396s
Localhost UDP 4Mb/sec2.9%74636 KB370.44.01 Mbits/sec, 4.78 MBytes in 153 packets54.407s
Localhost UDP 5Mb/sec3.96%74888 KB458.85.01 Mbits/sec, 5.97 MBytes in 191 packets54.424s
Localhost UDP 10Mb/sec5.44%74892 KB81210.0 Mbits/sec, 11.9 MBytes in 382 packets54.421s
Localhost UDP without limit20.8%76428 KB18606.94 Gbits/sec, 8.08 GBytes in 273844 packets54.414s
Remote server TCP20.26%67484 KB355294.66 Mbits/sec, 113 MBytes54.478s
Remote server UDP 1Mb/sec7.02%67736 KB899.41.00 Mbits/sec, 1.19 MBytes in 864 packets54.472s
Remote server UDP 2Mb/sec11.08%67740 KB17602.00 Mbits/sec, 2.38 MBytes in 1727 packets54.469s
Remote server UDP 3Mb/sec16.04%67736 KB2626.43.00 Mbits/sec, 3.58 MBytes in 2590 packets54.480s
Remote server UDP 4Mb/sec20.3%67868 KB3439.44.00 Mbits/sec, 4.77 MBytes in 3453 packets54.485s
Remote server UDP 5Mb/sec20.4%67740 KB3434.65.00 Mbits/sec, 5.96 MBytes in 4316 packets54.474s
Remote server UDP 10Mb/sec20.36%67992 KB3377.610.0 Mbits/sec, 11.9 MBytes in 8632 packets54.478s
Remote server UDP without limit20.34%67736 KB2919.295.7 Mbits/sec, 114 MBytes in 82620 packets54.484s

The CPU performance is a way more controlled and its number of packets count had an improvement in comparision to the last library: it starts to fail when using 4Mb/sec in the remote server scenario, still losing a lot of packets.

Pypcap + dpkt

TestUse of CPU (mean)Peak of memory use (max)N. of packets counted (mean)iperf3 flow dataTotal time (mean)
Localhost TCP19.38%21720 KB95302.36 Gbits/sec, 2.746 GBytes52.229s
Localhost UDP 1Mb/sec0.1%21336 KB69.81.02 Mbits/sec, 1.22 MBytes in 39 packets52.222s
Localhost UDP 2Mb/sec0.14%21336 KB1072.02 Mbits/sec, 2.41 MBytes in 77 packets52.239s
Localhost UDP 3Mb/sec0.2%21336 KB1463.01 Mbits/sec, 3.59 MBytes in 115 packets52.229s
Localhost UDP 4Mb/sec0.2%21336 KB183.24.01 Mbits/sec, 4.78 MBytes in 153 packets52.233s
Localhost UDP 5Mb/sec0.3%21336 KB221.85.01 Mbits/sec, 5.97 MBytes in 191 packets52.238s
Localhost UDP 10Mb/sec0.48%21336 KB412.210.0 Mbits/sec, 11.9 MBytes in 382 packets52.233s
Localhost UDP without limit19.4%21336 KB17037.64.05 Gbits/sec, 4.71 GBytes in 154540 packets52.223s
Remote server TCP19.4%21208 KB73000.894,7 Mbits/sec, 113 MBytes52.244s
Remote server UDP 1Mb/sec0.52%21208 KB895.61.00 Mbits/sec, 1.19 MBytes in 864 packets52.222s
Remote server UDP 2Mb/sec0.92%21208 KB1758.62.00 Mbits/sec, 2.38 MBytes in 1727 packets52.230s
Remote server UDP 3Mb/sec1.4%21208 KB26233.00 Mbits/sec, 3.58 MBytes in 2590 packets52.230s
Remote server UDP 4Mb/sec1.92%21208 KB3486.24.00 Mbits/sec, 4.77 MBytes in 3454 packets52.229s
Remote server UDP 5Mb/sec2.26%21208 KB4349.25.00 Mbits/sec, 5.96 MBytes in 4316 packets52.233s
Remote server UDP 10Mb/sec3.96%21208 KB8664.610.0 Mbits/sec, 11.9 MBytes in 8632 packets52.234s
Remote server UDP without limit18.86%21208 KB8157595.7 Mbits/sec, 114 MBytes in 82620 packets52.235s

And finally, our best observations: the library apparently is capable of hadling big volumes of traffic without low consume of CPU time, even without bitrate limit in the remote server scenario, with a few packets lost. Notice also that its use of memory is constant independently of the volume of data and below the another libraries.

Next steps

As defined in the post 05, our current goals are these:

  • Packet Parsing
    • Conduct experiments to verify the performance of Python libraries sniffing the network and processing the packages in a Raspberry Pi (different from what we did in post 4, in which we tested the lib’s with the CIC-IoT-2023 dataset and in a regular computer).
  • Inference
    • Run the baseline models proposed in post 02 in a Raspberry Pi to verify its performance.
  • Training (centralized IDS)
    • TBD.

I still want to revisit all the data reported in this current post to make more deeper analysis and also to perform more experiments, specially considering a DDoS attack scenario to see how the libraries will perform, so the packet parsing topic will still require some work :).

This post was made as a record of the progress of the research project “DDoS Detection in the Internet of Things using Machine Learning Methods with Retraining”, supervised by professor Daniel Batista, BCC - IME - USP. Project supported by the São Paulo Research Foundation (FAPESP), process nº 2024/10240-3. The opinions, hypothesis and conclusions or recommendations expressed in this material are those of the author and do not necessarily reflect the views of FAPESP.

  1. The pypcap library doesn’t implement a timeout mechanism that stops its execution after a given amount of time, so after the last 30 seconds (plus 2 seconds to have a safety margin) I do a simple ping to the server to generate a packet that will be out of the window of time defined manually in the code, so the loop breaks when the sniffer catches it. 

This post is licensed under CC BY 4.0 by the author.