package main import ( "encoding/binary" "fmt" "math/big" "net" "os" "path" "strconv" ) func main() { if len(os.Args) < 2 { fmt.Fprintf(os.Stderr, "usage: %s \n", os.Args[0]) os.Exit(1) } cmd := path.Base(os.Args[1]) switch cmd { case "ip2int": for _, ip := range os.Args[2:] { r, err := IPtoInt(ip) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse %s to an int: %s", ip, err) continue } fmt.Printf("%s\t%d\n", ip, r) } case "int2ip": for _, ip := range os.Args[2:] { r, err := IPtoN(ip) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse %s to an addresse IP: %s", ip, err) continue } fmt.Printf("%s\t%s", ip, r) } default: fmt.Printf("`%s' is not a supported command", cmd) os.Exit(1) } } func IPtoInt(ip string) (*big.Int, error) { i := net.ParseIP(ip) if len(i.To4()) == 4 { return big.NewInt(0).SetBytes(i.To4()), nil } else { return nil, fmt.Errorf("%s is not an IPv4 address", ip) } } func IPtoN(ip string) (string, error) { r, err := strconv.Atoi(ip) if err != nil { return "", fmt.Errorf("failed to parse %s to an int: %s", ip, err) } newIP := make(net.IP, 4) binary.BigEndian.PutUint32(newIP, uint32(r)) return newIP.To4().String(), nil }