Solved

VB or C++ -How to find out country of origin?

Posted on 1998-07-21
13
187 Views
Last Modified: 2013-12-25
hello,

I need to write a CGI script that determines what country the user comes from.  For example,  If a user in Germany runs the CGI script, the CGI script would be able to tell that that person comes from Germany.  I know that the IP address of the user is passed as an environmental variable, but how to make the jump to the actual domain name and/or country?
The CGI script can be in any language, but preferably in VB, C/C++, and/or Pearl.
Please help!!!
0
Comment
Question by:pizarro
  • 7
  • 5
13 Comments
 
LVL 7

Expert Comment

by:faster
ID: 1830928
After you get the ip address, do a inet_addr() to convert it into an unsigned long, then call gethostbyaddr() to get a pointer to a hostent structure. the h_name member of it is the domain name.

Check win32 help for detail about these APIs (winsock API).
0
 

Author Comment

by:pizarro
ID: 1830929
This might get the domain name but some domain names don't indicate what the country actually is.  Also, I could not find any reference for the gethostbyaddress function and the h_name structure.
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830930
The domain is the only easy way to guess the country, and even then often you can't tell or the information is unreliable. The information as to what country the user is in simply isn't sent to the web server, and there's no master database anywhere where you can look it up. You can often manually tell by doing a traceroute to look at the name of routers are upsteam of the final IP address, but there's no fixed naming convention so this can't be done automatically.

Domain isn't completely reliable, but it's the best you have.


0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:pizarro
ID: 1830931
I now agree that the domain will be the only information I will be able to use.  But I still could not get the API functions above to work.
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830932
I have some code for VB5 that uses GetHostByName, I think I could modify it to use GetHostByAddr. It's pretty tricky because you need to initialize the winsock properly. I would be willing to make the changes and post the full code if you'll agree to accept the answer if it works.
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830933
Or perl would be much easier, actually, when I posted that I reread the question and saw perl would be Ok. It's much easier in perl because perl does the setup for you. Take your pick.
0
 

Author Comment

by:pizarro
ID: 1830934
If it works I will accept it for sure.  Even if it quite doesn't work but I feel it gave me a good lead I will accept it.
0
 
LVL 6

Accepted Solution

by:
alamo earned 200 total points
ID: 1830935
Here it is in perl, about 100 lines shorter than VB :-)

use Socket;

$ipnum = inet_aton("207.114.128.129");
$hostname    = gethostbyaddr($ipnum, AF_INET);
print $hostname,"\n";

0
 
LVL 6

Expert Comment

by:alamo
ID: 1830936
And of course, since you asked about country, from the top level domain:

($TopLevelDomain) = $hostname =~/\.(.*?)$/;
print "Top level domain: $TopLevelDomain\n";
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830937
oops, ignore my last comment, the regexp is bad, I don't know what I was thinking. Here's a full script (since you originally asked for a script):

use Socket;
print "Content-type: text/plain\n\n";
$ipnum = inet_aton($ENV{REMOTE_ADDR});
$hostname    = gethostbyaddr($ipnum, AF_INET);
print "Your IP address is $ENV{REMOTE_ADDR}\n";
print "You are at $hostname\n";
($TopLevelDomain) = $hostname =~/\.([^.]+)$/;
print "Your top level domain is $TopLevelDomain\n";
0
 

Author Comment

by:pizarro
ID: 1830938
Can you post the VB code?  I don't like using perl on Windows NT servers...
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830939
I went ahead and wrote the program in VB to turn an IP address into a hostname, you can figure out how to make it into a CGI:

Private Const WS_VERSION_REQD = &H101
Private Const WS_VERSION_MAJOR = WS_VERSION_REQD \ &H100 And &HFF&
Private Const WS_VERSION_MINOR = WS_VERSION_REQD And &HFF&
Private Const MIN_SOCKETS_REQD = 1
Private Const SOCKET_ERROR = -1
Private Const WSADescription_Len = 256
Private Const WSASYS_Status_Len = 128
Private Const AF_INET = 2
Private Type HOSTENT
    hName As Long
    hAliases As Long
    hAddrType As Integer
    hLength As Integer
    hAddrList As Long
