Skip to main content

IP Inventory Table NQE

  • 6 August 2024
  • 0 replies
  • 55 views

Identifying all the IP addresses on your network can be a complex and tedious task - and even impossible on some networks. This NQE makes it significantly easier to identify all the IP addresses in use on your network, including those that are stale or obsolete.  

 

Overview

This NQE identifies IPv4 and IPv6 addresses that are in use within the network. Due to the scarcity and value of IPv4 addresses, companies often seek to maximize their utilization and identify any under utilized address space. This can help to either improve the utilization of owned addresses or free up unused address space for sale. Whether you’re consolidating for financial purposes or re-IPing due to mergers, acquisitions, or network reorganizations, this NQE is essential for identifying all the IP addresses within the network. 

Results

  • Improved IP Utilization: By identifying stale or obsolete IP addresses, this NQE enables organizations to optimize their IP space, reducing the need to purchase additional address space and potentially generating revenue from the sale of surplus addresses.
  • Streamlined Re-IPing Process: The tool simplifies the otherwise complex and error-prone task of reassigning IP addresses across a network, making it manageable and efficient.
  • Support for Mergers and Acquisitions: This NQE aids in the smooth integration of network resources during corporate mergers and acquisitions by providing a clear mapping of IP address usage and it makes it easier to spot address conflicts. 

Solution

This NQE looks through the normalized data in the data model to find specific IP addresses and subnets using  NAT sources and destinations, BGP router IDs, IP routes, and ACL sources and destinations. It offers a parameterized approach, enabling users to define the IP range or prefix of interest. You can also customize it to ignore IPv6 addresses if you are only interested in IPv4. This script significantly eases the complex and tedious task of IP address identification and reassignment.

 

/**
* @intent Find every IP address and subnet in the network
* @description Includes interface subnets, hosts addresses, NAT sources and dests,
* ACL sources and dests, IP routes, and BGP router IDs.
*
*/

import "@fwd/L3/IpAddressUtils";
import "@fwd/L3/Interface Utilities";

isIPv4(a) = isPresent(patternMatch(toString(a), `{ipv4Subnet}`));

isAddressIPv4(a) = isPresent(patternMatch(toString(a), `{ipv4Address}`));

addressType(a) = if isIPv4(a) then "IPv4" else "IPv6";

getIpSubnets(addresses) =
foreach addr in addresses
select ipSubnet(addr.ip, addr.prefixLength);

getInterfaceIps(device, ipSet, ipv6Subnets) =
foreach l3Iface in getL3Interfaces(device)
foreach record
in getIpv4Ips(device.name, l3Iface, ipSet) +
getIpv6Ips(device.name, l3Iface, ipv6Subnets)
select record;

getIpv4Ips(deviceName, l3Iface, ipSet) =
foreach subnet in getIpSubnets(l3Iface.ipv4.addresses)
where subnet in ipSet
select {
Subnet: subnet,
AddressType: "IPv4",
Type: "Interface IP",
Source: l3Iface.name,
MAC: null : MacAddress,
Device: deviceName
};

getIpv6Ips(deviceName, l3Iface, ipv6Subnets) =
foreach subnet in getIpSubnets(l3Iface.ipv6.addresses)
where length(ipv6Subnets) == 0 ||
max(foreach s in ipv6Subnets
select subnet in s)
select {
Subnet: subnet,
AddressType: "IPv6",
Type: "Interface IP",
Source: l3Iface.name,
MAC: null : MacAddress,
Device: deviceName
};

getHosts(device, ipSet) =
foreach host in device.hosts
foreach subnet in host.addresses
where subnet in ipSet
select {
Subnet: subnet,
AddressType: addressType(subnet),
Type: "Host",
Source: host.name,
MAC: host.macAddress,
Device: device.name
};

getNatIps(device, ipSet) =
foreach entry in device.natEntries
let dsts = (foreach subnet in entry.headerMatches.ipv4Dst
where subnet in ipSet
select {
Subnet: subnet,
AddressType: addressType(subnet),
Type: "NAT Destination",
Source: entry.name,
MAC: null : MacAddress,
Device: device.name
})
let srcs = (foreach subnet in entry.headerMatches.ipv4Src
where subnet in ipSet
select {
Subnet: subnet,
AddressType: addressType(subnet),
Type: "NAT Source",
Source: entry.name,
MAC: null : MacAddress,
Device: device.name
})
foreach ips in dsts + srcs
select ips;

getAclIps(device, ipSet) =
foreach entry in device.aclEntries
let dsts = (foreach subnet in entry.headerMatches.ipv4Dst
where subnet in ipSet
select {
Subnet: subnet,
AddressType: addressType(subnet),
Type: "ACL Destination",
Source: entry.name,
MAC: null : MacAddress,
Device: device.name
})
let srcs = (foreach subnet in entry.headerMatches.ipv4Src
where subnet in ipSet
select {
Subnet: subnet,
AddressType: addressType(subnet),
Type: "ACL Source",
Source: entry.name,
MAC: null : MacAddress,
Device: device.name
})
foreach ips in dsts + srcs
select ips;

getRouteIps(device, ipSet, ipv6Subnets) =
foreach vrf in device.networkInstances
let afts = vrf.afts
foreach record
in getIpv4RouteIps(device, afts, ipSet) +
getIpv6RouteIps(device, afts, ipv6Subnets) +
getBgpRouterIds(device, vrf, ipSet, ipv6Subnets)
select record;

getBgpRouterIds(device, vrf, ipSet, ipv6Subnets) =
foreach protocol in vrf.protocols
let bgp = protocol.bgp
where isPresent(bgp)
let routerId = bgp.routerId
where isPresent(routerId)
let isIpv4 = isAddressIPv4(routerId)
where if isIpv4
then routerId in ipSet
else length(ipv6Subnets) == 0 ||
max(foreach s in ipv6Subnets
select routerId in s)
select {
Subnet: ipSubnet(routerId, if isIpv4 then 32 else 128),
AddressType: if isIpv4 then "IPv4" else "IPv6",
Type: "BGP Router ID",
Source: "",
MAC: null : MacAddress,
Device: device.name
};

getIpv4RouteIps(device, afts, ipSet) =
foreach ipv4Unicast in 4afts.ipv4Unicast]
where isPresent(ipv4Unicast)
foreach entry in ipv4Unicast.ipEntries
where entry.prefix in ipSet
select {
Subnet: entry.prefix,
AddressType: "IPv4",
Type: "Route",
Source: "",
MAC: null : MacAddress,
Device: device.name
};

getIpv6RouteIps(device, afts, ipv6Subnets) =
foreach ipv6Unicast in 6afts.ipv6Unicast]
where isPresent(ipv6Unicast)
foreach entry in ipv6Unicast.ipEntries
where length(ipv6Subnets) == 0 ||
max(foreach s in ipv6Subnets
select entry.prefix in s)
select {
Subnet: entry.prefix,
AddressType: "IPv6",
Type: "Route",
Source: "",
MAC: null : MacAddress,
Device: device.name
};

getIps(device, ipSet, ipv6Subnets) =
getInterfaceIps(device, ipSet, ipv6Subnets) + getHosts(device, ipSet) +
getNatIps(device, ipSet) +
getAclIps(device, ipSet) +
getRouteIps(device, ipSet, ipv6Subnets);

@query
query(ipv4Subnets: List<IpSubnet>, ipv6Subnets: List<IpSubnet>) =
foreach device in network.devices
let ipSet = ipAddressSet(ipv4Subnets)
foreach ipRecord in getIps(device, ipSet, ipv6Subnets)
select ipRecord;

 

Be the first to reply!

Reply