|
-
Apr 15th, 2015, 11:01 PM
#1
[RESOLVED] Convert CIDR To Subnet Range (IPv4)
A friend at work asked if I knew how to extract the subnet range from a CIDR format. For those that don't know, CIDR is simply an IP address followed by a mask bit count (192.10.25.33/28).
After looking about, I found some truly complicated methods that convert IPs and masks to binary representations as strings, performing XOR, AND operations on the string characters, and other crazy stuff.
I think I've discovered a really short simple solution and would like input before I pass it off to that friend. Specifically, I have two questions:
1) Do you see anything wrong with the logic?
2) Stupid question maybe, but here I'll show my ignorance. Would network byte order affect the logic on how the mask is created, i.e., little/big endian?
Site I used to test my results: http://www.subnet-calculator.com/
Add this to a module and from your immediate window (Ctrl+G), simply pass it some CIDR formats, i.e.,
TestIt "126.192.22.254/30"
Code:
Public Sub TestIt(CIDR As String)
' CIDR format: xxx.xxx.xxx.xxx/mask bit count
' IP octets do not need leading zeros
' mask bit count must be between 8 and 32 inclusively
Dim lMask As Long, lMskWildCard As Long
Dim lIP As Long, sTokens() As String
Dim x As Long, lMin As Long, lMax As Long
x = InStr(CIDR, "/")
If x = 0 Then
MsgBox "Invalid CIDR format passed"
Exit Sub
End If
lMask = Val(Mid$(CIDR, x + 1))
If lMask < 8 Or lMask > 32 Then
MsgBox "Invalid CIDR mask passed"
Exit Sub
End If
sTokens() = Split(Left$(CIDR, x - 1), ".")
If UBound(sTokens) <> 3 Then
MsgBox "Invalid CIDR format passed"
Exit Sub
End If
lMskWildCard = 2& ^ (32& - lMask) - 1&
lMask = &HFFFFFFFF And Not lMskWildCard
On Error GoTo ErrHandler
lMax = &H10000
For x = 1 To 3
lMin = CLng(sTokens(x))
If lMin < 0 Or lMin > 255 Then Err.Raise 5
lIP = lIP Or lMin * lMax
lMax = lMax \ &H100&
Next
lMax = (lIP And lMask) Or lMskWildCard Or CLng("&H" & Hex(sTokens(0)) & "000000")
lMin = (lIP And lMask) Or ((lIP And (lMskWildCard Xor -1&)) And lMskWildCard) Or CLng("&H" & Hex(sTokens(0)) & "000000")
Debug.Print "Min/Max Range: "; _
sTokens(0); "."; _
CStr((lMin And &HFF0000) \ &H10000); "."; CStr((lMin And &HFF00&) \ &H100); "."; CStr(lMin And &HFF); " thru "; _
sTokens(0); "."; _
CStr((lMax And &HFF0000) \ &H10000); "."; CStr((lMax And &HFF00&) \ &H100); "."; CStr(lMax And &HFF)
ErrHandler:
If Err Then
Err.Clear
MsgBox "Invalid CIDR IP address passed"
End If
End Sub
I haven't decided how I want to return the min/max range (string/Long) & will do that once you network gurus give this a thumbs up. Thank you
Some notes.
1. This isn't a subnet calculator, so no verification of mask to network class is being performed. The data being sent to this routine would be real-world CIDR. Because of this, a 31-bit mask is not trapped as a 'bad format'. That being said, all the sanity checks in the code are primarily for testing only. The format of the CIDR will eventually be validated (in case of garbled data) before the function is ever called.
2. Number of usable hosts would equate to lMax - lMin -1 except that a 32-bit mask would result in just 1 host
3. The first useable host would be lMin+1 and last would be lMax-1. lMin would be the subnet ID and lMax would be the broadcast address
Last edited by LaVolpe; Apr 16th, 2015 at 12:55 PM.
Reason: fixed typos
-
Apr 17th, 2015, 07:41 AM
#2
Re: Convert CIDR To Subnet Range (IPv4)
I'll mark this resolved, but if anyone sees an issue, please post it here. The code appears to be working, I just don't want to leave my buddy hanging if there is a logic flaw
-
Oct 31st, 2021, 09:01 PM
#3
New Member
Re: [RESOLVED] Convert CIDR To Subnet Range (IPv4)
this post is a few years old but i just found it a few days ago and the posted code works great. The vb guru king lavolpe has come to the rescue once again. I was using a free service to find city country from IP with a call from VB6 inet but the service was missing in action last attempt so I thought I would try to knock out a quick solution in VB as i had previously done a country from IP a while back. Well, the country/city is not so easy as it requires the CIDR formula which, as lavolpe mentioned is complex. I have no idea HOW it works but I plugged in the lavolpe code and was good to go. Now i can see a list of where my users are from country/city without rely on third party service which can vanish at any time.
And thank you for the vb png which I also used in my bg game greedygammon (written in VB-5/6). As soon as i saw "lavolpe" in the CIDR search results from google i was like YESSS!! and was not disappointed
It took a while to get everything to work as the csv file from maxmind was 220 megs and VB6 tapped out under that load so I had to break up the file into 5 parts and ran a separate exe for each one. Only took about 2 minutes to process on my slow i3 machine but good enough for what i use it for
cheers,
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|