def ssid(self, ssid): """ Set the ssid. """ if not ssid or ssid == SSID(b'\0'): self._ssid = None else: self._ssid = ssid
def validate_ssid(value): try: SSID(value) except ValueError: msg = '%r is not a valid SSID.' % value raise ValidationError(msg)
def handle_response(self, response, wtp, _): """Handle WSS_RESPONSE message.""" block_id = response.iface_id # init data structures for the incoming block self.slice_stats[block_id] = {} for entry in response.entries: ssid = SSID(entry.ssid) if str(ssid) not in self.slice_stats[block_id]: self.slice_stats[block_id][str(ssid)] = {} self.slice_stats[block_id][str(ssid)][entry.slice_id] = { "deficit_used": entry.deficit_used, "max_queue_length": entry.max_queue_length, "tx_packets": entry.tx_packets, "tx_bytes": entry.tx_bytes, } # update wifi_stats module block = wtp.blocks[block_id] block.slice_stats = self.slice_stats[block_id] # handle callbacks self.handle_callbacks("slice_stats")
def to_python(cls, value): """Convert value back to Python.""" try: return SSID(value) except ValueError: msg = '%r is not a valid SSID.' % value raise ValidationError(msg)
def send_add_lvap_request(self, lvap, block, set_mask): """Send a ADD_LVAP message.""" flags = Container(ht_caps=lvap.ht_caps, authenticated=lvap.authentication_state, associated=lvap.association_state, set_mask=set_mask) encap = EtherAddress("00:00:00:00:00:00") if lvap.encap: encap = lvap.encap bssid = EtherAddress() if lvap.bssid: bssid = lvap.bssid ssid = SSID() if lvap.ssid: ssid = lvap.ssid msg = Container(length=80, flags=flags, assoc_id=lvap.assoc_id, iface_id=block.block_id, ht_caps_info=Container(**lvap.ht_caps_info), sta=lvap.addr.to_raw(), encap=encap.to_raw(), bssid=bssid.to_raw(), ssid=ssid.to_raw(), networks=[]) for network in lvap.networks: msg.length = msg.length + 6 + WIFI_NWID_MAXSIZE + 1 msg.networks.append( Container(bssid=network[0].to_raw(), ssid=network[1].to_raw())) return self.send_message(self.proto.PT_ADD_LVAP_REQUEST, msg, lvap.handle_add_lvap_response)
def _handle_slice_status_response(self, status): """Handle an incoming SLICE_STATUS_RESPONSE message.""" iface_id = status.iface_id slice_id = str(status.slice_id) ssid = SSID(status.ssid) project = self.manager.projects_manager.load_project_by_ssid(ssid) block = self.device.blocks[iface_id] if not project: self.log.warning("Slice status from unknown SSID %s", ssid) return if slice_id not in project.wifi_slices: self.log.warning("Slice %s not found. Removing slice.", slice_id) self.send_del_slice(project, int(slice_id), block) return slc = project.wifi_slices[slice_id] if slc.properties['quantum'] != status.quantum: if self.device.addr not in slc.devices: slc.devices[self.device.addr] = dict() slc.devices[self.device.addr]['quantum'] = status.quantum amsdu_aggregation = bool(status.flags.amsdu_aggregation) if slc.properties['amsdu_aggregation'] != amsdu_aggregation: if self.device.addr not in slc.devices: slc.devices[self.device.addr] = dict() slc.devices[self.device.addr]['amsdu_aggregation'] = \ amsdu_aggregation if slc.properties['sta_scheduler'] != status.sta_scheduler: if self.device.addr not in slc.devices: slc.devices[self.device.addr] = dict() slc.devices[self.device.addr]['sta_scheduler'] = \ status.sta_scheduler project.save() project.refresh_from_db() self.log.info("Slice status: %s", slc)
def _handle_vap_status_response(self, status): """Handle an incoming STATUS_VAP message.""" bssid = EtherAddress(status.bssid) ssid = SSID(status.ssid) project = self.manager.projects_manager.load_project_by_ssid(ssid) if not project: self.log.warning("Unable to find SSID %s", ssid) self.send_del_vap(bssid) return # If the VAP does not exists, then create a new one if bssid not in self.manager.vaps: incoming = self.device.blocks[status.iface_id] self.manager.vaps[bssid] = VAP(bssid, incoming, project.wifi_props.ssid) vap = self.manager.vaps[bssid] self.log.info("VAP status %s", vap)
def _handle_lvap_status_response(self, status): """Handle an incoming LVAP_STATUS_RESPONSE message.""" sta = EtherAddress(status.sta) # If the LVAP does not exists, then create a new one if sta not in self.manager.lvaps: self.manager.lvaps[sta] = \ LVAP(sta, assoc_id=status.assoc_id, state=PROCESS_RUNNING) lvap = self.manager.lvaps[sta] # update LVAP params lvap.encap = EtherAddress(status.encap) lvap.authentication_state = bool(status.flags.authenticated) lvap.association_state = bool(status.flags.associated) lvap.ht_caps = bool(status.flags.ht_caps) lvap.ht_caps_info = dict(status.ht_caps_info) del lvap.ht_caps_info['_io'] ssid = SSID(status.ssid) if ssid == SSID(): ssid = None bssid = EtherAddress(status.bssid) if bssid == EtherAddress("00:00:00:00:00:00"): bssid = None lvap.bssid = bssid incoming = self.device.blocks[status.iface_id] if status.flags.set_mask: lvap.downlink = incoming else: lvap.uplink.append(incoming) # if this is not a DL+UL block then stop here if not status.flags.set_mask: return # if an SSID is set and the incoming SSID is different from the # current one then raise an LVAP leave event if lvap.ssid and ssid != lvap.ssid: self.send_client_leave_message_to_self(lvap) lvap.ssid = None # if the incoming ssid is not none then raise an lvap join event if ssid: lvap.ssid = ssid self.send_client_join_message_to_self(lvap) # udpate networks networks = list() for network in status.networks: incoming = (EtherAddress(network.bssid), SSID(network.ssid)) networks.append(incoming) lvap.networks = networks self.log.info("LVAP status: %s", lvap)
def _handle_assoc_request(self, request): """Handle an incoming ASSOC_REQUEST message.""" sta = EtherAddress(request.sta) ht_caps = request.flags.ht_caps ht_caps_info = dict(request.ht_caps_info) del ht_caps_info['_io'] if sta not in self.manager.lvaps: self.log.info("Assoc request from unknown LVAP %s", sta) return lvap = self.manager.lvaps[sta] incoming_bssid = EtherAddress(request.bssid) if lvap.bssid != incoming_bssid: self.log.info("Assoc request for invalid BSSID %s", incoming_bssid) return incoming_ssid = SSID(request.ssid) # Check if the requested SSID is from a unique project for project in self.manager.projects_manager.projects.values(): if not project.wifi_props: continue if project.wifi_props.bssid_type == T_BSSID_TYPE_SHARED: continue bssid = project.generate_bssid(lvap.addr) if bssid != incoming_bssid: self.log.info("Invalid BSSID %s", incoming_bssid) continue if project.wifi_props.ssid == incoming_ssid: lvap.bssid = incoming_bssid lvap.authentication_state = True lvap.association_state = True lvap.ssid = incoming_ssid lvap.ht_caps = ht_caps lvap.ht_caps_info = ht_caps_info lvap.commit() self.send_assoc_response(lvap) return # Check if the requested SSID is from a unique project for project in self.manager.projects_manager.projects.values(): if not project.wifi_props: continue if project.wifi_props.bssid_type == T_BSSID_TYPE_UNIQUE: continue if incoming_bssid not in project.vaps: self.log.info("Invalid BSSID %s", incoming_bssid) continue if project.wifi_props.ssid == incoming_ssid: lvap.bssid = incoming_bssid lvap.authentication_state = True lvap.association_state = True lvap.ssid = incoming_ssid lvap.ht_caps = ht_caps lvap.ht_caps_info = ht_caps_info lvap.commit() self.send_assoc_response(lvap) return self.log.info("Unable to find SSID %s", incoming_ssid)
def _handle_probe_request(self, request): """Handle an incoming PROBE_REQUEST message.""" # Get station sta = EtherAddress(request.sta) # Incoming incoming_ssid = SSID(request.ssid) iface_id = request.iface_id ht_caps = request.flags.ht_caps ht_caps_info = dict(request.ht_caps_info) del ht_caps_info['_io'] msg = "Probe request from %s ssid %s iface_id %u ht_caps %u" if not incoming_ssid: self.log.debug(msg, sta, "Broadcast", iface_id, ht_caps) else: self.log.debug(msg, sta, incoming_ssid, iface_id, ht_caps) # Check is station is in ACL of any networks networks = self.manager.projects_manager.get_available_ssids(sta) if not networks: self.log.debug("No SSID available at this device") return # If lvap does not exist then create it. Otherwise just refresh the # list of available networks if sta not in self.manager.lvaps: # spawn new LVAP self.log.info("Spawning new LVAP %s on %s", sta, self.device.addr) assoc_id = randint(1, 2007) lvap = LVAP(sta, assoc_id=assoc_id) lvap.networks = networks lvap.ht_caps = ht_caps lvap.ht_caps_info = ht_caps_info # this will trigger an LVAP ADD message lvap.blocks = self.device.blocks[request.iface_id] # save LVAP in the runtime self.manager.lvaps[sta] = lvap # Send probe response self.send_probe_response(lvap, incoming_ssid) return lvap = self.manager.lvaps[sta] # If this probe request is not coming from the same interface on which # this LVAP is currenly running then ignore the probe if lvap.blocks[0].block_id != iface_id: return # If LVAP is not running then ignore if not lvap.is_running(): return # Update list of available networks lvap.networks = networks lvap.commit() # Send probe response self.send_probe_response(lvap, incoming_ssid)