How to get the following IP address?

I plan to call net.IP.String(), strings.Split(ip, ".")some code to calculate all corner cases, and finally net.ParseIP(s). Is there a better way to do this? Below is the code of my current implementation (no special case is processed).

package main

import (
    "fmt"
    "net"
    "strconv"
    "strings"
)

func main() {
    ip := net.ParseIP("127.1.0.0")
    next, err := NextIP(ip)
    if err != nil {
        panic(err)
    }
    fmt.Println(ip, next)
}

func NextIP(ip net.IP) (net.IP, error) {
    s := ip.String()
    sa := strings.Split(s, ".")
    i, err := strconv.Atoi(sa[2])
    if err != nil {
        return nil, err
    }
    i++
    sa[3] = strconv.Itoa(i)
    s = strings.Join(sa, ".")
    return net.ParseIP(s), nil
}
+4
source share
4 answers

Just increment the last octet in the IP address

ip := net.ParseIP("127.1.0.0")
// make sure it only 4 bytes
ip = ip.To4()
// check ip != nil
ip[3]++  // check for rollover
fmt.Println(ip)
//127.1.0.1

This, however, is technically incorrect, since the first address on the 127.1.0.1/8 subnet is 127.0.0.1. To get the true "first" address, you will also need IPMask. Since you did not specify one, you can use DefaultMask for IPv4 addresses (for IPv6 you cannot accept a mask, and you must provide it).

http://play.golang.org/p/P_QWwRIBIm

ip := net.IP{192, 168, 1, 10}
ip = ip.To4()
if ip == nil {
    log.Fatal("non ipv4 address")
}

ip = ip.Mask(ip.DefaultMask())
ip[3]++

fmt.Println(ip)
//192.168.1.1
+5
source

CIDR , IP , .

func incrementIP(origIP, cidr string) (string, error) {
    ip := net.ParseIP(origIP)
    _, ipNet, err := net.ParseCIDR(cidr)
    if err != nil {
        return origIP, err
    }
    for i := len(ip) - 1; i >= 0; i-- {
        ip[i]++
        if ip[i] != 0 {
            break
        }
    }
    if !ipNet.Contains(ip) {
        return origIP, errors.New("overflowed CIDR while incrementing IP")
    }
    return ip.String(), nil
}
0

If you only need to calculate the next IP address, the next nextIP () function will do the trick.

Using:

// output is 1.0.1.0
fmt.Println(nextIP(net.ParseIP("1.0.0.255"), 1))

nextIP ():

func nextIP(ip net.IP, inc uint) net.IP {
    i := ip.To4()
    v := uint(i[0])<<24 + uint(i[1])<<16 + uint(i[2])<<8 + uint(i[3])
    v += inc
    v3 := byte(v & 0xFF)
    v2 := byte((v >> 8) & 0xFF)
    v1 := byte((v >> 16) & 0xFF)
    v0 := byte((v >> 24) & 0xFF)
    return net.IPv4(v0, v1, v2, v3)
}

Playground: https://play.golang.org/p/vHrmftkVjn2

Gist: https://gist.github.com/udhos/b468fbfd376aa0b655b6b0c539a88c03

0
source

I ran into this problem just now, and I want to share my solution. This is not so effective, but solves the problem in a few lines.

func nextIP(ip net.IP) net.IP {
    // Convert to big.Int and increment
    ipb := big.NewInt(0).SetBytes([]byte(ip))
    ipb.Add(ipb, big.NewInt(1))

    // Add leading zeros
    b := ipb.Bytes()
    b = append(make([]byte, len(ip)-len(b)), b...)
    return net.IP(b)
}
0
source

All Articles