Community discussions

MikroTik App
 
royalpublishing
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

Return IP Octet Function

Tue May 20, 2014 1:02 am

ros code

# Usage: [$returnOctet <ip> <octet number (0-3)>]
# Input an IP Address and 0-3 argument to return a specific octet number 
:global returnOctet do={
    :if ($1="") do={ :error "You did not specify an IP Address."; }
    :if ($2="") do={ :error "You did not specify an octet to return."; }
    :if (($2>3) || ($2<0)) do={ :error "Octet argument out of range."; }
    :local decimalPos "0";
    :local octet1;
    :local octet2;
    :local octet3;
    :local octet4;
    :set decimalPos [:find $1 "."];
    :set octet1 [:pick $1 0 $decimalPos];
    :set decimalPos ($decimalPos+1);
    :set octet2  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet3  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet4 [:pick $1 $decimalPos [:len $1]];
    :if (($octet1<0 || $octet1>255) || ($octet2<0 || $octet2>255) || ($octet3<0 || $octet3>255) || ($octet4<0 || $octet4>255)) do={ :error "Octet out of range."; }
    :if ($2=0) do={ :return $octet1; }
    :if ($2=1) do={ :return $octet2; }
    :if ($2=2) do={ :return $octet3; }
    :if ($2=3) do={ :return $octet4; }
}
I'm on RouterOS 6.7. When I created this code everything works fine but since I converted it to a function, I'm having trouble figuring out why when I insert a :put directly after I set octet4 it shows the correct value but then the return value somehow gives me the value for $octet3. Arguments 0-2 all produce the expected results.
Last edited by royalpublishing on Fri Jun 13, 2014 10:37 pm, edited 2 times in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11968
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function returning wrong value

Tue May 20, 2014 2:51 am

Last edited by rextended on Fri Sep 17, 2021 2:40 am, edited 2 times in total.
 
royalpublishing
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

Re: Function returning wrong value

Tue May 20, 2014 4:53 pm

I appreciate the response rextended and the time you took to rewrite the function but I'd still like to know why the code that I wrote is not returning the proper results. I've upgraded to Router OS 6.13 and the issue still persists.
 
User avatar
mrz
MikroTik Support
MikroTik Support
Posts: 7038
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

Re: Function returning wrong value

Tue May 20, 2014 5:11 pm

Following should fix your problem

ros code

:if ($2="0") do={ :return $octet1; }
    :if ($2="1") do={ :return $octet2; }
    :if ($2="2") do={ :return $octet3; }
    :if ($2="3") do={ :return $octet4; }
Sometimes it is not possible to guess correct type, so unexpected results may appear.
Function variable is a string and you are comparing it to integer.
 
royalpublishing
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

Re: Function returning wrong value

Tue May 20, 2014 5:25 pm

I should have known it was something as easy at that. Thank you so much.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11968
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Function returning wrong value

Tue May 20, 2014 6:04 pm

In colors I evidence all necessary type check / convert ;)
:global returnOctet do={
:if ([:typeof [:toip $1]] != "ip") do={ :error message="You did not specify any VALID IP Address."; };
:if ( (($2 + 0) < 1) || (($2 + 0) > 4) ) do={ :error message="You did not specify any VALID octet to return."; };
:local workString value=[:tostr [:toip $1]];
:local endString value="";
:local thisChar value="";
:for i from=0 to=[:len $workString] step=1 do={
:set $thisChar value=[:pick $workString $i ($i+1)];
:if ($thisChar = ".") do={ :set $thisChar value=",";};
:set $endString value=($endString.$thisChar);
};
:local resultArray value=[:toarray $endString];
:return value=($resultArray->($2 - 1));
}
($2 + 0) and ($2 - 1) convert the $2 value surely to integer, because one addition are made... ;)
 
royalpublishing
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

Re: Function returning wrong value

Fri Jun 13, 2014 10:27 pm

Here was my final working version of my returnOctet function. I added the ability to return all octets as an array.

ros code

