netsniff-ng


the packet sniffing beast


Name

netsniff-ng — the packet sniffing beast

Synopsis

netsniff-ng [-d netdev] [-p pcap-file] [-r pcap-file] [-i pcap-file]
            [-f bpf-file] [-t pkt-type] [-b cpu-range] [-B cpu-range]
            [-S ring-size] [-e regex] [-IMHQnsqlxCXNvh]

DESCRIPTION

netsniff-ng is is a free (GPL), performant Linux network sniffer for packet inspection.

The gain of performance is reached by zero-copy mechanisms, so that the kernel does not need to copy packets from kernelspace to userspace.

For this purpose netsniff-ng is libpcap independent, but nevertheless supports the pcap file format for capturing, replaying and performing offline-analysis of pcap dumps. Furthermore we are focussing on building a robust, clean and secure analyzer and utilities that complete netsniff-ng as a support for penetration testing.

netsniff-ng can be used for protocol analysis, reverse engineering and network debugging.

OPTIONS

-d <netdev> , --dev <netdev>
<netdev> defines the packet capturing device. This can for instance be a typical device like eth0 or wlan0. Running netsniff-ng without a given device parameter, it looks for up and running networking devices and selects the first device that has been found.
-p <pcap-file> , --dump <pcap-file>
netsniff-ng stores the captured packets into the given <pcap-file>. It understands the PCAP specification, so that dumps can be read or postprocessed with other tools, too. Usually, this option should be combined with --silent and --bind-cpu to win some performance.
-r <pcap-file> , --replay <pcap-file>
The given <pcap-file> will be replayed via a memory mapped kernelspace TX_RING. A BPF filter may be combined to only replay parts of the PCAP formatted file.
-i <pcap-file> , --read <pcap-file>
<pcap-file> will be read in and printed to the console in order to perform an offline analysis. Same here: a BPF may be combined to only show relevant parts of the PCAP formatted file. Next to this, packet printing that are enabled on the normal mode are supported, too.
-f <bpf-file> , --filter <bpf-file>
Attaches a Berkeley Packet Filter to the socket in order to pre-filter traffic within the kernel. Example files are given within /etc/netsniff-ng/rules/. The section BERKELEY PACKET FILTER describes how to write filter files.
-t <pkt-type> , --type <pkt-type>
A <pkt-type> specification allows to post-filter packets within userspace context (therefore slower than BPF). The following types are supported: host - only show incoming packets to our host, broadcast - only show Broadcast packets, multicast - only show Multicast packets, others - only show packets from other hosts (promiscuous mode), outgoing - only show outgoing packets from our host
-b <cpu-range> , --bind-cpu <cpu-range>
Force system scheduler to schedule netsniff-ng only on specific CPUs. Parameters may be 0 for using only CPU0, 0,1 for using CPU0 and CPU1 or even 0-4 for using a whole CPU range. If you have a customized init process that leaves out a special CPU you could bind netsniff-ng on that free CPU for maximal performance. On the other hand, you can avoid scheduling netsniff-ng on CPUs which are reserved for other critical tasks. This can also be combined with taskset(1) in order to reschedule other processes on other CPUs to let netsniff-ng run on its own CPU.
-B <cpu-range> , --unbind-cpu <cpu-range>
Force system scheduler to not schedule netsniff-ng on specific CPUs. The parameter syntax is equivalent to -b and also the semantics are inverted to -b.
-S <ring-size> , --ring-size <size>
This manually sets the desired ring size for RX_RING or TX_RING. You should only use this option, if you know what you are doing, because choosing a ring size which is too large for your system, the kernel does neither warn you nor throws an error. It simply kills other processes to grab their space. The parameter can be defined in KB, MB or GB as 10MB for a 10 Megabyte ring size.
-I , --info
Shows information about available networking devices.
-M , --no-promisc
Forbids the NIC to enter the promiscuous mode. The promiscuous mode is activated by default. It is a configuration of a network card that makes the card pass all traffic it receives to the central processing unit rather than just frames addressed to it. Well, do not ask yourself why you cannot see traffic by others within a switched network. Unlike old hubs, switches are some kind of intelligent devices with internal ARP tables for each port in order to reduce traffic load and prevent sniffing other connections. If you really intent to sniff others traffic, go read about ARP cache poisoning / MITM.
-H , --prio-norm
This option prevents to automatically high priorize itself. Normally, netsniff-ng will be scheduled with high priority thus it use the full CPU timeslice.
-Q , --notouch-irq
If netsniff-ng will be bound to a single CPU, say CPU0, then it automatically rebinds the NIC interrupt affinity to that CPU, too for a better performance. This feature is intended to be enabled on non-wireless interfaces. notouch-irq forbids netsniff-ng to move the IRQ affinity.
-n , --non-block
Lets netsniff-ng run in non-blocking mode. Generally, you won’t need this feature very often unless there is some interest in performance behaviour analysis. This will bypass the ring polling mechanism thus CPU load will most certainly rise to 100 percent.
-s , --silent
Does not print packets to the terminal.
-q , --less
Prints one-liner information summary per packet.
-l , --payload
Shows only the payload information of the packet.
-x , --payload-hex
Shows only the payload information of the packet in hexadecimal format.
-C , --c-style
Instead of printing packet in usual hex format, a copy-and-paste C like format will be printed to the terminal.
-X , --all-hex
Shows not only the payload in hexadecimal format, but the whole packet.
-N , --no-payload
Shows only the packet header, not the payload.
-e <regex> , --regex <expr>
Regular expression printing is useful for grepping ASCII text out of packets, say certain HTML code for instance. Beware, that this has a impact on performance. Regular expressions that comply with the POSIX extended regular expression format are allowed.
-v , --version
Shows version number and exits.
-h , --help
Shows help and exits.

