IP Calculator Final Version
Ralph DiMola
rdimola at evergreeninfo.net
Tue Jan 27 18:53:25 EST 2015
I wrote the OS for a custom computer for solving the 3d solution of the
FA-18 Flight Simulator back in the 80's. I had to write the floating point
input/display routines. I was very proud how I anticipated all the combos
for FP input. 1.0/1/1e10/.0005 e-20/0.0005/-55/1.125 e0 and all the other(so
I thought) input expectations and error handling. I Demoed it for colleague
before I presented it to the team and he typed +0 and it crashed the OS.
Woops......
Ralph DiMola
IT Director
Evergreen Information Services
rdimola at evergreeninfo.net
-----Original Message-----
From: use-livecode [mailto:use-livecode-bounces at lists.runrev.com] On Behalf
Of Bob Sneidar
Sent: Tuesday, January 27, 2015 6:39 PM
To: How to use LiveCode
Subject: Re: IP Calculator Final Version
Hi Alex.
Thanks for testing this for me and your input. Here is an updated function
that accounts for any non-numerical octets and expands the limits of the
CIDR to 0-32. Also, if the IP or the CIDR ends in any number of periods it
returns an error. I have made the same check for subnet masks.
This reminds me of when I originally started programming. I would proudly
show off my new creation to a friend of mine who was a school principle, and
he would set about breaking it. :-) It was a good lesson.
function IPCalc theIPAddress, theSubnetMask
/* IPCalc yyy
Syntax:
IPCalc theIPAddress, [theSubnetMask]
Examples:
Description:
Derive Internet values from either CIDR notation in the IPAddress
or a standard IP and subnet mask
Input:
. theIPAddress - the IP address in CIDR notation
or
. theIPAddress - a standard IP address and
. theSubNetMask - a standard subNetMask
Returns an array of the following values:
. bcastaddr
. cidraddr
. cidrdepth
. firstaddr
. ipaddress
. lastaddr
. subnetaddr
. subnetmask
. usablecount
Returns a string beginning with ERROR: if the parameters are out of
range
Check that the returned value is an array to see if there was an error
Source:
Bob Sneidar, slylabs13 at icloud.com
IPCalc */
set the itemdelimiter to "."
-- check parameters
-- the IP address must be 4 octets of numbers
if the number of items of theIPAddress <>4 \
or the last char of theIPAddress is "." \
or ".." is in theIPAddress then
return "ERROR: The IP Address must be in the form:" & cr & \
"'nnn.nnn.nnn.nnn' or 'nnn.nnn.nnn.nnn/nn'. (ipaddress = '" &
theIPAddress & "')"
end if
-- initial setup
set the numberFormat to "00000000"
-- detemine format
if theIPAddress contains "/" then
put offset("/", theIPAddress) into theCIDRDelim
put char theCIDRDelim +1 to -1 of theIPAddress into theCIDRDepth
-- CIDR depth must be a WHOLE number
put cleanString(theCIDRDepth) into theCIDRDepth
if theCIDRDepth is not a number then
return "ERROR: The CIDR Depth must be a number between 0 and 32. "
& \
"(CIDRDepth = '" & theCIDRDepth & "')"
end if
put charx("1", theCIDRDepth) & charx("0", 32-theCIDRDepth) into
theBinSubnetMask
put baseconvert(char 1 to 8 of theBinSubnetMask, 2, 10) into item 1 of
theSubnetMask
put baseconvert(char 9 to 16 of theBinSubnetMask, 2, 10) into item 2
of theSubnetMask
put baseconvert(char 17 to 24 of theBinSubnetMask, 2, 10) into item 3
of theSubnetMask
put baseconvert(char 25 to 32 of theBinSubnetMask, 2, 10) into item 4
of theSubnetMask
put char 1 to theCIDRDelim -1 of theIPAddress into theIPAddress
else
-- subnet mask octets must be 4 numbers between 0 and 255
-- and all octets after the first octet less than 255 must be 0
if the number of items of theSubnetMask <>4 \
or the last char of theSubnetMask is "." \
or ".." is in theSubnetMask then
return "ERROR: The Subnet Mask must be in the form:" & cr & \
"'nnn.nnn.nnn.nnn' (subnetmask = '" & theSubnetMask & "')"
end if
put false into mustBeZero
repeat for each item theOctet in theSubnetMask
if theOctet <0 or theOctet >255 then
return "Each octet in the subnet mask must be a number between 0
and 255. " & \
"(subnetmask = '" & theSubnetMask & "')"
end if
if mustBeZero and theOctet >0 then
return "ERROR: All octets after an octet less than 255 must be
0. " & \
"(subnetmask = '" & theSubnetMask & "')"
end if
if theOctet <255 then
put true into mustBeZero
end if
end repeat
-- convert the subnet mask to binary
put 0 into whichOctet
repeat for each item theOctet in theSubnetMask
add 1 to whichOctet
-- subnet mask must contain only 4 octets
if whichOctet >4 then
return "ERROR: The Subnet Mask must contain 4 numbers between 0
and 255 " & \
"separated by periods. (subnetmask = '" & theSubnetMask &
"')"
end if
put value(baseConvert(theOctet, 10, 2)) after theBinSubnetMask
end repeat
put offset("0", theBinSubnetMask) -1 into theCIDRDepth
end if
-- CIDR depth must be between 0 and 32
if theCIDRDepth <0 or theCIDRDepth >32 then
return "ERROR: The CIDR Depth must be between 0 and 32. " & \
"(CIDRDepth = '" & theCIDRDepth & "')"
end if
-- All octets of the IP address must be between 0 and 255
repeat for each item theOctet in theIPAddress
if theOctet is empty or theOctet < 0 or theOctet > 255 then
return "ERROR: Each IP Address octet must be a number between 0 and
255. " & \
"(ipaddress = '" & theIPAddress & "')"
end if
end repeat
-- convert the ip address to binary
put 0 into whichOctet
repeat for each item theOctet in theIPAddress
add 1 to whichOctet
put baseConvert(theOctet, 10, 2) into theBinValue
add 0 to theBinValue
put theBinValue after theBinIPAddress
end repeat
-- calculate the binary subnet address
put char 1 to theCIDRDepth of theBinIPAddress into theBinNetworkAddr
put char theCIDRDepth +1 to -1 of theBinIPAddress into theBinNodeAddr
put theBinNodeAddr into theBinSubnetNodeAddr
set the numberFormat to "0"
replace "1" with "0" in theBinSubnetNodeAddr
put theBinNetworkAddr & theBinSubnetNodeAddr into theBinSubnetAddr
-- convert the binary subnet address to decimal
put baseconvert(char 1 to 8 of theBinSubnetAddr, 2, 10) into item 1 of
theSubnetAddr
put baseconvert(char 9 to 16 of theBinSubnetAddr, 2, 10) into item 2 of
theSubnetAddr
put baseconvert(char 17 to 24 of theBinSubnetAddr, 2, 10) into item 3 of
theSubnetAddr
put baseconvert(char 25 to 32 of theBinSubnetAddr, 2, 10) into item 4 of
theSubnetAddr
-- calculate the first usable IP address
put theSubnetAddr into theFirstAddr
add 1 to item 4 of theFirstAddr
-- calculate the binary broadcast address
put theBinNodeAddr into theBinBcastNodeAddr
replace "0" with "1" in theBinBcastNodeAddr
put theBinNetworkAddr & theBinBcastNodeAddr into theBinBcastAddr
-- convert the binary broadcast address to decimal
put baseconvert(char 1 to 8 of theBinBcastAddr, 2, 10) into item 1 of
theBcastAddr
put baseconvert(char 9 to 16 of theBinBcastAddr, 2, 10) into item 2 of
theBcastAddr
put baseconvert(char 17 to 24 of theBinBcastAddr, 2, 10) into item 3 of
theBcastAddr
put baseconvert(char 25 to 32 of theBinBcastAddr, 2, 10) into item 4 of
theBcastAddr
-- calculate the last usable IP address
put theBcastAddr into theLastAddr
subtract 1 from item 4 of theLastAddr
-- calculate the number of usable addresses
-- put item 4 of theLastAddr - item 4 of theFirstAddr +1 into
theAddrCount
put baseconvert(theBinBcastNodeAddr, 2, 10) -1 into theAddrCount
-- calculate the CIDR notation
put theIPAddress & "/" & theCIDRDepth into theCIDRAddr
-- create array
put theIPAddress into ipdata ["ipaddress"]
put theSubnetMask into ipdata ["subnetmask"]
put theSubnetAddr into ipdata ["subnetaddr"]
put theFirstAddr into ipdata ["firstaddr"]
put theBcastAddr into ipdata["bcastaddr"]
put theLastAddr into ipdata ["lastaddr"]
put theCIDRDepth into ipdata ["cidrdepth"]
put theAddrCount into ipdata ["usablecount"]
put theCIDRAddr into ipdata ["cidraddr"]
return ipdata
end IPCalc
Bob S
> On Jan 26, 2015, at 16:22 , Bob Sneidar <bobsneidar at iotecdigital.com>
wrote:
>
>> On Jan 26, 2015, at 12:14 , Alex Tweedly <alex at tweedly.net> wrote:
>>
>> A couple of error cases that aren't caught gracefully
>>
>> 192.168.1/24.1
>> 192.168..1/24
>>
>> One that is accepted and shouldn't be
>> 192.168.1.1/24. (note the trailing ".")
>>
>> Also, not sure why you limit CIDRDepth to between 1 and 30. RFC 4632
specifically says between 0 and 3 - and indeed host routes (/32s) are common
enough, as is default route.
>>
>> Thanks again for contributing this Bob.
>>
>> -- Alex.
_______________________________________________
use-livecode mailing list
use-livecode at lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
More information about the use-livecode
mailing list