Revision history for Perl extension Iptables.
0.01 Fri Oct 13 16:50:13 2000
- original version; created by h2xs 1.19
0.02 Sun Oct 15 16:56:28 2000
- Wrote wrappers for all functions, except those whose functionality
has been encased in a different way (iptc_(first|next)_(rule|chain),
and iptc_strerror()).
- Began helper function to explode struct ipt_entry into a Perl hash.
This will make it easier to manipulate rules. I considered encasing
the struct ipt_entry * in an object, and using methods to access the
rule values, but decided that won't do.
0.03 Tue Oct 17 08:04:54 2000
- Succeeded in writing the basic explode/pack routines to handle
struct ipt_entry data. Still need to handle target and match modules.
Currently I'm just forcing the standard (null) target, which is, of
course, completely and utterly wrong, but it lets me test things.
- Discovered that with a reference variable, you must ALWAYS push
the new value back up the call stack. That was causing a segfault if
I tried to commit() or do ANYTHING else after create_chain(), because
create_chain() reallocates the handle struct.
- Still wrestling with a segfault - if a chain is created with
create_chain(), and then either of the entry-adding calls
(insert_entry or append_entry) is made, this causes a segfault.
It dies on a free() in the insert_rules() routine. Still trying
to determine the cause.
0.04a Sat Nov 11 11:00:46 2000
- Took care of some endianness issues in width-value mask handling.
This is now endianness-independent. (using ntohl()/htonl() calls for
reordering)
- Removed the check_packet() method, as it presently does nothing.
- Sent a message to netfilter-devel to ask about the 'matchmask'
parameter to iptc_delete_entry(). I haven't been able to determine
its purpose, and calling it with nothing or a garbage string seems
to have no adverse effect on its behavior.
- Determined the cause of the earlier segfault. A bug in the libiptc
code was causing the problem, and Harald Welte has since remedied
it in the netfilter CVS tree.
- Basic rule and chain handling is pretty much complete, I am (for
now) satisfied with the interface I'm exporting. I now need to
determine how to handle all the match and target modules. (Other than
the check_packet call, and the delete_entry call, as noted
previously - I'm still waiting for feedback on these.)
0.05
- Added infrastructure for match and target modules. All hooks should
now be in place. I've got the standard target module and the UDP
protocol match module done, and I'm working on the TCP protocol match
module.
0.05a
- TCP protocol module should be working fully, but presently only
supports one input format for each field.
- ICMP protocol module should be working now also. Need to get some
extra handling in for the numeric identifiers. Had to modify the
protocol match module handling for a Netfilter weirdness related to
the ICMP protocol (if there is a match entry in the ipt_entry data
structure, it is not possible to just match any ICMP packet). This
takes a bit more black magic to make work right, but I think I have
it.
0.05b
- Took care of a bug that made any attempt to construct a chain-to-
chain jump in a rule cause a segfault. The STANDARD target module
(ipt_ip_standard.so) has to be loaded in the case of no target or
a chain-to-chain jump. (However, I beefed up my pointer checking
a bit, just in case.)
- Fixed the call to iptc_set_policy. Apparently between the 1.1.2 and
1.2 releases of iptables, an extra parameter was added. I'm still not
sure what it does. I'll have to do some more investigating. However,
for now, it appears that it's safe to just make it a NULL. So that's
what I'm going to do for now.
0.05c
- Hopefully I've now squashed the chain-to-chain jump bug. Had to
change the other find_module() calls that loaded target modules to
match the one I'd changed previously.
0.05d
- Found a boundary condition in find_module() where if the string
containing the path to the shared object to load (via dlopen()) had
a length that was a multiple of 4, apparently one byte of the return
address would get overwritten, causing a segfault. This only occurred
with the multiport match module, just because the path string was the
right length.
- Added code to, if a target module couldn't be found (and data is
present for it), add a key containing the raw data for it
(<target>-target-raw). Still need to integrate the module build
process with the rest of the build.
- Modified the packer to accept numeric protocols. Discovered I need
to generate a 'matches' list as part of the exploder. Also should add
code to accept the raw data for match modules, though we, of course,
don't want to have to use that much.
- Modified the packer to just ignore the 'bcnt' and 'pcnt' fields of
a rule hash.
- Removed sv_2mortal()s in the exploder - it was causing values to
disappear and get overwritten with junk. I'm confused.
- Started adding code to accept raw target data in the packer routine.
Forgot that if the module isn't available, then no data zone will be
allocated at all - one must be added. More work will be involved to get
the same for match modules, but with what I'm learning here, it
shouldn't be too difficult to make work.
- Got acceptance of raw target data working. Forgot I had to update
the entry and target size values as well. Oops. Works now, anyway.
- Rolled raw target data code into the main target setup code in the
packer. This simplifies the code somewhat.
- Implemented generation of the 'matches' list in the exploder, and
use of raw match data in the packer. The raw target and match data
handlers are only intended as a fallthrough condition, not for regular
use. However, skillful use of pack() and unpack() could be brought to
bear to manipulate the raw data. I still don't recommend this, it's
better to write a proper module for handling this.
- Added code to the set_policy method to allow setting packet and byte
counters on a (built-in) chain.
0.06 Thu Apr 26 22:52:11 MDT 2001
- With all the new changes and fixes, decided to roll the version
number.
- Modified the exploder to not include the protocol name in the list
of matches.
- Got raw match data retrieval working for the protocol as well.
- Had the packer use the "official" protocol name returned by
getprotobyname(), instead of the passed string, since the "official"
protocol name will always be lowercase, and therefore will match up
with the match module name.
- Setup an actual Makefile in the modules/ subdir. Maybe a slight
rearrangement of the source, and including a copy of the libiptc
source tree (to remove the dependency on having iptables) should be
undertaken?
- Modified the 'delete_entry' method, adding a function to helper.c
to generate the matchmask based on the (struct ipt_entry), and no
longer expect the user to input it. Now that I (sort of) understand
what the matchmask is for and how it's constructed, I think I have
the right way to build it (and it seems to be working).
- Extended the module interface with a final_check() call (to be
used as part of the packing routine), and added an extra parameter
to the parse_field and get_fields calls to pass a pointer to the
(struct ipt_entry), for checking things like the protocol in use
(necessary for the multiport match module, among others).
- Added a match module for multiport.
- Added a match module for state.
- Added a match module for owner.
- Added documentation for the multiport, state and owner match modules
to IPv4.pm. (A man page is automatically generated as part of the
'make' procedure, and the embedded documentation can be read using
'perldoc'.)
- Added a target module for LOG, and documentation for the module.
- Added a target module for REJECT, and documentation for the module.
- Added a bit of code in the REJECT target module's parse_field()
routine to, if tcp-reset rejection is requested, make sure TCP
protocol is being used.
- Modified code throughout, including in match and target modules, so
that modules can set $! to indicate why a failure has occurred when
packing a hash into a (struct ipt_entry).
- Modified TCP and UDP protocol match modules to provide and accept
port names when available. Also now am using asprintf in all the
match modules whenever possible, as it makes string generation far
simpler, since it takes care of string allocation.
0.10 Mon Apr 30 10:41:23 MDT 2001
- Rolled the version number over, due to the number of changes made.
- Improved documentation formatting and grammar, alphabetized method
descriptions, and did a general cleanup. Regenerated PDF file.
- Modified the memset() call in parse_iface() to write 0xFF values
instead of 1 in the mask string, to match the behavior of the iptables
command-line tool.
- Further cleanups in helper code and modules. Eliminated several
uses of realloc() in the exploder routine (using asprintf() instead),
changed packer routines to eliminate multiple call points per key for
hv_store(), and did the same in modules. Changed some code in modules
to pass back integer values when possible. In TCP and UDP protocol
matches, snipped out the code to build the SV containing the port
(or port range) into a separate function (one in each module), to
minimize previous errors (in the TCP module, I was mixing up src and
dst references - that could get very ugly later).
- Rewrote chunks of ipt_entry generator code, to follow the style of
the iptables codebase. It turns out this is more or less necessary to
handle the way certain match modules can extend their data area. (Of
course, it COULD be done the way I was doing it - it would be very
ugly, though.) Also cleaned up some uses of sprintf() and snprintf(),
replacing them with asprintf() (and free()s in the appropriate places).
- Changed the module interface (again) to pass a pointer to a pointer
for the match and target data blocks, so that the match and target
modules can reallocate their data blocks for those that wish to enlarge
their data areas (like SNAT and DNAT). Also changed plugins themselves
to match.
- Added SNAT target support. Should support mapping both based on
ports and IP addresses. Will add DNAT target support soon - it should
only involve minor changes to the SNAT target.
- Added DNAT target support. Also fixed minor bug in SNAT target
module.
- Added MASQUERADE target support, based on SNAT target code.
- Minor fix to setup() routine in MASQUERADE target.
- Added REDIRECT target support, based on MASQUERADE target code.
- Added documentation for SNAT and DNAT targets to IPv4.pm.
- Added mac match module.
- Fixed a bug in the unpacking code when handling rules with more
than one match module associated with them.
- Oops - remove debugging printf()s from helper.c! :p
- Added code to mac match module's final_check() routine to help
ensure that the MAC address gets set.
- Added unclean match module.
- Added MARK target module.
- Cleaned up some error case code (the code to set the Perl $! variable
in error cases in the modules).
- Added code to the MASQUERADE and REDIRECT targets to handle integer
values in their to-ports argument handlers.
- Changed the Makefile, removing .o files from the .PRECIOUS:
specifier line.
- Added MIRROR target module.
- Added mark match module.
- Added tos match module.
- Added TOS target module.
- Added documentation for MASQUERADE, REDIRECT, MARK and MIRROR
targets, and mac and unclean matches.
- Added documentation for the mark and tos matches.
- Added limit match module.
0.90 Thu Oct 4 20:47:21 MDT 2001
- Rolled over the internal version number.
- Added documentation for the limit match.
- Added libiptc source and headers from netfilter CVS (tagged version
1.2.3) for libip4tc.
- Added material to Makefile.PL and modules/Makefile to unify the
build process. libiptc and all modules will be built automatically,
and 'make install' will install modules to their appropriate location.