Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Related:
Script to assign and remove arbitrary secondary IPs to an interface

I'm trying to augment the script in the above question, by validating the user input so that the script will only work with valid IP addresses and subnet-masks. I'm aware there are a number of different regular expressions available that will check IPs, but I don't know how (or even if there is a way) to use this against the variables in my batch script with native Windows XP commands.

Can someone point me in the right direction, here?

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I've been tinkering. Don't ask me why... but here is quite an extensive check for your ipaddress/gateway/subnet-mask:

@Echo Off

set NEW-IPADDR=192.168.1.2
set NEW-MASK=255.255.255.240
set NEW-GW=192.168.1.1

set RETURN=isValidIP
goto checkIP

:isValidIP
echo.We are good to go.

REM ---------------------------------------------------------------------
REM Do whatever with the IP/mask/GW here.  The values appear to be valid.
REM ---------------------------------------------------------------------
goto :End

:checkIP
for /f "tokens=1,2,3,4 delims=. " %%a in ("%NEW-IPADDR%") do set ip1=%%a&set ip2=%%b&set ip3=%%c&set ip4=%%d
set /a decIP=(16777216*%ip1%)+(65536*%ip2%)+(256*%ip3%)+%ip4% 2> nil
for /f "tokens=1,2,3,4 delims=. " %%a in ("%NEW-MASK%") do set mask1=%%a&set mask2=%%b&set mask3=%%c&set mask4=%%d
set /a decMask=(16777216*%mask1%)+(65536*%mask2%)+(256*%mask3%)+%mask4% 2> nil
set /a netAddr="%decIP%&%decMask%" 2> nil
for /f "tokens=1,2,3,4 delims=. " %%a in ("%NEW-GW%") do set gw1=%%a&set gw2=%%b&set gw3=%%c&set gw4=%%d
set /a decGW=(16777216*%gw1%)+(65536*%gw2%)+(256*%gw3%)+%gw4% 2> nil
set /a gwNetAddr="%decGW%&%decMask%" 2> nil


set isBadLabel=badIP
if %ip1% EQU 127 (goto :badIP)
if %ip1% EQU 0 (goto :badIP)
set num=%ip1%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%ip2%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%ip3%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%ip4%
call :checkNum
if %badNum% equ 1 (goto :End)

set isBadLabel=badMask
set num=%mask1%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%mask2%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%mask3%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%mask4%
call :checkNum
if %badNum% equ 1 (goto :End)

set isBadLabel=badGW
set num=%gw1%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%gw2%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%gw3%
call :checkNum
if %badNum% equ 1 (goto :End)
set num=%gw4%
call :checkNum
if %badNum% equ 1 (goto :End)

set testmask=-2
set bcast=0

:loopmask
  set /a testmask=%testmask%+%testmask%
  if %decmask% EQU %testmask% (set bcast=%testmask%)
if %bcast% neq 0 (goto :goodMask)
if %testmask% geq -16777216 (goto :loopmask)

:badMask
echo.Bad subnet mask. (%NEW-MASK%)  Check and try again.
echo.
goto :End

:badIP
echo.Bad IP Address. (%NEW-IPADDR%)  Check and try again.
echo.
goto :End

:goodMask
set /a bcast="%bcast%^-1"
set /a bcast=%netAddr%+%bcast%
if %decIP% equ %bcast% (goto :badIP)

if %decIP% equ %decGW% (goto :badGW)
if %gwNetAddr% neq %netAddr% (goto :badGW)

if %decGW% equ %bcast% (goto :badGW)
if %decGW% equ %netAddr% (goto :badGW)

goto :goodGW
:badGW
echo.Bad Gateway Address. (%NEW-GW%)  Check and try again.
echo.
goto :End

:goodGW
goto %RETURN%

goto :End

:checkNum
set badNum=0
set /a numval=%num% 2> nil
if "z%num%" neq "z%numval%" (set badNum=1) else (
  if %num% GTR 255 (set badNum=1) else (
    if %num% LSS 0 (set badNum=1)
  )
)
if %badNum% equ 1 (goto %isBadLabel%)
goto :EOF

:End

It even works in vista, and 7.

---- whops forgot to check if the gateway is the net address/broadcast address. ----

share|improve this answer
    
Wow. I'm going to have to sit down with this and pick it apart sometime. Thanks. –  Iszi Dec 14 '11 at 15:41
    
I'm still trying to figure out why I did all of this. imho... The only confusing bit is when I did the subnet mask checking, I started with -2 and doubled it repeatedly. why a negative number? well batch files are processed in a 32-bit environment (even in 64-bit windows) with a signed integer. -2 = 0xFFFFFFFE = 11111111111111111111111111111110. I initially double it before I bother using that as a mask... so we start with 11111111111111111111111111111100 which translates as 255.255.255.252 which is the first usable subnet-mask. –  TheCompWiz Dec 14 '11 at 16:01
    
It should check the following: are the values in each octet between 0 & 255. does the IP start with 127... is the subnet mask actually valid... is the IP the network-address or broadcast address... is the gateway inside the same subnet as the IP... etc... –  TheCompWiz Dec 14 '11 at 16:06
    
Wow. That's a lot more than I'd have bothered to have it check. I would have been fine with each octet being <=255, really. If you could add more comments to the code, to help explain the usage and functions of some of the commands, it would be great. If not, I'll edit it in when I have time to pick it apart myself later. Thanks again! –  Iszi Dec 14 '11 at 20:18
    
Also, the initial three SET lines should be SET /P since the intent here is to validate IPs input by the user - not included in the script. –  Iszi Dec 14 '11 at 20:20
show 1 more comment

You can use FindStr with RegEx's:

/r : Uses search strings as regular expressions. Findstr interprets all metacharacters as regular expressions unless you use /l.

Using regular expressions with findstr

Findstr is capable of finding the exact text you are looking for in any ASCII file or files. However, sometimes you have only part of the information that you want to match, or you want to find a wider range of information. In such cases, findstr has the powerful capability to search for patterns of text using regular expressions.

Regular expressions are a notation for specifying patterns of text, as opposed to exact strings of characters. The notation uses literal characters and metacharacters. Every character that does not have special meaning in the regular expression syntax is a literal character and matches an occurrence of that character. For example, letters and numbers are literal characters. A metacharacter is a symbol with special meaning (an operator or delimiter) in the regular-expression syntax.

The following table lists the metacharacters that findstr accepts. enter image description here

Keep in mind that FindStr's RegEx system is not as robust as many others, so not all Regular Expressions will work without a little modification.

share|improve this answer
    
Findstr finds text, but can it return input to the batch script as to whether or not the text was found in a way that I can use for an IF statement? –  Iszi Dec 13 '11 at 13:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.