Exemple #1
0
    def test_lookup_genl_family(self, socket_mock):
        sock = socket_mock.return_value

        msg = get_genl_message(
            nla_u16(CTRL_ATTR_FAMILY_ID, 123) +
            nla(CTRL_ATTR_MCAST_GROUPS,
                nla(1,
                    nla_str(CTRL_ATTR_MCAST_GRP_NAME, "foo") +
                    nla_u32(CTRL_ATTR_MCAST_GRP_ID, 1)) +
                nla(2,
                    nla_str(CTRL_ATTR_MCAST_GRP_NAME, "bar") +
                    nla_u32(CTRL_ATTR_MCAST_GRP_ID, 2))))

        sock.recv.side_effect = [msg]

        family = lookup_genl_family("dummy_family")

        [msg] = sock.get_sent_messages()
        assert_bufs_equal(
            msg,
            get_genl_message(
                mtype=GENL_ID_CTRL,
                flags=NLM_F_REQUEST,
                cmd=CTRL_CMD_GETFAMILY,
                version=GNL_FAMILY_VERSION,
                payload=nla_str(CTRL_ATTR_FAMILY_NAME, "dummy_family")))

        self.assertEqual(family, GenlFamilyInfo(123, {"foo": 1, "bar": 2}))
Exemple #2
0
def main():
    parser = ArgumentParser(description=__doc__)
    parser.add_argument("command", help="Name of nl80211 command to call")
    parser.add_argument("params", help="JSON string with command params")
    args = parser.parse_args()

    family = lookup_genl_family("nl80211")

    sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, NETLINK_GENERIC)
    sock.bind((0, 0))

    msg = get_genl_message(mtype=family.id,
                           flags=NLM_F_REQUEST,
                           cmd=nl80211_constants[args.command],
                           payload=nl80211_schema.build(json.loads(
                               args.params)))
    sock.send(msg)

    msg = sock.recv(8192)
    nl_header, nl_payload = parse_nl_message(msg)
    if nl_header.mtype == NLMSG_ERROR:
        raise RuntimeError("Error {} from command".format(
            parse_nl_error(nl_payload)))

    nl_header, genl_header, payload = parse_genl_message(msg)
    print(
        json.dumps(nl80211_schema.parse(payload), cls=MyJsonEncoder, indent=4))
Exemple #3
0
def main():
    # We need to look up the family ID which will go in the nl header's type
    # field. This also gives us the IDs we'd need to subscribe the socket to any
    # broadcast groups exposed by the family.
    family = lookup_genl_family("nl80211")

    sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, NETLINK_GENERIC)
    sock.bind((0, 0))

    # We use get_genl_message to build a Generic Netlink message. The nl80211
    # command goes in the cmd field of the genl header.
    # The payload is built using the canned nl0211 schema, using kwargs to
    # specify the attribute values used to express command params.
    # We could instead pass a dict, in which case we'd use the full attribute
    # names instead of shortened Pythonic names, e.g. instead of ifindex=foo
    # we could pass {"NL80211_ATTR_IFINDEX": foo}.
    msg = get_genl_message(
        mtype=family.id,
        flags=NLM_F_REQUEST,
        cmd=NL80211_CMD_GET_INTERFACE,
        payload=nl80211_schema.build(ifindex=if_nametoindex(argv[1])))
    sock.send(msg)

    # Note the fixed size receive. This library lacks support for multi-part
    # messages.
    msg = sock.recv(8192)
    # Parse out the nl and genl header
    nl_header, genl_header, payload = parse_genl_message(msg)
    # Now we use the same canned schema to parse then attributes in the reply
    # payload
    info = nl80211_schema.parse(payload)

    # The attributes can be accessed like a dict; in this case the keys are the
    # full attribute names. For exmple if your WiFi is connected to a network ,
    # these prints will include a line something like:
    #   NL80211_ATTR_SSID = Darude-LANStorm
    print("Raw data:")
    for key in info:
        print("  {} = {}".format(key, info[key]))

    # Then for convenience we can also access the attributes as Python
    # attributes using nicer names. The nl80211 schema (see nl80211.py) doesn't
    # specify the names for the Python attributes, so we get the default
    # behaviour, which is that the Python names are determined by finding the
    # full name's unique suffix amongst its siblings and lower-casing it.
    # So instead of info["NL80211_ATTR_SSID"] we can just access info.ssid.
    print("\nname: '{}' | MAC: {} | Current SSID: '{}'".format(
        info.ifname, ":".join("{:02x}".format(b) for b in info.mac),
        info.ssid))
def do_nl80211_query(sock, cmd, **kwargs):
    """Call an nl80211 cmd (with **kwargs) and return the parsed response"""
    # We use get_genl_message to build a Generic Netlink message. The nl80211
    # command goes in the cmd field of the genl header.
    # The payload is built using the canned nl0211 schema, using kwargs to
    # specify the attribute values used to express command params.
    msg = get_genl_message(mtype=nl80211_family.id,
                           flags=NLM_F_REQUEST,
                           cmd=cmd,
                           payload=nl80211_schema.build(**kwargs))
    sock.send(msg)

    msg = sock.recv(8192)
    nl_header, genl_header, payload = parse_genl_message(msg)
    return nl80211_schema.parse(payload)