Skip to content

Commit

Permalink
Merge pull request #200 from pepoluan/add-goto-support
Browse files Browse the repository at this point in the history
Add goto support -- fixed!
  • Loading branch information
ldx authored Jan 3, 2017
2 parents edd1623 + d3df22b commit 838c875
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
/Vagrantfile
/.vagrant
/tags

# Added exclusion for PyCharm files
.idea/*
40 changes: 35 additions & 5 deletions iptc/ip4tc.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ class Target(IPTCModule):
does not take any value in the iptables extension, an empty string i.e. ""
should be used.
"""
def __init__(self, rule, name=None, target=None, revision=None):
def __init__(self, rule, name=None, target=None, revision=None, goto=None):
"""
*rule* is the Rule object this match belongs to; it can be changed
later via *set_rule()*. *name* is the name of the iptables target
Expand All @@ -672,6 +672,7 @@ def __init__(self, rule, name=None, target=None, revision=None):
should be used; different revisions use different structures in C and
they usually only work with certain kernel versions. Python-iptables
by default will use the latest revision available.
If goto is True, then it converts '-j' to '-g'.
"""
if name is None and target is None:
raise ValueError("can't create target based on nothing")
Expand All @@ -682,6 +683,28 @@ def __init__(self, rule, name=None, target=None, revision=None):
self._orig_parse = None
self._orig_options = None

# NOTE:
# get_ip() returns the 'ip' structure that contains (1)the 'flags' field, and
# (2)the value for the GOTO flag.
# We *must* use get_ip() because the actual name of the field containing the
# structure apparently differs between implementation
ipstruct = rule.get_ip()
f_goto_attrs = [a for a in dir(ipstruct) if a.endswith('_F_GOTO')]
if len(f_goto_attrs) == 0:
raise RuntimeError('What kind of struct is this? It does not have "*_F_GOTO" constant!')
_F_GOTO = getattr(ipstruct, f_goto_attrs[0])

if target is not None or goto is None:
# We are 'decoding' existing Target
self._goto = bool(ipstruct.flags & _F_GOTO)
if goto is not None:
assert isinstance(goto, bool)
self._goto = goto
if goto:
ipstruct.flags |= _F_GOTO
else:
ipstruct.flags &= ~_F_GOTO

self._xt = xtables(rule.nfproto)

module = (self._is_standard_target() and
Expand Down Expand Up @@ -831,6 +854,10 @@ def _get_target(self):
target = property(_get_target)
"""This is the C structure used by the extension."""

def _get_goto(self):
return self._goto
goto = property(_get_goto)


class Policy(object):
"""
Expand Down Expand Up @@ -960,11 +987,11 @@ def create_match(self, name, revision=None):
self.add_match(match)
return match

def create_target(self, name, revision=None):
def create_target(self, name, revision=None, goto=False):
"""Create a new *target*, and set it as this rule's target. *name* is
the name of the target extension, *revision* is the revision to
use."""
target = Target(self, name=name, revision=revision)
use. *goto* determines if target uses '-j' (default) or '-g'."""
target = Target(self, name=name, revision=revision, goto=goto)
self.target = target
return target

Expand Down Expand Up @@ -1207,7 +1234,10 @@ def get_fragment(self):

def set_fragment(self, frag):
self.entry.ip.invflags &= ~ipt_ip.IPT_INV_FRAG & ipt_ip.IPT_INV_MASK
self.entry.ip.flags = int(bool(frag))
if frag:
self.entry.ip.flags |= ipt_ip.IPT_F_FRAG
else:
self.entry.ip.flags &= ~ipt_ip.IPT_F_FRAG

fragment = property(get_fragment, set_fragment)
"""This means that the rule refers to the second and further fragments of
Expand Down

0 comments on commit 838c875

Please sign in to comment.