0

I hate to ask this question, but am very new to scripting and need help.

I would like to create a calculator using VBS that will accept my input and give me a range of IP address acceptable.

For example:

VBS asks for user input User inputs the IP address/netmask : 214.13.104.128/28

Output: IP Address Range = 214.13.104.129 - 214.13.104.190

I know that there are many online tools you can use, but I will need to use this on systems that cant access the internet.

Cœur
  • 37,241
  • 25
  • 195
  • 267
NuckinFutz
  • 85
  • 5
  • 18
  • why not download a portable app? – CustomX Nov 05 '12 at 14:03
  • well, downloading and transferring to the other computers is not allowed. this would need to be something i could retype the code on the other systems. Thanks – NuckinFutz Nov 05 '12 at 14:04
  • So i found this, and it looks like exactly what i need, but its in C# and i need it to be a .vbs. can anyone help me redo it in .vbs? http://stackoverflow.com/questions/1470792/how-to-calculate-the-ip-range-when-the-ip-address-and-the-netmask-is-given?rq=1 thank you – NuckinFutz Nov 06 '12 at 10:26

2 Answers2

4

Not sure if you still need this but for the sake of Informational Science and those who are searching for a solution I'm posting this anyways. I hope it at least helps someone looking for a solution. If not the OP... many other Stack Overflow users.

CIDRIP = "192.168.0.1/24" 'must be in CIDR Format as no error checking added
wscript.echo "IP Address Range " & CIDR2IP(CIDRIP, false) & " - " & CIDR2IP(CIDRIP, True)

Function CIDR2IP(ip, high)
    highs = "11111111111111111111111111111111"
    lows = "00000000000000000000000000000000"
    byte0 = Dec2bin(Split(ip, ".")(0))
    byte1 = Dec2bin(Split(ip, ".")(1))
    byte2 = Dec2bin(Split(ip, ".")(2))
    byte3 = Dec2bin(Split(Split(ip, ".")(3), "/")(0))
    Mask = Split(Split(ip, ".")(3), "/")(1)
    bytes = byte0 & byte1 & byte2 & byte3
    rangelow = Left(bytes, Mask) & Right(lows, 32 - Mask)
    rangehigh = Left(bytes, Mask) & Right(highs, 32 - Mask)
    iplow = bin2ip(Left(bytes, Mask) & Right(lows, 32 - Mask))
    iphigh = bin2ip(Left(bytes, Mask) & Right(highs, 32 - Mask))
    If high Then
        CIDR2IP = iphigh
    Else
        CIDR2IP = iplow
    End If
End Function

Function that converts a 32-bit Binary string into an IP Address

'expecting input like 00000000000000000000000000000000
Function bin2ip(strbin)
    ip0 = C2dec(Mid(strbin, 1, 8))
    ip1 = C2dec(Mid(strbin, 9, 8))
    ip2 = C2dec(Mid(strbin, 17, 8))
    ip3 = C2dec(Mid(strbin, 25, 8))
    'combines all of the bytes into a single string
    bin2ip = ip0 & "." & ip1 & "." & ip2 & "." & ip3 
End Function

Function that converts binary number to a decimal

'expecting input like 00010101
Function C2dec(strbin)
    length = Len(strbin)
    dec = 0
    For x = 1 To length
        binval = 2 ^ (length - x)
        temp = Mid(strbin, x, 1)
        If temp = "1" Then dec = dec + binval
    Next
    C2dec = dec
End Function

Function that converts decimal number into Binary

'Expecting input 0 thru 255
Function Dec2bin(dec)
    Const maxpower = 7
    Const length = 8
    bin = ""
    x = cLng(dec)
    For m = maxpower To 0 Step -1
        If x And (2 ^ m) Then
            bin = bin + "1"
        Else
            bin = bin + "0"
        End If
    Next
    Dec2bin = bin
End Function

Added Bonus - for anyone that knows MYSQL and using IP addresses in MYSQL, they'll immediately recognize the functions.

'expecting input like 10.120.44.1 and converts to 175647745
Function INET_NTOA(ip)
    ip0 = Split(ip, ".")(0)
    ip1 = Split(ip, ".")(1)
    ip2 = Split(ip, ".")(2)
    ip3 = Split(ip, ".")(3)
    urlobfs = 0
    urlobfs = ip0 * 256
    urlobfs = urlobfs + ip1
    urlobfs = urlobfs * 256
    urlobfs = urlobfs + ip2
    urlobfs = urlobfs * 256
    urlobfs = urlobfs + ip3
    INET_NTOA = urlobfs
End Function

'expecting input like 175647745 and converts to 10.120.44.1
'Bugs will occur for CLng ceiling numbers. +/- 2,147,483,647
Function INET_ATON(ip)
    Dim ipa()
    ReDim ipa(3)
    n2ip = ip
    For i = 3 To 1 Step -1
        ipa(i) = n2ip Mod 256
        n2ip = n2ip / 256
    Next
    ipa(0) = CInt(n2ip)
    INET_ATON = ipa(0) & "." & ipa(1) & "." & ipa(2) & "." & ipa(3)
End Function

Update Sept 2021 Popular request demanded returning a usable IP range from a CIDR Address and I had no idea... It's been sitting in my list of random IP functions forever.

Function CIDR2IPRANGE(cidr)
    ip = cidr
    highs = "11111111111111111111111111111111"
    lows = "00000000000000000000000000000000"
    byte0 = Dec2bin(Split(ip, ".")(0))
    byte1 = Dec2bin(Split(ip, ".")(1))
    byte2 = Dec2bin(Split(ip, ".")(2))
    byte3 = Dec2bin(Split(Split(ip, ".")(3), "/")(0))
    Mask = Split(Split(ip, ".")(3), "/")(1)
    bytes = byte0 & byte1 & byte2 & byte3
    lownetworkrange = Left(bytes, Mask)
    lowhostrange = Right(lows, 31 - Mask) & "1"
    rangelow = lownetworkrange + lowhostrange
    highnetworkrange = Left(bytes, Mask)
    highhostrange = Right(highs, 31 - Mask) & "0"
    rangehigh = highnetworkrange + highhostrange
    iplow = bin2ip(rangelow)
    iphigh = bin2ip(rangehigh)
    CIDR2IP = iplow & " - " & iphigh
End Function

Cheers!

Steve Kline
  • 805
  • 4
  • 11
  • 1
    Absolutely Brilliant @Steve Kline ! – AlexLaforge Mar 17 '21 at 02:55
  • It would be awesome to obtain the list of all IPs within this range... Actually trying to code this in VBScript, but no chance for me so far ;) – AlexLaforge Mar 17 '21 at 03:15
  • `INET_ATON` is sometimes producing the incorrect result for me by one number in the first and second octet (so far that I've seen). For example `1439729672` produces `86.209.136.8` when it should be converting to `85.208.136.8` I think it might be a rounding error, but need to investigate more when I have a minute. Any ideas? – Sum None Dec 20 '22 at 04:36
  • I edited your answer. I couldn't find a round down function for each loop of `n2ip` result and therefore just `split` (truncated) everything after the decimal. That's the best I can think of at the moment and seems to solve the issue. `Split` also seems to gracefully handle when there is no decimal delimiter (.i.e. `"."`) and just returns the whole number. – Sum None Dec 20 '22 at 05:23
  • Lastly, I removed `Mod` to eliminate the Mod overflow "bug" you mentioned for numbers greater than CLng. I ran into that one quickly with my application (e.g. 3039317790 = 181.40.79.30). – Sum None Dec 22 '22 at 10:54
  • Seems my edit was rejected or maybe timed out? It would be nice to know one way or the other. It was my first edit, so I don't know what to expect. Anyway, I tried. – Sum None Dec 23 '22 at 07:20
0

As an addition to the excellent @Steve kline answer, for those whishing to obtain the list of all IP addresses within a range of IPs, here is a script grabbed from http://www.intelliadmin.com/index.php/2012/04/use-vb-script-to-list-a-range-of-ip-addresses/ (with the help of the Wayback Machine).

I think that the iS4, iS3, iS2 variables should be turned to 0 instead of 1.

'*********************************
'* IntelliAdmin, LLC 2012        *
'* http://www.intelliadmin.com   *
'*********************************

'The start and end ip range
StartIP = "10.10.29.129"
EndIP = "10.10.29.240"


'This function contains the code that will execute
'against the remote hosts

Function ExecuteAction(HostName)

 'Put your code here and use the variable hostname
 WScript.Echo "Hostname: " & HostName

End Function


'Parsing code below

Dim iS1,iS2,iS3,iS4
Dim iE1,iE2,iE3,iE4
Dim iC1,iC2,iC3,iC4


'Convert our starting ip to octets

IPList = Split(StartIP, ".")

iS1 = cint(IPList(0))
iS2 = cint(IPList(1))
iS3 = cint(IPList(2))
iS4 = cint(IPList(3))

'Convert our endingip to octets

IPList = Split(EndIP, ".")

iE1 = cint(IPList(0))
iE2 = cint(IPList(1))
iE3 = cint(IPList(2))
iE4 = cint(IPList(3))

'Loop through our list of IP addresses

for iC1=iS1 to 255
 for iC2=iS2 to 255
  for iC3=iS3 to 255
   for iC4=iS4 to 255
    ExecuteAction(iC1 & "." & iC2 & "." & iC3 & "." & iC4)
    if ((iC1>=iE1) and (iC2>=iE2) and (iC3>=iE3) and (iC4>=iE4)) then
     iC1=255
     iC2=255
     iC3=255
     iC4=255
    end if
   next
   iS4=1
  next
  iS3=1
 next
 iS2=1
next
AlexLaforge
  • 499
  • 3
  • 19
  • I agree with you @SteveKline, but it's working so far. Thanks for your addition to your original upvoted answer ^!^ – AlexLaforge Sep 03 '21 at 17:14