summaryrefslogtreecommitdiffstats
path: root/node-admin/scripts/pyroute2/netlink/ipq/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'node-admin/scripts/pyroute2/netlink/ipq/__init__.py')
-rw-r--r--node-admin/scripts/pyroute2/netlink/ipq/__init__.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/node-admin/scripts/pyroute2/netlink/ipq/__init__.py b/node-admin/scripts/pyroute2/netlink/ipq/__init__.py
new file mode 100644
index 00000000000..7408f50e877
--- /dev/null
+++ b/node-admin/scripts/pyroute2/netlink/ipq/__init__.py
@@ -0,0 +1,131 @@
+# By Peter V. Saveliev https://pypi.python.org/pypi/pyroute2. Dual licensed under the Apache 2 and GPLv2+ see https://github.com/svinota/pyroute2 for License details.
+'''
+IPQ -- userspace firewall
+=========================
+
+Netlink family for dealing with `QUEUE` iptables
+target. All the packets routed to the target
+`QUEUE` should be handled by a userspace program
+and the program should response with a verdict.
+E.g., the verdict can be `NF_DROP` and in that
+case the packet will be silently dropped, or
+`NF_ACCEPT`, and the packet will be pass the
+rule.
+'''
+from pyroute2.netlink import NLM_F_REQUEST
+from pyroute2.netlink import nlmsg
+from pyroute2.netlink.nlsocket import NetlinkSocket
+from pyroute2.netlink.nlsocket import Marshal
+# constants
+IFNAMSIZ = 16
+IPQ_MAX_PAYLOAD = 0x800
+
+# IPQ messages
+IPQM_BASE = 0x10
+IPQM_MODE = IPQM_BASE + 1
+IPQM_VERDICT = IPQM_BASE + 2
+IPQM_PACKET = IPQM_BASE + 3
+
+# IPQ modes
+IPQ_COPY_NONE = 0
+IPQ_COPY_META = 1
+IPQ_COPY_PACKET = 2
+
+# verdict types
+NF_DROP = 0
+NF_ACCEPT = 1
+NF_STOLEN = 2
+NF_QUEUE = 3
+NF_REPEAT = 4
+NF_STOP = 5
+
+
+class ipq_base_msg(nlmsg):
+ def decode(self):
+ nlmsg.decode(self)
+ self['payload'] = self.buf.read(self['data_len'])
+
+ def encode(self):
+ init = self.buf.tell()
+ nlmsg.encode(self)
+ if 'payload' in self:
+ self.buf.write(self['payload'])
+ self.update_length(init)
+
+
+class ipq_packet_msg(ipq_base_msg):
+ fields = (('packet_id', 'L'),
+ ('mark', 'L'),
+ ('timestamp_sec', 'l'),
+ ('timestamp_usec', 'l'),
+ ('hook', 'I'),
+ ('indev_name', '%is' % IFNAMSIZ),
+ ('outdev_name', '%is' % IFNAMSIZ),
+ ('hw_protocol', '>H'),
+ ('hw_type', 'H'),
+ ('hw_addrlen', 'B'),
+ ('hw_addr', '6B'),
+ ('__pad', '9x'),
+ ('data_len', 'I'),
+ ('__pad', '4x'))
+
+
+class ipq_mode_msg(nlmsg):
+ pack = 'struct'
+ fields = (('value', 'B'),
+ ('__pad', '7x'),
+ ('range', 'I'),
+ ('__pad', '12x'))
+
+
+class ipq_verdict_msg(ipq_base_msg):
+ pack = 'struct'
+ fields = (('value', 'I'),
+ ('__pad', '4x'),
+ ('id', 'L'),
+ ('data_len', 'I'),
+ ('__pad', '4x'))
+
+
+class MarshalIPQ(Marshal):
+
+ msg_map = {IPQM_MODE: ipq_mode_msg,
+ IPQM_VERDICT: ipq_verdict_msg,
+ IPQM_PACKET: ipq_packet_msg}
+
+
+class IPQSocket(NetlinkSocket):
+ '''
+ Low-level socket interface. Provides all the
+ usual socket does, can be used in poll/select,
+ doesn't create any implicit threads.
+ '''
+
+ def bind(self, mode=IPQ_COPY_PACKET):
+ '''
+ Bind the socket and performs IPQ mode configuration.
+ The only parameter is mode, the default value is
+ IPQ_COPY_PACKET (copy all the packet data).
+ '''
+ NetlinkSocket.bind(self, groups=0, pid=0)
+ self.register_policy(MarshalIPQ.msg_map)
+ msg = ipq_mode_msg()
+ msg['value'] = mode
+ msg['range'] = IPQ_MAX_PAYLOAD
+ msg['header']['type'] = IPQM_MODE
+ msg['header']['flags'] = NLM_F_REQUEST
+ msg.encode()
+ self.sendto(msg.buf.getvalue(), (0, 0))
+
+ def verdict(self, seq, v):
+ '''
+ Issue a verdict `v` for a packet `seq`.
+ '''
+ msg = ipq_verdict_msg()
+ msg['value'] = v
+ msg['id'] = seq
+ msg['data_len'] = 0
+ msg['header']['type'] = IPQM_VERDICT
+ msg['header']['flags'] = NLM_F_REQUEST
+ msg.encode()
+ self.sendto(msg.buf.getvalue(), (0, 0))