Beispiel #1
0
def test_customer_bogon_routes(bf, customer_list):
    """Check that no BOGON routes are accepted from customers"""
    bf.asserts.current_assertion = 'Assert no BOGON prefixes accepted from customers'

    df = bf.q.routes(
        rib='bgp').answer().frame()  #retrieve BGP RIB for all devices
    bogons = []

    for customer in customer_list:
        for _, row in df.iterrows():
            if (row['Node'] == customer['Node']) & (
                    row['Next_Hop_IP'] == customer['Remote_IP']
            ):  #found routes learnt from customer
                z = IPNetwork(row['Network'])
                if (z.is_reserved() or z.is_private() or z.is_loopback()
                        or z.is_link_local() or z.is_multicast()):
                    bogons.append(
                        f"Prefix {row['Network']} from {customer['Remote_IP']} on {customer['Node']} should not be accepted"
                    )

    test = (len(bogons) == 0)
    pass_message = "No BOGON prefixes accepted from customers\n"
    fail_message = f"List of BOGON prefixes accepted from customers\n\n{bogons}"

    record_results(bf, test, pass_message, fail_message)
Beispiel #2
0
def _verify_network(name, network):
    """
    Verifies syntax of a specific network.

    :param str name: Name of network
    :param dict network: the network
    :return: Number of errors, Number of warnings
    :rtype: tuple(int, int)
    """
    num_warnings = 0
    num_errors = 0

    for key, value in network.items():
        # Subnet verification
        if "subnet" not in value:
            logging.warning("No subnet specified for %s %s", name, key)
            num_warnings += 1
        else:
            try:
                subnet = IPNetwork(value["subnet"])
            except AddrFormatError:
                logging.error("Invalid format for subnet '%s'",
                              str(value["subnet"]))
                num_errors += 1
            else:
                if subnet.is_reserved() \
                        or subnet.is_multicast() \
                        or subnet.is_loopback():
                    logging.error("%s %s is in a invalid IP address space",
                                  name, key)
                    num_errors += 1
                elif not subnet.is_private():
                    logging.warning("Non-private subnet used for %s %s", name,
                                    key)
                    num_warnings += 1

        # VLAN verification
        if "vlan" in value:
            if name == "unique-networks" and int(value["vlan"]) >= 2000:
                logging.error("VLAN must be less than 2000 for network %s",
                              key)
                num_errors += 1
            elif name == "generic-networks":
                logging.error(
                    "VLAN specification is not allowed "
                    "for network %s", key)
                num_errors += 1

        # Increment verification
        if "increment" in value:
            if name == "unique-networks":
                logging.error("Increment cannot be used for network %s", key)
                num_errors += 1
            elif not isinstance(value["increment"], bool):
                logging.error("Increment must be a boolean for network %s",
                              key)
                num_errors += 1
    return num_errors, num_warnings
def ip_validate(target):
    """Validates if input is a valid IP address"""
    validity = False
    try:
        valid_ip = IPNetwork(target).ip
        if (valid_ip.is_reserved() or valid_ip.is_netmask()
                or valid_ip.is_hostmask() or valid_ip.is_loopback()):
            validity = False
            logger.debug(f"IP {valid_ip} is invalid")
        if valid_ip.is_unicast():
            validity = True
            logger.debug(f"IP {valid_ip} is valid")
    except AddrFormatError:
        logger.debug(f"IP {target} is invalid")
        validity = False
    return validity
Beispiel #4
0
def get_ipcalc_network(query, netmask=""):
    """
    IP calculator tool: supports IPv6 and IPv4 networks. For list of values see below.

    IP list is optional since it will return many IPs for some subnets,
    if you need to show ip list you will have to append ``?iplist`` to your get request.

    **PLEASE NOTE:** iplist will print only 65536 addresses which is /16 in IPv4 subnetting or /112 in IPv6 subnetting.
    If you try to get more you will get an error.

    :param query: IP address or hostname
    :param netmask: (Optional) If you want the whole range of hosts

    **Example:**

        When getting single host

        $ GET ``/api/ipcalc/199.16.156.102/30``

        ::


            {
              "results": {
                "broadcast": "199.16.156.103",
                "cidr": "199.16.156.100/30",
                "first_host": "199.16.156.101",
                "hostmask": "0.0.0.3",
                "ip_bits": "11000111.00010000.10011100.01100110",
                "ip_version": 4,
                "is_linklocal": false,
                "is_loopback": false,
                "is_multicast": false,
                "is_private": false,
                "is_public": true,
                "is_reserved": false,
                "is_unicast": true,
                "last_host": "199.16.156.102",
                "netmask": "255.255.255.252",
                "netmask_bits": "11111111.11111111.11111111.11111100",
                "network": "199.16.156.100",
                "network_bits": "11000111.00010000.10011100.01100100",
                "num_addresses": 4,
                "prefixlen": 30,
                "supernet": [
                  "0.0.0.0/0",
                  "128.0.0.0/1",
                  "192.0.0.0/2",
                  "192.0.0.0/3",
                  "192.0.0.0/4",
                  "192.0.0.0/5",
                  "196.0.0.0/6",
                  "198.0.0.0/7",
                  "199.0.0.0/8",
                  "199.0.0.0/9",
                  "199.0.0.0/10",
                  "199.0.0.0/11",
                  "199.16.0.0/12",
                  "199.16.0.0/13",
                  "199.16.0.0/14",
                  "199.16.0.0/15",
                  "199.16.0.0/16",
                  "199.16.128.0/17",
                  "199.16.128.0/18",
                  "199.16.128.0/19",
                  "199.16.144.0/20",
                  "199.16.152.0/21",
                  "199.16.156.0/22",
                  "199.16.156.0/23",
                  "199.16.156.0/24",
                  "199.16.156.0/25",
                  "199.16.156.64/26",
                  "199.16.156.96/27",
                  "199.16.156.96/28",
                  "199.16.156.96/29"
                ],
                "to_ipv6": "::ffff:199.16.156.102/126"
              },
              "status": "ok"
            }

    """

    if netmask is not "":
        ip = query + '/' + netmask
    else:
        ip = query

    try:
        net = IPNetwork(ip)
    except AddrFormatError:
        abort(400)

    results = dict()
    results['broadcast'] = str(net.broadcast)
    results['network'] = str(net.network)
    results['netmask'] = str(net.netmask)
    results['cidr'] = str(net.cidr)
    results['num_addresses'] = net.size
    results['hostmask'] = str(net.hostmask)
    results['is_loopback'] = net.is_loopback()
    results['is_unicast'] = net.is_unicast()
    results['is_multicast'] = net.is_multicast()
    results['is_private'] = net.is_private()
    results['is_reserved'] = net.is_reserved()
    results['is_linklocal'] = net.is_link_local()
    results['is_public'] = net.is_unicast() and not net.is_private()
    results['prefixlen'] = net.prefixlen
    results['ip_version'] = net.version
    results['ip_bits'] = net.ip.bits()
    results['network_bits'] = net.network.bits()
    results['netmask_bits'] = net.netmask.bits()
    results['supernet'] = [str(supernet) for supernet in net.supernet()]

    if net.version == 4:
        results['to_ipv6'] = str(net.ipv6())

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

        if net.broadcast is not None:
            results['first_host'] = str(net.network + 1)
            results['last_host'] = str(net.broadcast - 1)
        else:
            results['first_host'] = str(net.ip)
            results['last_host'] = str(net.ip)

    elif net.version == 6:
        try:
            results['to_ipv4'] = str(net.ipv4())
        except AddrConversionError:
            results['to_ipv4'] = None

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

    return jsonify({'status': "ok",
                    'results': results})