コード例 #1
0
 def run(self):
     """ switch channels based on associted dwell times """
     while not self._done.is_set():
         # wait on connection for channel's dwell time. If no token, switch
         # to next channel. If token & it is a hold, block on the connection
         # until we get another token (assumes dyskt will not send consecutive
         # holds) which should be a resme or stop
         if self._tC.poll(self._ds[self._i]):
             token = self._tC.recv()
             if token == '!STOP!':
                 self._eQ.put(('!STOP!',time.time(),' '))
             elif token == '!HOLD!':
                 self._eQ.put(('!HOLD!',time.time(),' '))
                 token = self._tC.recv()
                 if token == '!RESUME!':
                     self._eQ.put(('!RESUME!',time.time(),' '))
                 elif token == '!STOP!':
                     self._eQ.put(('!STOP!',time.time(),' '))
         else:
             # no token, go to next channel
             try:
                 self._i = (self._i+1) % len(self._chs)
                 iw.chset(self._vnic,
                          str(self._chs[self._i][0]),
                          self._chs[self._i][1])
             except iw.IWException as e:
                 # iw related exception, set event token and stop execution
                 self._eQ.put(('!FAIL!',time.time(),e))
             except Exception as e:
                 # catch all
                 self._eQ.put(('!FAIL!',time.time(),e))
コード例 #2
0
ファイル: rdoctl.py プロジェクト: sh1nu11bi/wraith
    def run(self):
        """ switch channels based on associted dwell times """
        # starting paused or scanning?
        if self._state == TUNE_PAUSE:
            # notify rdoctl we are paused then hold on dyskt token q
            self._qR.put(('!PAUSE!',time.time(),(-1,' ')))
            self._conn.poll(None)
        else:
            self._qR.put(('!SCAN!',time.time(),(-1,self._chs)))

        # execution loop
        # wait on the internal connection for each channels dwell time.  IOT
        # avoid a state where we would continue to scan the same channel, i.e.
        # receiving repeated state commands, use a remaining time counter
        remaining = 0
        while not self._done.is_set():
            # set the dwell time to remaining if we need to finish this scan
            dwell = self._ds[self._i] if not remaining else remaining

            ts1 = time.time() # mark time
            if self._conn.poll(dwell):
                # get token and timestamp
                tkn = self._conn.recv()
                ts = time.time()

                # tokens will have 2 flavor's '!STOP!' and 'cmd:cmdid:params'
                # where params is empty or a '-' separated list
                if tkn == '!STOP!': self._qR.put(('!STOP!',ts,(-1,' ')))
                else:
                    # calculate time remaining for this channel
                    remaining = self._ds[self._i] - (ts-ts1)

                    # parse the requested command
                    try:
                        cmd,cid,ps = tkn.split(':') # force into 3 components
                        cid = int(cid)
                    except: # should never happen but just in case
                        self._qR.put(('!ERR!',ts,(-1,"invalid command format")))
                    else:
                        # for hold, pause & listen, notify rdoctl & then block
                        # on DySKT until we get another token (assumes DySKT wont
                        # send consecutive holds etc)
                        if cmd == 'state':
                            self._qR.put(('!STATE!',ts,(cid,TUNE_DESC[self._state])))
                            continue
                        elif cmd == 'scan':
                            if self._state != TUNE_SCAN:
                                self._state = TUNE_SCAN
                                self._qR.put(('!SCAN!',ts,(cid,self._chs)))
                                continue
                            else:
                                self._qR.put(('!ERR!',ts,(cid,'redundant command')))
                        elif cmd == 'txpwr': pass
                        elif cmd == 'spoof': pass
                        elif cmd == 'hold':
                            if self._state != TUNE_HOLD:
                                self._state = TUNE_HOLD
                                self._qR.put(('!HOLD!',ts,(cid,self.currch)))
                                self._conn.poll(None) # block until a new token
                                continue
                            else:
                                self._qR.put(('!ERR!',ts,(cid,'redundant command')))
                        elif cmd == 'pause':
                            if self._state != TUNE_PAUSE:
                                self._state = TUNE_PAUSE
                                self._qR.put(('!PAUSE!',ts,(cid,' ')))
                                self._conn.poll(None) # block until a new token
                                continue
                            else:
                                self._qR.put(('!ERR!',ts,(cid,'redundant command')))
                        elif cmd == 'listen':
                            # for listen, we ignore reduandacies as some other
                            # (external) process may have changed the channel
                            try:
                                ch,chw = ps.split('-')
                                iw.chset(self._vnic,ch,chw)
                                self._state = TUNE_LISTEN
                                self._qR.put(('!LISTEN',ts,(cid,"%s:%s" % (ch,chw))))
                                self._conn.poll(None) # block until a new token
                                continue
                            except ValueError:
                                self._qR.put(('!ERR!',ts,(cid,'invalid param format')))
                            except iw.IWException as e:
                                self._qR.put(('!ERR',ts,(cid,e)))
                        else:
                            self._qR.put(('!ERR!',ts,(cid,"invalid command %s" % cmd)))
            else:
                # no token, go to next channel
                try:
                    self._i = (self._i+1) % len(self._chs)
                    iw.chset(self._vnic,
                             str(self._chs[self._i][0]),
                             self._chs[self._i][1])
                    remaining = 0 # reset remaining
                except iw.IWException as e:
                    self._qR.put(('!FAIL!',time.time(),(-1,e)))
                except Exception as e: # blanket exception
                    self._qR.put(('!FAIL!',time.time(),(-1,e)))
