Sarfaraz Merchant

 
Click the link above to have a look at photos clicked by me.
 
 
Filter By Month
 
 

Update GeoIpfree Ip2country database
posted on 26.03.2006 @ 5:03 PM in category: Tech
view count: 6060, comments count: 32
 
Awstats comes with free plug-in called GeoIpfree. This plug-in locate website visitors' countries of origin by their IP address, rather than by the domain name of their ISP. Problem with this plug-in is, its ip2country database which has not been update for a very long time. It locates me from Hong Kong where as I am browsing from India. Due to this problem I thought of updating its ip2country database.

I hate doing work manually, especially which is to be done again & again. So I have written a small application which will solve this problem.

You can download my application from here. Next you will have to download updated ip2country CSV from http://software77.net/cgi-bin/ip-country/geo-ip.pl. They update their ip2country database almost everyday. Not only this you can download this database for free.

In my application you have to point to downloaded CSV and where you want to save DAT file. This application will remove all un-required data from CSV file and convert it plain text. After creating the text file it will use txt2ipct script provided with GeoIpfree plug-in to convert it into DAT file. I have included the script file along with my application. You will have to replace the old DAT file with this new file. That’s it you are done.

********
New Release on 26th May 2006

Changes done are:
1) Checks if Active Perl is installed or not.
2) Check txt2ipctl.pl file exists in the same directory
3) Frees up the memory after using.

Download (13.7 kb)
Comments + Trackbacks
 
 commented by Dhiraj Gupta on Thursday, May 11, 2006 @ 12:57 AM   
Way freaking cool!!!!

Awesome work, Saf!

-Dhiraj.
 
 commented by Luke on Monday, June 05, 2006 @ 12:58 PM   
Good app, rather helpful thanks.

But that perl script 'txt2ipct.pl' has some strict related errors with the latest ActivePerl install and default settings.

After fixing the handful of those it appears to work. Still yet to test.
 
 commented by Sarfaraz on Tuesday, June 06, 2006 @ 12:05 AM   
Luke I am glad that this app is helpful to you.

Can you specify your Active Perl version. Cause I am using 5.8.8 Build 817 and having no problems with 'txt2ipct.pl' script.
 
 commented by Luke on Wednesday, June 07, 2006 @ 1:29 PM   
yeah me too. perhaps there's something with the default strictness.. I dunno.. The output of my modified txt2ipct.pl didn't work so I ran your temp.txt through the script that came with GeoIP.pm on our linux webserver. That worked - so I got there in the end. Thanks again.
 
 commented by diggy on Monday, July 31, 2006 @ 2:52 PM   
where i can get text file database.
 
 commented by gordon on Monday, July 31, 2006 @ 8:09 PM   
Thanks for this, works great! Would it be possible to get a version that can run on a console-only linux box?
 
 commented by Chris on Tuesday, August 01, 2006 @ 11:45 PM   
Same thing as the last guy, except I am running on Solaris with no gui. Can you post your perl script that converts the cvs file? I'd like to put it in a cron job to run once a month. Thanx!
 
 commented by sarfaraz on Wednesday, August 02, 2006 @ 11:41 AM   
diggy

Which text file are you talking about? The one that my app creates from CSV? It is created in the same directory where my application is copied. Also note that it is delete once the .dat file is created. If you want this temp file then will have to kill the app once it creates the temp.txt file.

gordon

I am sorry I have never programmed for linux. So I by myself wont be able to create a linux app, but if you need any help you can always post here.

Chris

Chris I am not using perl script to convert csv file. I have written a small application in C#.
 
 commented by gordon on Thursday, August 03, 2006 @ 2:06 AM   
Ahhh, got ya. I think Chris and I were both looking for the same thing and assumed you made the program in perl. Thanks for your efforts!
 
 commented by Chris on Tuesday, August 08, 2006 @ 1:33 AM   
Here is a little script I wrote to do the same thing. Alot slower, but it works.

#!/bin/sh
#geoip.sh by Chris Gage
#Converts an IP CSV file to the GEOIPfree format
#
#To use update variables below to suite your system and add an
#entry like the following to your cron
#15 23 21 * * /usr/local/scripts/geoip.sh >/dev/null 2>&1

INFILE=ips.csv
TEMPFILE=raw_temp.$$
FINALFILE=ipscountry.dat
WGET=/usr/sfw/bin/wget
MAIL=/usr/bin/mailx
ADDRESS=email@domain.com
GEODIR=/usr/perl5/site_perl/5.8.4/Geo/
URL=http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download
GZIP=/usr/bin/gunzip
PERL=/usr/bin/perl
TXT_DB_SCRIPT=/usr/local/scripts/txt2ipct.pl
TMP_DIR=/tmp

if [ -f ${TMP_DIR}/${INFILE}.gz ]
then
rm ${TMP_DIR}/${INFILE}.gz
fi

$WGET -O ${TMP_DIR}/${INFILE}.gz $URL > /dev/null 2>&1

EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
echo "GEO IP Free failed to update while downloading from $URL"|$MAIL -s "GEOIPfree update failed `date +%m/%d/%Y`" $ADDRESS

if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/${INFILE}.gz ]
then
rm ${TMP_DIR}/${INFILE}.gz
fi
exit 1
fi

$GZIP ${TMP_DIR}/${INFILE}.gz > /dev/null 2>&1

for NEXTLINE in `grep -v "^#" ${TMP_DIR}/$INFILE`
do

TEST=`echo $NEXTLINE|cut -c2|grep -v [0-9]`
if [ "$TEST" != "" ]; then
continue
fi

NUM1=`echo $NEXTLINE|cut -d, -f1|sed 's/\"//g'`

NUM2=`echo $NEXTLINE|cut -d, -f2|sed 's/\"//g'`

CNTRY=`echo $NEXTLINE|cut -d, -f5|sed 's/\"//g'`

TEMP=`expr 256 "*" 256 "*" 256`

A1=`expr $NUM1 "/" $TEMP`
NUM1=`expr $NUM1 "-" $TEMP "*" $A1`

A2=`expr $NUM2 "/" $TEMP`
NUM2=`expr $NUM2 "-" $TEMP "*" $A2`

TEMP=`expr 256 "*" 256`

B1=`expr $NUM1 "/" $TEMP`
NUM1=`expr $NUM1 "-" $TEMP "*" $B1`

B2=`expr $NUM2 "/" $TEMP`
NUM2=`expr $NUM2 "-" $TEMP "*" $B2`

TEMP=256

C1=`expr $NUM1 "/" $TEMP`
NUM1=`expr $NUM1 "-" $TEMP "*" $C1`

C2=`expr $NUM2 "/" $TEMP`
NUM2=`expr $NUM2 "-" $TEMP "*" $C2`

IP1=${A1}.${B1}.${C1}.${NUM1}
IP2=${A2}.${B2}.${C2}.${NUM2}

echo "${CNTRY}: $IP1 $IP2" >> ${TMP_DIR}/$TEMPFILE

done

$PERL $TXT_DB_SCRIPT ${TMP_DIR}/$TEMPFILE ${TMP_DIR}/$FINALFILE > /dev/null 2>&1

EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
echo "GEO IP Free failed to update while running $TXT_DB_SCRIPT"|/bin/mailx -s "GEOIPfree update failed `date +%m/%d/%Y`" $MAIL
if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/$INFILE ]
then
rm ${TMP_DIR}/$INFILE
fi
if [ -f ${TMP_DIR}/$FINALFILE ]
then
rm ${TMP_DIR}/$FINALFILE
fi
exit 1
fi

if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi

if [ -f ${TMP_DIR}/$INFILE ]
then
rm ${TMP_DIR}/$INFILE
fi

if [ -f ${GEODIR}/$FINALFILE ]; then
mv ${GEODIR}/$FINALFILE ${GEODIR}/${FINALFILE}.bak
fi

mv ${TMP_DIR}/$FINALFILE ${GEODIR}/$FINALFILE

echo "GEO IP Free Successfully updated.\nThe new file is located at ${GEODIR}/${FINALFILE}"|$MAIL -s "GEOIPfree successfully updated on `date +%m/%d/%Y`" $ADDRESS
exit 0
 
 commented by sarfaraz on Tuesday, August 08, 2006 @ 12:48 PM   
Thanx a lot Chris for your effort & sharing it with us.
 
 commented by gordon on Tuesday, August 08, 2006 @ 9:51 PM   
yes, both of you = the man.
 
 commented by Chris on Saturday, August 19, 2006 @ 7:06 AM   
Ok, updated much faster shell script plus a little c. The expr commands each fork a new process which causes my first script to take over 48 hours to complete (but it does finish). compile this c code below to do the math part.
IE gcc -o geo-compute geoip.c

/*
Author: Chris Gage
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

int main ( void )
{
unsigned long tmp, a1, a2, b1, b2, c1, c2, d1, d2;
char cny[3];
char infile[100];
char outfile[100];
FILE* pfin;
FILE* pfout;

scanf ( " %99[^\n]", infile );
scanf ( " %99[^\n]", outfile );

pfin = fopen( infile, "r" );
if (pfin == NULL)
{
printf( "Error Opening %s\n", infile );
return 1;
}

pfout = fopen( outfile, "w" );
if (pfout == NULL)
{
printf( "Error Opening %s\n", outfile );
return 2;
}

for (;;)
{
fscanf( pfin, " %d,%d,%s", &d1, &d2, cny );
if (feof( pfin )) break;

tmp=256*256*256;

a1=d1/tmp;
d1=d1-(a1*tmp);

a2=d2/tmp;
d2=d2-(a2*tmp);

tmp=256*256;

b1=d1/tmp;
d1=d1-(b1*tmp);

b2=d2/tmp;
d2=d2-(b2*tmp);

tmp=256;

c1=d1/tmp;
d1=d1-(c1*tmp);

c2=d2/tmp;
d2=d2-(c2*tmp);

fprintf( pfout, "%s: %d.%d.%d.%d %d.%d.%d.%d\n", cny, a1, b1, c1, d1, a2, b2, c2,
d2);
}

fclose( pfin );
fclose( pfout );
return 0;
}
 
 commented by Chris on Saturday, August 19, 2006 @ 7:09 AM   
Now use this script to control the newly compiled c program. I put them all in /usr/local/scripts...

#!/bin/sh
#geoip.sh by Chris Gage
#Converts an IP CSV file to the GEOIPfree format
#
#To use update variables below to suite your system and add an
#entry like the following to your cron
#15 23 21 * * /usr/local/scripts/geoip.sh >/dev/null 2>&1
#
# TMP_DIR/TEMPFILE can be no longer than 99 characters
#
INFILE=ips.csv
TEMPFILE=raw_temp.$$
TEMPFILE2=raw_temp2.$$
FINALFILE=ipscountry.dat
WGET=/usr/sfw/bin/wget
MAIL=/usr/bin/mailx
ADDRESS=email@domain.com
GEODIR=/usr/perl5/site_perl/5.8.4/Geo
URL=http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download
GZIP=/usr/bin/gunzip
PERL=/usr/bin/perl
TXT_DB_SCRIPT=/usr/local/scripts/txt2ipct.pl
CSV_TO_TXT_SCRIPT=/usr/local/scripts/geo-compute
TMP_DIR=/tmp

if [ -f ${TMP_DIR}/${INFILE}.gz ]
then
rm ${TMP_DIR}/${INFILE}.gz
fi

$WGET -O ${TMP_DIR}/${INFILE}.gz $URL > /dev/null 2>&1

EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
echo "GEO IP Free failed to update while downloading from $URL"|$MAIL -s "GEOIPfree update failed `date +%m/%d/%Y`" $ADDRESS

if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/$TEMPFILE2 ]
then
rm ${TMP_DIR}/$TEMPFILE2
fi
if [ -f ${TMP_DIR}/${INFILE}.gz ]
then
rm ${TMP_DIR}/${INFILE}.gz
fi
exit 1
fi

$GZIP ${TMP_DIR}/${INFILE}.gz > /dev/null 2>&1

grep -v "^#" ${TMP_DIR}/$INFILE|sed 's/\"//g'|cut -d, -f1,2,5 > ${TMP_DIR}/$TEMPFILE2

(
echo ${TMP_DIR}/$TEMPFILE2
echo ${TMP_DIR}/$TEMPFILE
) 2>&1 | $CSV_TO_TXT_SCRIPT

EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
echo echo "GEO IP Free failed to update while running $CSV_TO_TXT_SCRIPT"|$MAIL -s "GEOIPfree update failed `date +%m/%d/%Y`" $ADDRESS

if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/$TEMPFILE2 ]
then
rm ${TMP_DIR}/$TEMPFILE2
fi
if [ -f ${TMP_DIR}/$INFILE ]
then
rm ${TMP_DIR}/$INFILE
fi
if [ -f ${TMP_DIR}/$FINALFILE ]
then
rm ${TMP_DIR}/$FINALFILE
fi

exit 1
fi

$PERL $TXT_DB_SCRIPT ${TMP_DIR}/$TEMPFILE ${TMP_DIR}/$FINALFILE > /dev/null 2>&1

EXITSTATUS=$?
if [ $EXITSTATUS != "0" ]
then
echo "GEO IP Free failed to update while running $TXT_DB_SCRIPT"|$MAIL -s "GEOIPfree update failed `date +%m/%d/%Y`" $ADDRESS
if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/$TEMPFILE2 ]
then
rm ${TMP_DIR}/$TEMPFILE2
fi
if [ -f ${TMP_DIR}/$INFILE ]
then
rm ${TMP_DIR}/$INFILE
fi
if [ -f ${TMP_DIR}/$FINALFILE ]
then
rm ${TMP_DIR}/$FINALFILE
fi
exit 1
fi

if [ -f ${TMP_DIR}/$TEMPFILE ]
then
rm ${TMP_DIR}/$TEMPFILE
fi
if [ -f ${TMP_DIR}/$TEMPFILE2 ]
then
rm ${TMP_DIR}/$TEMPFILE2
fi

if [ -f ${TMP_DIR}/$INFILE ]
then
rm ${TMP_DIR}/$INFILE
fi

if [ -f ${GEODIR}/$FINALFILE ]; then
mv ${GEODIR}/$FINALFILE ${GEODIR}/${FINALFILE}.bak
fi

mv ${TMP_DIR}/$FINALFILE ${GEODIR}/$FINALFILE

echo "GEO IP Free Successfully updated.\nThe new file is located at ${GEODIR}/${FINALFILE}"|$MAIL -s "GEOIPfree successfully updated on `date +%m/%d/%Y`" $ADDRESS
exit 0
 
 commented by Gizmhail on Thursday, August 31, 2006 @ 2:18 PM   
Thank you for this useful tool !
I'll just submit a tiny improvement :
I had some difficulties to run the C program : "high" IP where badly displayed (IP above 127.x.x.x). I think there is a problem in the types used in the fscanf and the final fprintf : instead of using %d, you should have used %lu, since variables are unsigned long ones.
Once I've changed this, results where fine for me. I've put the fixed code below.

Another tip to have better results with awstats : the file you'll get on software77.net doesn't say that 10.0.0.0 IPs are local ones (it just marks them as zz : Unknow). If this is important for you (if you have many connections from your firm's proxy for instance), replace ZZ by I0 for the local IPs in the file created by the C program (the last character of "I0" is the 0 digit, not the o letter : I did the mistake at first ;-) ).
Hope this'll help :o)

__________________________________


/*
Author: Chris Gage
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

int main ( void )
{
unsigned long tmp, a1, a2, b1, b2, c1, c2, d1, d2;
char cny[3];
char infile[100];
char outfile[100];
FILE* pfin;
FILE* pfout;

scanf ( " %99[^\n]", infile );
scanf ( " %99[^\n]", outfile );

pfin = fopen( infile, "r" );
if (pfin == NULL)
{
printf( "Error Opening %s\n", infile );
return 1;
}

pfout = fopen( outfile, "w" );
if (pfout == NULL)
{
printf( "Error Opening %s\n", outfile );
return 2;
}

for (;;)
{
fscanf( pfin, " %lu,%lu,%s", &d1, &d2, cny );
if (feof( pfin )) break;

tmp=256*256*256;

a1=d1/tmp;
d1=d1-(a1*tmp);

a2=d2/tmp;
d2=d2-(a2*tmp);

tmp=256*256;

b1=d1/tmp;
d1=d1-(b1*tmp);

b2=d2/tmp;
d2=d2-(b2*tmp);

tmp=256;

c1=d1/tmp;
d1=d1-(c1*tmp);

c2=d2/tmp;
d2=d2-(c2*tmp);

fprintf( pfout, "%s: %lu.%lu.%lu.%lu %lu.%lu.%lu.%lu\n", cny, a1, b1, c1, d1, a2, b2, c2,
d2);
}

fclose( pfin );
fclose( pfout );
return 0;
}


 
 commented by Chris on Friday, September 01, 2006 @ 2:52 AM   
Your right, I should have used %lu. My compiler (Solaris 10's standard) must have converted everything to long unsigned because mine works for IPs above 127.x.x.x.

Thanx for the tip on the 10 network. I added this to my C program, right above my fprintf line.

if (a1==10) strcpy (cny, "I0");
 
 commented by Gizmhail on Friday, September 01, 2006 @ 3:56 AM   
I was using gcc on Linux (Ubuntu) : it's been less tolerant ;-)

Good idea to insert the "i0" thing in the C !
Thank you again for this whole work ! :o)
 
 commented by Mischa on Monday, September 18, 2006 @ 8:43 AM   
Hello, would it be possible to modify GeoIPFree.exe so that it accepts command line parameters? I'm running this on Windows and I'd like to include it in a script.
Many thanks!
Mischa.
 
 commented by sarfaraz on Monday, September 18, 2006 @ 12:34 PM   
Hi Mischa, yes it is possible. The only thing is you will have to wait a little. Currently I am really busy with my daily job & plus I am also working on another small utility which is near completion. So probably after that I will take this up again.
In the mean time you can let me know the parameters that you want to pass.
 
 commented by Renzo on Tuesday, February 13, 2007 @ 3:31 PM   
Please add a -f on the gunzup command to overwrite existing files, if the script brakes.
 
 commented by reneweesp on Wednesday, February 28, 2007 @ 1:52 PM   
Can't run GeoIpfree.exe
getting error
can't initialize (0xc0000135) click ok to stop
 
 commented by sarfaraz on Wednesday, February 28, 2007 @ 3:46 PM   
Hi reneweesp
Which OS are using and what is your .NET Framework version?
 
 commented by Jason on Monday, June 04, 2007 @ 9:33 PM   
Hello,
I don't have a linux box, any chance you would be able to email me a copy of the DAT file?
 
 commented by reneweesp on Saturday, June 30, 2007 @ 3:30 AM   
now working copiled newly dat file date 30-06
 
 commented by Al on Wednesday, July 25, 2007 @ 12:14 PM   
Mega Thanks! If it really works i'll save lots of time... because have thought what i would doit by myself... but really wil be cool to have windows utility wich works without .Net Framework or perl/php script (my windows machine much faster than unix one)
 
 commented by Chris on Wednesday, October 17, 2007 @ 8:10 PM   
I couldn't get your program to work properly when it was invoked from the script via subshell echoes.

The changes below give the program the ability to take command line arguments so instead of this:

(
echo inputfile
echo outputfile
) 2>&1 | /path/to/geocompute


you can now invoke it with inputfile and outputfile as arguments:
/path/to/geocompute /path/to/input /path/to/output

I've included a complete copy of the updated source but the only changes are in leading up to the pfin.


___________________


/*
* Author: Chris Gage
* */
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, char** argv)
{
unsigned long tmp, a1, a2, b1, b2, c1, c2, d1, d2;
char cny[3];
char infile[100];
char outfile[100];
FILE* pfin;
FILE* pfout;

if (argc != 3) {
printf("Usage: %s in out\n", argv[0]);
exit(-1);
}

strcpy(infile, argv[1]);
strcpy(outfile, argv[2]);
//scanf ( " %99[^\n]", infile );
//scanf ( " %99[^\n]", outfile );
//

pfin = fopen( infile, "r" );
if (pfin == NULL)
{
printf( "Error Opening %s\n", infile );
return 1;
}

pfout = fopen( outfile, "w" );
if (pfout == NULL)
{
printf( "Error Opening %s\n", outfile );
return 2;
}

for (;;)
{
fscanf( pfin, " %lu,%lu,%s", &d1, &d2, cny );
if (feof( pfin )) break;

tmp=256*256*256;

a1=d1/tmp;
d1=d1-(a1*tmp);

a2=d2/tmp;
d2=d2-(a2*tmp);

tmp=256*256;

b1=d1/tmp;
d1=d1-(b1*tmp);

b2=d2/tmp;
d2=d2-(b2*tmp);

tmp=256;
c1=d1/tmp;
d1=d1-(c1*tmp);

c2=d2/tmp;
d2=d2-(c2*tmp);

if (a1==10) strcpy (cny, "I0");

fprintf( pfout, "%s: %lu.%lu.%lu.%lu %lu.%lu.%lu.%lu\n", cny, a1, b1, c1, d1, a2, b2, c2, d2);
}

fclose( pfin );
fclose( pfout );
return 0;
}
 
 commented by Chris on Friday, October 19, 2007 @ 10:14 PM   
