[dbohdan] 2015-03-18: Here is my solution for how to get your globally routable IP address. It is based on [http://serverfault.com/a/560059/204338%|%this helpful answer on ServerFault] and uses the [DNS] protocol. One upside of the approach is that the DNS servers used are more likely to last and have a good uptime than your average free your-IP-over-a-[REST]-API service. Download with [wiki-reaper]: `wiki-reaper -x 44451 0 > publicip-0.3.1.tm` ** See also ** * [how to find my own IP address] ** Code ** ====== #! /usr/bin/env tclsh # version 0.3.1 package require Tcl 8.5 namespace eval ::public-ip { package require dns variable services { ipv4 { google {{o-o.myaddr.l.google.com} -server ns1.google.com -type TXT} akamai {whoami.akamai.net -server ns1-1.akamaitech.net -type A} opendns {myip.opendns.com -server resolver1.opendns.com -type A} } } variable ready 0 } # Resolve the public IP address using one service. # Usage: query [google|akamai|opendns] proc ::public-ip::query {{service google} {protocol ipv4}} { set id [::dns::resolve \ {*}[dict get ${::public-ip::services} $protocol $service]\ -command ::public-ip::query-ready] vwait ::public-ip::ready if {[::dns::status $id] eq {ok}} { set rdata [dict get [lindex [::dns::result $id] 0] rdata] ::dns::cleanup $id return $rdata } else { set error [::dns::error $id] ::dns::cleanup $id error $error } } # Used internally by [query]. proc ::public-ip::query-ready token { set ::public-ip::ready 1 } # Resolve the public IP address using all of the available services for the # selected protocol. If one of the services returns a different address than the # others generate an error. proc ::public-ip::query-all {{protocol ipv4}} { set ip {} foreach service \ [dict keys [dict get ${::public-ip::services} $protocol]] { set resolved [query $service $protocol] if {$ip eq {}} { set ip $resolved set ipResolver $service } else { if {$ip ne $resolved} { error "got $protocol address $ip from $ipResolver but\ $resolved from $service" } } } return $ip } proc ::public-ip::test {{protocol ipv4}} { puts [query-all $protocol] } # If this is the main script... if {[info exists argv0] && ([file tail [info script]] eq [file tail $argv0])} { ::public-ip::test } ====== <>Internet