コード例 #3
0
ファイル: rdoctl.py プロジェクト: sh1nu11bi/wraith
    def _setup(self,conf):
        """
         1) sets radio properties as specified in conf
         2) prepares specified nic for monitoring and binds it
         3) creates a scan list and compile statistics
        """
        # if the nic specified in conf is present, set it
        if conf['nic'] not in iwt.wifaces():
            raise RuntimeError("%s:iwtools.wifaces:not found" % conf['role'])
        self._nic = conf['nic']
        self._role = conf['role']

        # get the phy and associated interfaces
        try:
            (self._phy,ifaces) = iw.dev(self._nic)
            self._mac = ifaces[0]['addr']
        except (KeyError, IndexError):
            raise RuntimeError("%s:iw.dev:error getting interfaces" % self._role)
        except iw.IWException as e:
            raise RuntimeError("%s:iw.dev:failed to get phy <%s>" % (self._role,e))

        # get properties (the below will return None rather than throw exception)
        self._chs = iw.chget(self._phy)
        self._std = iwt.iwconfig(self._nic,'Standards')
        self._txpwr = iwt.iwconfig(self._nic,'Tx-Power')
        self._driver = iwt.getdriver(self._nic)
        self._chipset = iwt.getchipset(self._driver)

        # spoof the mac address ??
        if conf['spoofed']:
            mac = None if conf['spoofed'].lower() == 'random' else conf['spoofed']
            try:
                iwt.ifconfig(self._nic,'down')
                self._spoofed = iwt.sethwaddr(self._nic,mac)
            except iwt.IWToolsException as e:
                raise RuntimeError("%s:iwtools.sethwaddr:%s" % (self._role,e))

        # delete all associated interfaces - we want full control
        for iface in ifaces: iw.devdel(iface['nic'])

        # determine virtual interface name
        ns = []
        for wiface in iwt.wifaces():
            cs = wiface.split('dyskt')
            try:
                if len(cs) > 1: ns.append(int(cs[1]))
            except ValueError:
                pass
        n = 0 if not 0 in ns else max(ns)+1
        self._vnic = "dyskt%d" % n

        # sniffing interface
        try:
            iw.phyadd(self._phy,self._vnic,'monitor') # create a monitor,
            iwt.ifconfig(self._vnic,'up')             # and turn it on
        except iw.IWException as e:
            # never added virtual nic, restore nic
            errMsg = "%s:iw.phyadd:%s" % (self._role,e)
            try:
                iwt.ifconfig(self._nic,'up')
            except iwt.IWToolsException:
                errMsg += " Failed to restore %s" % self._nic
            raise RuntimeError(errMsg)
        except iwt.IWToolsException as e:
            # failed to 'raise' virtual nic, remove vnic and add nic
            errMsg = "%s:iwtools.ifconfig:%s" % (self._role,e)
            try:
                iw.phyadd(self._phy,self._nic,'managed')
                iw.devdel(self._vnic)
                iwt.ifconfig(self._nic,'up')
            except (iw.IWException,iwt.IWToolsException):
                errMsg += " Failed to restore %s" % self._nic
            raise RuntimeError(errMsg)

        # wrap remaining in a try block, we must attempt to restore card and
        # release the socket after any failures ATT
        self._s = None
        try:
            # bind socket w/ a timeout of 5 just in case there is no wireless traffic
            self._s = socket.socket(socket.AF_PACKET,
                                    socket.SOCK_RAW,
                                    socket.htons(0x0003))
            self._s.settimeout(5)
            self._s.bind((self._vnic,0x0003))
            uptime = time.time()

            # read in antenna details and radio description
            if conf['antennas']['num'] > 0:
                self._antenna['num'] = conf['antennas']['num']
                self._antenna['type'] = conf['antennas']['type']
                self._antenna['gain'] = conf['antennas']['gain']
                self._antenna['loss'] = conf['antennas']['loss']
                self._antenna['x'] = [v[0] for v in conf['antennas']['xyz']]
                self._antenna['y'] = [v[1] for v in conf['antennas']['xyz']]
                self._antenna['z'] = [v[2] for v in conf['antennas']['xyz']]
            self._desc = conf['desc']

            # compile initial scan pattern from config
            scan = [t for t in conf['scan'] if str(t[0]) in self._chs and not t in conf['pass']]

            # sum hop times with side effect of removing any invalid channel tuples
            # i.e. Ch 14, Width HT40+ and channels the card cannot tune to
            i = 0
            hop = 0
            while scan:
                try:
                    t = time.time()
                    iw.chset(self._vnic,str(scan[i][0]),scan[i][1])
                    hop += (time.time() - t)
                    i += 1
                except iw.IWException as e:
                    # if invalid argument, drop the channel otherwise reraise error
                    if iw.ecode(str(e)) == iw.IW_INVALIDARG:
                        del scan[i]
                    else:
                        raise
                except IndexError:
                    # all channels checked
                    break
            if not scan: raise ValueError("Empty scan pattern")


            # calculate avg hop time, and interval time
            # NOTE: these are not currently used but may be useful later
            hop /= len(scan)
            interval = len(scan) * conf['dwell'] + len(scan) * hop

            # create list of dwell times
            ds = [conf['dwell']] * len(scan)

            # get start ch & set the initial channel
            try:
                ch_i = scan.index(conf['scan_start'])
            except ValueError:
                ch_i = 0
            iw.chset(self._vnic,str(scan[ch_i][0]),scan[ch_i][1])

            # initialize tuner thread
            self._qT = Queue()
            self._tuner = Tuner(self._qT,self._conn,self._vnic,scan,ds,ch_i,conf['paused'])

            # notify RTO we are good
            self._icomms.put((self._vnic,uptime,'!UP!',self.radio))
        except socket.error as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy,self._nic)
                iwt.ifconfig(self._nic,'up')
            except (iw.IWException,iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:Raw Socket:%s" % (self._role,e))
        except iw.IWException as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy,self._nic)
                iwt.ifconfig(self._nic,'up')
            except (iw.IWException,iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:iw.chset:Failed to set channel: %s" % (self._role,e))
        except (ValueError,TypeError) as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy,self._nic)
                iwt.ifconfig(self._nic,'up')
            except (iw.IWException,iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:config:%s" % (self._role,e))
        except Exception as e:
            # blanket exception
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy,self._nic)
                iwt.ifconfig(self._nic,'up')
            except (iw.IWException,iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:Unknown:%s" % (self._role,e))
コード例 #4
0
    def run(self):
        """ switch channels based on associted dwell times """
        # starting paused or scanning?
        if self._state == TUNE_PAUSE:
            # notify rdoctl we are paused then hold on dyskt token q
            self._qR.put(('!PAUSE!', time.time(), (-1, ' ')))
            self._conn.poll(None)
        else:
            self._qR.put(('!SCAN!', time.time(), (-1, self._chs)))

        # execution loop
        # wait on the internal connection for each channels dwell time.  IOT
        # avoid a state where we would continue to scan the same channel, i.e.
        # receiving repeated state commands, use a remaining time counter
        remaining = 0
        while not self._done.is_set():
            # set the dwell time to remaining if we need to finish this scan
            dwell = self._ds[self._i] if not remaining else remaining

            ts1 = time.time()  # mark time
            if self._conn.poll(dwell):
                # get token and timestamp
                tkn = self._conn.recv()
                ts = time.time()

                # tokens will have 2 flavor's '!STOP!' and 'cmd:cmdid:params'
                # where params is empty or a '-' separated list
                if tkn == '!STOP!': self._qR.put(('!STOP!', ts, (-1, ' ')))
                else:
                    # calculate time remaining for this channel
                    remaining = self._ds[self._i] - (ts - ts1)

                    # parse the requested command
                    try:
                        cmd, cid, ps = tkn.split(
                            ':')  # force into 3 components
                        cid = int(cid)
                    except:  # should never happen but just in case
                        self._qR.put(
                            ('!ERR!', ts, (-1, "invalid command format")))
                    else:
                        # for hold, pause & listen, notify rdoctl & then block
                        # on DySKT until we get another token (assumes DySKT wont
                        # send consecutive holds etc)
                        if cmd == 'state':
                            self._qR.put(
                                ('!STATE!', ts, (cid, TUNE_DESC[self._state])))
                            continue
                        elif cmd == 'scan':
                            if self._state != TUNE_SCAN:
                                self._state = TUNE_SCAN
                                self._qR.put(('!SCAN!', ts, (cid, self._chs)))
                                continue
                            else:
                                self._qR.put(
                                    ('!ERR!', ts, (cid, 'redundant command')))
                        elif cmd == 'txpwr':
                            pass
                        elif cmd == 'spoof':
                            pass
                        elif cmd == 'hold':
                            if self._state != TUNE_HOLD:
                                self._state = TUNE_HOLD
                                self._qR.put(
                                    ('!HOLD!', ts, (cid, self.currch)))
                                self._conn.poll(
                                    None)  # block until a new token
                                continue
                            else:
                                self._qR.put(
                                    ('!ERR!', ts, (cid, 'redundant command')))
                        elif cmd == 'pause':
                            if self._state != TUNE_PAUSE:
                                self._state = TUNE_PAUSE
                                self._qR.put(('!PAUSE!', ts, (cid, ' ')))
                                self._conn.poll(
                                    None)  # block until a new token
                                continue
                            else:
                                self._qR.put(
                                    ('!ERR!', ts, (cid, 'redundant command')))
                        elif cmd == 'listen':
                            # for listen, we ignore reduandacies as some other
                            # (external) process may have changed the channel
                            try:
                                ch, chw = ps.split('-')
                                iw.chset(self._vnic, ch, chw)
                                self._state = TUNE_LISTEN
                                self._qR.put(('!LISTEN', ts,
                                              (cid, "%s:%s" % (ch, chw))))
                                self._conn.poll(
                                    None)  # block until a new token
                                continue
                            except ValueError:
                                self._qR.put(('!ERR!', ts,
                                              (cid, 'invalid param format')))
                            except iw.IWException as e:
                                self._qR.put(('!ERR', ts, (cid, e)))
                        else:
                            self._qR.put(('!ERR!', ts,
                                          (cid, "invalid command %s" % cmd)))
            else:
                # no token, go to next channel
                try:
                    self._i = (self._i + 1) % len(self._chs)
                    iw.chset(self._vnic, str(self._chs[self._i][0]),
                             self._chs[self._i][1])
                    remaining = 0  # reset remaining
                except iw.IWException as e:
                    self._qR.put(('!FAIL!', time.time(), (-1, e)))
                except Exception as e:  # blanket exception
                    self._qR.put(('!FAIL!', time.time(), (-1, e)))
コード例 #5
0
    def _setup(self, conf):
        """
         1) sets radio properties as specified in conf
         2) prepares specified nic for monitoring and binds it
         3) creates a scan list and compile statistics
        """
        # if the nic specified in conf is present, set it
        if conf['nic'] not in iwt.wifaces():
            raise RuntimeError("%s:iwtools.wifaces:not found" % conf['role'])
        self._nic = conf['nic']
        self._role = conf['role']

        # get the phy and associated interfaces
        try:
            (self._phy, ifaces) = iw.dev(self._nic)
            self._mac = ifaces[0]['addr']
        except (KeyError, IndexError):
            raise RuntimeError("%s:iw.dev:error getting interfaces" %
                               self._role)
        except iw.IWException as e:
            raise RuntimeError("%s:iw.dev:failed to get phy <%s>" %
                               (self._role, e))

        # get properties (the below will return None rather than throw exception)
        self._chs = iw.chget(self._phy)
        self._std = iwt.iwconfig(self._nic, 'Standards')
        self._txpwr = iwt.iwconfig(self._nic, 'Tx-Power')
        self._driver = iwt.getdriver(self._nic)
        self._chipset = iwt.getchipset(self._driver)

        # spoof the mac address ??
        if conf['spoofed']:
            mac = None if conf['spoofed'].lower(
            ) == 'random' else conf['spoofed']
            try:
                iwt.ifconfig(self._nic, 'down')
                self._spoofed = iwt.sethwaddr(self._nic, mac)
            except iwt.IWToolsException as e:
                raise RuntimeError("%s:iwtools.sethwaddr:%s" % (self._role, e))

        # delete all associated interfaces - we want full control
        for iface in ifaces:
            iw.devdel(iface['nic'])

        # determine virtual interface name
        ns = []
        for wiface in iwt.wifaces():
            cs = wiface.split('dyskt')
            try:
                if len(cs) > 1: ns.append(int(cs[1]))
            except ValueError:
                pass
        n = 0 if not 0 in ns else max(ns) + 1
        self._vnic = "dyskt%d" % n

        # sniffing interface
        try:
            iw.phyadd(self._phy, self._vnic, 'monitor')  # create a monitor,
            iwt.ifconfig(self._vnic, 'up')  # and turn it on
        except iw.IWException as e:
            # never added virtual nic, restore nic
            errMsg = "%s:iw.phyadd:%s" % (self._role, e)
            try:
                iwt.ifconfig(self._nic, 'up')
            except iwt.IWToolsException:
                errMsg += " Failed to restore %s" % self._nic
            raise RuntimeError(errMsg)
        except iwt.IWToolsException as e:
            # failed to 'raise' virtual nic, remove vnic and add nic
            errMsg = "%s:iwtools.ifconfig:%s" % (self._role, e)
            try:
                iw.phyadd(self._phy, self._nic, 'managed')
                iw.devdel(self._vnic)
                iwt.ifconfig(self._nic, 'up')
            except (iw.IWException, iwt.IWToolsException):
                errMsg += " Failed to restore %s" % self._nic
            raise RuntimeError(errMsg)

        # wrap remaining in a try block, we must attempt to restore card and
        # release the socket after any failures ATT
        self._s = None
        try:
            # bind socket w/ a timeout of 5 just in case there is no wireless traffic
            self._s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                                    socket.htons(0x0003))
            self._s.settimeout(5)
            self._s.bind((self._vnic, 0x0003))
            uptime = time.time()

            # read in antenna details and radio description
            if conf['antennas']['num'] > 0:
                self._antenna['num'] = conf['antennas']['num']
                self._antenna['type'] = conf['antennas']['type']
                self._antenna['gain'] = conf['antennas']['gain']
                self._antenna['loss'] = conf['antennas']['loss']
                self._antenna['x'] = [v[0] for v in conf['antennas']['xyz']]
                self._antenna['y'] = [v[1] for v in conf['antennas']['xyz']]
                self._antenna['z'] = [v[2] for v in conf['antennas']['xyz']]
            self._desc = conf['desc']

            # compile initial scan pattern from config
            scan = [
                t for t in conf['scan']
                if str(t[0]) in self._chs and not t in conf['pass']
            ]

            # sum hop times with side effect of removing any invalid channel tuples
            # i.e. Ch 14, Width HT40+ and channels the card cannot tune to
            i = 0
            hop = 0
            while scan:
                try:
                    t = time.time()
                    iw.chset(self._vnic, str(scan[i][0]), scan[i][1])
                    hop += (time.time() - t)
                    i += 1
                except iw.IWException as e:
                    # if invalid argument, drop the channel otherwise reraise error
                    if iw.ecode(str(e)) == iw.IW_INVALIDARG:
                        del scan[i]
                    else:
                        raise
                except IndexError:
                    # all channels checked
                    break
            if not scan: raise ValueError("Empty scan pattern")

            # calculate avg hop time, and interval time
            # NOTE: these are not currently used but may be useful later
            hop /= len(scan)
            interval = len(scan) * conf['dwell'] + len(scan) * hop

            # create list of dwell times
            ds = [conf['dwell']] * len(scan)

            # get start ch & set the initial channel
            try:
                ch_i = scan.index(conf['scan_start'])
            except ValueError:
                ch_i = 0
            iw.chset(self._vnic, str(scan[ch_i][0]), scan[ch_i][1])

            # initialize tuner thread
            self._qT = Queue()
            self._tuner = Tuner(self._qT, self._conn, self._vnic, scan, ds,
                                ch_i, conf['paused'])

            # notify RTO we are good
            self._icomms.put((self._vnic, uptime, '!UP!', self.radio))
        except socket.error as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy, self._nic)
                iwt.ifconfig(self._nic, 'up')
            except (iw.IWException, iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:Raw Socket:%s" % (self._role, e))
        except iw.IWException as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy, self._nic)
                iwt.ifconfig(self._nic, 'up')
            except (iw.IWException, iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:iw.chset:Failed to set channel: %s" %
                               (self._role, e))
        except (ValueError, TypeError) as e:
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy, self._nic)
                iwt.ifconfig(self._nic, 'up')
            except (iw.IWException, iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:config:%s" % (self._role, e))
        except Exception as e:
            # blanket exception
            try:
                iw.devdel(self._vnic)
                iw.phyadd(self._phy, self._nic)
                iwt.ifconfig(self._nic, 'up')
            except (iw.IWException, iwt.IWToolsException):
                pass
            if self._s:
                self._s.shutdown(socket.SHUT_RD)
                self._s.close()
            raise RuntimeError("%s:Unknown:%s" % (self._role, e))