IP Calculator Final Version

Michael Doub mikedoub at gmail.com
Wed Jan 28 15:06:51 EST 2015


The MasterLibrary is now current with this version of IPCalc.  It also 
has a adaption of the Alejando Tejada's thumbnail extraction routine.

https://www.dropbox.com/s/3wpwn3hfbmpl7sk/MasterLibrary.livecode?dl=0

-= Mike


On 1/27/15 6:38 PM, Bob Sneidar wrote:
> 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