@@ -57,10 +57,14 @@ const (
5757)
5858
5959type IPTables struct {
60- path string
61- proto Protocol
62- hasCheck bool
63- hasWait bool
60+ path string
61+ proto Protocol
62+ hasCheck bool
63+ hasWait bool
64+ hasRandomFully bool
65+ v1 int
66+ v2 int
67+ v3 int
6468}
6569
6670// New creates a new IPTables.
@@ -76,15 +80,22 @@ func NewWithProtocol(proto Protocol) (*IPTables, error) {
7680 if err != nil {
7781 return nil , err
7882 }
79- checkPresent , waitPresent , err := getIptablesCommandSupport (path )
83+ vstring , err := getIptablesVersionString (path )
84+ v1 , v2 , v3 , err := extractIptablesVersion (vstring )
85+
86+ checkPresent , waitPresent , randomFullyPresent , err := getIptablesCommandSupport (v1 , v2 , v3 )
8087 if err != nil {
8188 return nil , fmt .Errorf ("error checking iptables version: %v" , err )
8289 }
8390 ipt := IPTables {
84- path : path ,
85- proto : proto ,
86- hasCheck : checkPresent ,
87- hasWait : waitPresent ,
91+ path : path ,
92+ proto : proto ,
93+ hasCheck : checkPresent ,
94+ hasWait : waitPresent ,
95+ hasRandomFully : randomFullyPresent ,
96+ v1 : v1 ,
97+ v2 : v2 ,
98+ v3 : v3 ,
8899 }
89100 return & ipt , nil
90101}
@@ -301,6 +312,16 @@ func (ipt *IPTables) ChangePolicy(table, chain, target string) error {
301312 return ipt .run ("-t" , table , "-P" , chain , target )
302313}
303314
315+ // Check if the underlying iptables command supports the --random-fully flag
316+ func (ipt * IPTables ) HasRandomFully () bool {
317+ return ipt .hasRandomFully
318+ }
319+
320+ // Return version components of the underlying iptables command
321+ func (ipt * IPTables ) GetIptablesVersion () (int , int , int ) {
322+ return ipt .v1 , ipt .v2 , ipt .v3
323+ }
324+
304325// run runs an iptables command with the given arguments, ignoring
305326// any stdout output
306327func (ipt * IPTables ) run (args ... string ) error {
@@ -355,18 +376,9 @@ func getIptablesCommand(proto Protocol) string {
355376}
356377
357378// Checks if iptables has the "-C" and "--wait" flag
358- func getIptablesCommandSupport (path string ) (bool , bool , error ) {
359- vstring , err := getIptablesVersionString (path )
360- if err != nil {
361- return false , false , err
362- }
363-
364- v1 , v2 , v3 , err := extractIptablesVersion (vstring )
365- if err != nil {
366- return false , false , err
367- }
379+ func getIptablesCommandSupport (v1 int , v2 int , v3 int ) (bool , bool , bool , error ) {
368380
369- return iptablesHasCheckCommand (v1 , v2 , v3 ), iptablesHasWaitCommand (v1 , v2 , v3 ), nil
381+ return iptablesHasCheckCommand (v1 , v2 , v3 ), iptablesHasWaitCommand (v1 , v2 , v3 ), iptablesHasRandomFully ( v1 , v2 , v3 ), nil
370382}
371383
372384// getIptablesVersion returns the first three components of the iptables version.
@@ -436,6 +448,20 @@ func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool {
436448 return false
437449}
438450
451+ // Checks if an iptables version is after 1.6.2, when --random-fully was added
452+ func iptablesHasRandomFully (v1 int , v2 int , v3 int ) bool {
453+ if v1 > 1 {
454+ return true
455+ }
456+ if v1 == 1 && v2 > 6 {
457+ return true
458+ }
459+ if v1 == 1 && v2 == 6 && v3 >= 2 {
460+ return true
461+ }
462+ return false
463+ }
464+
439465// Checks if a rule specification exists for a table
440466func (ipt * IPTables ) existsForOldIptables (table , chain string , rulespec []string ) (bool , error ) {
441467 rs := strings .Join (append ([]string {"-A" , chain }, rulespec ... ), " " )
0 commit comments