Link to home
Start Free TrialLog in
Avatar of detroitdr
detroitdr

asked on

How to get External IP of user

Using Access 2003 and would like to get the External IP address of the computer running my software.

www.ipchicken.com and lots of other sites gives you this info... is there any way of finding out the external IP address?

OR

the mac address of their network card

OR

something unique to that computer?

Avatar of Jim Dettman (EE MVE)
Jim Dettman (EE MVE)
Flag of United States of America image


Attached is a sample zip to get the MAC address. If you do a search of EE for "hard disk serial number", you should find several threads with the required API calls to retreive it.

As far as an external IP, I don't know that, but it must be doable as client programs from sites such as dyndns.org do it. However if your trying to uniquely identify a PC, then that's probably not a good thing to use as unless you has a static IP, it will change.

JimD.
MACAddr.zip
Avatar of detroitdr
detroitdr

ASKER

Jdettman:

I tried this, however it comes back as 000000

Any ideas?

basically I had to convert it to 2003
then created a form, but a text box MAC, and on the ON LOAD for the form put
me.mac = getmacaddress

answer is 000000

Any ideas?
External? In relation to the internal (localhost)? Or?

/gustav
Cactus, Yes external, however I'd settle for MAC address or Serial number of Hard drive, however the code JDettman gave me for MAC address only returns a 000000 for my computer. I tried it on my other computer and it did give me the MAC address. so why doesn't it work on this computer?

both running winXP

this computer (that returns 000000) has bluetooth connection and a NIC (on board) card.
the other computer (that returns a proper MAC) has only 1 nic card.

<<Any ideas?>>

  Works fine here.  I tested it before I posted.  My guess is that you have multiple adapters installed.  I'll see if I can come up with enumerating through the list of adapters installed in the system.

JimD.
Jdettman, Yes you are correct. and I've read something about that here on EE as well. I hope you know how to do the enumerating.

Thx
OK, I found how to enumerate the adapters using the LANA numbers, but it needs to be ported from C++ into VB.   I'm willing to do that (seems no one has bothered yet), but I did trip over the attached code, which looks at TCP/IP parameters and as part of that, gives you the MAC address of the adapter that is being used for the TCP/IP protocol.  That should be sufficent for your purposes.

Let me know,
JimD.
Option Compare Database
 
Public Const MAX_HOSTNAME_LEN = 132
Public Const MAX_DOMAIN_NAME_LEN = 132
Public Const MAX_SCOPE_ID_LEN = 260
Public Const MAX_ADAPTER_NAME_LENGTH = 260
Public Const MAX_ADAPTER_ADDRESS_LENGTH = 8
Public Const MAX_ADAPTER_DESCRIPTION_LENGTH = 132
Public Const ERROR_BUFFER_OVERFLOW = 111
Public Const MIB_IF_TYPE_ETHERNET = 6
Public Const MIB_IF_TYPE_TOKENRING = 9
Public Const MIB_IF_TYPE_FDDI = 15
Public Const MIB_IF_TYPE_PPP = 23
Public Const MIB_IF_TYPE_LOOPBACK = 24
Public Const MIB_IF_TYPE_SLIP = 28
 
Type IP_ADDR_STRING
            Next As Long
            IpAddress As String * 16
            IpMask As String * 16
            Context As Long
End Type
 
Type IP_ADAPTER_INFO
            Next As Long
            ComboIndex As Long
            AdapterName As String * MAX_ADAPTER_NAME_LENGTH
            Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH
            AddressLength As Long
            Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
            Index As Long
            Type As Long
            DhcpEnabled As Long
            CurrentIpAddress As Long
            IpAddressList As IP_ADDR_STRING
            GatewayList As IP_ADDR_STRING
            DhcpServer As IP_ADDR_STRING
            HaveWins As Byte
            PrimaryWinsServer As IP_ADDR_STRING
            SecondaryWinsServer As IP_ADDR_STRING
            LeaseObtained As Long
            LeaseExpires As Long
End Type
 
