171 lines
3.3 KiB
Go
171 lines
3.3 KiB
Go
|
package cmd
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"log"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
"os"
|
||
|
"strings"
|
||
|
"text/tabwriter"
|
||
|
|
||
|
"github.com/spf13/cobra"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
port string
|
||
|
host string
|
||
|
|
||
|
showTitle bool
|
||
|
showList bool
|
||
|
showAll bool
|
||
|
showCell bool
|
||
|
|
||
|
noPub bool
|
||
|
secure bool
|
||
|
)
|
||
|
|
||
|
var ClientCmd = &cobra.Command{
|
||
|
Use: "myip",
|
||
|
Short: "myip is a easy way to get public ip of current system.",
|
||
|
Run: func(cmd *cobra.Command, args []string) {
|
||
|
Scan()
|
||
|
},
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
ClientCmd.Flags().StringVarP(&port, "port", "p", "5080", "server port to connect")
|
||
|
ClientCmd.Flags().StringVarP(&host, "host", "u", "kumoly.io", "hostname to connect")
|
||
|
|
||
|
ClientCmd.Flags().BoolVarP(&showList, "list", "l", false, "show list")
|
||
|
ClientCmd.Flags().BoolVarP(&showTitle, "title", "t", false, "show title, used with --list")
|
||
|
ClientCmd.Flags().BoolVarP(&showCell, "cell", "c", false, "show cell, must used with --list")
|
||
|
ClientCmd.Flags().BoolVarP(&showAll, "all", "a", false, "show local ip")
|
||
|
|
||
|
ClientCmd.Flags().BoolVar(&noPub, "no-pub", false, "disable PublicIP")
|
||
|
ClientCmd.Flags().BoolVar(&secure, "secure", false, "use https")
|
||
|
}
|
||
|
|
||
|
func Scan() error {
|
||
|
// fmt.Printf("title: %v\nlist: %v\nall: %v\ntab: %v\n", showTitle, showList, showAll, showCell)
|
||
|
if !showAll {
|
||
|
if noPub {
|
||
|
return errors.New("`--no-pub` can only be used with `--all`")
|
||
|
}
|
||
|
ip, err := GetPublicIP()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
fmt.Println(ip)
|
||
|
} else {
|
||
|
var ip string
|
||
|
var err error
|
||
|
if !noPub {
|
||
|
ip, err = GetPublicIP()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
local, err := GetLocalIP()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if showList {
|
||
|
var wFlag uint = 0
|
||
|
if showCell {
|
||
|
wFlag = tabwriter.Debug
|
||
|
}
|
||
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', wFlag)
|
||
|
if showTitle {
|
||
|
fmt.Fprintln(w, "\tInterface\tIP\t")
|
||
|
if showCell {
|
||
|
fmt.Fprintln(w, "\t\t\t")
|
||
|
}
|
||
|
}
|
||
|
if !noPub {
|
||
|
fmt.Fprintf(w, "\t%v\t%v\t\n", "PublicIP", ip)
|
||
|
}
|
||
|
for k, v := range local {
|
||
|
fmt.Fprintf(w, "\t%v\t%v\t\n", k, v)
|
||
|
}
|
||
|
return w.Flush()
|
||
|
|
||
|
} else {
|
||
|
if !noPub {
|
||
|
fmt.Printf("%v ", ip)
|
||
|
}
|
||
|
for _, v := range local {
|
||
|
fmt.Printf("%v ", v)
|
||
|
}
|
||
|
fmt.Printf("\n")
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func GetLocalIP() (map[string]string, error) {
|
||
|
ret := map[string]string{}
|
||
|
ifaces, err := net.Interfaces()
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return ret, err
|
||
|
}
|
||
|
|
||
|
for _, i := range ifaces {
|
||
|
addrs, err := i.Addrs()
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return ret, err
|
||
|
}
|
||
|
|
||
|
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, nil
|
||
|
}
|
||
|
|
||
|
func GetPublicIP() (string, error) {
|
||
|
protocol := "http://"
|
||
|
if secure {
|
||
|
protocol = "https://"
|
||
|
}
|
||
|
res, err := http.Get(protocol + host + ":" + port)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return "", err
|
||
|
}
|
||
|
if res.StatusCode != 200 {
|
||
|
err = errors.New("http status error: " + res.Status)
|
||
|
log.Println(err)
|
||
|
return "", err
|
||
|
}
|
||
|
defer res.Body.Close()
|
||
|
body, err := ioutil.ReadAll(res.Body)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return "", err
|
||
|
}
|
||
|
return strings.TrimRight(string(body), "\r\n"), nil
|
||
|
}
|