I have an IP field that I'm trying to match against a lookup that contains DHCP ranges.
For example, assume the lookup contains the following:
Start_Address,End_Address
10.0.0.5,10.0.0.254
10.2.0.5,10.3.0.254
10.4.0.5,10.4.0.254
When matching the IP field, 10.0.0.10 would match, but 10.0.0.2 would not. That said, simply determining the CIDR notation (10.0.0.0/24) won't work. I've consider enumerating all IPs, resulting in a huge lookup, but I'm wondering if anyone has any other ideas.
@yuanliuthis is a great approach. However, I need to be able to do this in SPL at search time.
I was able to develop a little external lookup to do this, using the native ipaddress Python module.
For those of you interested, here's the Python file "cidr_lookup.py".
#!/usr/bin/env python
from __future__ import print_function
import csv
import ipaddress
import sys
# Given start and end IP addresses, return the CIDRs
def lookup(ip_start, ip_end):
try:
cidrs = [str(ipaddr) for ipaddr in ipaddress.summarize_address_range(
ipaddress.IPv4Address(ip_start),
ipaddress.IPv4Address(ip_end)
)
]
cidr_list = ','.join(cidrs)
return cidr_list
except:
return ''
def main():
if len(sys.argv) != 4:
print("Usage: python cidr_lookup.py "
"[ip_start field] [ip_end field] [cidr_list field]")
sys.exit(1)
ip_start_field = sys.argv[1]
ip_end_field = sys.argv[2]
cidr_list_field = sys.argv[3]
infile = sys.stdin
outfile = sys.stdout
r = csv.DictReader(infile)
header = r.fieldnames
w = csv.DictWriter(outfile, fieldnames=header)
w.writeheader()
for result in r:
if result[ip_start_field] and result[ip_end_field]:
result[cidr_list_field] = lookup(result[ip_start_field],
result[ip_end_field])
if result[cidr_list_field]:
w.writerow(result)
main()
Here's the transforms.conf.
[cidrlookup]
external_cmd = cidr_lookup.py ip_start ip_end cidr_list
fields_list = ip_start, ip_end, cidr_list
Here's a screenshot of the lookup in use.
What do you mean the CIDR notation won't work? I break down my DHCP range into CIDR notations and everything works perfectly.
10.0.0.5 - 10.0.0.254 | 10.0.0.5/32 10.0.0.6/31 10.0.0.8/29 10.0.0.16/28 10.0.0.32/27 10.0.0.64/26 10.0.0.128/26 10.0.0.192/27 10.0.0.224/28 10.0.0.240/29 10.0.0.248/30 10.0.0.252/31 10.0.0.254/32 |
10.2.0.5 - 10.3.0.254 | 10.2.0.5/32 10.2.0.6/31 10.2.0.8/29 10.2.0.16/28 10.2.0.32/27 10.2.0.64/26 10.2.0.128/25 10.2.1.0/24 10.2.2.0/23 10.2.4.0/22 10.2.8.0/21 10.2.16.0/20 10.2.32.0/19 10.2.64.0/18 10.2.128.0/17 10.3.0.0/25 10.3.0.128/26 10.3.0.192/27 10.3.0.224/28 10.3.0.240/29 10.3.0.248/30 10.3.0.252/31 10.3.0.254/32 |
10.3.0.5 - 10.4.0.254 | 10.3.0.5/32 10.3.0.6/31 10.3.0.8/29 10.3.0.16/28 10.3.0.32/27 10.3.0.64/26 10.3.0.128/25 10.3.1.0/24 10.3.2.0/23 10.3.4.0/22 10.3.8.0/21 10.3.16.0/20 10.3.32.0/19 10.3.64.0/18 10.3.128.0/17 10.4.0.0/25 10.4.0.128/26 10.4.0.192/27 10.4.0.224/28 10.4.0.240/29 10.4.0.248/30 10.4.0.252/31 10.4.0.254/32 |
You can calculate these CIDR's using for example https://www.ipaddressguide.com/cidr
@yuanliuthis is a great approach. However, I need to be able to do this in SPL at search time.
I was able to develop a little external lookup to do this, using the native ipaddress Python module.
For those of you interested, here's the Python file "cidr_lookup.py".
#!/usr/bin/env python
from __future__ import print_function
import csv
import ipaddress
import sys
# Given start and end IP addresses, return the CIDRs
def lookup(ip_start, ip_end):
try:
cidrs = [str(ipaddr) for ipaddr in ipaddress.summarize_address_range(
ipaddress.IPv4Address(ip_start),
ipaddress.IPv4Address(ip_end)
)
]
cidr_list = ','.join(cidrs)
return cidr_list
except:
return ''
def main():
if len(sys.argv) != 4:
print("Usage: python cidr_lookup.py "
"[ip_start field] [ip_end field] [cidr_list field]")
sys.exit(1)
ip_start_field = sys.argv[1]
ip_end_field = sys.argv[2]
cidr_list_field = sys.argv[3]
infile = sys.stdin
outfile = sys.stdout
r = csv.DictReader(infile)
header = r.fieldnames
w = csv.DictWriter(outfile, fieldnames=header)
w.writeheader()
for result in r:
if result[ip_start_field] and result[ip_end_field]:
result[cidr_list_field] = lookup(result[ip_start_field],
result[ip_end_field])
if result[cidr_list_field]:
w.writerow(result)
main()
Here's the transforms.conf.
[cidrlookup]
external_cmd = cidr_lookup.py ip_start ip_end cidr_list
fields_list = ip_start, ip_end, cidr_list
Here's a screenshot of the lookup in use.