Community discussions

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

### Return IP Octet Function

#### 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.

rextended
Forum Guru
Posts: 2950
Joined: Tue Feb 25, 2014 12:49 pm
Location: Capalbio, Tuscany, Italy

### Re: Function returning wrong value

``````: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));
}``````
EDIT: removed :put "yyy" debug string
Last edited by rextended on Tue May 20, 2014 6:05 pm, edited 1 time in total.
I'm Italian, not English. Sorry for my imperfect grammar.

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

### Re: Function returning wrong value

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.

mrz
MikroTik Support
Posts: 5997
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

### Re: Function returning wrong value

#### 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
Topic Author
Posts: 50
Joined: Mon Sep 23, 2013 5:47 pm

### Re: Function returning wrong value

I should have known it was something as easy at that. Thank you so much.

rextended
Forum Guru
Posts: 2950
Joined: Tue Feb 25, 2014 12:49 pm
Location: Capalbio, Tuscany, Italy

### Re: Function returning wrong value

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...
I'm Italian, not English. Sorry for my imperfect grammar.

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

### Re: Function returning wrong value

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; }
}```

rextended
Forum Guru
Posts: 2950
Joined: Tue Feb 25, 2014 12:49 pm
Location: Capalbio, Tuscany, Italy

### Re: Return IP Octet Function

Good, I add the same ability to my version
: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) > 5) ) do={ :error message="You did not specify any VALID argument 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];
:if ((\$2 + 0) = 4) do={ :return value=\$resultArray; } else={ :return value=(\$resultArray->(\$2 - 1)); };
}
``````: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) > 5) ) do={ :error message="You did not specify any VALID argument 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];
:if ((\$2 + 0) = 4) do={ :return value=\$resultArray; } else={ :return value=(\$resultArray->(\$2 - 1)); };
}``````
I'm Italian, not English. Sorry for my imperfect grammar.

rviteri
Frequent Visitor
Posts: 84
Joined: Fri Nov 18, 2011 5:53 pm

### Re: Return IP Octet Function

How do you use this script?

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

### Re: Return IP Octet Function

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 10.1.1.20 0]``