BERKELEY PACKET FILTER

The Berkeley Packet Filter or BSD Packet Filter was first introduced in 1993 by Steven McCanne and Van Jacobson at the USENIX. Its purpose is to filter packets within the kernel as early as possible, so that only the relevant packets will be brought to the user-level process.

The Linux kernel has adapted this feature, which nowadays is available in PF_PACKET. BPF therefore uses a register-based filter-machine that is efficient on todays RISCs. Since most applications of a packet filter reject far more packets than they accept and, thus, good performance of the packet filter is critical to good overall performance [1]. This should also be kept in mind during development of filters.

If you don’t want to write your own filters, we currently ship some examples within /etc/netsniff-ng/rules/ that can be used with netsniff-ngs -f option. Furthermore tcpdump -dd provides filter creation that netsniff-ng can read, but be warned - most certainly you might need to edit the return value, which defines the packet snaplen for your needs. Read section NOTES for more information about this. In future versions netsniff-ng will also ship its own filter compiler for a simple usage.

If you are an advanced user and if you would like to have full control of what should be filtered and what not, then writing your own filter could be a suitable choice. Hence, in the following the language specification will be described in short with given examples on how to use it.

The BPF pseudo-machine consists of an accumulator, an index register (X), a scratch memory store and an implicit program counter. Operations on this machine can be categorized into (all the following refering to [1]):

  1. Load instructions: Load instructions copy a value into the accumulator or index register. The source can be an immediate value, packet data at a fixed offset, packet data at a variable offset, the packet length, or the scratch memory store.
  2. Store instructions: Store instructions copy either the accumulator or index register into the scratch memory store.
  3. ALU instructions: ALU instructions perform arithmetic or logic on the accumulator using the index register or a constant as an operand.
  4. Branch instructions: Branch instructions alter the flow of control, based on comparison test between a constant or x register and the accumulator.
  5. Return instructions: Return instructions terminate the filter and indicated what portion of the packet to save. The packet is discarded entirely if the filter returns 0.
  6. Misc instructions: Misc instructions comprise everything else - currently, register transfer instructions.

The instruction format is of fixed length that is defined as the following:

+-----------+------+------+------+
| opcode:16 | jt:8 | jf:8 | k:32 |
+-----------+------+------+------+

The opcode field indicates the instruction type and addressing modes. The jt and jf fields are used by the conditional jump instructions and are the offsets from the next instruction to the true and false targets. The K field is a generic field used for various purposes.

All values are 32 bit words.

The Linux kernel has adapted this within linux/filter.h:

struct sock_filter {    /* Filter block */
        __u16   code;   /* Actual filter code */
        __u8    jt;     /* Jump true */
        __u8    jf;     /* Jump false */
        __u32   k;      /* Generic multiuse field */
};

struct sock_fprog {                        /* Required for SO_ATTACH_FILTER. */
        unsigned short             len;    /* Number of filter blocks */
        struct sock_filter __user *filter;
};

The instruction set is similar to assembler syntax. There are several instruction classes which are similar to the previous categorization:

 LD    0x00  Copy indicated value into accumulator
 LDX   0x01  Copy indicated value into index register
 ST    0x02  Copy accumulator value into the scratch memory store
 STX   0x03  Copy index register value into the scratch memory store
 ALU   0x04  Perform arithmetic or logic operation on the accumulator
 JMP   0x05  Perform a branch instruction
 RET   0x06  Return/exit from filter program
 MISC  0x07  Data transfer between index register and accumulator