# Usage: [$returnOctet <ip> <octet number (0-4)>]
# Input an IP Address and 0-3 argument to return a specific octet number or 4 to return the entire array
:global returnOctet do={
    :if ($1="") do={ :error "You did not specify an IP Address."; }
    :if ($2="") do={ :error "You did not specify an octet to return."; }
    :if (($2>"4") || ($2<"0")) do={ :error "Octet argument out of range."; }
    :local decimalPos "0";
    :local octet1;
    :local octet2;
    :local octet3;
    :local octet4;
    :local octetArray; 
    :set decimalPos [:find $1 "."];
    :set octet1 [:pick $1 0 $decimalPos];
    :set decimalPos ($decimalPos+1);
    :set octet2  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet3  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet4 [:pick $1 $decimalPos [:len $1]];
    :set octetArray [:toarray "$octet1,$octet2,$octet3,$octet4"];
    :if (($octet1<"0" || $octet1>"255") || ($octet2<"0" || $octet2>"255") || ($octet3<"0" || $octet3>"255") || ($octet4<"0" || $octet4>"255")) do={ :error "Octet out of range."; }
    :if ($2="0") do={ :return $octet1; }
    :if ($2="1") do={ :return $octet2; }
    :if ($2="2") do={ :return $octet3; }
    :if ($2="3") do={ :return $octet4; }
    :if ($2="4") do={ :return $octetArray; }
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11968
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Return IP Octet Function

Fri Jun 13, 2014 11:53 pm

Last edited by rextended on Fri Sep 17, 2021 2:40 am, edited 2 times in total.
 
rviteri
Frequent Visitor
Frequent Visitor
Posts: 85
Joined: Fri Nov 18, 2011 5:53 pm

Re: Return IP Octet Function

Wed Sep 17, 2014 6:45 am

How do you use this script?
 
royalpublishing
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

Re: Return IP Octet Function

Fri Jul 17, 2015 11:42 pm

How do you use this script?
Obviously the response is a year late or so but, to answer your question, all you do is copy and paste the ROS code above into whatever script your working on and as indicated in the usage statement above, you can call on it like this from inside your script:
:local ipAddress "10.1.1.20";
:put [$returnOctet $ipAddress 0]; 
It would return the first octet of "10" and print it to the terminal window. Also as noted above, the second argument 0-3 returns what octet you're looking for. So in the case above, if you put the number 0 through 3, it would return "10", "1", "1", or "20" respectively. It is very helpful in situations where you need to manipulate a specific octet of a variable that contains an IP address.

Or you can directly input the variable and it would output the same thing like this:
:put [$returnOctet 10.1.1.20 0]
Once you've ran the script one time, since it's a global variable, you could then call it directly from the terminal the same way or use it in any other script for that matter as long as you declare ":global returnOctet;" to initialize the variable before you use it as long as you haven't unset the variable by calling ":set returnOctet;" or rebooted your router since you ran the script. Global variables aren't kept after a reboot.

To actually run a script there are several ways that I know of (probably more than this), by opening a terminal and typing "/system script run nameOfScript" or in Winbox go to System > Scripts > Select the script and hit Run Script but you won't see any output that way.
 
User avatar
SiB
Forum Guru
Forum Guru
Posts: 1888
Joined: Sun Jan 06, 2013 11:19 pm
Location: Poland

Re: Return IP Octet Function

Sun Jun 14, 2020 3:10 am

Short version:
 {
local CurIP "192.168.10.0/24"
put ("IP1oct: ".[pick $CurIP  0 [find $CurIP "."]])
put ("IP2oct: ".[pick $CurIP  0 [find $CurIP "." ([find $CurIP "."]+1)  ]])
put ("IP3oct: ".[pick $CurIP  0 [find $CurIP "." ([find $CurIP "." ([find $CurIP "."]+1)]+1)  ]])
put ("IP4oct: ".[pick $CurIP  0 [find $CurIP "/" ]])                                             
}                                                   
IP1oct: 192
IP2oct: 192.168
IP3oct: 192.168.10
IP4oct: 192.168.10.0
Example: ip firewall connection remove [find connection-mark~"wan1_Orange<->LANs" src-address~$IP3oct ]

Edit after @eworm answer:
{
local CurIP "192.168.10.1/24"
local IPoct [pick $CurIP  0 [find $CurIP "/" ]]
put ("IP1oct: ".($IPoct & 255.0.0.0))
put ("IP2oct: ".($IPoct & 255.255.0.0))
put ("IP3oct: ".($IPoct & 255.255.255.0))
put ("IP4oct: ".$IPoct)
}
IP1oct: 192.0.0.0
IP2oct: 192.168.0.0
IP3oct: 192.168.10.0
IP4oct: 192.168.10.1

Edit after @eworm answer:
{
local CurIP "192.168.10.1/24"
local IPoct [pick $CurIP  0 [find $CurIP "/" ]]
put ("IP1oct: ". [tonum (($IPoct>>24)&0.0.0.255) ] )
put ("IP2oct: ". [tonum (($IPoct>>16)&0.0.0.255) ] )
put ("IP3oct: ". [tonum (($IPoct>>8)&0.0.0.255) ] )
put ("IP4oct: ". [tonum (($IPoct>>0)&0.0.0.255) ] )
}
IP1oct: 192
IP2oct: 168
IP3oct: 10
IP4oct: 1
Last edited by SiB on Thu Jul 28, 2022 5:19 pm, edited 4 times in total.
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1070
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: Return IP Octet Function

Mon Jun 15, 2020 5:00 pm

RouterOS supports bitwise operations, so you can calculate IP addresses like this, for example get the first octet:
:put (192.168.10.0 & 255.0.0.0)
192.0.0.0
Possibly useful to shorten your functions even further. :D
 
CalEdu89
just joined
Posts: 2
Joined: Sun Sep 12, 2021 5:27 am

Re: Function returning wrong value

Mon Sep 13, 2021 4:24 pm

Here was my final working version of my returnOctet function. I added the ability to return all octets as an array.

ros code

# Usage: [$returnOctet <ip> <octet number (0-4)>]
# Input an IP Address and 0-3 argument to return a specific octet number or 4 to return the entire array
:global returnOctet do={
    :if ($1="") do={ :error "You did not specify an IP Address."; }
    :if ($2="") do={ :error "You did not specify an octet to return."; }
    :if (($2>"4") || ($2<"0")) do={ :error "Octet argument out of range."; }
    :local decimalPos "0";
    :local octet1;
    :local octet2;
    :local octet3;
    :local octet4;
    :local octetArray; 
    :set decimalPos [:find $1 "."];
    :set octet1 [:pick $1 0 $decimalPos];
    :set decimalPos ($decimalPos+1);
    :set octet2  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet3  [:pick $1 $decimalPos [:find $1 "." $decimalPos]];
    :set decimalPos ([:find $1 "." $decimalPos]+1);
    :set octet4 [:pick $1 $decimalPos [:len $1]];
    :set octetArray [:toarray "$octet1,$octet2,$octet3,$octet4"];
    :if (($octet1<"0" || $octet1>"255") || ($octet2<"0" || $octet2>"255") || ($octet3<"0" || $octet3>"255") || ($octet4<"0" || $octet4>"255")) do={ :error "Octet out of range."; }
    :if ($2="0") do={ :return $octet1; }
    :if ($2="1") do={ :return $octet2; }
    :if ($2="2") do={ :return $octet3; }
    :if ($2="3") do={ :return $octet4; }
    :if ($2="4") do={ :return $octetArray; }
}
how do I really use this script after creating a firewall filter. I just ran it but I had a few snags, so i did not get to a point where its supposed to check the dns blacklist.
 
User avatar
SiB
Forum Guru
Forum Guru
Posts: 1888
Joined: Sun Jan 06, 2013 11:19 pm
Location: Poland

Re: Function returning wrong value

Fri Sep 17, 2021 1:04 am

CalEdu89 write
how do I really use this script after creating a firewall filter. I just ran it but I had a few snags, so i did not get to a point where its supposed to check the dns blacklist.
Please create a new thread/topic at forum and not dig old ones. This thread is about scripting not about solving a DNS BlackList.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11968
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Return IP Octet Function  [SOLVED]

Fri Sep 17, 2021 2:08 am

search tag # rextended ip2array ip split octet

Uhm... I forgot that script....

Actualized version, always return one array with:
0: IP passed as parameter
1: 1st octet
2: 2nd octet
3: 3rd octet
4: 4th octet
:global ip2array do={
    :local ip [:toip $1]
    :local array [:toarray ""]
    :if ([:typeof $ip] != "ip") do={:return $array}
    :set ($array->0) $ip
    :set ip [:tonum $ip]
    :set ($array->1) (($ip >> 24) & 255)
    :set ($array->2) (($ip >> 16) & 255)
    :set ($array->3) (($ip >>  8) & 255)
    :set ($array->4) ( $ip        & 255)
    :return $array
}


example for print 2nd octet (49) from 85.49.74.128

example code

:put ([$ip2array 85.49.74.128]->2)

Who is online

Users browsing this forum: infabo, JDF, UkRainUa and 26 guests