Skip to content

gonetx/ipset

Repository files navigation

gonetx/ipset

This package is a almost whole Golang wrapper to the ipset userspace utility. It allows Golang programs to easily manipulate ipset.

Visit http://ipset.netfilter.org/ipset.man.html for more ipset command details. And ipset requires version v6.0+.

Installation

Install ipset using the go get command:

go get -u github.com/gonetx/ipset

Quickstart

package main

import (
	"log"
	"time"

	"github.com/gonetx/ipset"
)

func init() {
	if err := ipset.Check(); err != nil {
		panic(err)
	}
}

func main() {
	// create test set even it's exist
	set, _ := ipset.New("test", ipset.HashIp, ipset.Exist(true), ipset.Timeout(time.Hour))
	// output: test
	log.Println(set.Name())

	_ = set.Flush()

	_ = set.Add("1.1.1.1", ipset.Timeout(time.Hour))

	ok, _ := set.Test("1.1.1.1")
	// output: true
	log.Println(ok)

	ok, _ = set.Test("1.1.1.2")
	// output: false
	log.Println(ok)

	info, _ := set.List()
	// output: &{test hash:ip 4 family inet hashsize 1024 maxelem 65536 timeout 3600 216 0 [1.1.1.1 timeout 3599]}
	log.Println(info)

	_ = set.Del("1.1.1.1")

	_ = set.Destroy()
}

Check

Before using this library, you should remember always to call ipset.Check first and handle the error. This method will check if ipset is in OS PATH and if its version is valid.

func init() {
	// err will be ipset.ErrNotFound
	// or ipset.ErrVersionNotSupported
	// if check failed.
	if err := ipset.Check(); err != nil {
		panic(err)
	}
}

New

Use ipset.New to create a set identified with setname and specified set type. If the ipset.Exist option is specified, ipset will ignore the error when the same set (setname and create parameters are identical) already exists.

set, _ := ipset.New("test", ipset.HashIp, ipset.Exist(true), ipset.Netmask(24))

Every set type may has different create options, visit SetType and Option for more details.

Once you created a set, you can use these methods:

// IPSet is abstract of ipset
type IPSet interface {
	// List dumps header data and the entries for the set to an
	// *Info instance. The Resolve option can be used to force
	// action lookups(which may be slow).
	List(options ...Option) (*Info, error)

	// List dumps header data and the entries for the set to the
	// specific file. The Resolve option can be used to force
	// action lookups(which may be slow).
	ListToFile(filename string, options ...Option) error

	// Name returns the set's name
	Name() string

	// Rename the set's action and the new action must not exist.
	Rename(newName string) error

	// Add adds a given entry to the set. If the Exist option is
	// specified, ipset ignores the error if the entry already
	// added to the set.
	Add(entry string, options ...Option) error

	// Del deletes an entry from a set. If the Exist option is
	// specified and the entry is not in the set (maybe already
	// expired), then the command ignores the error.
	Del(entry string, options ...Option) error

	// Test tests whether an entry is in a set or not.
	Test(entry string) (bool, error)

	// Flush flushed all entries from the the set.
	Flush() error

	// Destroy removes the set from kernel.
	Destroy() error

	// Save dumps the set data to a io.Reader in a format that restore
	// can read.
	Save(options ...Option) (io.Reader, error)

	// SaveToFile dumps the set data to s specific file in a format
	// that restore can read.
	SaveToFile(filename string, options ...Option) error

	// Restore restores a saved session from io.Reader generated by
	// save. Set exist to true to ignore exist error.
	Restore(r io.Reader, exist ...bool) error

	// RestoreFromFile restores a saved session from a specific file
	// generated by save. Set exist to true to ignore exist error.
	RestoreFromFile(filename string, exist ...bool) error
}

Swap

Use ipset.Swap to swap the content of two sets, or in another words, exchange the action of two sets. The referred sets must exist and compatible type of sets can be swapped only.

ipset.Swap("foo", "bar")

Flush

Use ipset.Flush to flush all entries from the specified set or flush all sets if none is given.

// Flush foo and bar set
ipset.Flush("foo", "bar")

// Flush all
ipset.Flush()

Destroy

Use ipset.Destroy to removes the specified set or all the sets if none is given. If the set has got reference(s), nothing is done and no set destroyed.

// Destroy foo and bar set
ipset.Destroy("foo", "bar")

// Destroy all
ipset.Destroy()