Next to classes, there are class-specific fields which are usually combined with bitwise OR:

LD/LDX specific fields:

 Size:
  W    0x00  Unsigned Word (32 Bit)
  H    0x08  Unsigned Halfword (16 Bit)
  B    0x10  Unsigned Byte
 Mode:
  IMM  0x00  Literal value stored in K
  ABS  0x20  Byte, halfword or word at offset K in the packet
  IND  0x40  Byte, halfword or word at offset X + K in the packet
  MEM  0x60  Word at offset K in the scratch memory store
  LEN  0x80  Length of the packet
  MSH  0xa0  4*([K]&0xf): four times the value of the low four bits
             of the byte at offset K in the packet

ALU/JMP operations perform the indicated operation using the accumulator and operand, and store the result back into the accumulator. Division by zero terminates the filter.

ALU/JMP specific fields:

 Operation:
  ADD  0x00  Addition
  SUB  0x10  Subtraction
  MUL  0x20  Multiplication
  DIV  0x30  Division

  OR   0x40  Bitwise OR
  AND  0x50  Bitwise AND
  LSH  0x60  Left Shift
  RSH  0x70  Right Shift
  NEG  0x80  Negation

  (Jump, to an offset by the current instruction + JT/JF + 1)

  JA   0x00  Jump to the current instruction + K + 1
  JEQ  0x10  Jump if K or X equals accumulator
  JGT  0x20  Jump if K or X is greater than accumulator
  JGE  0x30  Jump if K or X is greater or equals the accumulator
  JSET 0x40  Jump if K or X bitwise AND the accumulator > 0
 Source:
  K    0x00  Value stored in K
  X    0x08  Value stored in the index register

RET specific fields:

 Return val:
  A    0x10  Value stored in the accumulator
  K    0x00  Value stored in K
  X    0x08  Value stored in the index register

The index register cannot use the packet addressing modes. Instead, a packet value must be loaded into the accumulator and transferred to the index register, via tax. This is not a common occurrence, as the index register is used primarily to parse the variable length IP header, which can be loaded directly via the 4*([k]&0xf) addressing mode.

MISC specific fields:

 Operation:
  TAX  0x00 Transfer value from accumulator into index register
  TXA  0x80 Transfer value from index register to accumulator

Example filter:

netsniff-ngs filter parser treats all lines that doesn’t match a format of { 0xYY, X, X, 0xYYYYYYYY }, (X: decimal value, Y: hex value) as comments.

/etc/netsniff-ng/rules/arp.bpf:

1: { 0x28, 0, 0, 0x0000000c },
2: { 0x15, 0, 1, 0x00000806 },
3: { 0x06, 0, 0, 0xffffffff },
4: { 0x06, 0, 0, 0x00000000 },

The first instruction line is a load instruction, because we have LD|H|ABS which results in 0x28. So the 16 Bit valued halfword at the packet offset 0xc will be copied into the accumulator. This is the Ethernet type field. Instruction line 2 belongs to the class JMP, more specific JMP|JEQ and takes the value which is stored in K (0x806, the Ethernet type identifier for ARP). If 0x806 equals the value that has been loaded into the accumulator, the instruction pointer points to the current instruction plus jt value (which is 0) plus 1. So we end up at instruction line 3, which is the return opcode as RET|K. By using 0xffffffff as K, we tell the kernel that we would like to have a packet snaplen of 0xffffffff, which means that we end up with the complete (uncut) packet. 0xffffffff will be replaced by the real packet length if the kernel detects packets less than a length of 0xffffffff. Well, on the other hand we would trap into the jf value if we don’t have an ARP packet. There, the instruction pointer will point to line 4 where we tell the kernel to drop the packet. The length of 0 simply means: Do not hand over the packet to the BPF attached socket.

In pretty-print this filter looks like:

(000) ldh      [12]
(001) jeq      #0x806           jt 2   jf 3
(002) ret      #-1
(003) ret      #0

Source: [1] http://www.tcpdump.org/papers/bpf-usenix93.pdf

BARE-METAL PERFORMANCE

This section will provide some figures about the performance of the RX_RING and TX_RING. An IBM HS21 Blade with 2 x Intel Xeon E5430 (2.66GHz), 8 GB RAM, Broadcom NetXtreme BCM5704S Gigabit Ethernet cards and a 2.6.31-14 kernel (Ubuntu Server 9.10) has been used for testing purpose. The IXIA 400 has been used on the opposite side for traffic generation (Gigabit wire speed). Date: 17 Sep 2010.

