I'm behind a router, I need a simple command to discover my public ip (instead of googling what's my ip and clicking one the results)
Are there any standard protocols for this? I've heard about STUN but I don't know how can I use it?
P.S. I'm planning on writing a short python script to do it
getByIndex(int index) Get a network interface given its index. getByInetAddress(InetAddress addr) Convenience method to search for a network interface that has the specified Internet Protocol (IP) address bound to it. getByName(String name) Searches for the network interface with the specified name.
This may be the easiest way. Parse the output of the following commands:
For example, I am on a Windows machine, but the same idea should work from unix too.
> tracert -d www.yahoo.com Tracing route to www-real.wa1.b.yahoo.com [69.147.76.15] over a maximum of 30 hops: 1 <1 ms <1 ms <1 ms 192.168.14.203 2 * * * Request timed out. 3 8 ms 8 ms 9 ms 68.85.228.121 4 8 ms 8 ms 9 ms 68.86.165.234 5 10 ms 9 ms 9 ms 68.86.165.237 6 11 ms 10 ms 10 ms 68.86.165.242
The 68.85.228.121 is a Comcast (my provider) router. We can ping that:
> ping -r 9 68.85.228.121 -n 1 Pinging 68.85.228.121 with 32 bytes of data: Reply from 68.85.228.121: bytes=32 time=10ms TTL=253 Route: 66.176.38.51 -> 68.85.228.121 -> 68.85.228.121 -> 192.168.14.203
Voila! The 66.176.38.51 is my public IP.
Python code to do this (hopefully works for py2 or py3):
#!/usr/bin/env python def natIpAddr(): # Find next visible host out from us to the internet hostList = [] resp, rc = execute("tracert -w 100 -h 3 -d 8.8.8.8") # Remove '-w 100 -h d' if this fails for ln in resp.split('\n'): if len(ln)>0 and ln[-1]=='\r': ln = ln[:-1] # Remove trailing CR if len(ln)==0: continue tok = ln.strip().split(' ')[-1].split('.') # Does last token look like a dotted IP address? if len(tok)!=4: continue hostList.append('.'.join(tok)) if len(hostList)>1: break # If we found a second host, bail if len(hostList)<2: print("!!tracert didn't work, try removing '-w 100 -h 3' options") # Those options were to speed up tracert results else: resp, rc = execute("ping -r 9 "+hostList[1]+" -n 1") ii = resp.find("Route: ") if ii>0: return resp[ii+7:].split(' ')[0] return none def execute(cmd, showErr=True, returnStr=True): import subprocess if type(cmd)==str: cmd = cmd.split(' ') # Remove ' ' tokens caused by multiple spaces in str cmd = [xx for xx in cmd if xx!=''] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() if type(out)==bytes: # Needed for python 3 (stupid python) out = out.decode() try: err = err.decode() except Exception as ex: err = "!!--"+str(type(ex))+"--!!" if showErr and len(err)>0: out += err if returnStr and str(type(out))=="<type 'unicode'>": # Trying to make 'out' be an ASCII string whether in py2 or py3, sigh. out = out.encode() # Convert UNICODE (u'xxx') to string return out, proc.returncode if __name__ == "__main__": print("(This could take 30 sec)") print(natIpAddr())
Use it from the command line (on Windows) or from a python program:
import natIpAddr myip = natIpAddr.natIpAddr() print(myip)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With