@@ -3,9 +3,10 @@ NetfilterQueue
3
3
==============
4
4
5
5
NetfilterQueue provides access to packets matched by an iptables rule in
6
- Linux. Packets so matched can be accepted, dropped, altered, or given a mark.
6
+ Linux. Packets so matched can be accepted, dropped, altered, reordered,
7
+ or given a mark.
7
8
8
- Libnetfilter_queue (the netfilter library, not this module) is part of the
9
+ libnetfilter_queue (the netfilter library, not this module) is part of the
9
10
`Netfilter project <http://netfilter.org/projects/libnetfilter_queue/ >`_.
10
11
11
12
Example
@@ -15,18 +16,18 @@ The following script prints a short description of each packet before accepting
15
16
it. ::
16
17
17
18
from netfilterqueue import NetfilterQueue
18
-
19
+
19
20
def print_and_accept(pkt):
20
21
print(pkt)
21
22
pkt.accept()
22
-
23
+
23
24
nfqueue = NetfilterQueue()
24
25
nfqueue.bind(1, print_and_accept)
25
26
try:
26
27
nfqueue.run()
27
28
except KeyboardInterrupt:
28
29
print('')
29
-
30
+
30
31
nfqueue.unbind()
31
32
32
33
You can also make your own socket so that it can be used with gevent, for example. ::
@@ -56,7 +57,7 @@ To send packets destined for your LAN to the script, type something like::
56
57
Installation
57
58
============
58
59
59
- NetfilterQueue is a C extention module that links against libnetfilter_queue.
60
+ NetfilterQueue is a C extention module that links against libnetfilter_queue.
60
61
Before installing, ensure you have:
61
62
62
63
1. A C compiler
@@ -81,9 +82,9 @@ From source
81
82
82
83
To install from source::
83
84
84
- git clone git@ github.com:kti/ python-netfilterqueue.git
85
+ git clone https:// github.com/oremanj/ python-netfilterqueue
85
86
cd python-netfilterqueue
86
- python setup.py install
87
+ pip install .
87
88
88
89
If Cython is installed, Distutils will use it to regenerate the .c source from the .pyx. It will then compile the .c into a .so.
89
90
@@ -104,9 +105,12 @@ NetfilterQueue objects
104
105
A NetfilterQueue object represents a single queue. Configure your queue with
105
106
a call to ``bind ``, then start receiving packets with a call to ``run ``.
106
107
107
- ``QueueHandler.bind(queue_num, callback[, max_len[, mode[, range, [sock_len]]]]) ``
108
- Create and bind to the queue. ``queue_num `` must match the number in your
109
- iptables rule. ``callback `` is a function or method that takes one
108
+ ``QueueHandler.bind(queue_num, callback[, max_len[, mode[, range[, sock_len]]]]) ``
109
+ Create and bind to the queue. ``queue_num `` uniquely identifies this
110
+ queue for the kernel. It must match the ``--queue-num `` in your iptables
111
+ rule, but there is no ordering requirement: it's fine to either ``bind() ``
112
+ first or set up the iptables rule first.
113
+ ``callback `` is a function or method that takes one
110
114
argument, a Packet object (see below). ``max_len `` sets the largest number
111
115
of packets that can be in the queue; new packets are dropped if the size of
112
116
the queue reaches this number. ``mode `` determines how much of the packet
@@ -119,17 +123,21 @@ a call to ``bind``, then start receiving packets with a call to ``run``.
119
123
Remove the queue. Packets matched by your iptables rule will be dropped.
120
124
121
125
``QueueHandler.get_fd() ``
122
- Get the file descriptor of the queue handler.
126
+ Get the file descriptor of the socket used to receive queued
127
+ packets and send verdicts. If you're using an async event loop,
128
+ you can poll this FD for readability and call ``run(False) `` every
129
+ time data appears on it.
123
130
124
131
``QueueHandler.run([block]) ``
125
- Send packets to your callback. By default, this method blocks. Set
126
- block=False to let your thread continue. You can get the file descriptor
127
- of the socket with the ``get_fd `` method.
132
+ Send packets to your callback. By default, this method blocks, running
133
+ until an exception is raised (such as by Ctrl+C). Set
134
+ block=False to process the pending messages without waiting for more.
135
+ You can get the file descriptor of the socket with the ``get_fd `` method.
128
136
129
137
``QueueHandler.run_socket(socket) ``
130
138
Send packets to your callback, but use the supplied socket instead of
131
139
recv, so that, for example, gevent can monkeypatch it. You can make a
132
- socket with ``socket.fromfd(nfqueue.get_fd(), socket.AF_UNIX , socket.SOCK_STREAM ) ``
140
+ socket with ``socket.fromfd(nfqueue.get_fd(), socket.AF_NETLINK , socket.SOCK_RAW ) ``
133
141
and optionally make it non-blocking with ``socket.setblocking(False) ``.
134
142
135
143
Packet objects
@@ -138,55 +146,78 @@ Packet objects
138
146
Objects of this type are passed to your callback.
139
147
140
148
``Packet.get_payload() ``
141
- Return the packet's payload as a string (Python 2) or bytes (Python 3).
149
+ Return the packet's payload as a bytes object. The returned value
150
+ starts with the IP header. You must call ``retain() `` if you want
151
+ to be able to ``get_payload() `` after your callback has returned.
142
152
143
153
``Packet.set_payload(payload) ``
144
- Set the packet payload. ``payload `` is a bytes.
154
+ Set the packet payload. Call this before ``accept() `` if you want to
155
+ change the contents of the packet before allowing it to be released.
156
+ Don't forget to update the transport-layer checksum (or clear it,
157
+ if you're using UDP), or else the recipient is likely to drop the
158
+ packet. If you're changing the length of the packet, you'll also need
159
+ to update the IP length, IP header checksum, and probably some
160
+ transport-level fields (such as UDP length for UDP).
145
161
146
162
``Packet.get_payload_len() ``
147
163
Return the size of the payload.
148
164
149
165
``Packet.set_mark(mark) ``
150
- Give the packet a kernel mark. ``mark `` is a 32-bit number.
166
+ Give the packet a kernel mark, which can be used in future iptables
167
+ rules. ``mark `` is a 32-bit number.
151
168
152
169
``Packet.get_mark() ``
153
- Get the mark already on the packet.
170
+ Get the mark already on the packet (either the one you set using
171
+ ``set_mark() ``, or the one it arrived with if you haven't called
172
+ ``set_mark() ``).
154
173
155
174
``Packet.get_hw() ``
156
175
Return the hardware address as a Python string.
157
176
177
+ ``Packet.retain() ``
178
+ Allocate a copy of the packet payload for use after the callback
179
+ has returned. ``get_payload() `` will raise an exception at that
180
+ point if you didn't call ``retain() ``.
181
+
158
182
``Packet.accept() ``
159
- Accept the packet.
183
+ Accept the packet. You can reorder packets by accepting them
184
+ in a different order than the order in which they were passed
185
+ to your callback.
160
186
161
187
``Packet.drop() ``
162
188
Drop the packet.
163
-
189
+
164
190
``Packet.repeat() ``
165
- Iterate the same cycle once more.
166
-
191
+ Restart processing of this packet from the beginning of its
192
+ Netfilter hook (iptables chain, roughly). Any changes made
193
+ using ``set_payload() `` or ``set_mark() `` are preserved; in the
194
+ absence of such changes, the packet will probably come right
195
+ back to the same queue.
196
+
167
197
Callback objects
168
198
----------------
169
199
170
- Your callback can be function or a method and must accept one argument, a
171
- Packet object. You must call either Packet.accept() or Packet.drop() before
172
- returning.
173
-
174
- ``callback(packet) `` or ``callback(self, packet) ``
175
- Handle a single packet from the queue. You must call either
176
- ``packet.accept() `` or ``packet.drop() ``.
200
+ Your callback can be any one-argument callable and will be invoked with
201
+ a ``Packet `` object as argument. You must call ``retain() `` within the
202
+ callback if you want to be able to ``get_payload() `` after the callback
203
+ has returned. You can hang onto ``Packet `` objects and resolve them later,
204
+ but note that packets continue to count against the queue size limit
205
+ until they've been given a verdict (accept, drop, or repeat). Also, the
206
+ kernel stores the enqueued packets in a linked list, so keeping lots of packets
207
+ outstanding is likely to adversely impact performance.
177
208
178
209
Usage
179
210
=====
180
211
181
212
To send packets to the queue::
182
213
183
214
iptables -I <table or chain> <match specification> -j NFQUEUE --queue-num <queue number>
184
-
215
+
185
216
For example::
186
217
187
218
iptables -I INPUT -d 192.168.0.0/24 -j NFQUEUE --queue-num 1
188
-
189
- The only special part of the rule is the target. Rules can have any match and
219
+
220
+ The only special part of the rule is the target. Rules can have any match and
190
221
can be added to any table or chain.
191
222
192
223
Valid queue numbers are integers from 0 to 65,535 inclusive.
@@ -228,7 +259,7 @@ Limitations
228
259
* Omits methods for getting information about the interface a packet has
229
260
arrived on or is leaving on
230
261
* Probably other stuff is omitted too
231
-
262
+
232
263
Source
233
264
======
234
265
@@ -237,7 +268,7 @@ https://github.com/kti/python-netfilterqueue
237
268
License
238
269
=======
239
270
240
- Copyright (c) 2011, Kerkhoff Technologies, Inc.
271
+ Copyright (c) 2011, Kerkhoff Technologies, Inc, and contributors .
241
272
242
273
`MIT licensed <https://github.com/kti/python-netfilterqueue/blob/master/LICENSE.txt >`_
243
274
0 commit comments