Exemple #1
0
    def send_message(self, msg_type, msg, callback=None):
        """Send message and set common parameters."""

        parser = self.proto.PT_TYPES[msg_type]

        if self.stream.closed():
            self.log.warning("Stream closed, unabled to send %s message to %s",
                             parser.name, self.device)
            return 0

        msg.version = self.proto.PT_VERSION
        msg.seq = self.seq
        msg.type = msg_type
        msg.xid = self.xid

        if not self.device:
            msg.device = EtherAddress("00:00:00:00:00:00").to_raw()
        else:
            msg.device = self.device.addr.to_raw()

        addr = self.stream.socket.getpeername()

        self.log.debug("Sending %s message to %s seq %u", parser.name, addr[0],
                       msg.seq)

        self.stream.write(parser.build(msg))

        if callback:
            self.xids[msg.xid] = (msg, callback)

        return msg.xid
Exemple #2
0
    def bssid(self, bssid):
        """ Set the bssid. """

        if bssid == EtherAddress("00:00:00:00:00:00"):
            self._bssid = None
        else:
            self._bssid = bssid
Exemple #3
0
    def post(self, *args, **kwargs):
        """Add entry in ACL.

        Args:

            [0], the project id (mandatory)

        Example URLs:

            POST /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                wifi_acl

            {
                "addr": "60:57:18:B1:A4:B8",
                "desc": "Dell Laptop"
            }
        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        desc = "Generic Station" if 'desc' not in kwargs else kwargs['desc']
        addr = EtherAddress(kwargs['addr'])

        acl = project.upsert_acl(addr, desc)

        url = "/api/v1/projects/%s/wifi_acl/%s" % (project_id, acl.addr)

        self.set_header("Location", url)
Exemple #4
0
    def put(self, *args, **kwargs):
        """Update entry in ACL.

        Args:

            [0], the project id (mandatory)
            [1]: the device address (mandatory)

        Example URLs:

            PUT /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                wifi_acl/60:57:18:B1:A4:B8

            {
                "desc": "Dell Laptop"
            }
        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        desc = "Generic Station" if 'desc' not in kwargs else kwargs['desc']
        addr = EtherAddress(args[1])

        project.upsert_acl(addr, desc)
Exemple #5
0
    def post(self, *args, **kwargs):
        """Add a new device.

        Request:

            version: protocol version (1.0)
            addr: the device address (mandatory)
            desc: a human readable description of the device (optional)

        Example URLs:

            POST /api/v1/vbses

            {
                "version":"1.0",
                "addr": "00:00:00:00:00:01"
            }

            POST /api/v1/vbses

            {
                "version":"1.0",
                "addr": "00:00:00:00:00:01",
                "desc": "Ettus B210"
            }
        """

        addr = EtherAddress(kwargs['addr'])

        if 'desc' in kwargs:
            device = self.service.create(addr, kwargs['desc'])
        else:
            device = self.service.create(addr)

        self.set_header("Location", "/api/v1/vbses/%s" % device.addr)
Exemple #6
0
    def _handle_caps_response(self, caps):
        """Handle an incoming CAPS message."""

        for block in caps.blocks:

            self.device.blocks[block.block_id] = \
                ResourceBlock(self.device,
                              block.block_id,
                              EtherAddress(block.hwaddr),
                              block.channel,
                              block.band)

        # set state to online
        self.device.set_online()

        # fetch active lvaps
        self.send_lvap_status_request()

        # fetch active vaps
        self.send_vap_status_request()

        # fetch active traffic rules
        self.send_slice_status_request()

        # fetch active tramission policies
        self.send_tx_policy_status_request()

        # send vaps
        self.update_vaps()

        # send slices
        self.update_slices()
