示例#1
0
 def parse_routes(self, items):
     routes = []
     while items:
         if items[0] == '*':
             logger.debug("parse traceroute like: *")
             route = {
                 'ip': '*',
                 'hostname': '*',
                 'location': None,
                 'response_times': 0
             }
             items = items[1:]
         elif items.index('ms') == 3:
             logger.debug(
                 "parse traceroute like: \"bogon (10.199.13.51)  6.527 ms\""
             )
             hostname = items[0].strip()
             ip = items[1].strip('(').strip(')').strip()
             ipt = IpLocation(self.parameters)
             location = ipt.get_location(ip)
             rtime = float(items[2])
             route = {
                 'ip': ip,
                 'hostname': hostname,
                 'location': location,
                 'response_times': rtime
             }
             items = items[4:]
         elif items.index('ms') == 1:
             logger.debug("parse traceroute like: \"6.527 ms\"")
             rtime = float(items[0])
             preroute = routes[len(routes) - 1]
             if preroute:
                 route = {
                     'ip': preroute['ip'],
                     'hostname': preroute['hostname'],
                     'location': preroute['location'],
                     'response_times': rtime
                 }
             else:
                 route = {
                     'ip': '*',
                     'hostname': '*',
                     'location': '',
                     'response_times': rtime
                 }
             items = items[2:]
         else:
             logger.error("Can not parse route: %s" % items)
         routes.append(route)
     return routes
示例#2
0
    def execute(self):
        data = dict()
        ip_list = []
        cname_list = []
        mx_list = []
        ns_list = []

        # terminal_request_send_time
        self.terminal_request_send_time = time.time()
        self.parameters["terminal_request_send_time"] = self.terminal_request_send_time
        if self.dns_server:
            try:
                dns_query = dns.message.make_query(qname=self.destination, rdtype=self.rdtype)
                querya = dns.query.udp(dns_query, self.dns_server, timeout=self.dns_timeout)
                data_ptime = querya.time * 1000
                answer = querya.answer
            except dns.exception.Timeout as e:
                logger.exception("dns timeout exception")
                return DnsError(url=self.destination, error=e, parameters=self.parameters).dns_timeout_error()
            except (resolver.NXDOMAIN, socket.gaierror) as e:
                logger.exception("dns server exception")
                return DnsError(url=self.destination, error=e, parameters=self.parameters).dns_server_error()
        else:
            dns_servers = resolver.get_default_resolver().nameservers
            if not dns_servers:
                logger.error("do not have dns servers")
                return DnsError(url=self.destination, parameters=self.parameters).miss_default_error()

            dns_query = dns.message.make_query(qname=self.destination, rdtype=self.rdtype)

            timeout_flag = 0
            dns_server_flag = 0
            for dns_server in dns_servers:
                try:
                    querya = dns.query.udp(dns_query, dns_server, timeout=self.dns_timeout)
                    data_ptime = querya.time * 1000
                    answer = querya.answer
                    self.dns_server = dns_server
                    break
                except dns.exception.Timeout as e:
                    logger.exception("dns server {} got timeout exception".format(str(dns_server)))
                    timeout_flag += 1
                    if timeout_flag + dns_server_flag == len(dns_servers):
                        return DnsError(url=self.destination, error=e, parameters=self.parameters).dns_timeout_error()
                except (resolver.NXDOMAIN, socket.gaierror) as e:
                    logger.exception("dns server {} got server exception".format(str(dns_server)))
                    dns_server_flag += 1
                    if timeout_flag + dns_server_flag == len(dns_servers):
                        return DnsError(url=self.destination, error=e, parameters=self.parameters).dns_server_error()

        self.terminal_response_receive_time = time.time()

        ipt = IpLocation(self.parameters)

        for queryans in answer:
            for item in queryans.items:
                # A记录 又称IP指向
                if item.rdtype == rdatatype.A:
                    ip_dict = dict()
                    ip = item.address
                    ip_dict["ip"] = ip
                    location = ipt.get_location(ip)
                    ip_dict["location"] = location
                    ip_list.append(ip_dict)
                #  CNAME 通常称别名指向
                elif item.rdtype == rdatatype.CNAME:
                    cname_list.append(str(item.target))
                # MAIL记录
                elif item.rdtype == rdatatype.MX:
                    mx_list.append(str(item.exchange))
                # NS记录
                elif item.rdtype == rdatatype.NS:
                    ns_list.append(str(item.target))

        if self.dns_method == "mx":
            if mx_list:
                data["mxs"] = mx_list
            else:
                return DnsError(url=self.destination, parameters=self.parameters).dns_query_error()
        elif self.dns_method == "a":
            if ip_list:
                data["ips"] = ip_list
            else:
                return DnsError(url=self.destination, parameters=self.parameters).dns_query_error()
        elif self.dns_method == "ns":
            if ns_list:
                data["ns"] = ns_list
            else:
                return DnsError(url=self.destination, parameters=self.parameters).dns_query_error()
        elif self.dns_method == "cname":
            if cname_list:
                data["cnames"] = cname_list
            else:
                return DnsError(url=self.destination, parameters=self.parameters).dns_query_error()
        else:
            return DnsError(url=self.destination, parameters=self.parameters).dns_query_error()
        data["destination"] = self.destination
        data["ptime"] = data_ptime
        data["dns_server"] = dict()
        data["dns_server"]["ip"] = self.dns_server
        data["dns_server"]["location"] = ipt.get_location(self.dns_server)

        result = {
            "status": 0,
            "data": data,
            "stamp": {
                "server_request_generate_time": self.server_request_generate_time,
                "terminal_request_receive_time": self.terminal_request_receive_time,
                "terminal_request_send_time": self.terminal_request_send_time,
                "terminal_response_receive_time": self.terminal_response_receive_time,
            }
        }
        return result
