Last active
October 25, 2022 15:18
-
-
Save kkirsche/ed0dd0fc7c044705fd1a56a7e1b1fa24 to your computer and use it in GitHub Desktop.
inet_aton and inet6_aton in Golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
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())
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.