Exemple #7
0
    def put(self, *args, **kwargs):
        """Modify the LVAP

        Args:

            [0], the project id (mandatory)
            [1]: the lvap address (mandatory)

        Example URLs:

            PUT /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/lvaps/
                60:F4:45:D0:3B:FC

            {
                "version": "1.0",
                "wtp": "04:F0:21:09:F9:AA"
            }
        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        lvap = project.lvaps[EtherAddress(args[1])]

        if "blocks" in kwargs:

            wtp = project.wtps[EtherAddress(kwargs['wtp'])]

            pool = ResourcePool()

            for block_id in kwargs["blocks"]:
                pool.append(wtp.blocks[block_id])

            lvap.blocks = pool

        elif "wtp" in kwargs:

            lvap.wtp = project.wtps[EtherAddress(kwargs['wtp'])]

        if "encap" in kwargs:

            encap = EtherAddress(kwargs["encap"])
            lvap.encap = encap
Exemple #8
0
    def generate_bssid(self, mac):
        """ Generate a new BSSID address. """

        base_mac = self.get_prefix()

        base = str(base_mac).split(":")[0:3]
        unicast_addr_mask = int(base[0], 16) & 0xFE
        base[0] = str(format(unicast_addr_mask, 'X'))
        suffix = str(mac).split(":")[3:6]

        return EtherAddress(":".join(base + suffix))
Exemple #9
0
    def upsert_mcast_service(self, ipaddress, receivers, status, service_type):
        """Update/insert new mcast services.

        Expected input:

        {
            "ip": "224.0.1.200",
            "receivers": ["ff:ff:ff:ff:ff:ff"],
            "status": True,
            "type": "emergency"
        }
        """

        addr = self.mcast_ip_to_ether(ipaddress)

        if addr not in self.mcast_services:

            schedule = self.schedule[-self._services_registered:] + \
                    self.schedule[:-self._services_registered]

            self.mcast_services[addr] = {
                "addr": addr,
                "ipaddress": ipaddress,
                "mcs": 6,
                "schedule": schedule,
                "receivers": [EtherAddress(x) for x in receivers],
                "status": status,
                "service_type": service_type
            }

            self._services_registered += 1

        else:

            self.mcast_services[addr]["receivers"] = \
                [EtherAddress(x) for x in receivers]
            self.mcast_services[addr]["status"] = status
            self.mcast_services[addr]["service_type"] = service_type

        return addr
Exemple #10
0
    def put(self, *args, **kwargs):
        """Modify the LVAP

        Args:

            [0]: the lvap address (mandatory)

        Example URLs:

            PUT /api/v1/lvaps/60:F4:45:D0:3B:FC

            {
                "version": "1.0",
                "wtp": "04:F0:21:09:F9:AA"
            }
        """

        lvap = self.service.lvaps[EtherAddress(args[0])]

        if "blocks" in kwargs:

            addr = EtherAddress(kwargs['wtp'])
            wtp = self.service.devices[addr]
            pool = ResourcePool()

            for block_id in kwargs["blocks"]:
                pool.append(wtp.blocks[block_id])

            lvap.blocks = pool

        elif "wtp" in kwargs:

            wtp = self.service.devices[EtherAddress(kwargs['wtp'])]
            lvap.wtp = wtp

        if "encap" in kwargs:

            encap = EtherAddress(kwargs["encap"])
            lvap.encap = encap
Exemple #11
0
    def __init__(self, slice_id, properties=None, devices=None):

        # set read-only parameters
        self.slice_id = int(slice_id)

        # logger :)
        self.log = logging.getLogger(self.__class__.__module__)

        # parse properties
        self.properties = self._parse_properties(properties)

        # parse per device properties
        self.devices = {}
        if devices:
            for device in devices:
                self.devices[EtherAddress(device)] = \
                    self._parse_properties(devices[device])
Exemple #12
0
    def delete(self, *args, **kwargs):
        """Delete one or all devices.

        Args:

            [0]: the device address

        Example URLs:

            DELETE /api/v1/vbses
            DELETE /api/v1/vbses/00:00:00:00:00:01
        """

        if args:
            self.service.remove(EtherAddress(args[0]))
        else:
            self.service.remove_all()
Exemple #13
0
    def delete(self, *args, **kwargs):
        """Delete one or all devices.

        Args:

            [0]: the device address (mandatory)

        Example URLs:

            DELETE /api/v1/wtps
            DELETE /api/v1/wtps/00:0D:B9:2F:56:64
        """

        if args:
            self.service.remove(EtherAddress(args[0]))
        else:
            self.service.remove_all()
Exemple #14
0
    def delete(self, *args, **kwargs):
        """Delete the mcast_services .

        Args:

            [0]: the project id (mandatory)
            [1]: the app id (mandatory)
            [3]: the mcast service MAC address (mandatory)

        Example URLs:

            DELETE /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/apps/
                mcast_services/01:00:5E:00:01:C8
        """

        self.service.delete_mcast_service(EtherAddress(args[2]))
        self.service.save_service_state()
Exemple #15
0
    def get(self, *args, **kwargs):
        """Lists all clients in the ACL.

        Args:

            [0], the project id (mandatory)
            [0]: the device address (optional)

        Example URLs:

            GET /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                wifi_acl/

            {
                "60:57:18:B1:A4:B8": {
                    "addr": "60:57:18:B1:A4:B8",
                    "desc": "Dell Laptop"
                },
                "18:5E:0F:E3:B8:68": {
                    "addr": "18:5E:0F:E3:B8:68",
                    "desc": "Dell Laptop"
                },
                "60:F4:45:D0:3B:FC": {
                    "addr": "60:F4:45:D0:3B:FC",
                    "desc": "Roberto's iPhone"
                }
            }

            GET /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                wifi_acl/60:57:18:B1:A4:B8

            {
                "addr": "60:57:18:B1:A4:B8",
                "desc": "Dell Laptop"
            }
        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        allowed = project.wifi_props.allowed

        return allowed if not args else allowed[str(EtherAddress(args[1]))]
