package main import ( "flag" "fmt" "io/ioutil" "log" "net" "net/http" "os" "strings" "text/tabwriter" ) var ( serverMode bool addr string port string envP string host string envHost string showVer bool showHeader bool showAll bool showTab bool // iface string // envIface string ) var Version = "v0.1.0" func init() { envP = os.Getenv("MYIP_PORT") envHost = os.Getenv("MYIP_HOST") flag.BoolVar(&showVer, "v", false, "show version") flag.BoolVar(&serverMode, "s", false, "run in server mode") flag.BoolVar(&showAll, "a", false, "show all interface") flag.BoolVar(&showHeader, "t", false, "show header") flag.BoolVar(&showTab, "T", false, "show tab") flag.StringVar(&host, "u", "kumoly.io", "hostname to ask for") flag.StringVar(&port, "p", "5080", "port to listen|connect") flag.StringVar(&addr, "b", "0.0.0.0", "the address the server binds on") // flag.StringVar(&port, "p", "5080", "port to listen|connect") } func usage() { fmt.Fprintf(os.Stderr, "Usage: myip [options]\n") flag.PrintDefaults() } func main() { flag.Parse() if showVer { fmt.Println(Version) return } if envP != "" { port = envP } if envHost != "" { host = envHost } if serverMode { StartServer() } else { var wFlag uint = 0 if showTab { wFlag = tabwriter.Debug } w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', wFlag) if showHeader { fmt.Fprintln(w, "\tInterface\tIP\t") } fmt.Fprintln(w, fmt.Sprintf("\t%v\t%v\t", "PublicIP", GetPublicIP())) if showAll { for k, v := range GetLocalIP() { fmt.Fprintln(w, fmt.Sprintf("\t%v\t%v\t", strings.Trim(k, " "), v)) } } w.Flush() } } func StartServer() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ip := r.Header.Get("X-Real-Ip") if ip == "" { ip = r.Header.Get("X-Forwarded-For") } if ip == "" { var err error ip, _, err = net.SplitHostPort(r.RemoteAddr) if err != nil { ip = r.RemoteAddr } } fmt.Fprint(w, ip+"\n") }) http.HandleFunc("/version", func(rw http.ResponseWriter, r *http.Request) { fmt.Fprintf(rw, Version) }) err := http.ListenAndServe(addr+":"+port, nil) if err != nil { fmt.Println(err) os.Exit(1) } } func GetLocalIP() map[string]string { ret := map[string]string{} ifaces, err := net.Interfaces() if err != nil { log.Println(err) return ret } for _, i := range ifaces { addrs, err := i.Addrs() if err != nil { log.Println(err) return ret } for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP if ip.IsLoopback() { continue } if ip.To4() == nil { continue } case *net.IPAddr: continue // ip = v.IP // if ip.IsLoopback() { // continue // } } ret[i.Name] = ip.String() break } } return ret } func GetPublicIP() string { res, err := http.Get("http://" + host + ":" + port) if err != nil { log.Println(err) return "" } body, err := ioutil.ReadAll(res.Body) res.Body.Close() if err != nil { log.Println(err) return "" } return strings.TrimRight(string(body), "\r\n") }