Splunk Search

How to convert an IP Range to an enumerated list of IP Addresses?

arappeport
Engager

I am receiving a field that contains IP Addresses that look like this: 192.168.1.1-192.168.1.4. In order to make use of this information, I need to be able to create a multivalue field that lists out all the IP addresses individually (I can't use CIDR format because the list of IPs may not necessarily take up a complete CIDR range). Any ideas on how to do this via SPL, or am I better off writing a python script to handle this?

0 Karma
1 Solution

niketn
Legend

@arappeport, try the following run anywhere search. Commands from makeresults to mvexpand generate two sample IP Address ranges i.e. 192.168.1.1-192.168.1.15; and 192.169.1.30-192.170.1.35. The rex Regular Expression is used to extract the common IP Address Prefix (in the example it is 192.168.1.), and the start IP and end IP i.e. 1, 15 for example 1 and 30, 35 for example 2 respectively. The mvrange()eval function is used to generate multivalues between start and end IP. Then IP Address prefix is added to all the IPs from start to end to generate the ipAddress multivalue field as requested:

| makeresults 
| eval myfield= "192.168.1.1-192.168.1.15;192.169.1.30-192.170.1.35"
| makemv myfield delim=";"
| mvexpand myfield
| rex field=myfield "^(?<prefixIP>.*\.)(?<startIP>[^-]+)\-.*\.(?<endIP>[^$]+)$"
| makemv delim=" " myfield 
| mvexpand myfield
| eval endIPIndex=endIP+1
| eval ipRange=mvrange(startIP,endIPIndex,1)
| nomv ipRange
| eval ipAddress=prefixIP.replace(ipRange,"\s"," ".prefixIP)
| makemv ipAddress delim=" "

Please try out and confirm!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

View solution in original post

niketn
Legend

@arappeport, try the following run anywhere search. Commands from makeresults to mvexpand generate two sample IP Address ranges i.e. 192.168.1.1-192.168.1.15; and 192.169.1.30-192.170.1.35. The rex Regular Expression is used to extract the common IP Address Prefix (in the example it is 192.168.1.), and the start IP and end IP i.e. 1, 15 for example 1 and 30, 35 for example 2 respectively. The mvrange()eval function is used to generate multivalues between start and end IP. Then IP Address prefix is added to all the IPs from start to end to generate the ipAddress multivalue field as requested:

| makeresults 
| eval myfield= "192.168.1.1-192.168.1.15;192.169.1.30-192.170.1.35"
| makemv myfield delim=";"
| mvexpand myfield
| rex field=myfield "^(?<prefixIP>.*\.)(?<startIP>[^-]+)\-.*\.(?<endIP>[^$]+)$"
| makemv delim=" " myfield 
| mvexpand myfield
| eval endIPIndex=endIP+1
| eval ipRange=mvrange(startIP,endIPIndex,1)
| nomv ipRange
| eval ipAddress=prefixIP.replace(ipRange,"\s"," ".prefixIP)
| makemv ipAddress delim=" "

Please try out and confirm!

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"

arappeport
Engager

Works like a charm. Thank you for the help!

0 Karma

DalJeanis
Legend

1) I'd probably go with python as more manageable. However, IF, and only if, the last node is the only one that will have a range of numbers, then a simple SPL routine would do it.

This is run-anywhere aircode. Something like this should work. You CAN do code for if the third node could be different, but it would be a little more complex than I'd like to code without an instance to verify the logic on.

| makeresults 
| eval myfield= "192.168.1.1-192.168.1.4 192.169.1.1-192.170.1.4" 
| rex field=myfield "\b(?<IP1A>(\d{1,3}\.\d{1,3}\.\d{1,3}\.)(?<IP1B>\d{1,3})-(?<IP2A>\d{1,3}\.\d{1,3}\.\d{1,3}\.)(?<IP2B>\d{1,3})\b"
| makemv delim=" " myfield
| mvexpand myfield
| rename COMMENT as "The above creates test data"


| eval endIP=IP2B+1
| eval myflag=case(IP1A=IP2A,"OK", 
       true(),"ERROR")
| eval myfan=case(IP1A=IP2A,mvrange(IP1B,endIP), 
       true(),"ERROR")
| mvexpand myfan
| eval IPout = IP1A.".".myfan
0 Karma

niketn
Legend

@DalJeanis you have an extra ( in your rex command after ?<IP1A>.

| rex field=myfield "\b(?<IP1A>(\d{1,3}\.\d{1,3}\.\d{1,3}\.)

Should actually be

| rex field=myfield "\b(?<IP1A>\d{1,3}\.\d{1,3}\.\d{1,3}\.)

However, I feel the question was to generate multivalue IP Addresses from the IP Address range in the log.

____________________________________________
| makeresults | eval message= "Happy Splunking!!!"
0 Karma
Get Updates on the Splunk Community!

Introducing the 2024 SplunkTrust!

Hello, Splunk Community! We are beyond thrilled to announce our newest group of SplunkTrust members!  The ...

Introducing the 2024 Splunk MVPs!

We are excited to announce the 2024 cohort of the Splunk MVP program. Splunk MVPs are passionate members of ...

Splunk Custom Visualizations App End of Life

The Splunk Custom Visualizations apps End of Life for SimpleXML will reach end of support on Dec 21, 2024, ...