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 [email protected] -----Original Message----- From: use-livecode [mailto:[email protected]] 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, [email protected] 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 <[email protected]> wrote: > >> On Jan 26, 2015, at 12:14 , Alex Tweedly <[email protected]> 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 [email protected] Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode _______________________________________________ use-livecode mailing list [email protected] Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
