# Get external public IP address from private LAN net



## Seeker (May 2, 2015)

Before I start, *please, without solutions* which consider using external web services which show you your public IP!

Solution must be resolved by FreeBSD LAN client (i.e; 192.168.0.*) using command line tools as ping/traceroute/etc.
When its IP packet destination has a public IP, it passes through a router (ISP's embedded) which does NAT and sends it to the internet.
At that moment, when it passes through router's NIC with public IP, I want to get router's public IP.
Routers LAN private ip is a 192.168.0.1
	
	



```
# traceroute -nI $pub_ip
1  192.168.0.1  63.351 ms  9.950 ms  20.352 ms
2  0.0.0.0  29.347 ms  17.720 ms  140.800 ms
3  $pub_ip  177.774 ms  243.006 ms  145.638 ms
```
Where 0.0.0.0 is, I expected public WAN's IP.
But when I target public WAN's IP directly it is just 1 hop away.
	
	



```
# traceroute -nI $wan_ip
1  $wan_ip  172.432 ms  92.916 ms  208.902 ms
```


----------



## asteriskRoss (May 3, 2015)

I am happy to be proven wrong, but I don't believe it is possible to retrieve a NAT router's public IP using traceroute(8) or ping(8).  Although NAT routers decrement the TTL, I would expect a "Time to live exceeded" reply from the private interface, not the public one.

Accepting that you don't want to use a reply from an external web service, you may be able to query the NAT router for the information using your own script.  Most SOHO (Small Office / Home Office) routers have a command line interface accessible over telnet.  The drawback of such a solution is that your client will need the login credentials for the router and will need to send them in the clear across your private network.  I have seen some SOHO routers that allow creation of additional restricted accounts.  If yours supports that then you could minimise the impact of any compromise of credentials.  Alternatively, it may be possible to script an interaction with the router's web interface, which if you are lucky may even offer a secure connection using TLS.


----------



## Seeker (May 3, 2015)

Yes it is SOHO and it has telnet access, but that is not a point.

Issue must be solved by clients own net tools by looking packets. Could something from ports help, like security/nmap?
I really don't understand why do I get 0.0.0.0 as a second hop, instead SOHO's public IP NIC.
First hop is logical as it is enter in SOHO (192.168.0.1), but exit NIC from SOHO to internet has public IP!
Packet passing through SOHO passes through 2 SOHO's NICs.


----------



## obsigna (May 3, 2015)

Also here your traceroute command does not give the correct answer, here it responds with a real IP at the second hop, but this is not the publc IP of my router. Try the following:

`ping -c 1 -n -R www.facebook.com`

```
PING star.c10r.facebook.com (69.171.230.5): 56 data bytes
64 bytes from 69.171.230.5: icmp_seq=0 ttl=76 time=354.207 ms
RR: 1xx.1xx.2xx.1xx
    2xx.1xx.8xx.xx
    1zz.zzz.zzz.zz
    yyy.yyy.yy.yy
    103.4.96.149
    31.13.29.141
    204.15.23.44
    10.41.226.52
    10.40.219.10
```
The IP on the line starting with RR: is indeed the public IP of my router.


----------



## asteriskRoss (May 4, 2015)

Thanks very much, obsigna, I'm happily proven wrong.  Using ping(8) with the RECORD_ROUTE option does indeed capture the public IP address on the inbound leg.  I found that I needed to ping a host inside my ISP's network though as it appears that my ISP is filtering out such packets before they reach the public Internet.


----------



## SirDice (May 4, 2015)

Keep in mind most of time this is disabled, along with Strict Source Route and Loose Source Route.


----------



## usdmatt (May 4, 2015)

> I really don't understand why do I get 0.0.0.0 as a second hop, instead SOHO's public IP NIC.
> First hop is logical as it is enter in SOHO (192.168.0.1), but exit NIC from SOHO to internet has public IP!
> Packet passing through SOHO passes through 2 SOHO's NICs.



To be honest, I don't quite know why 0.0.0.0 appears in that traceroute, I've never seen that before. However, regardless of the packet passing through 2 interfaces, a traceroute usually only gets one response from each router. The packet will enter the router and get the TTL decremented. If the TTL is now 0 (packet hop limit expired), an ICMP response will be sent back via the interface it came in on, using the address of that interface. This is how traceroute builds the list of routers. Traceroute will then send a new packet with a TTL one bigger, causing the packet to make it to the next router before expiring.


----------



## obsigna (May 4, 2015)

asteriskRoss said:


> ... I found that I needed to ping a host inside my ISP's network though as it appears that my ISP is filtering out such packets before they reach the public Internet.



Some years ago, I replaced an old wireless G router SMC2804WBR by a new N one. The old G router, responded on `ping -c 1 -n -R 0.0.0.0` with the exact one RR line showing its correct public IP. I guess, this was a bug (or a feature  ) in the routers firmware, since this never worked again with more modern hardware that I had my hands on. Anyway, it's a quick test and worth a try, since with that, said ping would not leave your network.


----------



## Seeker (May 4, 2015)

Thank you all for your help.
I already tried `ping -c 1 -n -R ...` before going for traceroute, except that now I tried 0.0.0.0 which failed too.
For ping(8)'s -R flag:
_



			"Many hosts ignore or discard the RECORD_ROUTE option; the traceroute() command is usually better at determining the route packets take."
		
Click to expand...

_
Obviously SOHO is doing filtering/ignoring ...
But I would still like to evade it somehow.


----------



## gkontos (May 4, 2015)

Seeker said:


> Before I start, *please, without solutions* which consider using external web services which show you your public IP!



I could not resist...

`curl ipecho.net/plain ; echo`


----------



## Seeker (May 4, 2015)

You could not resist?!? Eh!
Here you go another one for your fetish ... 

```
% curl -s ifconfig.me
```


----------



## zeux (May 5, 2015)

You can use:

`wget -qO - http://wtfismyip.com/text`
`curl ifconfig.me/ip`
Bye...


----------



## kpa (May 5, 2015)

Well, there's one obvious way but it requires you to install net/miniupnpd on the router that does the NAT and then use the matching client net/miniupnpc on the LAN host.


```
$ upnpc -s
upnpc : miniupnpc library test client. (c) 2005-2014 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
desc: http://10.71.14.1:5555/rootDesc.xml
st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://10.71.14.1:5555/ctl/IPConn
Local LAN ip address : 10.71.14.8
Connection Type : IP_Routed
Status : Connected, uptime=996421s, LastConnectionError : ERROR_NONE
  Time started : Thu Apr 23 22:55:08 2015
MaxBitRateDown : 10485760 bps (10.4 Mbps)   MaxBitRateUp 1048576 bps (1.0 Mbps)
ExternalIPAddress = 88.195.xxx.yyy
Bytes:   Sent: 3235058368    Recv: 2192664991
Packets: Sent: 17784186    Recv: 28370785
```

This might work on an unknown network as well, UPnP is pretty common on routers nowadays and even if port forwarding is disabled you can still query the status of the UPnP device.


----------



## usdmatt (May 5, 2015)

Thinking along the lines of the previous post, but with something more likely to be available if the router is not just a PC with Linux/BSD/etc installed (although would the above work if the router had basic uPNP support like many of them do?), what about SNMP?

Following seems to be available on my Mikrotik

```
# snmpwalk -v 2c -c public 192.168.0.10 IP-MIB::ipAdEntAddr
IP-MIB::ipAdEntAddr.a.b.c.d = IpAddress: a.b.c.d
```
 It's basically a mini Linux router though, so may have a more extensive SNMP implementation that your average Netgear/Asus/Draytek/whatever box.


----------



## Seeker (May 26, 2015)

kpa => If I could install anything on router, that would imply I have access to it. It would be easiest then to just run `ifconfig` instead.

usdmatt => Strange, but on 10.1-RELEASE, with base OpenSSL, I get:

```
Shared object "libcrypto.so.8" not found, required by "snmpwalk"
```
And snmpwalk is a part of base.


----------



## junovitch@ (May 27, 2015)

Seeker said:


> usdmatt => Strange, but on 10.1 REL, wit BASE openssl, I get:
> 
> ```
> Shared object "libcrypto.so.8" not found, required by "snmpwalk"
> ...



/usr/bin/bsnmpwalk is part of base.  /usr/local/bin/snmpwalk is part of net-mgmt/net-snmp


----------



## Seeker (May 27, 2015)

junovitch said:


> /usr/bin/bsnmpwalk is part of base.  /usr/local/bin/snmpwalk is part of net-mgmt/net-snmp


I've attempted `pkg which <file>` but it said not in DB. Timestamps of bins were almost 2 years old, so obviously those were unregistered leftovers of port during migration to PKGNG.
Ok, I've installed net-mgmt/net-snmp and error is gone and `pkg which <file>` confirms it.

I have never used SNMP in my life, so first I'll have to learn what SNMP and MIB is/are and for what are they used and on which OSI layer they operate on and ...
Ah you get a point!


----------

