Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface Combinations #48

Open
fnoop opened this issue May 22, 2019 · 0 comments
Open

Interface Combinations #48

fnoop opened this issue May 22, 2019 · 0 comments

Comments

@fnoop
Copy link

fnoop commented May 22, 2019

There doesn't appear to be any way to extract interface combinations, crucial info to create virtual interfaces.

iw list returns (this is for a raspberry pi 3):

	valid interface combinations:
		 * #{ managed } <= 1, #{ P2P-device } <= 1, #{ P2P-client, P2P-GO } <= 1,
		   total <= 3, #channels <= 2
		 * #{ managed } <= 1, #{ AP } <= 1, #{ P2P-client } <= 1, #{ P2P-device } <= 1,
		   total <= 4, #channels <= 1

phyinfo() doesn't return this info. With a bit of wrangling it's possible like this:

import pyric
import pyric.pyw as pyw

import pyric.net.wireless.nl80211_h as nl80211h # nl80211 definition
import pyric.lib.libnl as nl                    # netlink (library) functions
import pyric.net.netlink_h as nlh               # netlink definition

def parse_combinations(cs):
    _combinations = []
    try:
       for _, combo in nl.nla_parse_nested(cs.encode()):
            _combodata = {'limits': []}
            for combofield, combovalue in nl.nla_parse_nested(combo):
                if combofield == nl80211h.NL80211_IFACE_COMB_MAXNUM:
                    _combodata['max'] = struct.unpack_from('I', combovalue, 0)[0]
                if combofield == nl80211h.NL80211_IFACE_COMB_NUM_CHANNELS:
                    _combodata['channels'] = struct.unpack_from('I', combovalue, 0)[0]
                if combofield == nl80211h.NL80211_IFACE_COMB_LIMITS:
                    for combo_option in nl.nla_parse_nested(combovalue):
                        combo_option_unpacked = nl.nla_parse_nested(combo_option[1])
                        for combo_option_fragment in combo_option_unpacked:
                            if combo_option_fragment[0] == 1:
                                option_max = struct.unpack_from('I', combo_option_fragment[1], 0)[0]
                            if combo_option_fragment[0] == 2:
                                option_types = [nl80211h.NL80211_IFTYPES[x[0]] for x in nl.nla_parse_nested(combo_option_fragment[1])]
                        _combodata['limits'].append((option_max, option_types))
            _combinations.append(_combodata)
    except Exception as e:
        print("Error: {}".format(repr(e)))
    return _combinations

def combinations(interface):
    card = pyw.getcard(interface)
    nlsock = None
    try:
        # Open netlink socket
        nlsock = nl.nl_socket_alloc(timeout=2)
        try:
            # Request physical device info through netlink
            msg = nl.nlmsg_new(nltype=pyw._familyid_(nlsock),
                               cmd=nl80211h.NL80211_CMD_GET_WIPHY,
                               flags=nlh.NLM_F_REQUEST | nlh.NLM_F_ACK)
            nl.nla_put_u32(msg, card.phy, nl80211h.NL80211_ATTR_WIPHY)
            nl.nl_sendmsg(nlsock, msg)
            rmsg = nl.nl_recvmsg(nlsock)
            # Parse the response and extract supported interface combinations
            _, cs, d = nl.nla_find(rmsg, nl80211h.NL80211_ATTR_INTERFACE_COMBINATIONS, False)
            if d != nlh.NLA_ERROR: return parse_combinations(cs)
            else: return None
        except AttributeError:
            raise pyric.error(pyric.EINVAL, "Invalid Card")
        except nl.error as e:
            raise pyric.error(e.errno, e.strerror)
    except nl.error as e:
        raise pyric.error(e.errno, pyric.strerror(e.errno))
    except pyric.error:
        raise
    finally:
        if nlsock: nl.nl_socket_free(nlsock)

PR to come to add this to phyinfo()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant