-
-
Save kkirsche/ed0dd0fc7c044705fd1a56a7e1b1fa24 to your computer and use it in GitHub Desktop.
package nessusProcessor | |
import ( | |
"encoding/hex" | |
"math/big" | |
"net" | |
) | |
// Inet_Aton converts an IPv4 net.IP object to a 64 bit integer. | |
func Inet_Aton(ip net.IP) int64 { | |
ipv4Int := big.NewInt(0) | |
ipv4Int.SetBytes(ip.To4()) | |
return ipv4Int.Int64() | |
} | |
// Inet6_Aton converts an IP Address (IPv4 or IPv6) net.IP object to a hexadecimal | |
// representaiton. This function is the equivalent of | |
// inet6_aton({{ ip address }}) in MySQL. | |
func Inet6_Aton(ip net.IP) string { | |
ipv4 := false | |
if ip.To4() != nil { | |
ipv4 = true | |
} | |
ipInt := big.NewInt(0) | |
if ipv4 { | |
ipInt.SetBytes(ip.To4()) | |
ipHex := hex.EncodeToString(ipInt.Bytes()) | |
return ipHex | |
} | |
ipInt.SetBytes(ip.To16()) | |
ipHex := hex.EncodeToString(ipInt.Bytes()) | |
return ipHex | |
} |
Is there a way to reverse it, ie. for IPv4 from int64 back to net.IP, and for IPv6 from string back to IPv6.
I know this is super old but this should do the trick, all you have todo is decode the hex and return it as a net.IP.
func Inet6_Aton_Decode(ipHex string) (ip net.IP, err error) {
hex, err := hex.DecodeString(ipHex)
if err != nil {
return nil, err
}
return net.IP(hex), nil
}
These are my drive by comments:
These functions are named backwards.
https://linux.die.net/man/3/inet_aton takes a string and returns an address. "a to n" as in "address(ascii) to network".
What is implemented here would be better named IPToInt
and IPToN
respectively. inet_ntoa
is also documented in the linked man page.
I played around with your examples it it works great, but
mysql SELECT INET6_ATON('11:22:33:44:55:66:77:88');
returns 0x00110022003300440055006600770088
length 32
go Inet6_Aton("11:22:33:44:55:66:77:88")
returns 110022003300440055006600770088
length 30
I made a full example and I update it to go1.18 netip (go doc says this package's Addr type takes less memory)
import (
"encoding/hex"
"fmt"
"math/big"
"net/netip"
"strings"
)
// INET_ATON converts an IPv4 netip.Addr object to a 64 bit integer.
func INET_ATON(ip netip.Addr) (int64, error) {
if !ip.Is4() {
return 0, fmt.Errorf("ip is not ipv4")
}
ipv4Int := big.NewInt(0)
ipv4 := ip.As4()
ipv4Int.SetBytes(ipv4[:])
return ipv4Int.Int64(), nil
}
// INET6_ATON converts an IP Address (IPv4 or IPv6) netip.Addr object to a hexadecimal
// representaiton. This function is the equivalent of
// inet6_aton({{ ip address }}) in MySQL.
func INET6_ATON(ip netip.Addr) (string, error) {
ipInt := big.NewInt(0)
switch {
case ip.Is4():
ipv4 := ip.As4()
ipInt.SetBytes(ipv4[:])
return hex.EncodeToString(ipInt.Bytes()), nil
case ip.Is6():
ipv6 := ip.As16()
ipInt.SetBytes(ipv6[:])
return hex.EncodeToString(ipInt.Bytes()), nil
default:
return "", fmt.Errorf("invalid ip address")
}
}
// INET_NTOA came from https://go.dev/play/p/JlYJXZnUxl
func INET_NTOA(ipInt64 uint32) (ip netip.Addr) {
ipArray := [4]byte{byte(ipInt64 >> 24), byte(ipInt64 >> 16), byte(ipInt64 >> 8), byte(ipInt64)}
ip = netip.AddrFrom4(ipArray)
return
}
func INET6_NTOA(ipHex string) (ip netip.Addr, err error) {
ipHex = strings.TrimPrefix(ipHex, "0x")
HEX, err := hex.DecodeString(ipHex)
if err != nil {
err = fmt.Errorf("error decoding hex %w", err)
return
}
if len(HEX) > 16 {
//adding all caraters that mising of the begening
HEX = append(make([]byte, 16-len(HEX)), HEX...)
}
ip, ok := netip.AddrFromSlice(HEX)
if !ok {
err = fmt.Errorf("invalid ip hax")
}
return
}
test.go
import (
"net/netip"
"testing"
)
func TestINET_ATON(t *testing.T) {
ipv4, _ := netip.ParseAddr("192.168.1.1")
aton, err := INET_ATON(ipv4)
if err != nil {
t.Errorf("err: %s", err.Error())
return
}
t.Logf("number: %d", aton)
}
func TestINET6_ATON(t *testing.T) {
ipv4, _ := netip.ParseAddr("11:22:33:44:55:66:77:88")
aton, err := INET6_ATON(ipv4)
if err != nil {
t.Errorf("err: %s", err.Error())
return
}
t.Logf("hex: 0x%s", aton)
}
func TestINET_NTOA(t *testing.T) {
ntoa := INET_NTOA(3232235777)
t.Logf("ipv4: %s",ntoa.String())
}
func TestINET6_NTOA(t *testing.T) {
ntoa, err := INET6_NTOA("0x110022003300440055006600770088")
if err != nil {
t.Errorf("err: %s", err.Error())
return
}
t.Logf("ipv6: %s",ntoa.String())
}
Is there a way to reverse it, ie. for IPv4 from int64 back to net.IP, and for IPv6 from string back to IPv6.