示例#3
0
    def ping(self):
        try:
            terminal_request_send_time = time.time()
            logger.debug("starting ping {} ......".format(self.destination))
            pobj = Ping(self.destination, self.parameters)
            data = pobj.ping()
            logger.debug("ending ping {} ......".format(self.destination))
            terminal_response_receive_time = time.time()
        except Exception as e:
            exc_msg = repr(e)
            # import traceback
            # exc_msg = traceback.format_exc()
            ping_result = {
                "status": 1,
                "data": {
                    "errorinfo": exc_msg,
                    "errorcode": 140
                },
                "stamp": {
                    "server_request_generate_time":
                    self.server_request_generate_time,
                    "terminal_request_receive_time":
                    self.terminal_request_receive_time,
                    "terminal_request_send_time": terminal_request_send_time,
                    "terminal_response_receive_time": time.time(),
                }
            }
            return ping_result

        if data:
            ipt = IpLocation(self.parameters)
            ping_result = {
                "status": 0,
                "data": {
                    "destination": self.destination,
                    "destination_ip": data.destination_ip,
                    "destination_location":
                    ipt.get_location(data.destination_ip),
                    "packet_send": self.count,
                    "packet_receive": (self.count - data.packet_lost),
                    "packet_loss": data.packet_lost,
                    "packet_size": data.packet_size,
                    "avg_time": data.avg_rtt,
                    "max_time": data.max_rtt,
                    "min_time": data.min_rtt,
                },
                "stamp": {
                    "server_request_generate_time":
                    self.server_request_generate_time,
                    "terminal_request_receive_time":
                    self.terminal_request_receive_time,
                    "terminal_request_send_time":
                    terminal_request_send_time,
                    "terminal_response_receive_time":
                    terminal_response_receive_time,
                }
            }
        else:
            ping_result = {
                "status": 1,
                "data": {
                    "errorinfo":
                    "Unable to establish communication, data acquisition failed:"
                    + self.destination,
                    "errorcode":
                    141
                },
                "stamp": {
                    "server_request_generate_time":
                    self.server_request_generate_time,
                    "terminal_request_receive_time":
                    self.terminal_request_receive_time,
                    "terminal_request_send_time":
                    terminal_request_send_time,
                    "terminal_response_receive_time":
                    terminal_response_receive_time,
                }
            }
        return ping_result
