Non-functioning experiment at iptables netfilter support
This commit is contained in:
@@ -65,9 +65,11 @@ class CStruct
|
||||
define_type :uchar, :pattern => "C"
|
||||
define_type :uint16, :pattern => "S", :align => true
|
||||
define_type :uint32, :pattern => "L", :align => true
|
||||
define_type :uint64, :pattern => "Q", :align => true
|
||||
define_type :char, :pattern => "c"
|
||||
define_type :int16, :pattern => "s", :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 :uint, :pattern => "I", :align => true
|
||||
define_type :ulong, :pattern => "L_", :align => true
|
||||
|
@@ -3,6 +3,8 @@ class Socket
|
||||
# From bits/socket.h
|
||||
PF_NETLINK = 16 unless defined? Socket::PF_NETLINK
|
||||
AF_NETLINK = PF_NETLINK unless defined? Socket::AF_NETLINK
|
||||
# From in.h
|
||||
IPPROTO_IPV6 = 41 unless defined? Socket::IPPROTO_IPV6
|
||||
end
|
||||
|
||||
module Netlink
|
||||
@@ -327,6 +329,20 @@ module Netlink
|
||||
NF_REPEAT = 4
|
||||
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
|
||||
IPQ_COPY_NONE = 0
|
||||
IPQ_COPY_META = 1
|
||||
@@ -340,4 +356,41 @@ module Netlink
|
||||
# linux/netfilter_ipv4/ipt_ULOG.h
|
||||
ULOG_MAC_LEN = 80
|
||||
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
|
||||
|
76
lib/netlink/iptables4.rb
Normal file
76
lib/netlink/iptables4.rb
Normal 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
|
Reference in New Issue
Block a user