diff --git a/CHANGES b/CHANGES index d4302dd..777613f 100644 --- a/CHANGES +++ b/CHANGES @@ -97,6 +97,7 @@ v 0.1.4 - covclassget - retryshortget - retrylongget + - ifinfo o modified devadd. User is allowed to submit a Card object or a physical index o removed hardcoded values for covclassset, retry(short|long)set, retsthreshet and fragrthreshset @@ -111,4 +112,6 @@ v 0.1.4 o added new functions from 0.1.3 and 0.1.4 to unittests o updated nl80211_h w/ additional constants included in kernel v 4 header o added propietary concept of set to netlink processing - - nl80211 appears to define a set of like-sized elements (see cipher_suites) \ No newline at end of file + - nl80211 appears to define a set of like-sized elements (see cipher_suites) + o modified pyric exceptions + - imports errno codes into pyric, conforming how functions access error codes \ No newline at end of file diff --git a/README.md b/README.md index 62e4b76..5f21c21 100644 --- a/README.md +++ b/README.md @@ -66,13 +66,12 @@ halved. ATT, PyRIC accomplishes my core needs but it is still a work in progress. It currently pyw provides the following: * enumerate interfaces and wireless interfaces -* identify a cards chipset and driver +* identify a cards driver, chipset and manufacturer * get/set hardware address * get/set ip4 address, netmask and or broadcast * turn card on/off -* get supported standards -* get supported commands -* get supported modes +* get supported standards, commands or modes +* get if info * get dev info * get phy info * get/set regulatory domain @@ -158,8 +157,8 @@ To use PyRIC, see the examples folder or read throuhg PyRIC.pdf. However, for those impatient types: ```python -import pyric # pyric error and EUNDEF error code -from pyric import pyw iw functionality +import pyric # pyric errors +from pyric import pyw # iw functionality ``` will import the basic requirements and unless otherwise stated is assumed for the @@ -170,6 +169,21 @@ that these examples use one-time sockets. Although not all functions require root, we assume that the below have been executed with root permissions. +Before proceeding with the examples, let's talk about pyric error handling. The +pyric module imports the errorcodes found in the errno module as its own. The +pyric error subclasses EnvironmentError and all pyric errors are tuples of the +form t = (error code,error message). + +```python +>>> try: +... #some pyric code +... except pyric.error as e: +... #handle the error +``` + +Work is ongoing to help clarify some of the error messages returned by default +by os.strerror for example. + ### a. System/Wireless Core Functionality These functions do not work with a specific device rather with the system. @@ -298,6 +312,17 @@ and Fragmentation thresholds see http://resources.infosecinstitute.com/rts-thres #### iv. Getting Info On Your Card ```python +>>> iinfo = pyw.ifinfo(w0) +>>> for i in iinfo: print i, iinfo[i] +... +mask 255.255.255.192 +driver iwlwifi +hwaddr a0:88:b4:9e:68:58 +chipset Intel 4965/5xxx/6xxx/1xxx +bcast 192.168.3.63 +inet 192.168.3.7 +manufacturer Intel Corporate +>>> >>> dinfo = pyw.devinfo(w0) >>> for d in dinfo: print d, dinfo[d] ... diff --git a/docs/PyRIC.pdf b/docs/PyRIC.pdf index efde8f2..eeebb3a 100644 Binary files a/docs/PyRIC.pdf and b/docs/PyRIC.pdf differ diff --git a/docs/PyRIC.tex b/docs/PyRIC.tex index 3e093ad..7cd4382 100644 --- a/docs/PyRIC.tex +++ b/docs/PyRIC.tex @@ -464,7 +464,7 @@ \subsubsection{One-time vs Persistent Sockets} \begin{lstlisting}[caption={Using Persistent Sockets}, label={lst:persistent}, language=Python] - 1: import pyric # pyric error (and ecode EUNDEF) + 1: import pyric # pyric errors 2: from pyric import pyw # for iw functionality 3: from pyric.lib import libnl as nl # for netlink sockets 4: @@ -911,7 +911,7 @@ \subsection{Constants} \subsection{Functions} \begin{enumerate} -\item parse([opath]): returns a dict of oui:manufacturer key->value pairs stored +\item load([opath]): returns a dict of oui:manufacturer key->value pairs stored in the text file at opath. If opath is not specified, uses the default \item fetch([opath]): retrieves oui.txt from the IEEE website, parses the files and stores the results in a PyRIC friendly format in opath. If opath is not diff --git a/examples/info.py b/examples/info.py index 7fd0345..5c3eb2e 100644 --- a/examples/info.py +++ b/examples/info.py @@ -6,79 +6,85 @@ """ import argparse as ap +import sys import pyric # pyric error (and ecode EUNDEF) from pyric import pyw # for iw functionality -import pyric.utils.hardware as hw # for chipset/driver -from pyric.utils import ouifetch # for oui dict from pyric.utils.channels import rf2ch # rf to channel conversion -def execute(dev): +def execute(dev,itype): # ensure dev is a wireless interfaces wifaces = pyw.winterfaces() if dev not in wifaces: print "Device {0} is not wireless, use one of {1}".format(dev,wifaces) + # get info dicts dinfo = pyw.devinfo(dev) card = dinfo['card'] pinfo = pyw.phyinfo(card) - driver = hw.ifdriver(card.dev) - chipset = hw.ifchipset(driver) + iinfo = pyw.ifinfo(card) - manuf = hw.manufacturer(ouifetch.parse(),dinfo['mac']) + if itype == 'all' or itype == 'if': + msg = "Interface {0}\n".format(card.idx) + msg += "\tDriver: {0} Chipset: {1}\n".format(iinfo['driver'],iinfo['chipset']) + msg += "\tHW Addr: {0} Manufacturer: {1}\n".format(iinfo['hwaddr'], + iinfo['manufacturer']) + msg += "\tInet: {0} Bcast: {1} Mask: {2}\n".format(iinfo['inet'], + iinfo['bcast'], + iinfo['mask']) + print msg - msg = "Device {0}\n".format(dev) - msg += "\tDriver: {0} Chipset: {1}\n".format(driver,chipset) - msg += "\tManufacturer: {0}\n".format(manuf) - msg += "\tifindex: {0}\n".format(card.idx) - msg += "\twdev: {0}\n".format(dinfo['wdev']) - msg += "\taddr: {0}\n".format(dinfo['mac']) - msg += "\tmode: {0}\n".format(dinfo['mode']) - msg += "\twiphy: {0}\n".format(card.phy) - if dinfo['mode'] == 'managed': - msg += "\tchannel: {0} ({1} MHz), width: {2}, CF: {3}\n".format(rf2ch(dinfo['RF']), - dinfo['RF'], - dinfo['CHW'], - dinfo['CF']) - else: - msg += "\tDevice not associated\n" - print msg + if itype == 'all' or itype == 'dev': + msg = "Device {0}\n".format(card.dev) + msg += "\tifindex: {0}\n".format(card.idx) + msg += "\twdev: {0}\n".format(dinfo['wdev']) + msg += "\taddr: {0}\n".format(dinfo['mac']) + msg += "\tmode: {0}\n".format(dinfo['mode']) + msg += "\twiphy: {0}\n".format(card.phy) + if dinfo['mode'] != 'managed': msg += "\tDevice not associated\n" + else: + msg += "\tchannel: {0} ({1} MHz), width: {2}, CF: {3} MHz\n".format(rf2ch(dinfo['RF']), + dinfo['RF'], + dinfo['CHW'], + dinfo['CF']) + print msg - msg = "Wiphy phy{0}\n".format(card.phy) - msg += "\tGeneration: {0}m Coverage Class: {1}\n".format(pinfo['generation'], - pinfo['cov_class']) - msg += "\tMax # scan SSIDs: {0}\n".format(pinfo['scan_ssids']) - msg += "\tRetry Short: {0}, Long: {1}\n".format(pinfo['retry_short'], - pinfo['retry_long']) - msg += "\tThreshold Frag: {0}, RTS: {1}\n".format(pinfo['frag_thresh'], - pinfo['rts_thresh']) - msg += "\tSupported Modes:\n" - for mode in pinfo['modes']: - msg += "\t * {0}\n".format(mode) - msg += "\tSupported Commands:\n" - for cmd in pinfo['commands']: - msg += "\t * {0}\n".format(cmd) - msg += "\tSupported Frequencies:\n" - for rf in pinfo['freqs']: - msg += "\t * {0} ({1})\n".format(rf,rf2ch(rf)) - #for ch in map(rf2ch,pinfo['freqs']): - # msg += "\t * {0}\n".format(ch) - msg += "\tSupported Ciphers:\n" - for cipher in pinfo['ciphers']: - msg += "\t * {0}\n".format(cipher) + if itype == 'all' or itype == 'phy': + msg = "Wiphy phy{0}\n".format(card.phy) + msg += "\tGeneration: {0}m Coverage Class: {1}\n".format(pinfo['generation'], + pinfo['cov_class']) + msg += "\tMax # scan SSIDs: {0}\n".format(pinfo['scan_ssids']) + msg += "\tRetry Short: {0}, Long: {1}\n".format(pinfo['retry_short'], + pinfo['retry_long']) + msg += "\tThreshold Frag: {0}, RTS: {1}\n".format(pinfo['frag_thresh'], + pinfo['rts_thresh']) + msg += "\tSupported Modes:\n" + for mode in pinfo['modes']: msg += "\t * {0}\n".format(mode) + msg += "\tSupported Commands:\n" + for cmd in pinfo['commands']: msg += "\t * {0}\n".format(cmd) + msg += "\tSupported Frequencies:\n" + for rf in pinfo['freqs']: msg += "\t * {0} ({1})\n".format(rf,rf2ch(rf)) + msg += "\tSupported Ciphers:\n" + for cipher in pinfo['ciphers']: msg += "\t * {0}\n".format(cipher) - print msg + print msg if __name__ == '__main__': # create arg parser and parse command line args print "Wireless Device Info Display using PyRIC v{0}".format(pyric.__version__) argp = ap.ArgumentParser(description="Wireless Device Data") argp.add_argument('-d','--dev',help="Wireless Device") + argp.add_argument('-t','--type',help="Info type one of {all|if|dev|phy}") args = argp.parse_args() try: - dev = args.dev - if dev is None: - print "usage: python details.py -d " - else: - execute(dev) + dname = args.dev + infotype = args.type + if dname is None: + print "usage: python details.py -d [-t ]" + sys.exit(0) + if infotype is None: infotype = 'all' + if infotype not in ['all','if','dev','phy']: + print "usage: python details.py -d [-t one of {all|if|dev|phy}]" + sys.exit(0) + execute(dname,infotype) except pyric.error as e: print e \ No newline at end of file diff --git a/pyric/__init__.py b/pyric/__init__.py index 7b94d95..14cbfcc 100644 --- a/pyric/__init__.py +++ b/pyric/__init__.py @@ -32,6 +32,8 @@ changes: See CHANGES in top-level directory + WARNING: DO NOT import * + """ __name__ = 'pyric' @@ -43,21 +45,29 @@ __email__ = 'wraith.wireless@yandex.com' __status__ = 'Production' -from os import strerror - -# all exceptions are tuples t=(error code,error message) -# we use errno.errocodes and use codes < 0 as an undefined error code -EUNDEF = -1 +# define pyric exceptions +# all exceptions are tuples t=(error code,error message) +# we use error codes defined in errno, adding -1 to define the undefined error +# EUNDEF. I don't like importing all from errno but it provides conformity in +# error handling i.e modules using pyric.error do not need to call pyric.EUNDEF +# and errno.EINVAL but can call pyric.EUNDEF and pyric.EINVAL +EUNDEF = -1 # undefined error +from errno import * # make all errno errors pyric errors +errorcode['EUNDEF'] = -1 # add ours to errorcode dicts class error(EnvironmentError): pass - -def perror(e): - """ - :param e: error code - :returns: string description of error code - """ - # anything less than 0 is an unknown - return strerror(e) - +# BELOW IS STILL A WORK IN PRGORESS +def strerror(errno): + import os + if errno < 0: return "Undefined error" + elif errno == EPERM: return "Superuser privileges required" + elif errno == EINVAL: return "Invalid parameter" + else: + return os.strerror(errno) + +# for setup.py use +# redefine version for easier access +version = __version__ +# define long description long_desc = """ # PyRIC 0.1.4: Python Radio Interface Controller ## Linux wireless library for the Python Wireless Developer and Pentester diff --git a/pyric/net/if_h.py b/pyric/net/if_h.py index baab202..865512b 100644 --- a/pyric/net/if_h.py +++ b/pyric/net/if_h.py @@ -287,6 +287,6 @@ def ifreq(ifrn,ifru=None,param=None): else: raise AttributeError("ifru {0} not supported".format(ifru)) except (TypeError,IndexError): - raise AttributeError("param is invalid") + raise AttributeError("parameters are invalid") return ifr \ No newline at end of file diff --git a/pyric/pyw.py b/pyric/pyw.py index 534f5ef..826cdca 100644 --- a/pyric/pyw.py +++ b/pyric/pyw.py @@ -76,12 +76,12 @@ import struct # ioctl unpacking import pyric # pyric exception -import errno # error codes import re # check addr validity +from pyric.nlhelp.nlsearch import cmdbynum # get command name from pyric.utils import channels # channel related from pyric.utils import rfkill # block/unblock -from pyric.nlhelp.nlsearch import cmdbynum # get command name import pyric.utils.hardware as hw # device related +from pyric.utils import ouifetch # get oui dict import pyric.net.netlink_h as nlh # netlink definition import pyric.net.genetlink_h as genlh # genetlink definition import pyric.net.wireless.nl80211_h as nl80211h # nl80211 definition @@ -163,10 +163,10 @@ def iswireless(dev, *argv): _ = io.io_transfer(iosock, sioch.SIOCGIWNAME, ifh.ifreq(dev)) return True except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except io.error as e: # ENODEV or ENOTSUPP means not wireless, reraise any others - if e.errno == errno.ENODEV or e.errno == errno.EOPNOTSUPP: return False + if e.errno == pyric.ENODEV or e.errno == pyric.EOPNOTSUPP: return False else: raise pyric.error(e.errno, e.strerror) def regget(*argv): @@ -197,7 +197,8 @@ def regset(rd, *argv): :param rd: regulatory domain code :param argv: netlink socket at argv[0] (or empty) """ - if len(rd) != 2: raise pyric.error(errno.EINVAL, "Invalid reg. domain") + if len(rd) != 2: + raise pyric.error(pyric.EINVAL, "Invalid reg. domain {0}".format(rd)) try: nlsock = argv[0] except IndexError: @@ -267,7 +268,7 @@ def validcard(card, *argv): try: return card == devinfo(card.dev, nlsock)['card'] except pyric.error as e: - if e.errno == errno.ENODEV: return False + if e.errno == pyric.ENODEV: return False else: raise ################################################################################ @@ -291,13 +292,12 @@ def macget(card, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(card.dev, flag)) fam = struct.unpack_from(ifh.sa_addr, ret, ifh.IFNAMELEN)[0] if fam in [ifh.ARPHRD_ETHER, ifh.AF_UNSPEC,ifh.ARPHRD_IEEE80211_RADIOTAP]: - #if fam == ifh.ARPHRD_ETHER or fam == ifh.AF_UNSPEC: # confirm hwaddr return _hex2mac_(ret[18:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return hwaddr family {0}".format(fam)) except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -312,7 +312,7 @@ def macset(card, mac, *argv): :param argv: ioctl socket at argv[0] (or empty) :returns: mac address after operation """ - if not _validmac_(mac): raise pyric.error(errno.EINVAL, "Invalid mac address") + if not _validmac_(mac): raise pyric.error(pyric.EINVAL, "Invalid mac address") try: iosock = argv[0] @@ -324,13 +324,13 @@ def macset(card, mac, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(card.dev, flag, [mac])) fam = struct.unpack_from(ifh.sa_addr, ret, ifh.IFNAMELEN)[0] if fam in [ifh.ARPHRD_ETHER, ifh.AF_UNSPEC, ifh.ARPHRD_IEEE80211_RADIOTAP]: - #if fam == ifh.ARPHRD_ETHER or fam == ifh.AF_UNSPEC: # confirm hwaddr return _hex2mac_(ret[18:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return hwaddr family {0}".format(fam)) except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -356,7 +356,7 @@ def inetget(card, *argv): if fam == ifh.AF_INET: ip4 = _hex2ip4_(ret[20:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return ip family {0}".format(fam)) # netmask @@ -366,7 +366,7 @@ def inetget(card, *argv): if fam == ifh.AF_INET: netmask = _hex2ip4_(ret[20:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return netmask family {0}".format(fam)) # broadcast @@ -376,16 +376,16 @@ def inetget(card, *argv): if fam == ifh.AF_INET: brdaddr = _hex2ip4_(ret[20:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return broadcast family {0}".format(fam)) except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: # catch address not available, which means the card currently does not # have any addresses set - raise others - if e.errno == errno.EADDRNOTAVAIL: return None, None, None + if e.errno == pyric.EADDRNOTAVAIL: return None, None, None raise pyric.error(e.errno, e.strerror) return ip4, netmask, brdaddr @@ -413,14 +413,14 @@ def inetset(card, ipaddr, netmask, broadcast, *argv): """ # ensure one of params is set & that all set params are valid ip address if not ipaddr and not netmask and not broadcast: - raise pyric.error(errno.EINVAL, + raise pyric.error(pyric.EINVAL, "One of ipaddr/netmask/broadcast must be set") if ipaddr and not _validip4_(ipaddr): - raise pyric.error(errno.EINVAL, "Invalid ip4 address") + raise pyric.error(pyric.EINVAL, "Invalid ip4 address") if netmask and not _validip4_(netmask): - raise pyric.error(errno.EINVAL, "Invalid netmask") + raise pyric.error(pyric.EINVAL, "Invalid netmask") if broadcast and not _validip4_(broadcast): - raise pyric.error(errno.EINVAL, "Invalid broadcast") + raise pyric.error(pyric.EINVAL, "Invalid broadcast") try: iosock = argv[0] @@ -436,12 +436,12 @@ def inetset(card, ipaddr, netmask, broadcast, *argv): except pyric.error as e: # an ambiguous error is thrown if attempting to set netmask or broadcast # without an ip address already set on the card - if not ipaddr and e.errno == errno.EADDRNOTAVAIL: - raise pyric.error(errno.EINVAL, "Set ip4 addr first") + if not ipaddr and e.errno == pyric.EADDRNOTAVAIL: + raise pyric.error(pyric.EINVAL, "Set ip4 addr first") else: raise except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) @@ -455,7 +455,7 @@ def ip4set(card, ipaddr, *argv): :returns: the new ip address NOTE: setting the ip will set netmask and broadcast accordingly """ - if not _validip4_(ipaddr): raise pyric.error(errno.EINVAL, "Invalid ipaddr") + if not _validip4_(ipaddr): raise pyric.error(pyric.EINVAL, "Invalid ipaddr") try: iosock = argv[0] @@ -469,10 +469,10 @@ def ip4set(card, ipaddr, *argv): if fam == ifh.AF_INET: return _hex2ip4_(ipaddr) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return ip family {0}".format(fam)) except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -489,7 +489,7 @@ def netmaskset(card, netmask, *argv): NOTE: 1) throws error if netmask is set and card does not have an ip assigned """ - if not _validip4_(netmask): raise pyric.error(errno.EINVAL, "Invalid netmask") + if not _validip4_(netmask): raise pyric.error(pyric.EINVAL, "Invalid netmask") try: iosock = argv[0] except IndexError: @@ -502,17 +502,17 @@ def netmaskset(card, netmask, *argv): if fam == ifh.AF_INET: return _hex2ip4_(ret[20:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return netmask family {0}".format(fam)) except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: # an ambiguous error is thrown if attempting to set netmask or broadcast # without an ip address already set on the card - if e.errno == errno.EADDRNOTAVAIL: - raise pyric.error(errno.EINVAL, "Cannot set netmask. Set ip first") + if e.errno == pyric.EADDRNOTAVAIL: + raise pyric.error(pyric.EINVAL, "Cannot set netmask. Set ip first") else: raise pyric.error(e, e.strerror) @@ -529,7 +529,7 @@ def broadcastset(card, broadcast, *argv): 2) can set broadcast to erroneous values i.e. ipaddr = 192.168.1.2 and broadcast = 10.0.0.31. """ - if not _validip4_(broadcast): raise pyric.error(errno.EINVAL, "Invalid bcast") + if not _validip4_(broadcast): raise pyric.error(pyric.EINVAL, "Invalid bcast") try: iosock = argv[0] @@ -544,24 +544,24 @@ def broadcastset(card, broadcast, *argv): if fam == ifh.AF_INET: return _hex2ip4_(ret[20:24]) else: - raise pyric.error(errno.EAFNOSUPPORT, + raise pyric.error(pyric.EAFNOSUPPORT, "Invalid return broadcast family {0}".format(fam)) except pyric.error as e: # an ambiguous error is thrown if attempting to set netmask or broadcast # without an ip address already set on the card - if e.errno == errno.EADDRNOTAVAIL: - raise pyric.error(errno.EINVAL, "Cannot set broadcast. Set ip first") + if e.errno == pyric.EADDRNOTAVAIL: + raise pyric.error(pyric.EINVAL, "Cannot set broadcast. Set ip first") else: raise except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: # an ambiguous error is thrown if attempting to set netmask or broadcast # without an ip address already set on the card - if e.errno == errno.EADDRNOTAVAIL: - raise pyric.error(errno.EINVAL, "Cannot set broadcast. Set ip first") + if e.errno == pyric.EADDRNOTAVAIL: + raise pyric.error(pyric.EINVAL, "Cannot set broadcast. Set ip first") else: raise pyric.error(e, e.strerror) @@ -584,7 +584,7 @@ def isup(card, *argv): try: return _issetf_(_flagsget_(card.dev, iosock), ifh.IFF_UP) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") def up(card, *argv): """ @@ -603,7 +603,7 @@ def up(card, *argv): if not _issetf_(flags, ifh.IFF_UP): _flagsset_(card.dev, _setf_(flags, ifh.IFF_UP), iosock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") def down(card, *argv): """ @@ -622,7 +622,7 @@ def down(card, *argv): if _issetf_(flags, ifh.IFF_UP): _flagsset_(card.dev, _unsetf_(flags, ifh.IFF_UP), iosock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") def isblocked(card): """ @@ -635,7 +635,7 @@ def isblocked(card): idx = rfkill.getidx(card.phy) return rfkill.soft_blocked(idx), rfkill.hard_blocked(idx) except AttributeError: - raise pyric.error(errno.ENODEV, "Device is no longer regsitered") + raise pyric.error(pyric.ENODEV, "Device is no longer regsitered") def block(card): """ @@ -646,7 +646,7 @@ def block(card): idx = rfkill.getidx(card.phy) rfkill.rfkill_block(idx) except AttributeError: - raise pyric.error(errno.ENODEV, "Device no longer registered") + raise pyric.error(pyric.ENODEV, "Device no longer registered") def unblock(card): """ @@ -657,7 +657,7 @@ def unblock(card): idx = rfkill.getidx(card.phy) rfkill.rfkill_unblock(idx) except AttributeError: - raise pyric.error(errno.ENODEV, "Device no longer registered") + raise pyric.error(pyric.ENODEV, "Device no longer registered") ################################################################################ #### RADIO PROPERTIES #### @@ -683,7 +683,7 @@ def pwrsaveget(card, *argv): nl.nl_sendmsg(nlsock, msg) rmsg = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -712,9 +712,9 @@ def pwrsaveset(card, on, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except ValueError: - raise pyric.error(errno.EINVAL, "Invalid parameter on") + raise pyric.error(pyric.EINVAL, "Invalid parameter on") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -747,7 +747,7 @@ def covclassset(card, cc, *argv): # this can work 'incorrectly' on non-int values but these will # be caught later during conversion msg = "Coverage class must be integer {0} - {1}" - raise pyric.error(errno.EINVAL, msg.format(wlan.COVERAGE_CLASS_MIN, + raise pyric.error(pyric.EINVAL, msg.format(wlan.COVERAGE_CLASS_MIN, wlan.COVERAGE_CLASS_MAX)) try: @@ -764,9 +764,9 @@ def covclassset(card, cc, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except ValueError: - raise pyric.error(errno.EINVAL, "Invalid parameter value for cc") + raise pyric.error(pyric.EINVAL, "Invalid parameter value for cc") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -798,7 +798,7 @@ def retryshortset(card, lim, *argv): # be caught later during conversion msg = "Retry short must be integer {0} - {1}".format(wlan.RETRY_MIN, wlan.RETRY_MAX) - raise pyric.error(errno.EINVAL, msg) + raise pyric.error(pyric.EINVAL, msg) try: nlsock = argv[0] @@ -814,9 +814,9 @@ def retryshortset(card, lim, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except ValueError: - raise pyric.error(errno.EINVAL, "Invalid parameter value for lim") + raise pyric.error(pyric.EINVAL, "Invalid parameter value for lim") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -847,7 +847,7 @@ def retrylongset(card, lim, *argv): # this can work 'incorrectly' on non-int values but these will # be caught later during conversion msg = "Retry long must be integer {0} - {1}" - raise pyric.error(errno.EINVAL, msg.format(wlan.RETRY_MIN, wlan.RETRY_MAX)) + raise pyric.error(pyric.EINVAL, msg.format(wlan.RETRY_MIN, wlan.RETRY_MAX)) try: nlsock = argv[0] @@ -863,9 +863,9 @@ def retrylongset(card, lim, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except ValueError: - raise pyric.error(errno.EINVAL, "Invalid parameter value for lim") + raise pyric.error(pyric.EINVAL, "Invalid parameter value for lim") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -897,7 +897,7 @@ def rtsthreshset(card, thresh, *argv): elif thresh == wlan.RTS_THRESHOLD_OFF: pass elif thresh < wlan.RTS_THRESHOLD_MIN or thresh > wlan.RTS_THRESHOLD_MAX: msg = "Threshold must be 'off' or integer {0} - {1}" - raise pyric.error(errno.EINVAL, msg.format(wlan.RTS_THRESHOLD_MIN, + raise pyric.error(pyric.EINVAL, msg.format(wlan.RTS_THRESHOLD_MIN, wlan.RTS_THRESHOLD_MAX)) try: @@ -914,9 +914,9 @@ def rtsthreshset(card, thresh, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except ValueError: - raise pyric.error(errno.EINVAL, "Invalid parameter value for thresh") + raise pyric.error(pyric.EINVAL, "Invalid parameter value for thresh") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -948,7 +948,7 @@ def fragthreshset(card, thresh, *argv): elif thresh == wlan.FRAG_THRESHOLD_OFF: pass elif thresh < wlan.FRAG_THRESHOLD_MIN or thresh > wlan.FRAG_THRESHOLD_MAX: msg = "Threshold must be 'off' or an integer {0} - {1}" - raise pyric.error(errno.EINVAL, msg.format(wlan.FRAG_THRESHOLD_MIN, + raise pyric.error(pyric.EINVAL, msg.format(wlan.FRAG_THRESHOLD_MIN, wlan.FRAG_THRESHOLD_MAX)) try: @@ -965,7 +965,7 @@ def fragthreshset(card, thresh, *argv): nl.nl_sendmsg(nlsock, msg) _ = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1021,7 +1021,7 @@ def devstds(card, *argv): stds = stds.replace('IEEE 802.11', '') # remove IEEE 802.11 return [std for std in stds] except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except IndexError: return None except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) @@ -1056,6 +1056,45 @@ def devcmds(card, *argv): return phyinfo(card, nlsock)['commands'] +def ifinfo(card, *argv): + """ + get info for interface (ifconfig ) + :param card: Card object + :param argv: ioctl socket at argv[0] (or empty) + :returns: dict with the following key:value pairs + driver -> card's driver + chipset -> card's chipset + manufacturer -> card's manufacturer + hwaddr -> card's mac address + inet -> card's inet address + bcast -> card's broadcast address + mask -> card's netmask address + """ + try: + iosock = argv[0] + except IndexError: + return _iostub_(ifinfo, card) + + # get oui dict + ouis = {} + try: + ouis = ouifetch.load() + except pyric.error: + pass + + try: + drvr, chips = hw.ifcard(card.dev) + mac = macget(card, iosock) + ip4, nmask, bcast = inetget(card, iosock) + info = {'driver':drvr, 'chipset':chips, + 'hwaddr':mac, 'manufacturer':hw.manufacturer(ouis,mac), + 'inet':ip4, 'bcast':bcast, 'mask':nmask} + #except pyric.error # allow pyric errors to fall through + except AttributeError: + raise pyric.error(pyric.EINVAL, "Invalid Card object") + + return info + def devinfo(card, *argv): """ get info for device (iw dev info) @@ -1142,7 +1181,7 @@ def phyinfo(card, *argv): nl.nl_sendmsg(nlsock, msg) rmsg = nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1211,10 +1250,10 @@ def txset(card, setting, lvl, *argv): """ # sanity check on power setting and power level if not setting in TXPWRSETTINGS: - raise pyric.error(errno.EINVAL, "Invalid power setting {0}".format(setting)) + raise pyric.error(pyric.EINVAL, "Invalid power setting {0}".format(setting)) if setting != 'auto': if lvl is None: - raise pyric.error(errno.EINVAL, "Power level must be specified") + raise pyric.error(pyric.EINVAL, "Power level must be specified") try: nlsock = argv[0] @@ -1236,9 +1275,9 @@ def txset(card, setting, lvl, *argv): nl.nl_recvmsg(nlsock) except ValueError: # only relevent when converting to mbm - raise pyric.error(errno.EINVAL, "Invalid txpwr {0}".format(lvl)) + raise pyric.error(pyric.EINVAL, "Invalid txpwr {0}".format(lvl)) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1261,7 +1300,7 @@ def txget(card, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(card.dev, flag)) return struct.unpack_from(ifh.ifr_iwtxpwr, ret, ifh.IFNAMELEN)[0] except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except IndexError: return None except struct.error as e: @@ -1300,7 +1339,7 @@ def chset(card, ch, chw=None, *argv): deleting all other existing managed interfaces allows for the new virtual device's channels to be changed """ - if ch not in channels.channels(): raise pyric.error(errno.EINVAL, "Invalid channel") + if ch not in channels.channels(): raise pyric.error(pyric.EINVAL, "Invalid channel") try: nlsock = argv[0] @@ -1318,9 +1357,9 @@ def freqset(card, rf, chw=None, *argv): :param chw: channel width oneof {[None|'HT20'|'HT40-'|'HT40+'} :param argv: netlink socket at argv[0] (or empty) """ - if rf not in channels.freqs(): raise pyric.error(errno.EINVAL, "Invalid frequency") + if rf not in channels.freqs(): raise pyric.error(pyric.EINVAL, "Invalid RF") if chw in channels.CHTYPES: chw = channels.CHTYPES.index(chw) - else: raise pyric.error(errno.EINVAL, "Invalid width") + else: raise pyric.error(pyric.EINVAL, "Invalid width") try: nlsock = argv[0] @@ -1337,7 +1376,7 @@ def freqset(card, rf, chw=None, *argv): nl.nl_sendmsg(nlsock, msg) nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL,"Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1370,13 +1409,13 @@ def modeset(card, mode, flags=None, *argv): to monitor mode) :param argv: netlink socket at argv[0] (or empty) """ - if mode not in IFTYPES: raise pyric.error(errno.EINVAL, 'Invalid mode') + if mode not in IFTYPES: raise pyric.error(pyric.EINVAL, 'Invalid mode') if flags: if mode != 'monitor': - raise pyric.error(errno.EINVAL, 'Can only set flags in monitor mode') + raise pyric.error(pyric.EINVAL, 'Can only set flags in monitor mode') for flag in flags: if flag not in MNTRFLAGS: - raise pyric.error(errno.EINVAL, 'Invalid flag: {0}'.format(flag)) + raise pyric.error(pyric.EINVAL, 'Invalid flag: {0}'.format(flag)) else: flags = [] try: @@ -1397,7 +1436,7 @@ def modeset(card, mode, flags=None, *argv): nl.nl_sendmsg(nlsock, msg) nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1421,7 +1460,7 @@ def ifaces(card, *argv): if info['card'].phy == card.phy: ifs.append((info['card'], info['mode'])) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) return ifs @@ -1441,13 +1480,13 @@ def devadd(card, vdev, mode, flags=None, *argv): :param argv: netlink socket at argv[0] (or empty) :returns: the new Card """ - if mode not in IFTYPES: raise pyric.error(errno.EINVAL, 'Invalid mode') + if mode not in IFTYPES: raise pyric.error(pyric.EINVAL, 'Invalid mode') if flags: if mode != 'monitor': - raise pyric.error(errno.EINVAL, 'Can only set flags in monitor mode') + raise pyric.error(pyric.EINVAL, 'Can only set flags in monitor mode') for flag in flags: if flag not in MNTRFLAGS: - raise pyric.error(errno.EINVAL, 'Invalid flag: {0}'.format(flag)) + raise pyric.error(pyric.EINVAL, 'Invalid flag: {0}'.format(flag)) else: flags = [] try: @@ -1475,7 +1514,7 @@ def devadd(card, vdev, mode, flags=None, *argv): nl.nl_sendmsg(nlsock, msg) rmsg = nl.nl_recvmsg(nlsock) # success returns new device attributes except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1503,7 +1542,7 @@ def devdel(card, *argv): nl.nl_sendmsg(nlsock, msg) nl.nl_recvmsg(nlsock) except AttributeError: - raise pyric.error(errno.EINVAL, "Invalid Card object") + raise pyric.error(pyric.EINVAL, "Invalid Card object") except nl.error as e: raise pyric.error(e.errno, e.strerror) @@ -1590,7 +1629,7 @@ def _flagsget_(dev, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(dev, flag)) return struct.unpack_from(ifh.ifr_flags, ret, ifh.IFNAMELEN)[0] except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -1614,7 +1653,7 @@ def _flagsset_(dev, flags, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(dev, flag, [flags])) return struct.unpack_from(ifh.ifr_flags, ret, ifh.IFNAMELEN)[0] except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -1703,7 +1742,7 @@ def _ifindex_(dev, *argv): ret = io.io_transfer(iosock, flag, ifh.ifreq(dev, flag)) return struct.unpack_from(ifh.ifr_ifindex, ret, ifh.IFNAMELEN)[0] except AttributeError as e: - raise pyric.error(errno.EINVAL, e) + raise pyric.error(pyric.EINVAL, e) except struct.error as e: raise pyric.error(pyric.EUNDEF, "Error parsing results: {0}".format(e)) except io.error as e: @@ -1785,8 +1824,8 @@ def _fut_chset(card, ch, chw, *argv): uses *_SET_WIPHY however, ATT does not work raise Errno 22 Invalid Argument NOTE: This only works for cards in monitor mode """ - if ch not in channels.channels(): raise pyric.error(errno.EINVAL, "Invalid channel") - if chw not in channels.CHTYPES: raise pyric.error(errno.EINVAL, "Invalid channel width") + if ch not in channels.channels(): raise pyric.error(pyric.EINVAL, "Invalid channel") + if chw not in channels.CHTYPES: raise pyric.error(pyric.EINVAL, "Invalid channel width") try: nlsock = argv[0] except IndexError: diff --git a/pyric/utils/hardware.py b/pyric/utils/hardware.py index 8c1dca5..f68777a 100644 --- a/pyric/utils/hardware.py +++ b/pyric/utils/hardware.py @@ -84,7 +84,7 @@ def ifcard(dev): :returns: tuple t = (driver,chipset) """ driver = ifdriver(dev) - return driver, ifchipset(driver) + return driver,ifchipset(driver) def ifdriver(dev): """ diff --git a/pyric/utils/ouifetch.py b/pyric/utils/ouifetch.py index 23defd3..d801822 100644 --- a/pyric/utils/ouifetch.py +++ b/pyric/utils/ouifetch.py @@ -40,7 +40,7 @@ OUIURL = 'http://standards-oui.ieee.org/oui.txt' OUIPATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),'data/oui.txt') -def parse(opath=None): +def load(opath=None): """ parse oui.txt file :param opath: path of oui text file diff --git a/setup.py b/setup.py index 47ac11b..75f21ed 100644 --- a/setup.py +++ b/setup.py @@ -35,11 +35,11 @@ import pyric setup(name='PyRIC', - version=pyric.__version__, + version=pyric.version, description="Python Wireless Library", long_description=pyric.long_desc, url='http://wraith-wireless.github.io/pyric', - download_url="https://github.com/wraith-wireless/pyric/archive/"+pyric.__version__+".tar.gz", + download_url="https://github.com/wraith-wireless/pyric/archive/"+pyric.version+".tar.gz", author=pyric.__author__, author_email=pyric.__email__, maintainer=pyric.__maintainer__,