End Type
Private Type WSADATA
    wversion As Integer
    wHighVersion As Integer
    szDescription(0 To WSADescription_Len) As Byte
    szSystemStatus(0 To WSASYS_Status_Len) As Byte
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpszVendorInfo As Long
End Type
Private Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long
Private Declare Function WSAStartup Lib "WSOCK32.DLL" (ByVal wVersionRequired&, lpWSAData As WSADATA) As Long
Private Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
Private Declare Sub RtlMoveMemory Lib "KERNEL32" (hpvDest As Any, ByVal hpvSource&, ByVal cbCopy&)
Private Declare Function inet_addr Lib "WSOCK32.DLL" (ByVal ipnum As String) As Long
Private Declare Function gethostbyaddr Lib "WSOCK32.DLL" (ipnum As Long, ByVal iplen As Long, ByVal iptype As Long) As Long

Private Sub Command1_Click()
    host$ = GetHostByAddress("207.114.128.129")
    Debug.Print host$
End Sub

Public Function GetHostByAddress(ipnum As String) As String
Dim hostname As String
Dim host As HOSTENT
Dim hostip_addr As Long
Dim hostent_addr As Long
   
  SocketsInitialize
  hostip_addr = inet_addr(ipnum)
  hostent_addr = gethostbyaddr(hostip_addr, 4, AF_INET)
  If hostent_addr = 0 Then
    MsgBox "Winsock.dll is not responding."
    Exit Function
  End If
  RtlMoveMemory host, hostent_addr, LenB(host)
  hostname = Space$(256)
  RtlMoveMemory ByVal hostname, host.hName, LenB(hostname)
  If InStr(hostname, Chr$(0)) Then hostname = Left$(hostname, InStr(hostname, Chr$(0)) - 1)
  SocketsCleanup
  GetHostByAddress = hostname
End Function

Function hibyte(ByVal wParam As Integer)
   hibyte = wParam \ &H100 And &HFF&
End Function

Function lobyte(ByVal wParam As Integer)
    lobyte = wParam And &HFF&
End Function

Sub SocketsInitialize()
Dim WSAD As WSADATA
Dim iReturn As Integer
Dim sLowByte As String, sHighByte As String, sMsg As String

    iReturn = WSAStartup(WS_VERSION_REQD, WSAD)
    If iReturn <> 0 Then
        MsgBox "Winsock.dll is not responding."
        End
    End If
    If lobyte(WSAD.wversion) < WS_VERSION_MAJOR Or (lobyte(WSAD.wversion) = WS_VERSION_MAJOR And hibyte(WSAD.wversion) < WS_VERSION_MINOR) Then
        sHighByte = Trim$(Str$(hibyte(WSAD.wversion)))
        sLowByte = Trim$(Str$(lobyte(WSAD.wversion)))
        sMsg = "Windows Sockets version " & sLowByte & "." & sHighByte
        sMsg = sMsg & " is not supported by winsock.dll "
        MsgBox sMsg
        End
    End If
    If WSAD.iMaxSockets < MIN_SOCKETS_REQD Then
        sMsg = "This application requires a minimum of "
        sMsg = sMsg & Trim$(Str$(MIN_SOCKETS_REQD)) & " supported sockets."
        MsgBox sMsg
        End
    End If
End Sub

Sub SocketsCleanup()
Dim lReturn As Long
  lReturn = WSACleanup()
  If lReturn <> 0 Then
    MsgBox "Socket error " & Trim$(Str$(lReturn)) & " occurred in Cleanup "
    End
  End If
End Sub
0
 

Author Comment

by:pizarro
ID: 1830940
thanks.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It is becoming increasingly popular to have a front-page slider on a web site. Nearly every TV website,  magazine or online news has one on their site, and even some e-commerce sites have one. Today you can use sliders with Joomla, WordPress or …
In this tutorial I will show you how to provide a dynamic RTF document on your website generated with data from your database. For this tutorial you will need Microsoft Word or WordPad, WhizBase and Microsoft Access. In this tutorial I will show …
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question