示例#4
0
    def get_access_interface(self, interface):
        interface_json = {"type": "wired", "name": interface}
        wireless_keys = ["wlan"]
        for wireless_key in wireless_keys:
            if interface.find(wireless_key) >= 0:
                interface_json["type"] = "wireless"
                break
        info = netifaces.ifaddresses(interface)
        # 地址信息
        interface_json["macaddress"] = None
        info_mac = info.get(netifaces.AF_LINK)
        if info_mac:
            if len(info_mac) == 1:
                interface_json["macaddress"] = info_mac[0].get("addr").replace(
                    ":", "").lower()
            else:
                logger.error(
                    "get mac address for interface {} wrong: {}".format(
                        interface, str(info_mac)))
        else:
            logger.error(
                "cannot get mac address for interface {}".format(interface))

        ipl = IpLocation(self.parameters)
        ipp = IpPublic(self.parameters)

        # ip地址信息, need to consider with gateway
        info_ipv4 = info.get(netifaces.AF_INET)
        if info_ipv4 and len(info_ipv4) == 1:
            local_ip = info_ipv4[0].get("addr")
            interface_json["local_ip"] = local_ip
            interface_json["local_location"] = ipl.get_location(local_ip)
            interface_json["netmask"] = info_ipv4[0].get("netmask")
            interface_json["broadcast"] = info_ipv4[0].get("broadcast")
            interface_json["is_default"] = False
        elif info_ipv4 and len(info_ipv4) > 1:
            """
            存在1个接口对应n个IP, 例如
            $ ip addr
            1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
                link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
                inet 127.0.0.1/8 scope host lo
                   valid_lft forever preferred_lft forever
                inet6 ::1/128 scope host 
                   valid_lft forever preferred_lft forever
            2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
                link/ether b8:27:eb:f9:41:74 brd ff:ff:ff:ff:ff:ff
                inet 10.10.36.222/24 brd 10.10.36.255 scope global eth0
                   valid_lft forever preferred_lft forever
                inet 10.10.36.55/24 brd 10.10.36.255 scope global secondary eth0
                   valid_lft forever preferred_lft forever
                inet6 fe80::ba27:ebff:fef9:4174/64 scope link 
                   valid_lft forever preferred_lft forever
            """
            msg = "interface: {} have {} ip, natrix do not support, please check your network!".format(
                interface, len(info))
            logger.warning(msg)

            local_ip = None
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                # doesn't even have to be reachable
                s.connect(('10.255.255.255', 1))
                local_ip = s.getsockname()[0]
            except Exception:
                msg = "Cannot get an default ip for interface {}".format(
                    interface)
                logger.exception(msg)

            if local_ip:
                for info in info_ipv4:
                    if info.get("addr") == local_ip:
                        interface_json["local_ip"] = info.get("addr")
                        interface_json["local_location"] = ipl.get_location(
                            local_ip)
                        interface_json["netmask"] = info.get("netmask")
                        interface_json["broadcast"] = info.get("broadcast")
                        interface_json["is_default"] = False

            if not interface_json.get("local_ip"):
                interface_json["local_ip"] = None
                interface_json["local_location"] = None
                interface_json["netmask"] = None
                interface_json["broadcast"] = None
                interface_json["is_default"] = False
        else:
            msg = "interface {} do not have IPV4 address".format(interface)
            logger.warning(msg)
            interface_json["local_ip"] = None
            interface_json["local_location"] = None
            interface_json["netmask"] = None
            interface_json["broadcast"] = None
            interface_json["is_default"] = False

        # in all situation, set gateway to None
        interface_json["gateway"] = None

        # 公网IP
        if interface_json["local_ip"]:
            public_ip = ipp.get_publicip(interface)
            interface_json["public_ip"] = public_ip
        else:
            interface_json["public_ip"] = None

        if interface_json.get("public_ip"):
            interface_json["public_location"] = ipl.get_location(
                interface_json.get("public_ip"))
        else:
            interface_json["public_location"] = None

        # 连接信息
        if interface_json["local_ip"]:
            interface_json["access_intranet"] = self.access_intranet(interface)
            interface_json["access_corporate"] = self.access_corporate(
                interface)
            interface_json["access_internet"] = self.access_internet(interface)
        else:
            interface_json["access_intranet"] = False
            interface_json["access_corporate"] = False
            interface_json["access_internet"] = False
        return interface_json
