List chains (#25)
This commit is contained in:
parent
8d26daf060
commit
900c47abbb
92
chain.go
92
chain.go
|
@ -15,6 +15,8 @@
|
||||||
package nftables
|
package nftables
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/google/nftables/binaryutil"
|
"github.com/google/nftables/binaryutil"
|
||||||
|
@ -106,3 +108,93 @@ func (cc *Conn) AddChain(c *Chain) *Chain {
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListChains returns currently configured chains in the kernel
|
||||||
|
func (cc *Conn) ListChains() ([]*Chain, error) {
|
||||||
|
conn, err := cc.dialNetlink()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
msg := netlink.Message{
|
||||||
|
Header: netlink.Header{
|
||||||
|
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_GETCHAIN),
|
||||||
|
Flags: netlink.Request | netlink.Dump,
|
||||||
|
},
|
||||||
|
Data: extraHeader(uint8(unix.AF_UNSPEC), 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := conn.Execute(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var chains []*Chain
|
||||||
|
for _, m := range response {
|
||||||
|
c, err := chainFromMsg(m)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
chains = append(chains, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return chains, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func chainFromMsg(msg netlink.Message) (*Chain, error) {
|
||||||
|
chainHeaderType := netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWCHAIN)
|
||||||
|
if got, want := msg.Header.Type, chainHeaderType; got != want {
|
||||||
|
return nil, fmt.Errorf("unexpected header type: got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var c Chain
|
||||||
|
|
||||||
|
ad, err := netlink.NewAttributeDecoder(msg.Data[4:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for ad.Next() {
|
||||||
|
switch ad.Type() {
|
||||||
|
case unix.NFTA_CHAIN_NAME:
|
||||||
|
c.Name = ad.String()
|
||||||
|
case unix.NFTA_TABLE_NAME:
|
||||||
|
c.Table = &Table{Name: ad.String()}
|
||||||
|
case unix.NFTA_CHAIN_TYPE:
|
||||||
|
c.Type = ChainType(ad.String())
|
||||||
|
case unix.NFTA_CHAIN_HOOK:
|
||||||
|
ad.Do(func(b []byte) error {
|
||||||
|
c.Hooknum, c.Priority, err = hookFromMsg(b)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hookFromMsg(b []byte) (ChainHook, ChainPriority, error) {
|
||||||
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
|
||||||
|
var hooknum ChainHook
|
||||||
|
var prio ChainPriority
|
||||||
|
|
||||||
|
for ad.Next() {
|
||||||
|
switch ad.Type() {
|
||||||
|
case unix.NFTA_HOOK_HOOKNUM:
|
||||||
|
hooknum = ChainHook(ad.Uint32())
|
||||||
|
case unix.NFTA_HOOK_PRIORITY:
|
||||||
|
prio = ChainPriority(ad.Uint32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hooknum, prio, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue