discussion here
a revised version of Convert IP address to country name and code
provided by Wayne Diamond
because of new the forums i am posting it here
this program gets it ipaddress from a file listing
the program does not say this but the listing of ip address can be just the numbers themselves.
a revised version of Convert IP address to country name and code
provided by Wayne Diamond
because of new the forums i am posting it here
this program gets it ipaddress from a file listing
the program does not say this but the listing of ip address can be just the numbers themselves.
Code:
'ip2cntry.bas 'compiled with pbcc 4.04 'program gets a listing of ip addresses from a file then displays results 'use file redirection to send output to file. ' 'the output file will be easy to sort and additional information can be placed in the results file including comments 'from the input file, the comments need to be after a comma ' 'the data base will be sorted in the array C2IPinf in numerical order using the field C2IPData.dwFrom 'the search for the ip address is in binary 'the binary search is not perfectly written but it does work to get close before trying a match 'my test show it took 5 seconds to find 432000 ip addresses from a file in a 103000 ip country database with ranges 'the test does not include showing the results to the console or redirection to a file 'with reporting results to a file took an additional 5 seconds, basically this program is fast. #COMPILE EXE "ip2cntry.exe" #REGISTER NONE #INCLUDE "win32api.inc" TYPE C2IPData dwFrom AS QUAD dwdivider AS STRING * 1 dwTo AS QUAD dwCode AS STRING * 2 dwName AS STRING * 50 END TYPE TYPE C2IPDatasort dwfromstr AS STRING * 16 dwFrom AS QUAD dwTo AS QUAD dwCode AS STRING * 2 dwName AS STRING * 50 END TYPE GLOBAL C2IPinf() AS C2IPData GLOBAL C2IPmax AS DWORD FUNCTION AppPath() EXPORT AS STRING LOCAL zTmp AS ASCIIZ * 256 LOCAL sTmp AS STRING LenExeName& = GetModuleFileName(BYVAL %NULL, zTmp, SIZEOF(zTmp)) IF LenExeName& THEN LenExeName& = MIN&(LenExeName&, SIZEOF(zTmp)) sTmp = LEFT$(zTmp, LenExeName&) sTmp = LEFT$(sTmp,INSTR(-1,sTmp,"\")) FUNCTION = sTmp END IF END FUNCTION SUB C2IP_Init() LOCAL sDat AS STRING LOCAL ssdat AS STRING LOCAL lMax AS LONG LOCAL i AS LONG LOCAL sdatafileipcountry AS STRING DIM b(3)AS STRING DIM C2IPinfsort() AS C2IPData sdatafileipcountry=AppPath & "ip2cntry.dat" TRY OPEN sdatafileipcountry FOR INPUT AS #1 LEN=16384 CATCH CLOSE C2IPmax = 0& STDOUT "cannot find file "+sdatafileipcountry EXIT SUB END TRY i=1& TRY PRINT "reading file with ip addresses of countries" lmax=0& WHILE NOT EOF(1) LINE INPUT #1,sdat ssdat=TRIM$(sdat) IF LEN(ssdat)<3& THEN ITERATE IF i THEN IF LEFT$(ssdat,2)="##" THEN i=0&:PRINT RIGHT$(ssdat,LEN(ssdat)-2) END IF IF LEFT$(ssdat,1&)<>$DQ THEN ITERATE IF TALLY(ssdat,",")<>3& THEN ITERATE IF TALLY(ssdat,$DQ)<>8& THEN ITERATE INCR lmax WEND CLOSE CATCH C2IPmax = 0& STDOUT "problem reading file "+sdatafileipcountry EXIT SUB END TRY REDIM C2IPinfsort(1:lmax) AS C2IPDatasort TRY OPEN sdatafileipcountry FOR INPUT AS #1 LEN=16384 I=0& WHILE I<>LMAX IF EOF(1) THEN EXIT LOOP LINE INPUT #1,sdat ssdat=TRIM$(sdat) IF LEN(ssdat)<3& THEN ITERATE IF LEFT$(ssdat,1&)<>CHR$(34) THEN ITERATE IF TALLY(ssdat,",")<>3& THEN ITERATE IF TALLY(ssdat,$DQ)<>8& THEN ITERATE INCR I PARSE ssdat, b() C2IPinfsort(i).dwFrom = VAL(b(0)) C2IPinfsort(i).dwfromstr=RIGHT$(SPACE$(16)+TRIM$(b(0)),16) C2IPinfsort(i).dwTo = VAL(b(1)) C2IPinfsort(i).dwCode = b(2) C2IPinfsort(i).dwName = b(3) WEND CLOSE 1 C2IPmax = I CATCH C2IPmax = 0& STDOUT "problem reading file "+sdatafileipcountry CLOSE 1 EXIT SUB END TRY PRINT "reading done" ARRAY SORT c2ipinfsort() REDIM C2IPinf(1:lmax) AS C2IPData FOR i=1 TO c2ipmax C2IPinf(i).dwFrom=C2IPinfsort(i).dwFrom C2IPinf(i).dwTo=C2IPinfsort(i).dwTo C2IPinf(i).dwCode=C2IPinfsort(i).dwCode C2IPinf(i).dwName=C2IPinfsort(i).dwName NEXT i END SUB FUNCTION PBMAIN() AS LONG LOCAL I AS DWORD LOCAL J AS LONG LOCAL K AS LONG LOCAL iindex1 AS LONG LOCAL iindex2 AS LONG LOCAL iindexlow AS LONG LOCAL iindexhigh AS LONG LOCAL QIP AS QUAD DIM ipBit() AS INTEGER REDIM ipbit(4) LOCAL sip AS STRING LOCAL siplocation AS STRING LOCAL sdatafileinput AS STRING LOCAL sdatainput AS STRING LOCAL sipnotation AS STRING LOCAL STEMP AS STRING sdatafileinput=COMMAND$ IF LEN(sdatafileinput)=0 THEN GOTO displayhelp IF INSTR(sdatafileinput,"?") THEN GOTO displayhelp TRY OPEN sdatafileinput FOR INPUT AS #1 LEN=16384 CLOSE 1 CATCH STDOUT "cannot find the input file "+sdatafileinput GOTO finish END TRY 'load the country ip database C2IP_Init IF C2IPMAX<1 THEN GOTO finish PRINT "no of country ip addresses loaded"+STR$(c2ipmax) TRY OPEN sdatafileinput FOR INPUT AS #1 LEN=16384 CATCH STDOUT "problem reading file "+sdatafileinput CLOSE 1 GOTO finish END TRY PRINT "processing list of ip addresses in "+sdatafileinput readdatafileagain: IF EOF(1) THEN GOTO endofdatafile LINE INPUT #1,sdatainput sdatainput=TRIM$(sdatainput) IF LEN(sdatainput)>7 THEN K=INSTR(sdatainput,",") IF K>7 THEN SIP=LEFT$(sdatainput,k-1) sdatainput=sdatainput+" " sipnotation=RIGHT$(sdatainput,LEN(sdatainput)-k) IF LEN(sipnotation)>1 THEN IF LEFT$(sipnotation,1)=$DQ THEN sipnotation=RIGHT$(sipnotation,LEN(sipnotation)-1):sipnotation=TRIM$(sipnotation) END IF IF LEN(sipnotation)>1 THEN IF RIGHT$(sipnotation,1)=$DQ THEN sipnotation=LEFT$(sipnotation,LEN(sipnotation)-1):sipnotation=TRIM$(sipnotation) END IF ELSE SIP=TRIM$(sdatainput) sipnotation="" END IF GOSUB GETIPINFO STDOUT RIGHT$(SPACE$(15)+sip,15)+" "+siplocation+" "+TRIM$(sipnotation) END IF GOTO readdatafileagain endofdatafile: CLOSE 1 PRINT "program finished" GOTO FINISH GETIPinfo: REPLACE $DQ WITH "" IN sip REPLACE " " WITH "" IN sip sip=TRIM$(sip) IF LEN(sip)<7 THEN siplocation="00 bad ip address given ":RETURN IF TALLY(sip,".")<>3 THEN siplocation="00 bad ip address given ":RETURN IF TALLY(sip,"..")>0 THEN siplocation="00 bad ip address given ":RETURN IF LEFT$(sip,1)="." THEN siplocation="00 bad ip address given ":RETURN IF RIGHT$(sip,1)="." THEN siplocation="00 bad ip address given ":RETURN stemp=sip REPLACE ANY "0123456789" WITH "" IN stemp stemp=TRIM$(stemp) IF LEN(stemp) THEN siplocation="00 bad ip address given ":RETURN FOR j = 1& TO 4&:ipBit(j) = VAL(PARSE$(sIP, ".", j)): NEXT QIp= (ipBit(1&)*16777216) + (ipBit(2&)*65536) + (ipBit(3&)*256) + (ipBit(4&)) iindex1=1 IF qip>C2IPInf(C2IPmax).dwTo THEN GOTO noipmatch IF qip<=C2IPInf(1).dwto THEN GOTO finditnow iindexlow=1& iindexhigh=c2ipmax iindex2=iindexhigh\2 indexit: IF iindex2<2 THEN iindex1=1:GOTO finditnow IF iindexlow>(c2ipmax-3&) THEN iindex1=c2ipmax-3:GOTO finditnow IF (iindexhigh-iindexlow)<5& THEN iindex1=iindexlow:GOTO finditnow 'print iindexlow,iindexhigh IF QIP >C2IPInf(iindex2).dwfrom THEN iindexlow=iindex2:iindex2=iindexlow+((iindexhigh-iindexlow)\2):GOTO indexit IF QIP <C2IPInf(iindex2).dwto THEN iindexhigh=iindex2:iindex2=iindexlow+((iindexhigh-iindexlow)\2):GOTO indexit finditnow: IF iindex1<1 THEN iindex1=1 IF iindex1>c2ipmax THEN iindex1=c2ipmax FOR I = iindex1 TO C2IPmax IF QIP => C2IPInf(i).dwFrom AND QIP <= C2IPInf(i).dwTo THEN siplocation=UCASE$(LEFT$(C2IPinf(i).dwCode & " " & TRIM$(C2IPinf(i).dwName)+SPACE$(24),24)) RETURN END IF IF qip<C2IPInf(i).dwfrom THEN GOTO noipmatch NEXT I 'a catch all noipmatch: siplocation="XX IP OF COUNTRY UNKNOWN" RETURN displayhelp: PRINT "place the input file with ip addresses on the command line" PRINT "file should have two strings on each line separated by a comma" PRINT PRINT "format of input file lines should look like:" PRINT $DQ+"201.202.203.205"+$DQ+","+$DQ+"then any notes you want in ouput"+$DQ PRINT PRINT "the ip2cntry.dat should look like this, with the first line having ##" PRINT "## this file with ip addresses of countries is provide by abc company" PRINT $DQ+"50331648"+$DQ+","+$DQ+"67108863"+$DQ+","+$DQ+"US"+$DQ+","+$DQ+"UNITED STATES"+$DQ PRINT $DQ+"3384803328"+$DQ+","+$DQ+"3385851903"+$DQ+","+$DQ+"CR"+$DQ+","+$DQ+"COSTA RICA"+$DQ finish: END FUNCTION
Comment