95 lines
2.1 KiB
Go
95 lines
2.1 KiB
Go
package xt
|
|
|
|
import (
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// TableFamily specifies the address family of the table Match or Target Info
|
|
// data is contained in. On purpose, we don't import the expr package here in
|
|
// order to keep the option open to import this package instead into expr.
|
|
type TableFamily byte
|
|
|
|
// InfoAny is a (un)marshaling implemented by any info type.
|
|
type InfoAny interface {
|
|
marshal(fam TableFamily, rev uint32) ([]byte, error)
|
|
unmarshal(fam TableFamily, rev uint32, data []byte) error
|
|
}
|
|
|
|
// Marshal a Match or Target Info type into its binary representation.
|
|
func Marshal(fam TableFamily, rev uint32, info InfoAny) ([]byte, error) {
|
|
return info.marshal(fam, rev)
|
|
}
|
|
|
|
// Unmarshal Info binary payload into its corresponding dedicated type as
|
|
// indicated by the name argument. In several cases, unmarshalling depends on
|
|
// the specific table family the Target or Match expression with the info
|
|
// payload belongs to, as well as the specific info structure revision.
|
|
func Unmarshal(name string, fam TableFamily, rev uint32, data []byte) (InfoAny, error) {
|
|
var i InfoAny
|
|
switch name {
|
|
case "addrtype":
|
|
switch rev {
|
|
case 0:
|
|
i = &AddrType{}
|
|
case 1:
|
|
i = &AddrTypeV1{}
|
|
}
|
|
case "conntrack":
|
|
switch rev {
|
|
case 1:
|
|
i = &ConntrackMtinfo1{}
|
|
case 2:
|
|
i = &ConntrackMtinfo2{}
|
|
case 3:
|
|
i = &ConntrackMtinfo3{}
|
|
}
|
|
case "tcp":
|
|
i = &Tcp{}
|
|
case "udp":
|
|
i = &Udp{}
|
|
case "SNAT":
|
|
if fam == unix.NFPROTO_IPV4 {
|
|
i = &NatIPv4MultiRangeCompat{}
|
|
}
|
|
case "DNAT":
|
|
switch fam {
|
|
case unix.NFPROTO_IPV4:
|
|
if rev == 0 {
|
|
i = &NatIPv4MultiRangeCompat{}
|
|
break
|
|
}
|
|
fallthrough
|
|
case unix.NFPROTO_IPV6:
|
|
switch rev {
|
|
case 1:
|
|
i = &NatRange{}
|
|
case 2:
|
|
i = &NatRange2{}
|
|
}
|
|
}
|
|
case "MASQUERADE":
|
|
switch fam {
|
|
case unix.NFPROTO_IPV4:
|
|
i = &NatIPv4MultiRangeCompat{}
|
|
}
|
|
case "REDIRECT":
|
|
switch fam {
|
|
case unix.NFPROTO_IPV4:
|
|
if rev == 0 {
|
|
i = &NatIPv4MultiRangeCompat{}
|
|
break
|
|
}
|
|
fallthrough
|
|
case unix.NFPROTO_IPV6:
|
|
i = &NatRange{}
|
|
}
|
|
}
|
|
if i == nil {
|
|
i = &Unknown{}
|
|
}
|
|
if err := i.unmarshal(fam, rev, data); err != nil {
|
|
return nil, err
|
|
}
|
|
return i, nil
|
|
}
|