44 lines
968 B
Go
44 lines
968 B
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"log"
|
|
"net"
|
|
|
|
"github.com/cespare/xxhash/v2"
|
|
)
|
|
|
|
// TODO: write more convenient version
|
|
func addrMap(srcIp net.IP, dstCidr *net.IPNet) net.IP {
|
|
addrlen := len(srcIp)
|
|
if addrlen != len(dstCidr.IP) {
|
|
log.Fatalf("addrMap(): src/dst size mismatch: %v vs %v", len(srcIp), len(dstCidr.IP))
|
|
}
|
|
|
|
var addr net.IP = make([]byte, addrlen)
|
|
|
|
hsum := xxhash.Sum64(srcIp)
|
|
bsum := binary.NativeEndian.AppendUint64([]byte{}, hsum)
|
|
blen := len(bsum)
|
|
if addrlen > blen {
|
|
// extend bsum
|
|
tmp := append(make([]byte, addrlen-blen), bsum...)
|
|
bsum = tmp
|
|
}
|
|
if addrlen < blen {
|
|
// trim bsum
|
|
bsum = bsum[:addrlen]
|
|
}
|
|
|
|
// apply inverted mask to bsum and sum with addr
|
|
for i := range addrlen / 4 {
|
|
a := binary.NativeEndian.Uint32(dstCidr.IP[i*4:])
|
|
b := binary.NativeEndian.Uint32(bsum[i*4:])
|
|
m := binary.NativeEndian.Uint32(dstCidr.Mask[i*4:])
|
|
a += (b & ^m)
|
|
binary.NativeEndian.PutUint32(addr[i*4:], a)
|
|
}
|
|
|
|
return addr
|
|
}
|