Exemple #16
0
    def _handle_tx_policy_status_response(self, status):
        """Handle an incoming TX_POLICY_STATUS_RESPONSE message."""

        block = self.device.blocks[status.iface_id]
        addr = EtherAddress(status.sta)

        if addr not in block.tx_policies:
            block.tx_policies[addr] = TxPolicy(addr, block)

        txp = block.tx_policies[addr]

        txp.set_mcs([float(x) / 2 for x in status.mcs])
        txp.set_ht_mcs([int(x) for x in status.mcs_ht])
        txp.set_rts_cts(status.rts_cts)
        txp.set_max_amsdu_len(status.max_amsdu_len)
        txp.set_mcast(status.tx_mcast)
        txp.set_no_ack(status.flags.no_ack)

        self.log.info("TX policy status: %s", txp)
Exemple #17
0
    def handle_ucqm_response(self, response, wtp, _):
        """Handle UCQM_RESPONSE message."""

        block = wtp.blocks[response.iface_id]
        block.ucqm = {}

        # generate data points
        points = []
        timestamp = datetime.utcnow()

        for entry in response.entries:
            addr = EtherAddress(entry['addr'])
            block.ucqm[addr] = {
                'addr': addr,
                'last_rssi_std': entry['last_rssi_std'],
                'last_rssi_avg': entry['last_rssi_avg'],
                'last_packets': entry['last_packets'],
                'hist_packets': entry['hist_packets'],
                'mov_rssi': entry['mov_rssi']
            }

            tags = dict(self.params)
            tags["wtp"] = wtp.addr
            tags["block_id"] = response.iface_id
            tags["addr"] = addr

            sample = {
                "measurement": self.name,
                "tags": tags,
                "time": timestamp,
                "fields": block.ucqm[addr]
            }

            points.append(sample)

        # save to db
        self.write_points(points)

        self.ucqm[block.block_id] = block.ucqm

        # handle callbacks
        self.handle_callbacks()
Exemple #18
0
    def get(self, *args, **kwargs):
        """Access the mcast_services .

        Args:

            [0]: the project id (mandatory)
            [1]: the app id (mandatory)
            [2]: the mcast service MAC address (optional)

        Example URLs:

            GET /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/apps/
                mcast_services/01:00:5E:00:01:C8

            {
                addr: "01:00:5E:00:01:C8",
                ipaddress: "224.0.1.200",
                mcs: 0,
                schedule: [
                    1,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0
                ],
                receivers: [
                    "FF:FF:FF:FF:FF:FF"
                ],
                status: "true",
                service_type: "emergency"
            }
        """

        if len(args) == 2:
            return self.service.mcast_services

        return self.service.mcast_services[EtherAddress(args[2])]
