pcap
Version, currently 0.5.015 versions
- 0.6.1latestDec 17, 2019
- 0.6.0not indexedMay 17, 2020
- 0.5.0not indexedMay 17, 2020
- 0.4.1not indexedMay 17, 2020
- 0.4.0not indexedMay 17, 2020
- 0.3.0not indexedMay 17, 2020
- 0.2.7not indexedMay 17, 2020
- 0.2.6not indexedMay 17, 2020
- 0.2.5not indexedMay 17, 2020
- 0.2.4not indexedMay 17, 2020
- 0.2.2not indexedMay 17, 2020
- 0.2.1not indexedMay 17, 2020
- 0.2.0not indexedMay 17, 2020
- 0.1.0not indexedMay 17, 2020
- crystal-0.17.4not indexedMay 17, 2020
github.com/maiha/pcap.cr
Crystal bindings for libpcap
29 stars
0 dependents
License: MIT
Nothing has been indexed for 0.5.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.
Installation
# Add this to your shard.yml
dependencies:
pcap:
github: maiha/pcap.cr
version: ~> 0.5.0Then run:
shards installshard.yml
No shard.yml has been indexed for 0.5.0. You can read it on the repository.
Dependencies
Unknown: the shard.yml for this version has not been read yet.
README
This README is the one indexed from the repository at its latest ref, not from the tag for this version.
# pcap.cr [](https://travis-ci.org/maiha/pcap.cr)
Crystal high level bindings for `libpcap`.
- `crystal-libpcap(libpcap.cr)` is a low level bindings for `libpcap` created by [puppetpies].
- `pcap.cr` is a wrapper for it and provides rich interface for packets like `ruby-pcap`.
- Crystal: 0.27.0
- x86_64 binary: https://github.com/maiha/pcap.cr/releases
## Usage : loop with handler
- `Pcap::Capture#loop` : `NoReturn`
is a easiest way to read all packets, and loop forever.
`tcpdump` uses this style to capture packets.
```crystal
require "pcap"
pcap = Pcap::Capture.open_live("eth0")
pcap.setfilter("tcp port 80")
pcap.loop do |pkt|
if pkt.tcp_data?
# p pkt.ether_header
# p pkt.ip_header
# p pkt.tcp_header
p pkt.tcp_data.to_s
end
end
```
```
"GET / HTTP/1.1\r\nHost: localhost\r\nUser-Agent: curl/7.47.0\r\nAccept: */*\r\n\r\n"
"HTTP/1.1 200 OK\r\nServer: nginx/1.10.0 (Ubuntu)\r\nDate: Mon, 13 Jun 2016 ...
```
## Usage : reads a packet without blocking
- `Pcap::Capture#next_ex` : `Pcap::NextError` | `Pcap::Packet`
reads a next packet without blocking.
```crystal
pkt = pcap.next_ex
case pkt
when Pcap::Packet ; # use pkt as you like
when Pcap::NextError::Timeout; # try again
when Pcap::NextError::Error ; abort "libpcap error"
when Pcap::NextError::EOF ; # found only in offline mode
end
```
- `Pcap::Capture#get?` : `Pcap::Packet?`
is a easiest way to read a packet. This api would block because `get?` = `next_ex` + timeout retry.
```crystal
if pkt = pcap.get?
puts pkt
else
abort "EOF reached"
end
```
```
22:36:51.327153 IP 127.0.0.1.56903 > 127.0.0.1.6379: Flags [S], seq 3742863884, win 43690, length 0
```
## Status
- support only tcp
## TODO
- [x] `libpcap` api (0.1.0)
- [x] Crystal closure support in `Pcap::Handler` (0.2.0)
- [x] Ether Header (0.1.0)
- [x] parse
- [x] inspect
- [x] Ip Header (0.1.0)
- [x] parse
- [x] inspect
- [x] Tcp Header (0.1.0)
- [x] parse
- [x] inspect
- [ ] Udp Header
- [ ] parse
- [ ] inspect
- [ ] Other Headers
- [ ] parse
- [ ] inspect
- [ ] Test
- [x] `Pcap::Capture` offline
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
pcap:
github: maiha/pcap.cr
version: 0.6.1
```
And then
```shell
% shards update
```
## Example applications
#### `filtertest`
Test a string of `pcap-filter`.
```shell
% filtertest 'tcp'
% filtertest 'tcp 80'
syntax error
% filtertest 'tcp port 80'
% filtertest -f filter.data # for large string
```
(As it works, this command will not display any output.)
#### `tcpsniffer`
- (run as root)
```shell
% crystal examples/tcpsniffer.cr
# (or binary)
% tcpsniffier -p 6379
% tcpsniffier -f '(tcp port 80) or (tcp port 8080)'
% tcpsniffier -i eth0 -p 10080
```
- send some packets to your specified port by `curl localhost`
```
12:29:01.445261 IP 127.0.0.1.56016 > 127.0.0.1.80: Flags [S], seq 746220255, win 43690, length 0
12:29:01.445282 IP 127.0.0.1.80 > 127.0.0.1.56016: Flags [SA], seq 4032610561, ack 746220256, win 43690, length 0
```
##### further output
- `-x` prints hexdump of packets
```shell
% tcpsniffer -x
12:30:12.305080 IP 127.0.0.1.56018 > 127.0.0.1.80: Flags [S], seq 4253528483, win 43690, length 0
0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E.
0x0010: 003c 8c99 4000 4006 b020 7f00 0001 7f00 .<..@.@.. ......
0x0020: 0001 dad2 0050 fd87 b1a3 0000 0000 a002 .....P..........
0x0030: aaaa fe30 0000 0204 ffd7 0402 080a 092a ...0...........*
0x0040: 3d3a 0000 0000 0103 0307 =:........
```
- `-v` prints packet structures (calls `inspect` internally)
```shell
% tcpsniffer -v
--------------------------------------------------------------------------------
Packet Header
Time : 2016-06-11 22:42:09 +0900 (1465652529.994580)
Packet Size : 68 (total: 74) bytes
Ethernet Header
Destination eth addr : 00:00:00:00:00:00
Source ether addr : 00:00:00:00:00:00
Packet type ID : IPv4 (2048)
IpHeader
Version : 4
Header Length : 5 words (20 bytes)
Service Type : 0
Total Length : 60
Identification : 4307
Flags : 16384
TTL : 64
Protocol : 6
Header Checksum : 11239
Src IP Addr : 127.0.0.1
Dst IP Addr : 127.0.0.1
...
```
- `-d` prints only packets where tcp data exist
- `-b` prints body oriented format (body mode)
- `-x` ignore all packets that contain only white spaces
```shell
% tcpsniffer -b -d
17:12:24.261729: "GET / HTTP/1.1\r\nHost: localhost\r\nUser-Agent: curl/7.47.0\r\nAccept: */*\r\n\r\n"
17:12:24.262003: "HTTP/1.1 200 OK\r\nServer: nginx/1.10.0 (Ubuntu)\r\nDate: Mon, 13 Jun 2016 ...
```
- `-W DIR` writes each tcp data by file in the DIR
```shell
% tcpsniffer -p 6379 -d -W pcap
16:37:03.683540 IP 127.0.0.1.52182 > 127.0.0.1.6379: Flags [PA], seq 3176296709, ack 3372892385, win 342, length 14
16:37:03.683611 IP 127.0.0.1.6379 > 127.0.0.1.52182: Flags [PA], seq 3372892385, ack 3176296723, win 342, length 7
% redis-cli ping
PONG
% ls -l pcap
-rw-r--r-- 1 root root 14 Mar 6 16:37 1.pcap
-rw-r--r-- 1 root root 7 Mar 6 16:37 2.pcap
% hd pcap/1.pcap
00000000 2a 31 0d 0a 24 34 0d 0a 50 49 4e 47 0d 0a |*1..$4..PING..|
0000000e
% hd pcap/2.pcap
00000000 2b 50 4f 4e 47 0d 0a |+PONG..|
00000007
```
##### replay
- `-r file` reads from pcap file (same as `tcpdump -r`)
```shell
# record packets by root with tcpdump
% tcpdump -i lo -s 0 -w /tmp/redis.dump 'port 6379'
# in other shell
% redis-cli ping
# stop tcpdump by `Ctl-c`
# reply by tcpsniffer
% tcpsniffer -r /tmp/redis.dump -p 6379 -b -d
reading from file: /tmp/redis.dump
11:47:14.001208: "*1\r\n$4\r\nping\r\n"
11:47:14.001569: "+PONG\r\n"
```
## Contributing
1. Fork it ( https://github.com/maiha/pcap.cr/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create a new Pull Request
## Contributors
- [maiha](https://github.com/maiha) maiha - creator, maintainer
- [puppetpies](https://github.com/puppetpies) Brian Hood - `libpcap.cr`
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.5.0- Tagged
- May 17, 2020
- Commit
b1bf4b177aba- Indexed
- not yet
Dependents
No indexed shard depends on this one yet.
Repository
github.com/maiha/pcap.cr
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 15