World: r3wp
[Core] Discuss core issues
older newer | first last |
Pekr 14-Apr-2010 [16322] | ok, thanks ... I thought that maybe there is some get-modes trick, but there is probably not :-) |
Gregg 14-Apr-2010 [16323] | FSUTIL is your friend. I have a REBOL wrapper if you want. fsutil fsinfo volumeinfo c:\ |
Pekr 14-Apr-2010 [16324] | thanx! |
Pekr 16-Apr-2010 [16325x3] | Did anyone do IP arithmetics? I need to check, if some ip is in correct range :-) I have e.g. IP 10.10.10.10, and I need to check, if it belongs to 10.10.0.0/16. I have very primitive (but probably complicated function, which can't however count with cases where mask is different from 8. 16, 24, or 32: in-ip-range?: func [ip-fw ip-sq /local is? ip-sq-tmp ip-fw-tmp][ ;--- turn ip-string into block of separated values- removes dots and slash ["10" "10" "10" "10" "24"] ip-sq-tmp: parse ip-sq "./" ip-fw-tmp: parse ip-fw "." mask: last ip-sq-tmp ip-sq: copy/part ip-sq-tmp 4 ip-fw: copy/part ip-fw-tmp 4 switch/default mask [ "8" [either (copy/part ip-fw 1) = (copy/part ip-sq 1) [is?: true][is?: false]] "16" [either (copy/part ip-fw 2) = (copy/part ip-sq 2) [is?: true][is?: false]] "24" [either (copy/part ip-fw 3) = (copy/part ip-sq 3) [is?: true][is?: false]] "32" [either (copy/part ip-fw 4) = (copy/part ip-sq 4) [is?: true][is?: false]] ][ is?: false print ["Mas not found: " mask ", the result will most probably contain false positives ..."] ] return is? ] |
calling convetions: is-in-range? "10.10.10.10" "10.10.10.0/24" | |
ah, should be in-ip-range? in line above ... | |
BrianH 16-Apr-2010 [16328x5] | Convert to integers (through tuple then binary) and do bitwise operations. >> ip: to-tuple "10.10.10.10" == 10.10.10.10 >> ip-as-integer: to-integer to-binary to-tuple "10.10.10.10" == 168430090 >> set [mask-ip mask-range] parse "10.10.10.0/24" "/" == ["10.10.10.0" "24"] >> mask-ip: to-tuple mask-ip == 10.10.10.0 >> mask-range: to-integer mask-range == 24 >> mask-integer: (to-integer to-binary mask-ip) and (-1 xor (to-integer 2 ** (32 - mask-range)) - 1) == 168430080 >> mask-integer = (ip-as-integer and mask-integer) == true |
That process can be converted to the algorithm for your function: in-ip-range?: funct [ip-fw ip-sq] [ ; Convert ip to integer ip-as-integer: to-integer to-binary to-tuple ip-fw ; Convert mask to tuple and range integer set [mask-ip mask-range] parse ip-sq "/" mask-ip: to-tuple mask-ip mask-range: to-integer mask-range ; Calculate mask as integer mask-integer: (to-integer to-binary mask-ip) and (-1 xor (to-integer 2 ** (32 - mask-range)) - 1) ; Is ip within mask? mask-integer = (ip-as-integer and mask-integer) ] | |
Passes testing here, R2 and R3. | |
Of course FUNCT was added in 2.7.7, so if you use earlier versions use FUNC and collect your own locals. | |
And this version can handle all mask ranges, not just 8, 16, 24 and 32. | |
Steeve 16-Apr-2010 [16333x3] | >> (-1 xor (to-integer 2 ** (32 - mask-range)) - 1) same thing than: >>shift -1 mask-range |
sorry, I mean shift -1 32 - mask-range | |
not tested though... | |
Andreas 16-Apr-2010 [16336] | Only in R3, though, where, per default, shift == lshift, in R2 shift == rshift. |
Steeve 16-Apr-2010 [16337] | ah yes, I forgot |
Andreas 16-Apr-2010 [16338x4] | R2 needs shift/left to lshift, R3 rshifts with negative offsets. |
And Brian, I fear your function is flawed. | |
>> in-ip-range? "10.10.10.10" "10.10.0.0/24" ; == true Which is wrong. | |
From a quick glance your masking logic is wrong. You need to mask both the address and the network and then compare if the results match. | |
Steeve 16-Apr-2010 [16342] | I guess it's in the last line:::: ip-as-integer = (ip-as-integer and mask-integer) |
Andreas 16-Apr-2010 [16343x3] | I have a correct function for R3 lying around somewhere ... if only I could find it :) |
Ah, got it. | |
cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] [ mask: skip to-binary (shift -1 32 - bits) 4 (mask and to-binary address) = (mask and to-binary network) ] | |
Steeve 16-Apr-2010 [16346] | not R2 though ;-) |
Andreas 16-Apr-2010 [16347] | For R3 , as I mentioned. |
Steeve 16-Apr-2010 [16348] | I on |
Andreas 16-Apr-2010 [16349x3] | Usage: >> cidr-match? 10.10.10.10 10.10.0.0 16 ; == true >> cidr-match? 10.10.10.10 10.10.0.0 24 ; == false |
It's much nicer in R3, as to-binary on numbers works properly :) | |
In any case, here's an R2 version (assuming 2.7.7+ for funct): cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] [ mask: shift/left -1 32 - bits (mask and to-integer to-binary address) = (mask and to-integer to-binary network) ] | |
Steeve 16-Apr-2010 [16352] | See that weird one :) cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] [ mask: to-tuple skip to-binary (shift -1 32 - bits) 4 mask and address xor network = .0. ] |
BrianH 16-Apr-2010 [16353] | Andreas, I'm sure my function is flawed - I just came up with it right then. Thanks for the fix :) |
Steeve 16-Apr-2010 [16354] | rather optimized... cidr-match?: funct [address [tuple!] network [tuple!] bits [integer!]] [ mask: to-tuple to-binary shift -1 64 - bits mask and address xor network = .0. ] |
Andreas 16-Apr-2010 [16355] | Heh, that's great Steeve. Esp the ".0." |
Steeve 16-Apr-2010 [16356] | yeah, .0. = 0.0.0 = 0.0.0.0.0 ... |
Andreas 16-Apr-2010 [16357] | Yeah :) |
BrianH 16-Apr-2010 [16358x2] | Yeah, silly me, forgot about SHIFT :) |
That should work on R2 with 32 instead of 64. | |
Steeve 16-Apr-2010 [16360] | Yup |
Andreas 16-Apr-2010 [16361] | Nope. You'd need shift/left on R2 |
Steeve 16-Apr-2010 [16362] | He knew... :) |
Andreas 16-Apr-2010 [16363] | Just a reminder :) |
BrianH 16-Apr-2010 [16364x2] | The last time I did IP calculations in REBOL was before 2.7.6 came out, so the reminder is appreciated :) |
Though your functions do indicate the value of using REBOL's datatypes properly. Take note, Pekr, no strings :) | |
Pekr 17-Apr-2010 [16366x2] | wow, what a bunch of reactions :-) BrianH - I used strings, because of original Mikrotik format. They use 10.10.10.10/24 format for IP, so it was easier for me to carry around in a string form, then parse it later when needed .... IP arithmetics, and ranges would be 2 nice new datatypes for REBOL imo :-) |
Steeve - your optimised version for R2 does not work correctly: >> cidr-match? 10.10.10.10 10.10.10.0 24 == false | |
Steeve 17-Apr-2010 [16368] | Because it was for R3 only, try this for R2: cidr-match?: func [address [tuple!] network [tuple!] bits [integer!]] [ address xor network and (to-tuple debase/base to-hex shift/left -1 32 - bits 16) = .0. ] Don't know if it's faster than Andreas's, though |
ChristianE 17-Apr-2010 [16369] | (-:-:- = -:0:-) = (0:-:0 = 0:0:0) |
Steeve 17-Apr-2010 [16370x2] | -:- |
and so: +:+ | |
older newer | first last |