123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- package netlink
- import (
- "fmt"
- "syscall"
- "github.com/vishvananda/netlink/nl"
- )
- type GenlOp struct {
- ID uint32
- Flags uint32
- }
- type GenlMulticastGroup struct {
- ID uint32
- Name string
- }
- type GenlFamily struct {
- ID uint16
- HdrSize uint32
- Name string
- Version uint32
- MaxAttr uint32
- Ops []GenlOp
- Groups []GenlMulticastGroup
- }
- func parseOps(b []byte) ([]GenlOp, error) {
- attrs, err := nl.ParseRouteAttr(b)
- if err != nil {
- return nil, err
- }
- ops := make([]GenlOp, 0, len(attrs))
- for _, a := range attrs {
- nattrs, err := nl.ParseRouteAttr(a.Value)
- if err != nil {
- return nil, err
- }
- var op GenlOp
- for _, na := range nattrs {
- switch na.Attr.Type {
- case nl.GENL_CTRL_ATTR_OP_ID:
- op.ID = native.Uint32(na.Value)
- case nl.GENL_CTRL_ATTR_OP_FLAGS:
- op.Flags = native.Uint32(na.Value)
- }
- }
- ops = append(ops, op)
- }
- return ops, nil
- }
- func parseMulticastGroups(b []byte) ([]GenlMulticastGroup, error) {
- attrs, err := nl.ParseRouteAttr(b)
- if err != nil {
- return nil, err
- }
- groups := make([]GenlMulticastGroup, 0, len(attrs))
- for _, a := range attrs {
- nattrs, err := nl.ParseRouteAttr(a.Value)
- if err != nil {
- return nil, err
- }
- var g GenlMulticastGroup
- for _, na := range nattrs {
- switch na.Attr.Type {
- case nl.GENL_CTRL_ATTR_MCAST_GRP_NAME:
- g.Name = nl.BytesToString(na.Value)
- case nl.GENL_CTRL_ATTR_MCAST_GRP_ID:
- g.ID = native.Uint32(na.Value)
- }
- }
- groups = append(groups, g)
- }
- return groups, nil
- }
- func (f *GenlFamily) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
- for _, a := range attrs {
- switch a.Attr.Type {
- case nl.GENL_CTRL_ATTR_FAMILY_NAME:
- f.Name = nl.BytesToString(a.Value)
- case nl.GENL_CTRL_ATTR_FAMILY_ID:
- f.ID = native.Uint16(a.Value)
- case nl.GENL_CTRL_ATTR_VERSION:
- f.Version = native.Uint32(a.Value)
- case nl.GENL_CTRL_ATTR_HDRSIZE:
- f.HdrSize = native.Uint32(a.Value)
- case nl.GENL_CTRL_ATTR_MAXATTR:
- f.MaxAttr = native.Uint32(a.Value)
- case nl.GENL_CTRL_ATTR_OPS:
- ops, err := parseOps(a.Value)
- if err != nil {
- return err
- }
- f.Ops = ops
- case nl.GENL_CTRL_ATTR_MCAST_GROUPS:
- groups, err := parseMulticastGroups(a.Value)
- if err != nil {
- return err
- }
- f.Groups = groups
- }
- }
- return nil
- }
- func parseFamilies(msgs [][]byte) ([]*GenlFamily, error) {
- families := make([]*GenlFamily, 0, len(msgs))
- for _, m := range msgs {
- attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
- if err != nil {
- return nil, err
- }
- family := &GenlFamily{}
- if err := family.parseAttributes(attrs); err != nil {
- return nil, err
- }
- families = append(families, family)
- }
- return families, nil
- }
- func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
- msg := &nl.Genlmsg{
- Command: nl.GENL_CTRL_CMD_GETFAMILY,
- Version: nl.GENL_CTRL_VERSION,
- }
- req := h.newNetlinkRequest(nl.GENL_ID_CTRL, syscall.NLM_F_DUMP)
- req.AddData(msg)
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
- if err != nil {
- return nil, err
- }
- return parseFamilies(msgs)
- }
- func GenlFamilyList() ([]*GenlFamily, error) {
- return pkgHandle.GenlFamilyList()
- }
- func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
- msg := &nl.Genlmsg{
- Command: nl.GENL_CTRL_CMD_GETFAMILY,
- Version: nl.GENL_CTRL_VERSION,
- }
- req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0)
- req.AddData(msg)
- req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name)))
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
- if err != nil {
- return nil, err
- }
- families, err := parseFamilies(msgs)
- if len(families) != 1 {
- return nil, fmt.Errorf("invalid response for GENL_CTRL_CMD_GETFAMILY")
- }
- return families[0], nil
- }
- func GenlFamilyGet(name string) (*GenlFamily, error) {
- return pkgHandle.GenlFamilyGet(name)
- }
|