示例#5
0
    def parse_response_info(self):
        # 最后一次请求的URL
        last_url = self.pcurl.getinfo(pycurl.EFFECTIVE_URL)
        # 响应代码  get_status
        http_code = self.pcurl.getinfo(pycurl.HTTP_CODE)
        # 重定向
        # 重定向次数
        redirect_count = self.pcurl.getinfo(pycurl.REDIRECT_COUNT)
        # 如果存在转向的话,花费的时间
        # 重定向所消耗的时间
        redirect_time = self.pcurl.getinfo(pycurl.REDIRECT_TIME) * 1000
        # TODO, 重定向历史信息
        # 最后一次连接的远程IP地址
        ipt = IpLocation(self.parameters)
        remote_ip = self.pcurl.getinfo(pycurl.PRIMARY_IP)
        remote_location = ipt.get_location(remote_ip)
        # TODO, 通过IP信息得到地址和地域信息
        # 最后一次连接的远程端口号
        remote_port = self.pcurl.getinfo(pycurl.PRIMARY_PORT)
        # 最后一次连接的本地IP地址
        local_ip = self.pcurl.getinfo(pycurl.LOCAL_IP)
        local_location = ipt.get_location(local_ip)
        # 最后一次连接的本地端口号
        local_port = self.pcurl.getinfo(pycurl.LOCAL_PORT)

        # 时间信息
        # 请求总的时间 get_total_time
        # 传输结束时所消耗的总时间
        total_time = self.pcurl.getinfo(pycurl.TOTAL_TIME) * 1000
        # DNS解析-->TCP连接-->跳转【如有】-->SSL握手【如有】-->客户端准备-->服务器响应-->数据传输
        # 域名解析时间 ms
        # DNS解析所消耗的时间
        namelookup_time = self.pcurl.getinfo(pycurl.NAMELOOKUP_TIME) * 1000
        # 建立连接时间 ms
        # 建立连接所消耗的时间
        connect_time = self.pcurl.getinfo(pycurl.CONNECT_TIME) * 1000
        # 从发起请求到SSL建立握手时间
        appconnect_time = self.pcurl.getinfo(pycurl.APPCONNECT_TIME) * 1000
        # 连接上后到开始传输时的时间
        # 从建立连接到准备传输所消耗的时间
        pretransfer_time = self.pcurl.getinfo(pycurl.PRETRANSFER_TIME) * 1000
        # 接收到第一个字节的时间
        # 从建立连接到数据开始传输所消耗的时间
        starttransfer_time = self.pcurl.getinfo(
            pycurl.STARTTRANSFER_TIME) * 1000

        # 需要对时间做一些处理
        # 从而让
        # DNS解析-->TCP连接-->SSL握手(如有)-->客户端准备-->服务器响应-->数据传输
        # totoal_time = period_nslookup + period_tcp_connect + period_ssl_connect
        # + period_request + period_response + period_transfer
        # TCP连接耗时
        period_tcp_connect = connect_time - namelookup_time
        # SSL连接耗时
        if appconnect_time > connect_time:
            period_ssl_connect = appconnect_time - connect_time
        else:
            period_ssl_connect = 0
        # Request请求耗时
        if appconnect_time > connect_time:
            period_request = pretransfer_time - appconnect_time
        else:
            period_request = pretransfer_time - connect_time
        # Response处理耗时
        period_response = starttransfer_time - pretransfer_time
        # Response传输耗时
        period_transfer = float(total_time) - float(starttransfer_time)

        # 数据信息
        # 上传数据包大小
        size_upload = self.pcurl.getinfo(pycurl.SIZE_UPLOAD)
        # 下载数据包大小
        size_download = self.pcurl.getinfo(pycurl.SIZE_DOWNLOAD)
        # 上传速度
        speed_upload = self.pcurl.getinfo(pycurl.SPEED_UPLOAD)
        # 下载速度
        speed_download = self.pcurl.getinfo(pycurl.SPEED_DOWNLOAD)
        # 头部大小
        header_size = self.pcurl.getinfo(pycurl.HEADER_SIZE)

        self.http_result = {
            "status": 0,
            "data": {
                "url": self.destination,
                "last_url": last_url,
                "status_code": http_code,
                "redirect_count": redirect_count,
                "redirect_time": redirect_time,
                "remote_ip": remote_ip,
                "remote_location": remote_location,
                "remote_port": remote_port,
                "local_ip": local_ip,
                "local_location": local_location,
                "local_port": local_port,
                "total_time": total_time,
                "period_nslookup": namelookup_time,
                "period_tcp_connect": period_tcp_connect,
                "period_ssl_connect": period_ssl_connect,
                "period_request": period_request,
                "period_response": period_response,
                "period_transfer": period_transfer,
                "header_size": header_size,
                "size_upload": size_upload,
                "size_download": size_download,
                "speed_upload": speed_upload,
                "speed_download": speed_download,
            },
            "stamp": {
                "server_request_generate_time":
                self.server_request_generate_time,
                "terminal_request_receive_time":
                self.terminal_request_receive_time,
                "terminal_request_send_time":
                self.terminal_request_send_time,
                "terminal_response_receive_time":
                self.terminal_response_receive_time,
            }
        }
        return self.http_result