Non-functioning experiment at iptables netfilter support

This commit is contained in:
Brian Candler
2011-05-03 21:44:02 +01:00
parent 9bfa6e5b2c
commit f1c29980a8
3 changed files with 131 additions and 0 deletions

View File

@@ -65,9 +65,11 @@ class CStruct
define_type :uchar, :pattern => "C" define_type :uchar, :pattern => "C"
define_type :uint16, :pattern => "S", :align => true define_type :uint16, :pattern => "S", :align => true
define_type :uint32, :pattern => "L", :align => true define_type :uint32, :pattern => "L", :align => true
define_type :uint64, :pattern => "Q", :align => true
define_type :char, :pattern => "c" define_type :char, :pattern => "c"
define_type :int16, :pattern => "s", :align => true define_type :int16, :pattern => "s", :align => true
define_type :int32, :pattern => "l", :align => true define_type :int32, :pattern => "l", :align => true
define_type :int64, :pattern => "q", :align => true
define_type :ushort, :pattern => "S_", :align => true define_type :ushort, :pattern => "S_", :align => true
define_type :uint, :pattern => "I", :align => true define_type :uint, :pattern => "I", :align => true
define_type :ulong, :pattern => "L_", :align => true define_type :ulong, :pattern => "L_", :align => true

View File

@@ -3,6 +3,8 @@ class Socket
# From bits/socket.h # From bits/socket.h
PF_NETLINK = 16 unless defined? Socket::PF_NETLINK PF_NETLINK = 16 unless defined? Socket::PF_NETLINK
AF_NETLINK = PF_NETLINK unless defined? Socket::AF_NETLINK AF_NETLINK = PF_NETLINK unless defined? Socket::AF_NETLINK
# From in.h
IPPROTO_IPV6 = 41 unless defined? Socket::IPPROTO_IPV6
end end
module Netlink module Netlink
@@ -327,6 +329,20 @@ module Netlink
NF_REPEAT = 4 NF_REPEAT = 4
NF_STOP = 5 NF_STOP = 5
NF_INET_PRE_ROUTING = 0
NF_INET_LOCAL_IN = 1
NF_INET_FORWARD = 2
NF_INET_LOCAL_OUT = 3
NF_INET_POST_ROUTING = 4
NF_INET_NUMHOOKS = 5
NFPROTO_UNSPEC = 0
NFPROTO_IPV4 = 2
NFPROTO_ARP = 3
NFPROTO_BRIDGE = 7
NFPROTO_IPV6 = 10
NFPROTO_DECNET = 12
# linux/netfilter_ipv4/ip_queue.h # linux/netfilter_ipv4/ip_queue.h
IPQ_COPY_NONE = 0 IPQ_COPY_NONE = 0
IPQ_COPY_META = 1 IPQ_COPY_META = 1
@@ -340,4 +356,41 @@ module Netlink
# linux/netfilter_ipv4/ipt_ULOG.h # linux/netfilter_ipv4/ipt_ULOG.h
ULOG_MAC_LEN = 80 ULOG_MAC_LEN = 80
ULOG_PREFIX_LEN = 32 ULOG_PREFIX_LEN = 32
# linux/netfilter/x_tables.h
XT_TABLE_MAXNAMELEN = 32
XT_CONTINUE = 0xffffffff
XT_RETURN = (-NF_REPEAT - 1)
XT_INV_PROTO = 0x40
# linux/netfilter_ipv4/ip_tables.h
IPT_TABLE_MAXNAMELEN = XT_TABLE_MAXNAMELEN
IPT_F_FRAG = 0x01
IPT_F_GOTO = 0x02
IPT_F_MASK = 0x03
IPT_INV_VIA_IN = 0x01
IPT_INV_VIA_OUT = 0x02
IPT_INV_TOS = 0x04
IPT_INV_SRCIP = 0x08
IPT_INV_DSTIP = 0x10
IPT_INV_FRAG = 0x20
IPT_INV_PROTO = XT_INV_PROTO
IPT_INV_MASK = 0x7f
IPT_BASE_CTL = 64
IPT_SO_SET_REPLACE = IPT_BASE_CTL
IPT_SO_SET_ADD_COUNTERS = IPT_BASE_CTL + 1
IPT_SO_GET_INFO = IPT_BASE_CTL
IPT_SO_GET_ENTRIES = IPT_BASE_CTL + 1
IPT_SO_GET_REVISION_MATCH = IPT_BASE_CTL + 2
IPT_SO_GET_REVISION_TARGET = IPT_BASE_CTL + 3
IPT_CONTINUE = XT_CONTINUE
IPT_RETURN = XT_RETURN
end end

76
lib/netlink/iptables4.rb Normal file
View File

@@ -0,0 +1,76 @@
require 'socket'
require 'netlink/c_struct'
require 'netlink/message' # just for :dev_name type
require 'netlink/constants'
module Netlink
#-
# Definitions mainly from linux/netfilter_ipv4/ip_tables.h
#+
# struct ipt_getinfo
class IPTGetInfo < CStruct
field :name, :pattern=>"Z#{IPT_TABLE_MAXNAMELEN}", :default=>EMPTY_STRING
field :valid_hooks, :int
#field :hook_entry, :pattern=>"I#{NF_INET_NUMHOOKS}", :default=>[0]*NF_INET_NUMHOOKS
#field :underflow, :pattern=>"I#{NF_INET_NUMHOOKS}", :default=>[0]*NF_INET_NUMHOOKS
field :hook_entry, :pattern=>"a#{NF_INET_NUMHOOKS*4}", :default=>EMPTY_STRING
field :underflow, :pattern=>"a#{NF_INET_NUMHOOKS*4}", :default=>EMPTY_STRING
field :num_entries, :int
field :size, :int
end
# struct ipt_get_entries
class IPTGetEntries < CStruct
field :name, :pattern=>"Z#{IPT_TABLE_MAXNAMELEN}", :default=>EMPTY_STRING
field :size, :uint
#field :entrytable, :pattern=>
field :entrytable, :binary # struct ipt_entry entrytable[]
end
# struct ipt_entry
class IPTEntry < CStruct
#### struct ipt_ip
field :src, :nl # struct in_addr
field :dst, :nl
field :smsk, :nl
field :dmsk, :nl
field :iniface, :dev_name
field :outiface, :dev_name
field :iniface_mask, :dev_name
field :outiface_mask, :dev_name
field :proto, :uint16
field :flags, :uchar
field :invflags, :uchar
####
field :nfcache, :int
field :target_offset, :uint16
field :next_offset, :uint16
field :comefrom, :uint
field :packet_count, :uint64
field :byte_count, :uint64
field :elems, :binary
end
# Class for handling iptables. Note that this doesn't actually use
# Netlink at all :-(
class Iptables4
TC_AF = Socket::AF_INET
TC_IPPROTO = Socket::IPPROTO_IP
SO_GET_INFO = IPT_SO_GET_INFO
STRUCT_GETINFO = IPTGetInfo
STRUCT_GET_ENTRIES = IPTGetEntries
def initialize(tablename = "filter")
@socket = Socket.new(TC_AF, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
info = STRUCT_GETINFO.new(:name => tablename)
# FIXME: ruby won't let us pass structure to getsockopt!!
@socket.getsockopt(TC_IPPROTO, SO_GET_INFO, info)
warn "valid_hooks=0x%08x, num_entries=%d, size=%d" % [info.valid_hooks, info.size, info.num_entries]
end
end
end
if __FILE__ == $0
iptables = Netlink::Iptables4.new
end