Type FIXED_INFO
            HostName As String * MAX_HOSTNAME_LEN
            DomainName As String * MAX_DOMAIN_NAME_LEN
            CurrentDnsServer As Long
            DnsServerList As IP_ADDR_STRING
            NodeType As Long
            ScopeId  As String * MAX_SCOPE_ID_LEN
            EnableRouting As Long
            EnableProxy As Long
            EnableDns As Long
End Type
 
Public Declare Function GetNetworkParams Lib "IPHlpApi.dll" _
       (FixedInfo As Any, pOutBufLen As Long) As Long
Public Declare Function GetAdaptersInfo Lib "IPHlpApi.dll" _
       (IpAdapterInfo As Any, pOutBufLen As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
       (Destination As Any, Source As Any, ByVal Length As Long)
 
Sub main()
    Dim error As Long
    Dim FixedInfoSize As Long
    Dim AdapterInfoSize As Long
    Dim i As Integer
    Dim PhysicalAddress  As String
    Dim NewTime As Date
    Dim AdapterInfo As IP_ADAPTER_INFO
    Dim AddrStr As IP_ADDR_STRING
    Dim FixedInfo As FIXED_INFO
    Dim Buffer As IP_ADDR_STRING
    Dim pAddrStr As Long
    Dim pAdapt As Long
    Dim Buffer2 As IP_ADAPTER_INFO
    Dim FixedInfoBuffer() As Byte
    Dim AdapterInfoBuffer() As Byte
 
    ' Get the main IP configuration information for this machine
    ' using a FIXED_INFO structure.
    FixedInfoSize = 0
    error = GetNetworkParams(ByVal 0&, FixedInfoSize)
    If error <> 0 Then
        If error <> ERROR_BUFFER_OVERFLOW Then
           MsgBox "GetNetworkParams sizing failed with error " & error
           Exit Sub
        End If
    End If
    ReDim FixedInfoBuffer(FixedInfoSize - 1)
 
    error = GetNetworkParams(FixedInfoBuffer(0), FixedInfoSize)
    If error = 0 Then
            CopyMemory FixedInfo, FixedInfoBuffer(0), FixedInfoSize
            MsgBox "Host Name:  " & FixedInfo.HostName
            MsgBox "DNS Servers:  " & FixedInfo.DnsServerList.IpAddress
            pAddrStr = FixedInfo.DnsServerList.Next
            Do While pAddrStr <> 0
                  CopyMemory Buffer, ByVal pAddrStr, LenB(Buffer)
                  MsgBox "DNS Servers:  " & Buffer.IpAddress
                  pAddrStr = Buffer.Next
            Loop
 
            Select Case FixedInfo.NodeType
                       Case 1
                                  MsgBox "Node type: Broadcast"
                       Case 2
                                  MsgBox "Node type: Peer to peer"
                       Case 4
                                  MsgBox "Node type: Mixed"
                       Case 8
                                  MsgBox "Node type: Hybrid"
                       Case Else
                                  MsgBox "Unknown node type"
            End Select
 
            MsgBox "NetBIOS Scope ID:  " & FixedInfo.ScopeId
            If FixedInfo.EnableRouting Then
                       MsgBox "IP Routing Enabled "
            Else
                       MsgBox "IP Routing not enabled"
            End If
            If FixedInfo.EnableProxy Then
                       MsgBox "WINS Proxy Enabled "
            Else
                       MsgBox "WINS Proxy not Enabled "
            End If
            If FixedInfo.EnableDns Then
                      MsgBox "NetBIOS Resolution Uses DNS "
            Else
                      MsgBox "NetBIOS Resolution Does not use DNS  "
            End If
    Else
            MsgBox "GetNetworkParams failed with error " & error
            Exit Sub
    End If
 
    ' Enumerate all of the adapter specific information using the
    ' IP_ADAPTER_INFO structure.
    ' Note:  IP_ADAPTER_INFO contains a linked list of adapter entries.
 
    AdapterInfoSize = 0
    error = GetAdaptersInfo(ByVal 0&, AdapterInfoSize)
    If error <> 0 Then
        If error <> ERROR_BUFFER_OVERFLOW Then
           MsgBox "GetAdaptersInfo sizing failed with error " & error
           Exit Sub
        End If
    End If
    ReDim AdapterInfoBuffer(AdapterInfoSize - 1)
 
    ' Get actual adapter information
    error = GetAdaptersInfo(AdapterInfoBuffer(0), AdapterInfoSize)
    If error <> 0 Then
       MsgBox "GetAdaptersInfo failed with error " & error
       Exit Sub
    End If
 
    ' Allocate memory
     CopyMemory AdapterInfo, AdapterInfoBuffer(0), AdapterInfoSize
    pAdapt = AdapterInfo.Next
 
    Do
     CopyMemory Buffer2, AdapterInfo, AdapterInfoSize
       Select Case Buffer2.Type
              Case MIB_IF_TYPE_ETHERNET
                   MsgBox "Adapter name: Ethernet adapter "
              Case MIB_IF_TYPE_TOKENRING
                   MsgBox "Adapter name: Token Ring adapter "
              Case MIB_IF_TYPE_FDDI
                   MsgBox "Adapter name: FDDI adapter "
              Case MIB_IF_TYPE_PPP
                   MsgBox "Adapter name: PPP adapter"
              Case MIB_IF_TYPE_LOOPBACK
                   MsgBox "Adapter name: Loopback adapter "
              Case MIB_IF_TYPE_SLIP
                   MsgBox "Adapter name: Slip adapter "
              Case Else
                   MsgBox "Adapter name: Other adapter "
       End Select
       MsgBox "AdapterDescription: " & Buffer2.Description
 
       PhysicalAddress = ""
       For i = 0 To Buffer2.AddressLength - 1
           PhysicalAddress = PhysicalAddress & Hex(Buffer2.Address(i))
       Next
       MsgBox "Physical Address: " & PhysicalAddress
 
       If Buffer2.DhcpEnabled Then
          MsgBox "DHCP Enabled "
       Else
          MsgBox "DHCP disabled"
       End If
 
       MsgBox "IP Address: " & Buffer2.IpAddressList.IpAddress
       MsgBox "Subnet Mask: " & Buffer2.IpAddressList.IpMask
       pAddrStr = Buffer2.IpAddressList.Next
       Do While pAddrStr <> 0
          CopyMemory Buffer, Buffer2.IpAddressList, LenB(Buffer)
          MsgBox "IP Address: " & Buffer.IpAddress
          MsgBox "Subnet Mask: " & Buffer.IpMask
          pAddrStr = Buffer.Next
          If pAddrStr <> 0 Then
             CopyMemory Buffer2.IpAddressList, ByVal pAddrStr, _
                        LenB(Buffer2.IpAddressList)
          End If
       Loop
 
       MsgBox "Default Gateway: " & Buffer2.GatewayList.IpAddress
       pAddrStr = Buffer2.GatewayList.Next
       Do While pAddrStr <> 0
          CopyMemory Buffer, Buffer2.GatewayList, LenB(Buffer)
          MsgBox "IP Address: " & Buffer.IpAddress
          pAddrStr = Buffer.Next
          If pAddrStr <> 0 Then
             CopyMemory Buffer2.GatewayList, ByVal pAddrStr, _
                        LenB(Buffer2.GatewayList)
          End If
       Loop
 
       MsgBox "DHCP Server: " & Buffer2.DhcpServer.IpAddress
       MsgBox "Primary WINS Server: " & _
              Buffer2.PrimaryWinsServer.IpAddress
       MsgBox "Secondary WINS Server: " & _
              Buffer2.SecondaryWinsServer.IpAddress
 
       ' Display time.
       NewTime = DateAdd("s", Buffer2.LeaseObtained, #1/1/1970#)
       MsgBox "Lease Obtained: " & _
              CStr(Format(NewTime, "dddd, mmm d hh:mm:ss yyyy"))
 
       NewTime = DateAdd("s", Buffer2.LeaseExpires, #1/1/1970#)
       MsgBox "Lease Expires :  " & _
              CStr(Format(NewTime, "dddd, mmm d hh:mm:ss yyyy"))
       pAdapt = Buffer2.Next
       If pAdapt <> 0 Then
           CopyMemory AdapterInfo, ByVal pAdapt, AdapterInfoSize
        End If
      Loop Until pAdapt = 0
End Sub

Open in new window

This crashes both my A97 and A2003 at line 161.

/gustav

  Here's a A2000 MDB in a zip that works on my main dev machine which is XP SP3.

  let me know if it works or not.  If it doesn't, I'll port the C++ code I found to the other sample DB.  Would take a day or so though as I'm more then a little busy this week.

JimD.
MACADDRESS2.zip
Nope. This time Access2002/XP. Same OS.

However, four NICs are installed: LAN, two VMware virtual NICs, Bluetooth adapter.

/gustav
same here. HOWEVER getting the MAC address of the TCP adapter is the BEST solution by far! is there any way of getting that working?
JDettman,

your code does work here. just tested it. I'll try on a laptop that has many more nics installed.
Sad news, the laptop crashed the module.  :<
gustav:

<<However, four NICs are installed: LAN, two VMware virtual NICs, Bluetooth adapter.>>

  Hum, may be the Bluetooth.  I've got multiple adapters; two real NICs, one Virtual for a Cisco VPN, and one for Firewire.   I'll install a Bluetooh driver and see if it crashes.  Won't be till latter though.  I've got an EDI 810 invoice I need to get mapped, tested, and out the door before the day is out.

  I'll try and get the TCP/IP code working before I fall back to the other code.  This is code BTW I got off AccessD.  And looking back, we went around on the multiple adapter problem back in 2004<g>.  Said I was going to look at enumerating the LANA's back then as well.  Guess I never got to it<g>.

detroitdr:

<<Sad news, the laptop crashed the module.  :<>>

  Did it crash on the same line as it did for gustav?  Line 161?

JimD.
Yes, I remember it faintly. Haven't had a need for that code, though.

/gustav
Jdettman,

the laptop only has Access Runtime so I can not tell what line it crashes on, however I can tell you that
the MSGBOX's that come up before it crashes are:

Host Name
DNS
Node Type
NetBios Scope ID
IP Routing Not enabled
WINS Proxy not..
Net Bios Resolution
CRASHES
Thanks.  I'm going to try it on a couple of laptops here a little latter.

JimD.
As for the MAC address, another option exists on newer machines:

  http://bobbo.me.uk/?p=35

and:

  https://www.experts-exchange.com/questions/23886916/How-to-read-a-registry-key-in-VBA.html

/gustav
All,

  Well I've now tried the MACADDRESS2.ZIP code on five machines here and I am unable to get it to fail.  I have no idea on why both of you are seeing problems with it.   In all cases, it has correctly reported all TCP/IP parameters for each adapter that is bound to a TCP/IP protocol.

   Given that, I'll be going back to the original code I posted and add a loop to enumerate the LANA numbers to get all the adapters.

JimD.
On a side note I tried another laptop Wed and it worked fine on that one... so I'm happy with it working most of the  time. Thank-you for your efforst. after you post I'll close this question off.  

Much appreciated.
Out of curiosity, could any of you, while checking, see if the "shortcut" I posted above returns identical values?
It will probably only work for regularly updated machines running Win2000+.

/gustav
OK as promised, here is the revised code for getting the MAC Address with Netbios calls. So that's the good news. Bad news is in the process of porting it, I've discovered that Netbios commands are no longer supported by Windows Vista or Windows Server 2008.

In researching all this, I've also discovered that there are three basic methods of getting the MAC address yourself:

1. Using Netbios (MACAddress.Zip and the new zip attached here which polls all the LANA numbers).
2. Polling the adpater info (which is the MACAddress2.Zip above)
3. Talking to an adpater directly with with device IO (no code in this thread to do this).

Then there is the method gustav posted, which relies on WGA being run on the PC and reading the registry.

For #3, I found some old VB4 code which could have been ported to VBA easily enough, but the code is so low level, I don't think it would be worth using. Seems like it would break easily. Next up is #1 and 2, but as noted, #1 is not going to work with Vista or Windows 2008 or any future Windows OS.

So that leaves #2 and the registry read of WGA keys. But if you have not as yet run WGA, then I don't believe those keys will exist. I don't know if there is a method that you can use to ensure that WGA has been run before you allow your process to occur. If so, then I would go with that as a solution for getting the MAC Address considering that your trying to get the address for software protection. Anyone that doesn't want to run WGA probably has a counterfit copy of windows anyway and someone you would not want running your software.

But WGA is always subject to change, so it would be nice if we could get #2 to work on every machine.

FWIW,
JimD.
MACAddress-NetBiosLoopLANAs.zip
Nice work Jim.
It came to my mind that a fifth, though primitive, method exists: Run IpConfig.
The output can easily be redirected to a file and read - it's the line Physical Address.

However, the content is localized so it requires a bit more than just doing it. See the attached example. The line is:

Fysisk adresse . . . . . . . . . . . . . . . : 00-19-DB-B8-26-FA

/gustav
C:\Users\Gustav>ipconfig /all
 
Windows IP-konfiguration
 
   Værtsnavn. . . . . . . . . . . . . . . . . . : COLORADO
   Primært DNS-suffiks. . . . . . . . . . . . . :
   Nodetype . . . . . . . . . . . . . . . . . . : Hybrid
   IP-routing aktiveret . . . . . . . . . . . . : Nej
   WINS-proxy aktiveret . . . . . . . . . . . . : Nej
 
Ethernet-netværkskort LAN-forbindelse:
 
   Forbindelsesspecifikt DNS-suffiks. . . . . . :
   Beskrivelse. . . . . . . . . . . . . . . . . : Marvell Yukon 88E8071 PCI-E Gigabit Ethernet Controller
   Fysisk adresse . . . . . . . . . . . . . . . : 00-19-DB-B8-26-FA
   DHCP aktiveret . . . . . . . . . . . . . . . : Ja
   Automatisk konfiguration aktiveret . . . . . : Ja
   Link-local-IPv6-adresse . . . . . : fe80::b419:718a:d5c3:8e88%9(Foretrukken)
 
   IPv4-adresse . . . . . . . . . . . . . . . . : 192.168.10.33(Foretrukken)
   Undernetmaske. . . . . . . . . . . . . . . . : 255.255.255.0
   Rettigheden opnået . . . . . . . . . . . . . : 12. november 2008 22:06:14
   Rettigheden udløber. . . . . . . . . . . . . : 18. november 2008 12:37:59
   Standardgateway. . . . . . . . . . . . . . . : 192.168.10.1
   DHCP-server. . . . . . . . . . . . . . . . . : 192.168.10.1
   DNS-servere. . . . . . . . . . . . . . . . . : 192.168.10.1
   NetBIOS over Tcpip . . . . . . . . . . . . . : Aktiveret
 
Tunnel-netværkskort LAN-forbindelse* 6:
 
   Medietilstand. . . . . . . . . . . . . . . . : Mediet afbrudt
   Forbindelsesspecifikt DNS-suffiks. . . . . . :
   Beskrivelse. . . . . . . . . . . . . . . . . : isatap.{41D9949C-7334-4264-81C5-3DE73F56EAE0}
   Fysisk adresse . . . . . . . . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP aktiveret . . . . . . . . . . . . . . . : Nej
   Automatisk konfiguration aktiveret . . . . . : Ja
 
Tunnel-netværkskort LAN-forbindelse* 9:
 
   Forbindelsesspecifikt DNS-suffiks. . . . . . :
   Beskrivelse. . . . . . . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface
   Fysisk adresse . . . . . . . . . . . . . . . : 02-00-54-55-4E-01
   DHCP aktiveret . . . . . . . . . . . . . . . : Nej
   Automatisk konfiguration aktiveret . . . . . : Ja
   IPv6-adresse. . . . . . . . . . . : 2001:0:d5c7:a2ca:14ce:85f:3f57:f5de(Foretrukken)
   Link-local-IPv6-adresse . . . . . : fe80::14ce:85f:3f57:f5de%8(Foretrukken)
   Standardgateway. . . . . . . . . . . . . . . : ::
   NetBIOS via TCP/IP . . . . . . . . . . . . . : Deaktiveret

Open in new window

<<It came to my mind that a fifth, though primitive, method exists: Run IpConfig.
The output can easily be redirected to a file and read - it's the line Physical Address. >>

  Yes that is workable and it has been done in the past.  It might actually be the best method moving forward. I actually knew about it, but it seems so inefficent when compared to going after it directly and it won't work on Win98 or prior (no IPCONFIG command, although this is probably a moot point by now).  Looking at the above, you'd need to handle language issues as well.  Although I suppose you could look for the dashes (-) and it would work no matter what.

  I would really like to figure out what is wrong with that MACAddress2 adapter code.   Maybe in a few days I can go through it again and possibly spot something.  Would be really nice if I could find a machine that it fails on.

  Nice thread.  I'm glad you put that in!

JimD.
It runs on my Vista Business with A2007 with no errors, though a leading zero is missing:

00-19-DB-B8-26-FA
019DBB826FA

/gustav
<<It runs on my Vista Business with A2007 with no errors, though a leading zero is missing:>>

  Really, the net bios version?  There were warnings all over the place in MSDN that said it wasn't supported.

JimD.
Yes, no errors. But no NetBIOS info even if IpConfig claims it to be Activated over Tcpip

/gustav
My 2 cents... Although IPCONFIG /ALL is a cheap way of getting it... It really isn't a bad idea at all! It would be great to have a code to read that... infact I believe it's already past this posts scope (reading output of a file) so I will ask another question on how to read it in.

On sad news.. the original mac code I tried at another site and out of 5 machines.. only 2 returned the mac address.. the other 3 were all 0000000.

<<the other 3 were all 0000000.>>

  The original MAC address only checks LANA 0.  Try using the new code I posted, which enumerates all the LANA numbers in a system.

  I'm willing to write the code for doing the ipconfig/all method, but I'll leave that up to gustav; he writes better code then I do more often then not ;).

JimD.
Thanks Jim, please on. I'm not sure I can find the time for this.

Main problem, as I see it, is to locate the line to read as the leading text is localized. This leaves you with some parsing using RegEx for the address.

However, on my machine, I can cut the text down to one line using good old DOS Find and piping:

C:\Users\Gustav>ipconfig /all | find /N "-" | find "[14]" > macaddr.txt

This feeds the output from IpConfig to Find which enumerates the lines and filters for line with a "-". This is further fed to another Find which filter for line 14 which, of course, extracts one line only which is written to file macaddr.txt.
Now the mac address can be read as the last part of that line:

[14]   Fysisk adresse . . . . . . . . . . . . . . . : 00-19-DB-B8-26-FA

I guess the line length is fixed for any language, thus it is quite easy to locate the part of the line.

However, from system to system, the line number for the line with the mac address may vary ...

/gustav

/gustav
myNcb.ncb_lana_num = intLana

AfterrunningYourCodeMykeyboarInputsAreMessedUpHoeverItCrashesAtTheAboveLine

  Wow.  I'll look at it again and try it on a few more systems here.

JimD.
Yes this time it didn't mess up my keyboard.. but the error is Run time error '6'
Overflow.

Last time it made my keyboard messed up. no space, and everything went backwards. so as you typed it would put the letter BEFORE the last letter you typed. very weird. This time just the above error.

(You are working TOO hard on this one!)
:>

Evidently, I am messing up with the allocation of the buffer for the LANA structure or the pointer to it. Please do not use the code again until I have gone over it. Obviously it's overwriting something in memory that it should not be.

JimD.
ASKER CERTIFIED SOLUTION
Avatar of Jim Dettman (EE MVE)
Jim Dettman (EE MVE)
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'll double check the formatting of the address.  I hadn't realized is was off and didn't do anything with that.
As for the virtual adapters, it's up to the driver when it decides to supply a MAC address (if at all).  Also one thing everyone needs to realize is that this code relies on Netbios calls so it's only going to report transports involved with that.  That may or may not be the same thing as what you get with ipconfig.  You can take a look here:
http://msdn.microsoft.com/en-us/library/bb870907(VS.85).aspx
 Which gives an explanation.
 I'm just trying to finish this off so it's workable, but the main thing I think is that for the purposes of getting an IP address, use of IPCONFIG is probably the way to go.  
JimD.
 
Thank-you for your hard work!