wifi icon indicating copy to clipboard operation
wifi copied to clipboard

Support for Linux AP scanning

Open oldgalileo opened this issue 3 years ago • 4 comments

Adds support for Linux AP scanning, with unit tests handling unicode in AP SSIDs.

oldgalileo avatar Apr 22 '21 18:04 oldgalileo

This needs a rebase.

SuperQ avatar Jun 14 '23 12:06 SuperQ

(maybe stupid question) Why is multicast group needed here?

I am getting operation not supported when using dump flag on the TRIGGER_SCAN.

I don't know enough about netlink and nl80211 yet, but I am trying to learn. I would love if anyone could point me in a direction. Right now the only method I have is to try out commands from here and parsing the response manually. I am looking at iw, and wpa_supplicant sourcecode as well, but it is not easy for me to understand because I am not a C programmer.

I changed the first call to socket using the get method on the cli, and I changed dump to acknowlegde, because then I will get other errors.

	msgs, err := c.get(
		unix.NL80211_CMD_TRIGGER_SCAN,
		netlink.Acknowledge,
		ifi,
		func(ae *netlink.AttributeEncoder) {
			ae.Nested(unix.NL80211_ATTR_SCAN_SSIDS,
				func(nae *netlink.AttributeEncoder) error {
					nae.Bytes(
						unix.NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
						nlenc.Bytes(""),
					)
					return nil
				})
			ae.Bytes(
				unix.NL80211_ATTR_IFINDEX,
				nlenc.Uint32Bytes(uint32(ifi.Index)),
			)
		},
	)
	if err != nil {
		return nil, fmt.Errorf("failed to trigger scheduled scan: %s", err)
	}

First error was not permitted, so I run with sudo, and get: netlink validate: mismatched sequence in netlink reply.

So I removed the part where you create a multicast group and join it.

Then I get the error that the header version is not the family version and the response from the first call to socket is:

{{0 0} [48 0 0 0 36 0 5 0 203 41 13 27 209 148 2 0]}

I don't know how to interpret it.

The final response from CMD_GET_SCAN is one or more of this:

&{  0 0s 0s authenticated}
&{  0 0s 0s authenticated}
&{  0 0s 0s authenticated}
&{  0 0s 0s authenticated}

Here is a copy of the whole function, how it look on my machine now

func (c *client) Scan(ifi *Interface) ([]*BSS, error) {
	//family, err := c.c.GetFamily(unix.NL80211_GENL_NAME)
	//if err != nil {
	//	return nil, err
	//}
	//var mcastScan genetlink.MulticastGroup
	//for _, mcast := range family.Groups {
	//	if mcast.Name == unix.NL80211_MULTICAST_GROUP_SCAN {
	//		mcastScan = mcast
	//	}
	//}
	//if mcastScan.Name != unix.NL80211_MULTICAST_GROUP_SCAN {
	//	return nil, errMissingMulticastGroupScan
	//}

	//err = c.c.JoinGroup(mcastScan.ID)
	//if err != nil {
	//	return nil, err
	//}

	msgs, err := c.get(
		unix.NL80211_CMD_TRIGGER_SCAN,
		netlink.Acknowledge,
		ifi,
		func(ae *netlink.AttributeEncoder) {
			ae.Nested(unix.NL80211_ATTR_SCAN_SSIDS,
				func(nae *netlink.AttributeEncoder) error {
					nae.Bytes(
						unix.NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
						nlenc.Bytes(""),
					)
					return nil
				})
			ae.Bytes(
				unix.NL80211_ATTR_IFINDEX,
				nlenc.Uint32Bytes(uint32(ifi.Index)),
			)
		},
	)
	if err != nil {
		return nil, fmt.Errorf("failed to trigger scheduled scan: %s", err)
	}

	for _, m := range msgs {
		fmt.Println(m)
		//if m.Header.Version != c.familyVersion {
		//	fmt.Println(m.Header.Version)
		//	return nil, errInvalidFamilyVersion
		//}
		if m.Header.Command == unix.NL80211_CMD_ABORT_SCAN {
			return nil, errScanAborted
		}
		if m.Header.Command == unix.NL80211_CMD_NEW_SCAN_RESULTS {
			fmt.Println("ok")
			break
		}
	}

	//err = c.c.LeaveGroup(mcastScan.ID)
	//if err != nil {
	//	return nil, err
	//}

	msgs, err = c.get(unix.NL80211_CMD_GET_SCAN, netlink.Dump, ifi,
		func(ae *netlink.AttributeEncoder) {
			ae.Bytes(
				unix.NL80211_ATTR_IFINDEX,
				nlenc.Uint32Bytes(uint32(ifi.Index)),
			)
		},
	)
	if err != nil {
		return nil, err
	}

	//if err := c.checkMessages(msgs, unix.NL80211_CMD_NEW_SCAN_RESULTS); err != nil {
	//	return nil, err
	//}

	bssm, err := parseBSSMulti(msgs)
	if err != nil {
		return nil, err
	}

	return bssm, nil
}

DAT4 avatar Aug 19 '23 18:08 DAT4

@oldgalileo Do you still work on this?

I am planing to implement something similar (Trigger Scans and more importantly receive all scan results). Can I join into the effort?

lukas-mbag avatar Dec 01 '23 10:12 lukas-mbag

@lukas-mbag this seems to be abandoned long enough that I would go ahead with what you want to work on. You're welcome to cherry-pick changes from this PR if that makes sense.

SuperQ avatar Dec 01 '23 11:12 SuperQ