3 # This file parses an sfatables command and generates XML files that parameterize
4 # matches and targets. Each such XML file defines a rule. Rules are dropped in directories
5 # that represent 'chains.' SFA loads rules from various chains and invokes them at certain
6 # 'hook points.' For example, it invokes rules in the 'OUTGOING' chain before returning
7 # the output of 'get_resources.'
14 from optparse import OptionParser
15 from sfatables import commands, matches, targets
16 from sfatables.xmlextension import Xmlextension
17 from sfatables.globals import *
19 def load_commands(module, list):
22 for command_name in list:
23 command_module = __import__(".".join([module,command_name]),fromlist=[module])
24 command = getattr(command_module, command_name)
25 command_dict[command_name]=command()
29 def load_xml_extensions(module, dir, list):
33 module = Xmlextension(dir, ext_name)
34 ext_dict[ext_name]=module
39 def create_parser(command_dict):
40 parser = OptionParser(usage="sfatables [command] [chain] [match] [target]",
41 description='See "man sfatables" for more detail.')
43 for k in command_dict.keys():
44 command = command_dict[k]
45 for (short_option,long_option) in command.options:
46 parser.add_option(short_option,long_option,dest=command.type,action=command.action,const=k,help=command.help,metavar="CHAIN")
50 def create_parser_xml_ext(ext_dict):
51 parser = OptionParser(usage="sfatables [command] [chain] [match] [target]",
52 description='See "man sfatables" for more detail.')
54 for k in ext_dict.keys():
56 for arg in command.arguments:
57 parser.add_option('',"--"+arg['name'],dest=arg['name'],help=arg['help'],metavar=arg['target'])
62 def partition(sep, lst):
77 # sfatables <command> -- <match> -- <target>
78 pargs = partition('--', sys.argv[1:])
80 command_dict = load_commands("sfatables.commands",commands.all)
81 command_parser = create_parser(command_dict)
82 (options, args) = command_parser.parse_args(pargs[0])
83 setattr(options, 'args', args)
85 command = command_dict[options.command]
89 raise Exception("Must specify match for this command")
90 match_dict = load_xml_extensions("sfatables.matches",match_dir, matches.all)
91 match_parser = create_parser_xml_ext(match_dict)
92 matches_str = ",".join(match_dict.keys())
93 match_parser.add_option('-m','--match',dest='name',help='Match name (one of %s)'%matches_str, metavar = 'MATCH')
94 match_parser.add_option('-n','--negate',dest='negate',help='Negate result',action='store_true')
95 (match_options, args) = match_parser.parse_args(pargs[1])
97 name = match_options.name
99 print "Must specify match name with -m"
101 if (match_dict.has_key(name)):
102 setattr(match_options, 'arguments', match_dict[name].arguments)
104 raise Exception('Match %s not found'%name)
109 if (command.targets):
111 raise Exception("Must specify a target for this command")
112 target_dict = load_xml_extensions("sfatables.targets",target_dir,targets.all)
113 target_parser = create_parser_xml_ext(target_dict)
114 targets_str = ",".join(target_dict.keys())
115 target_parser.add_option('-j','--jump',dest='name',help='Target name (one of %s)'%targets, metavar = 'TARGET')
116 target_parser.add_option('-e','--element',dest='element',help='Element name', metavar = 'ELEMENT')
117 (target_options, args) = target_parser.parse_args(pargs[2])
119 name = target_options.name
121 print "Must specify target name with -j"
123 if (target_dict.has_key(name)):
124 setattr(target_options, 'arguments', target_dict[name].arguments)
126 raise Exception('Target %s not found'%name)
129 target_options = None
131 command(options, match_options, target_options)
133 if __name__=='__main__':