TX_RING, 1GbE:

The test was about flushing as much frames as possible of a fixed size. The IXIA was the counterpart that showed the incoming figures. Figures have been rounded to thousands.

Pkt size, TX_RING pps
   64     422,000
  128     422,000
  250     402,000
  500     239,000
  750     162,000
1,000     122,000
1,500      82,000

RX_RING, 1GbE:

The test included the reception of frames into the ring buffer, a counter increment per frame and the summation of the frame length. Figures have been rounded to thousands.

64-Byte fixed
Pkt rate (IXIA), % of BW, RX_RING pps
  100,000          6.75   100,000
  175,000         11.76   175,000
  250,000         16.80   250,000
  500,000         33.60   338,000
1,000,000         67.20   354,000
1,488,000        100.00   303,000
250-Byte fixed
Pkt rate (IXIA), % of BW, RX_RING pps
100,000           21.60   100,000
175,000           37.80   175,000
250,000           54.00   244,000
463,000          100.00   381,000
500-Byte fixed
Pkt rate (IXIA), % of BW, RX_RING pps
100,000           41.60   100,000
175,000           72.80   169,000
240,000          100.00   226,000
1,500-Byte fixed
Pkt rate (IXIA), % of BW, RX_RING pps
82,000           100.00   82,000
IMIX distribution (64:7, 570:4, 1518:1)
Pkt rate (IXIA), % of BW, RX_RING pps
100,000           29.99   100,000
175,000           52.35   175,000
250,000           74.80   240,000
334,000          100.00   303,000
Tolly distribution (64:55, 78:5, 576:17, 1518:23)
Pkt rate (IXIA), % of BW, RX_RING pps
100,000           40.50   100,000
175,000           70.90   174,000
247,000          100.00   193,000

EXAMPLES

Dump packets on eth0 into a file:

netsniff-ng --dev eth0 --dump out.pcap --silent --bind-cpu 0

Replay a PCAP file via eth0:

netsniff-ng --dev eth0 --replay out.pcap --bind-cpu 0

Only show ICQ related packets:

netsniff-ng --filter /etc/netsniff-ng/rules/icq.bpf

Show only packet headers of a PCAP file:

netsniff-ng --read out.pcap --no-payload

Show only packets that match a regular expression:

netsniff-ng --regex "foo.*bar"

Show only outgoing packets in hex format from wlan0:

netsniff-ng --dev wlan0 --all-hex --type outgoing

NOTES

If you try to create custom socket filters with tcpdump -dd, you have to edit the ret opcode of the resulting filter, otherwise your payload will be cut off:

0x6, 0, 0, 0xFFFFFFFF instead of 0x6, 0, 0, 0x00000060

The Linux kernel now takes skb→len instead of 0xFFFFFFFF. If you do not change it, the kernel will take 0x00000060 as buffer length and packets larger than 96 Byte will be cut off (filled with zero Bytes)!

Read http://dev.netsniff-ng.org/#4 for further technical details.

LICENSE

This program is distributed under the terms of the GNU General Public License as published by the Free Software Foundation. See COPYING for details on the License and the lack of warranty.

AVAILABILITY

The latest version of this program can be found at http://pub.netsniff-ng.org/netsniff-ng/.

BUGS

Bugs, what bugs? ;-) Okay, seriously …

The TX_RING is part of the kernel since 2.6.31. Needs kind of a compatibility mode for older kernels.

Currently, we don’t have a BPF compiler built-in, so that either the user needs to use filter definitions from /etc/netsniff-ng/rules, tcpdump -dd or write his own filter by hand.

Please send problems, bugs, questions, desirable enhancements, etc. to bugs@netsniff-ng.org.

GIT

git clone git://repo.or.cz/netsniff-ng.git

AUTHOR

netsniff-ng was originally written by Daniel Borkmann (daniel@netsniff-ng.org).

Current authors:

Daniel Borkmann (daniel@netsniff-ng.org), Emmanuel Roullit (emmanuel@netsniff-ng.org)

http://www.netsniff-ng.org/

The manpage has been written by Daniel Borkmann.

SEE ALSO

bpf(4), pcap(3), tcpdump(8)

IN HONOREM

To my alma mater:

Leipzig University of Applied Science,
Faculty of Computer Science, Mathematics and Natural Sciences


powered by Debian  powered by vim  best viewed with vt100  no epatents  qdn


Copyright (C) 2009, 2010 Daniel Borkmann and Emmanuel Roullit