msantos / epcap Goto Github PK
View Code? Open in Web Editor NEWErlang packet capture interface using pcap
Home Page: http://listincomprehension.com/2009/12/erlang-packet-sniffer-using-ei-and.html
License: BSD 3-Clause "New" or "Revised" License
Erlang packet capture interface using pcap
Home Page: http://listincomprehension.com/2009/12/erlang-packet-sniffer-using-ei-and.html
License: BSD 3-Clause "New" or "Revised" License
Finally I got the stream parser of josemic/enose working (under Ubuntu). It tracks the TCP sequence numbers against acknowledge numbers of TCP connections. (The code will be on Github soon.)
It uses Epcap to capture the packets. Under normal load conditions around 80% (according to Erlang observer) there is no packet loss, which is great.
Under high load conditions, when the load reaches 100% for a short time, instead of the Erlang VM queueing the messages, the messages get lost. The packages are still dumped into tcpdump. Epcap/Erlang, however does not seem to get these messages. The results is that enose loosing sequence and indicates failures. Logs have shown that about 26 subsequent packages were lost by Epcap.
Note:
No packet loss occurs if Epcap/enose is run from Pcap file, even if the load gets long time to 100%.
There are multiple solutions to this problem:
I have found that after calling epcap:start_link/1
, the function call will finish before the epcap binary itself is bound to the chosen interface and ready to actually capture packets.
I imagine it's not possible to actually tell if epcap is ready from erlang's side after the binary has started; however, would it be possible for the binary to let erlang know when it is ready to capture packets, which could be sent to the epcap caller in the form of a message (e.g. epcap_ready
)?
Without knowing when epcap is ready to capture packets, I am forced to use timer:sleep/1
for about 500ms in the hopes that it is ready by then. Usually it is, but under heavy system load this isn't always the case, and it would not be good to wait longer. Receiving a ready message would be very helpful so that I do not miss packets that I expect to capture due to epcap starting later than estimated.
Is there any way to use epcap "inline" where it can capture traffic transparently on a bridge? Or would i need to create a separate interface to NF_QUEUE?
Thanks,
While picking up a project that worked well 2 years ago, I now get timeout issues when trying to use it with Linux 5.4.0 and libpcap 1.9.1 on Ubuntu 20.04.
The epcap test suite also fails with timeouts for most test cases.
The (default) {timeout, 0} on Linux conflicts with the description in pcap_set_timeout(3) which explicitly states that the behaviour for to_ms <= 0 is undefined, while pcap(3) tells that using "zero value ... on platforms that support a packet buffer timeout, will cause a read to wait forever ... with no timeout".
I have added #28 which solves that issue by providing an option to enable the immediate mode and by using that in the test cases. It was my intention to not change the default setting even if it leads to undefined behaviour on some platforms.
I deployed a system built on Ubuntu 20.04, and everything worked great. After building a second unit, using Ubuntu 22.04, I have run afoul of the setrlimit()
behavior in restrict_process_rlimit.c
. By setting the RLIMIT to 1, I get an error message can't poll on packet socket: Invalid argument
when epcap
goes into the pcap_loop()
call.
The values for rlim_cur
and rlim_max
are 1024
and 1048576
before epcap
decides to set them to 1
.
I'm not sure yet if this is a libpcap
issue -- perhaps the version of libpcap
that ships with Ubuntu 22.04 does something with the FD that violates the RLIMIT_NOFILES
rules. This is a Linux internals area that I'm not very familiar with.
Anyway, it seems I can't work around this without a code change -- I either have to define EPCAP_RLIMIT_NOFILES
somehow at compile time to a value higher than 1
, or remove the call to restrict_process_capture()
in epcap.c
.
15:37:20.635 [error] GenServer #PID<0.272.0> terminating
** (stop) {:port_terminated, 0}
Last message: {#Port<0.18>, {:exit_status, 0}}
State: {:state, #PID<0.271.0>, #Port<0.18>}
This happens after about a minute or less. Every time.
Hi,
First of all, thx for this useful tool.
I'm using epcap over centos 8-stream and libpcp 1.9.1. It looks like the {timeout, immediate} or epcap -t 0 doesn't work as expected. the packet seems to be buffered.
if -t option is omitted, it seems to work in immediate mode.
can you please confirm if you can observe the same issue
br
rvd
Currently it is only possible to subscribe all packages including payload packages. This causes high traffic. Therefore it might be useful to subscribe for just Syn and Ack packages for 1) or just for Rst packages for 2). Optionally it might be useful to restrict the subscription to certain port number / port number range or a certain IP-address / IP-subnet.
Here is the code I use to decode the packet:
Header = epcap_port_lib:header(Hdr),
{flags, Flags} = lists:keyfind(flags, 1, Header),
Syn = lists:member(syn, Flags),
Ack = lists:member(ack, Flags),
Fin = lists:member(fin, Flags),
Rst = lists:member(rst, Flags),
{seq, Seqno} = lists:keyfind(seq, 1, Header),
{ack, Ackno} = lists:keyfind(ack, 1, Header),
{win, Win} = lists:keyfind(win, 1, Header),
[Ether, IP, Hdr, Payload] = epcap_port_lib:decode(pkt:link_type(DLT), Packet),
PayloadLength = byte_size(Payload),
The windows-size does not seem to be decoded correctly:
{Ack=true,Syn=false,Fin=false,Rst=false,SeqNo=2200786594,AckNo=2223605307,Win=331},
{{"192.168.178.30",52024},{"173.194.113.155",80}},
1,
{1381,693845,846187},
66,
Payload=<<156,199,166,109,119,220,0,37,34,169,124,93,8,0,69,
0,0,52,150,193,64,0,64,6,17,222,192,168,178,30,
173,194,113,155,203,56,0,80,131,45,86,162,132,137,
134,59,128,16,1,75,80,38,0,0,1,1,8,10,0,97,251,10,
203,114,28,43>>,
PayloadLen= 0},
Wireshark shows the Win-size as: 42368 instead of the window size 31 shown by Epcap. In wireshark screenshot below the packet is highlighted.
Here is a screenshot from both:
PS:
I guess this applies to other packets too, but I have not checked it.
There are 2 issues with CentOS 6.5:
Error message:
sudo: sorry, you must have a tty to run sudo
Solution (as root):
export VISUAL=nano; visudo
Add to the fie:
Defaults:youruser !requiretty
where:
Error message "sudo: sorry, you are not allowed to set the following environment variables: PCAP_PF_RING_CLUSTER_ID"
Solution:
"Defaults env_reset" to “Defaults !env_reset” in /etc/sudoers
Add this to the readme.
Hello, Msantos:
when I setup :
cd epcap
make
error occurred:
==> epcap (compile)
Dependency not available: pkt-.* ({git,"git://github.com/msantos/pkt.git",
"master"})
make: *** [compile] error 1
I try to get PF_RING working yet.
It fails when started with the configuration:
[{interface,"eth1"},{cluster_id,1},{filter,"tcp"}
with error message:
sudo: sorry, you are not allowed to set the following environment variables: PCAP_PF_RING_CLUSTER_ID
Any ideas?
Here I found information on PF_RING:
safemedia.com/builds/UsersGuide.pdf
https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Suricatayaml
With CentOS 6.5 the following error message occurs:
"epcap: group does not exist: nogroup"
Solution (as root):
groupadd nogroup
This should be added to the Readme.
Hello Michael,
What is the difference between epcap_net and pkt modules? As far I see these are identical.
What is the sence to have pkt as dependency for epcap? Which one is prefered to use to decapsulate packets?
Thank you.
Hello Team,
I really appreciate your great work, I would like to know if any plan for DPDK support implementation is planned like PF_RING ?
If No I would like to start it, please give some guidelines to get started, like highlighting code portions required to focus and zoom in.
This packet is decoded by epcap as to have 6 bytes payload, while Wireshark does not show any payload.
<<0,37,34,169,124,93,156,199,166,109,119,220,8,
0,69,0,0,40,79,99,64,0,56,6,192,67,91,215,100,
139,192,168,178,30,0,80,225,205,214,149,255,
217,25,137,180,211,80,17,0,46,245,145,0,0,0,0,
0,0,0,0>>
Hi.
Is there any possible way to dump packets that are captured using epcap to .pcap file?
Preferably using epcap, otherwise I'll appreciate if you can give me any suggestion.
Regards
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.