Exemple #19
0
    def delete(self, *args, **kwargs):
        """Delete an entry in ACL.

        Args:

            [0], the project id (mandatory)
            [0]: the device address (mandatory)

        Example URLs:

            DELETE /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/
                wifi_acl/60:57:18:B1:A4:B8
        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        if len(args) == 2:
            project.remove_acl(EtherAddress(args[1]))
        else:
            project.remove_acl()
Exemple #20
0
    def handle_ncqm_response(self, response, wtp, _):
        """Handle NCQM_RESPONSE message."""

        block = wtp.blocks[response.iface_id]
        block.ncqm = {}

        for entry in response.entries:
            addr = EtherAddress(entry['addr'])
            block.ncqm[addr] = {
                'addr': addr,
                'last_rssi_std': entry['last_rssi_std'],
                'last_rssi_avg': entry['last_rssi_avg'],
                'last_packets': entry['last_packets'],
                'hist_packets': entry['hist_packets'],
                'mov_rssi': entry['mov_rssi']
            }

        self.ncqm = block.ncqm

        # handle callbacks
        self.handle_callbacks()
Exemple #21
0
    def handle_response(self, response, *_):
        """Handle WIFI_SLICE_STATS_RESPONSE message."""

        wtp = EtherAddress(response.device)

        # update this object
        if wtp not in self.stats:
            self.stats[wtp] = {}

        # generate data points
        points = []
        timestamp = datetime.utcnow()

        for entry in response.stats:

            self.stats[wtp][entry.iface_id] = {
                'deficit_used': entry.deficit_used,
                'max_queue_length': entry.max_queue_length,
                'tx_packets': entry.tx_packets,
                'tx_bytes': entry.tx_bytes,
            }

            tags = dict(self.params)
            tags["wtp"] = wtp
            tags["iface_id"] = entry.iface_id

            sample = {
                "measurement": self.name,
                "tags": tags,
                "time": timestamp,
                "fields": self.stats[wtp][entry.iface_id]
            }

            points.append(sample)

        # save to db
        self.write_points(points)

        # handle callbacks
        self.handle_callbacks()
Exemple #22
0
    def get(self, *args, **kwargs):
        """List devices.

        Args:

            [0]: the device address (optional)

        Example URLs:

            GET /api/v1/vbses

            [
                {
                    "addr": "00:00:00:00:00:01",
                    "cells": {},
                    "connection": null,
                    "desc": "Ettus B210",
                    "last_seen": 0,
                    "last_seen_ts": "1970-01-01T01:00:00.000000Z",
                    "period": 0,
                    "state": "disconnected"
                }
            ]

            GET /api/v1/vbses/00:00:00:00:00:01

            {
                "addr": "00:00:00:00:00:01",
                "cells": {},
                "connection": null,
                "desc": "Ettus B210",
                "last_seen": 0,
                "last_seen_ts": "1970-01-01T01:00:00.000000Z",
                "period": 0,
                "state": "disconnected"
            }
        """

        return self.service.devices \
            if not args else self.service.devices[EtherAddress(args[0])]
Exemple #23
0
    def mcast_ip_to_ether(cls, ip_mcast_addr):
        """Transform an IP multicast address into an Ethernet one."""

        if ip_mcast_addr is None:
            return '\x00' * 6

        # The first 24 bits are fixed according to class D IP
        # and IP multicast address convenctions
        mcast_base = '01:00:5e'

        # The 23 low order bits are mapped.
        ip_addr_bytes = str(ip_mcast_addr).split('.')

        # The first IP byte is not use,
        # and only the last 7 bits of the second byte are used.
        second_byte = int(ip_addr_bytes[1]) & 127
        third_byte = int(ip_addr_bytes[2])
        fourth_byte = int(ip_addr_bytes[3])

        mcast_upper = format(second_byte, '02x') + ':' + \
            format(third_byte, '02x') + ':' + \
            format(fourth_byte, '02x')

        return EtherAddress(mcast_base + ':' + mcast_upper)
Exemple #24
0
    def put(self, *args, **kwargs):
        """Update the description of the device.

        Request:

            version: protocol version (1.0)
            desc: a human readable description of the device (optional)

        Example URLs:

            PUT /api/v1/vbses/00:0D:B9:2F:56:64

            {
                "version":"1.0",
                "desc": "SrsLTE eNB"
            }
        """

        addr = EtherAddress(args[0])

        if 'desc' in kwargs:
            self.service.update(addr, kwargs['desc'])
        else:
            self.service.update(addr)
Exemple #25
0
    def _handle_vap_status_response(self, status):
        """Handle an incoming STATUS_VAP message."""

        bssid = EtherAddress(status.bssid)
        ssid = SSID(status.ssid)

        project = srv_or_die("projectsmanager").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)
Exemple #26
0
    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)
Exemple #27
0
    def get(self, *args, **kwargs):
        """List the LVAPs.

        Args:

            [0], the project id (mandatory)
            [1]: the lvap address (optional)

        Example URLs:

            GET /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/lvaps

            [
                {
                    "addr": "60:F4:45:D0:3B:FC",
                    "assoc_id": 732,
                    "association_state": true,
                    "authentication_state": true,
                    "blocks": [
                        ...
                    ],
                    "bssid": "52:31:3E:D0:3B:FC",
                    "encap": "00:00:00:00:00:00",
                    "ht_caps": true,
                    "ht_caps_info": {
                        "DSSS_CCK_Mode_in_40_MHz": false,
                        "Forty_MHz_Intolerant": false,
                        "HT_Delayed_Block_Ack": false,
                        "HT_Greenfield": false,
                        "LDPC_Coding_Capability": true,
                        "L_SIG_TXOP_Protection_Support": false,
                        "Maximum_AMSDU_Length": false,
                        "Reserved": false,
                        "Rx_STBC": 0,
                        "SM_Power_Save": 3,
                        "Short_GI_for_20_MHz": true,
                        "Short_GI_for_40_MHz": true,
                        "Supported_Channel_Width_Set": true,
                        "Tx_STBC": false
                    },
                    "networks": [
                        [
                            "52:31:3E:D0:3B:FC",
                            "EmPOWER"
                        ]
                    ],
                    "pending": [],
                    "ssid": "EmPOWER",
                    "state": "running",
                    "wtp": {
                        ...
                    }
                }
            ]

            GET /api/v1/projects/52313ecb-9d00-4b7d-b873-b55d3d9ada26/lvaps/
                60:F4:45:D0:3B:FC

            {
                "addr": "60:F4:45:D0:3B:FC",
                "assoc_id": 732,
                "association_state": true,
                "authentication_state": true,
                "blocks": [
                    ...
                ],
                "bssid": "52:31:3E:D0:3B:FC",
                "encap": "00:00:00:00:00:00",
                "ht_caps": true,
                "ht_caps_info": {
                    "DSSS_CCK_Mode_in_40_MHz": false,
                    "Forty_MHz_Intolerant": false,
                    "HT_Delayed_Block_Ack": false,
                    "HT_Greenfield": false,
                    "LDPC_Coding_Capability": true,
                    "L_SIG_TXOP_Protection_Support": false,
                    "Maximum_AMSDU_Length": false,
                    "Reserved": false,
                    "Rx_STBC": 0,
                    "SM_Power_Save": 3,
                    "Short_GI_for_20_MHz": true,
                    "Short_GI_for_40_MHz": true,
                    "Supported_Channel_Width_Set": true,
                    "Tx_STBC": false
                },
                "networks": [
                    [
                        "52:31:3E:D0:3B:FC",
                        "EmPOWER"
                    ]
                ],
                "pending": [],
                "ssid": "EmPOWER",
                "state": "running",
                "wtp": {
                    ...
                }
            }

        """

        project_id = uuid.UUID(args[0])
        project = self.service.projects[project_id]

        return project.lvaps \
            if len(args) == 1 else project.lvaps[EtherAddress(args[1])]
Exemple #28
0
    def on_read(self, future):
        """Assemble message from agent.

        Appends bytes read from socket to a buffer. Once the full packet
        has been read the parser is invoked and the buffers is cleared. The
        parsed packet is then passed to the suitable method or dropped if the
        packet type in unknown.
        """

        try:
            self.buffer = self.buffer + future.result()
        except StreamClosedError as stream_ex:
            self.log.error(stream_ex)
            return

        hdr = self.proto.HEADER.parse(self.buffer)

        if len(self.buffer) < hdr.length:
            remaining = hdr.length - len(self.buffer)
            future = self.stream.read_bytes(remaining)
            future.add_done_callback(self.on_read)
            return

        # Check if we know the message type
        if hdr.type not in self.proto.PT_TYPES:
            self.log.warning("Unknown message type %u, ignoring.", hdr.type)
            return

        # Check if the Device is among the ones we known
        addr = EtherAddress(hdr.device)

        if addr not in self.manager.devices:
            self.log.warning("Unknown Device %s, closing connection.", addr)
            self.stream.close()
            return

        device = self.manager.devices[addr]

        # Log message informations
        parser = self.proto.PT_TYPES[hdr.type]
        msg = parser.parse(self.buffer)
        self.log.debug("Got %s message from %s seq %u", parser.name,
                       EtherAddress(addr), hdr.seq)

        # If Device is not online and is not connected, then the only message
        # type we can accept is HELLO_RESPONSE
        if not device.is_connected():

            if msg.type != self.proto.PT_HELLO_REQUEST:
                if not self.stream.closed():
                    self.wait()
                return

            # This is a new connection, set pointer to the device
            self.device = device

            # The set pointer from device connection to this object
            device.connection = self

            # Transition to connected state
            device.set_connected()

            # Start hb worker
            self.hb_worker.start()

            # Send caps request
            self.send_caps_request()

        # If device is not online but it is connected, then we can accept both
        # HELLO_RESPONSE and CAP_RESPONSE message
        if device.is_connected() and not device.is_online():
            valid = (self.proto.PT_HELLO_REQUEST, self.proto.PT_CAPS_RESPONSE)
            if msg.type not in valid:
                if not self.stream.closed():
                    self.wait()
                return

        # Otherwise handle message
        try:
            method = self.proto.PT_TYPES[msg.type].name
            self.handle_message(method, msg)
        except Exception as ex:
            self.log.exception(ex)
            self.stream.close()

        if not self.stream.closed():
            self.wait()
Exemple #29
0
    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 srv_or_die("projectsmanager").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 srv_or_die("projectsmanager").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)
Exemple #30
0
    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)