#!/usr/bin/env python """ nlhelp.py: nl80211 help functions Copyright (C) 2016 Dale V. Patterson (wraith.wireless@yandex.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Redistribution and use in source and binary forms, with or without modifications, are permitted provided that the following conditions are met: o Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. o Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. o Neither the name of the orginal author Dale V. Patterson nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. A set of functions to assist in finding info on nl80211 commands and attributes. These are stored in the "data" files commands.help and attributes.help which are json files. """ __name__ = 'nlhelp' __license__ = 'GPLv3' __version__ = '0.0.1' __date__ = 'August 2014' __author__ = 'Dale Patterson' __maintainer__ = 'Dale Patterson' __email__ = 'wraith.wireless@yandex.com' __status__ = 'Production' import os import json import pyric import pyric.net.wireless.nl80211_h as nl80211h # get current working directory fpath = os.path.dirname(os.path.realpath(__file__)) # read in the files here cmdpath = os.path.join(fpath,'commands.help') commands = None # cmd -> desc,attributes used dict cmdlookup = None # reverse lookup for command constants cin = None try: # first three lines are comments, 4th line is empty cin = open(cmdpath,'r') for _ in range(4): _in = cin.readline() commands = json.loads(cin.readline()) cmdlookup = json.loads(cin.readline()) except: raise pyric.error(pyric.EUNDEF,"Failed to process commands.help") finally: if cin: cin.close() attrpath = os.path.join(fpath,'attributes.help') attributes = None # attr -> desc, commands used by, datatype attrlookup = None # reverse lookup for attribute constants ain = None try: # first three lines are comments, 3th line is empty ain = open(attrpath,'r') for _ in range(4): _in = ain.readline() attributes = json.loads(ain.readline()) attrlookup = json.loads(ain.readline()) except: raise pyric.error(pyric.EUNDEF, "Failed to process attributes.help") finally: if ain: ain.close() def command(cmd): """ shows help on command can either be the full name i.e. NL80211_CMD_GET_WIPHY or a shortened version GET_WIPHY :param cmd: command to show description of. :returns: description of command, attributes used in command and the constant that refers to the command """ try: cmd = cmd.upper().replace('@','') # in the event it comes from cmdbynum if not cmd.startswith("NL80211_CMD_"): cmd = "@NL80211_CMD_" + cmd else: cmd = '@' + cmd entry = commands[cmd] attrs = ", ".join([attr.replace('%','') for attr in entry['attrs']]) out = "{0}\tValue={1}\n".format(cmd,eval('nl80211h.' + cmd[1:])) out += "------------------------------------------------------\n" out += "Description: {0}\n".format(entry['desc']) out += "------------------------------------------------------\n" out += "Attributes: {0}".format(attrs) return out except KeyError: return "No entry found for command {0}".format(cmd) except AttributeError: return "{0} not found in nl80211_h".format(cmd) def cmdbynum(n): """ reverse lookup n to corresponding command variable :param n: integer value to search for :returns: string representation of the command variable corresponding to n """ return cmdlookup[str(n)] def attribute(attr): """ shows help on attribute can either be the full name i.e. NL80211_ATTR_MAC or a shortened version MAC :param attr: attribute to show description of. :returns: description of attribute, commands that use the attribute, datatype of the attribute and the constant that refers to the attribute """ try: attr = attr.upper().replace('@','') # in the event it comes from attrbynum if not attr.startswith("NL80211_ATTR_"): attr = "@NL80211_ATTR_" + attr else: attr = '@' + attr entry = attributes[attr] cmds = ", ".join([cmd.replace('%', '') for cmd in entry['cmds']]) out = "{0}\tValue={1}\tDatatype={2}\n".format(attr, eval('nl80211h.' + attr[1:]), entry['type']) out += "------------------------------------------------------\n" out += "Description: {0}\n".format(entry['desc']) out += "------------------------------------------------------\n" out += "Commands: {0}".format(cmds) return out except KeyError: return "No entry found for attribute {0}".format(attr) except AttributeError: return "{0} not found in nl80211_h".format(attr) def attrbynum(n): """ reverse lookup n to corresponding attribute variable :param n: integer value to search for :returns: string representation of the command variable corresponding to n """ return attrlookup[str(n)][0] def search(tkn): """ searches for and returns any commands,attributes with tkn :param tkn: :returns: a list of commands,attributes with tkn in them """ tkn = tkn.upper() if len(tkn) < 3: raise pyric.error(pyric.EUNDEF,"{0} is to ambiguous".format(tkn)) found = [cmd for cmd in commands if tkn in cmd] found += [attr for attr in attributes if tkn in attr] return found