Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 1998-07-21
13
191 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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Building Windows 10 1 84
Studying Angular for employability 5 93
Batch command to determine the Office version installed 2 207
copy-item script help 15 80
This tutorial will discuss the log-in process using WhizBase. In this article I assume you already know HTML. I will write the code using WhizBase Server Pages, so you need to know some basics in WBSP (you might look at some of my other articles abo…
Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

840 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