## Filters
## Introduction
Filters are powerful programming constructs in p2sh. For a formal introduction
of filters, please refer to the language reference.
Filters statements start with a '@' character and is of the following form.
```
@ pattern { action }
```
The pattern is an expression that evaluates to a true or false. Actions are
statements executed as a consequence.
Filters resemble constructs found in the AWK language.
Filter statements execute against every pcap packet read in the pcap stream.
## Examples
Note: While using the command mode, use single quotes to pass in the command
instead of a double quotes to avoid cli such as bash intefering with special
symbols such as '$0'.
Note: Advanced examples are in the `examples/filters` directory.
### Match every packet
```bash
p2sh -c '@ true' < in.pcap > out.pcap
```
Here, the default action is to write the pcap. The output pcap file will look
exactly like the input pcap file.
### Match 64 byte packets
```bash
p2sh -c '@ ($0).caplen <= 64 true' < in.pcap > out.pcap
p2sh -c '@ ($0).wirelen <= 64 true' < in.pcap > out.pcap
```
Here, the only 64 byte packets are matched and only those will end up in the
output pcap file.
### Print packet number and length
This example displays the packet number and its length. Use the '-s'
flag to skip writing the pcap header, as we're only showing packet
number and length within the action.
```bash
p2sh -s -c '@ { eprintln("{}: {}", NP, PL) }' < in.pcap
```
### Print timestamp and length
This example prints the packet timestamp and its length.
```bash
p2sh -s -c '@ { eprintln("{}.{}: {}", ($0).sec, ($0).usec, PL) }' < in.pcap
```
### Protocols at different depth
```bash
p2sh -sc '@ { puts(($0)); }' < in.pcap
p2sh -sc '@ { puts(($1)); }' < in.pcap
p2sh -sc '@ { puts(($2)); }' < in.pcap
```
### Source to destination
```bash
p2sh -sc '@ { eprintln("{} -> {}", ($1).src, ($1).dst);}' < in.pcap
p2sh -sc '@ { eprintln("{} -> {}", ($2).src, ($2).dst);}' < in.pcap
```
### Packets from a specific source
```bash
p2sh -sc '@ ($2).src == "192.168.29.58" { puts(($2).src, " -> ", ($2).dst); }' < in.pcap
```
### Modify fields
```bash
p2sh -c '@ { ($1).src = "11:22:33:44:55:66" } @true ' < in.pcap > out.pcap
p2sh -c '@ { ($2).src = "192.168.0.1" } @ true ' < in.pcap > out.pcap
p2sh -c '@ { ($3).srcport = 1111 } @ true ' < in.pcap > out.pcap
```
### Interact with other programs
Display the packet timestamp and length but use the input from another program.
```bash
### Print summary info
Save this in a file named `script.p2`
```bash
#!/usr/bin/env p2sh
let cap_size = 0;
let wire_size = 0;
@ { cap_size = cap_size + PL; }
@ { wire_size = wire_size + WL; }
@ end {
eprintln("Number of packets: {}", NP);
eprintln("Total capture size: {}", cap_size);
eprintln("Total size on wire: {}", wire_size);
}
./script.p2 -s < test.pcap
```
Use the '-s' flag to skip writing the pcap header, as we're displaying
only the packet summary.