iptables.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package ip
  2. import (
  3. "os/exec"
  4. "syscall"
  5. )
  6. type IPTables struct {
  7. path string
  8. }
  9. func NewIPTables() (*IPTables, error) {
  10. path, err := exec.LookPath("iptables")
  11. if err != nil {
  12. return nil, err
  13. }
  14. return &IPTables{path}, nil
  15. }
  16. func (ipt *IPTables) Exists(table string, args ...string) (bool, error) {
  17. cmd := append([]string{"-t", table, "-C"}, args...)
  18. err := exec.Command(ipt.path, cmd...).Run()
  19. switch {
  20. case err == nil:
  21. return true, nil
  22. case err.(*exec.ExitError).Sys().(syscall.WaitStatus).ExitStatus() == 1:
  23. return false, nil
  24. default:
  25. return false, err
  26. }
  27. }
  28. func (ipt *IPTables) Append(table string, args ...string) error {
  29. cmd := append([]string{"-t", table, "-A"}, args...)
  30. return exec.Command(ipt.path, cmd...).Run()
  31. }
  32. // AppendUnique acts like Append except that it won't add a duplicate
  33. func (ipt *IPTables) AppendUnique(table string, args ...string) error {
  34. exists, err := ipt.Exists(table, args...)
  35. if err != nil {
  36. return err
  37. }
  38. if !exists {
  39. return ipt.Append(table, args...)
  40. }
  41. return nil
  42. }
  43. func (ipt *IPTables) ClearChain(table, chain string) error {
  44. cmd := append([]string{"-t", table, "-N", chain})
  45. err := exec.Command(ipt.path, cmd...).Run()
  46. switch {
  47. case err == nil:
  48. return nil
  49. case err.(*exec.ExitError).Sys().(syscall.WaitStatus).ExitStatus() == 1:
  50. // chain already exists. Flush (clear) it.
  51. cmd := append([]string{"-t", table, "-F", chain})
  52. return exec.Command(ipt.path, cmd...).Run()
  53. default:
  54. return err
  55. }
  56. }