Thats a really good idea. Thanx for the improvement. I think I'll change the one I have running as well.
 
 commented by Chris on Tuesday, April 22, 2008 @ 10:04 PM   
One last thing, we should probably use strncpy to keep from overrunning the variables. So like this....

strncpy(infile, argv[1], 99);
strncpy(outfile, argv[2], 99);
 
 commented by Javier on Saturday, June 14, 2008 @ 7:55 PM   
good!, you really help me
 
 commented by Warren on Monday, August 04, 2008 @ 12:23 AM   
I've taken this approach (for Linux users) for converting the file provided by webnet77 to a format that can be understood by txt2ipct.pl.

1. Download and unpack the txt file from webnet77 (IpToCountry.csv.gz)

2. cat IpToCountry.csv | grep -v '^#' $1|grep -v '^$'|awk 'BEGIN { FS = "\"" } ; { printf "%s: %i.%i.%i.%i %i.%i.%i.%i\n", $10, $2 / 16777216, ($2 % 16777216)/65536, (($2 % 16777216)% 65536)/256, (($2 % 16777216)% 65536)% 256, $4 / 16777216, ($4 % 16777216)/65536, (($4 % 16777216)% 65536)/256, (($4 % 16777216)% 65536)% 256}' > iptocountry.txt

3. perl txt2ipct.pl iptocountry.txt ipscountry.dat.new

Bit of long one liner, but works for me!
 
 commented by Warren on Monday, August 04, 2008 @ 12:29 AM   
Ooops, slight error there (the $1 belongs when running from a script not from the command line). Try this instead :

cat IpToCountry.csv | grep -v '^#' |grep -v '^$'|awk 'BEGIN { FS = "\"" } ; { printf "%s: %i.%i.%i.%i %i.%i.%i.%i\n", $10, $2 / 16777216, ($2 % 16777216)/65536, (($2 % 16777216)% 65536)/256, (($2 % 16777216)% 65536)% 256, $4 / 16777216, ($4 % 16777216)/65536, (($4 % 16777216)% 65536)/256, (($4 % 16777216)% 65536)% 256}' > iptocountry.txt
 
 commented by www.Raaj.Com.Np on Monday, September 15, 2008 @ 10:00 PM   
good to know
<<Listing Page  
Post a comment






Post Comment   Cancel
© Sarfaraz Merchant