// StationInfo requests that nl80211 return station info for the specified // Interface. func (c *client) StationInfo(ifi *Interface) (*StationInfo, error) { b, err := netlink.MarshalAttributes(ifi.stationInfoAttrs()) if err != nil { return nil, err } // Ask nl80211 to retrieve station info for the interface specified // by its attributes req := genetlink.Message{ Header: genetlink.Header{ // From nl80211.h: // * @NL80211_CMD_GET_STATION: Get station attributes for station identified by // * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. Command: nl80211.CmdGetStation, Version: c.familyVersion, }, Data: b, } flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump msgs, err := c.c.Execute(req, c.familyID, flags) if err != nil { return nil, err } switch len(msgs) { case 0: return nil, os.ErrNotExist case 1: break default: return nil, errMultipleMessages } if err := c.checkMessages(msgs, nl80211.CmdNewStation); err != nil { return nil, err } return parseStationInfo(msgs[0].Data) }
// Get retrieves a generic netlink family with the specified name. If the // family does not exist, the error value can be checked using os.IsNotExist. func (s *FamilyService) Get(name string) (Family, error) { b, err := netlink.MarshalAttributes([]netlink.Attribute{{ Type: attrFamilyName, Data: nlenc.Bytes(name), }}) if err != nil { return Family{}, err } req := Message{ Header: Header{ Command: ctrlCommandGetFamily, Version: ctrlVersion, }, Data: b, } msgs, err := s.c.Execute(req, Controller, netlink.HeaderFlagsRequest) if err != nil { return Family{}, err } // TODO(mdlayher): consider interpreting generic netlink header values families, err := buildFamilies(msgs) if err != nil { return Family{}, err } if len(families) != 1 { // If this were to ever happen, netlink must be in a state where // its answers cannot be trusted panic(fmt.Sprintf("netlink returned multiple families for name: %q", name)) } return families[0], nil }