diff --git a/LICENSE.TXT b/LICENSE.TXT index 1ebca50..b1aebb5 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 IP2Location.com +Copyright (c) 2019 IP2Location.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index cd7d4c7..fb76cb7 100644 --- a/README.md +++ b/README.md @@ -87,4 +87,4 @@ Use the IPv6 BIN file if you need to query BOTH IPv4 and IPv6 addresses. Copyright ========= -Copyright (C) 2018 by IP2Location.com, support@ip2location.com +Copyright (C) 2019 by IP2Location.com, support@ip2location.com diff --git a/ip2location.go b/ip2location.go index 810d9cc..cb45067 100644 --- a/ip2location.go +++ b/ip2location.go @@ -72,10 +72,17 @@ var mobilebrand_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 var elevation_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19} var usagetype_position = [25]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20} -const api_version string = "8.0.3" +const api_version string = "8.1.0" var max_ipv4_range = big.NewInt(4294967295) var max_ipv6_range = big.NewInt(0) +var from_v4mapped = big.NewInt(281470681743360) +var to_v4mapped = big.NewInt(281474976710655) +var from_6to4 = big.NewInt(0) +var to_6to4 = big.NewInt(0) +var from_teredo = big.NewInt(0) +var to_teredo = big.NewInt(0) +var last_32bits = big.NewInt(4294967295) const countryshort uint32 = 0x00001 const countrylong uint32 = 0x00002 @@ -166,6 +173,22 @@ func checkip(ip string) (iptype uint32, ipnum *big.Int, ipindex uint32) { if v6 != nil { iptype = 6 ipnum.SetBytes(v6) + + if ipnum.Cmp(from_v4mapped) >= 0 && ipnum.Cmp(to_v4mapped) <= 0 { + // ipv4-mapped ipv6 should treat as ipv4 and read ipv4 data section + iptype = 4 + ipnum.Sub(ipnum, from_v4mapped) + } else if ipnum.Cmp(from_6to4) >= 0 && ipnum.Cmp(to_6to4) <= 0 { + // 6to4 so need to remap to ipv4 + iptype = 4 + ipnum.Rsh(ipnum, 80) + ipnum.And(ipnum, last_32bits) + } else if ipnum.Cmp(from_teredo) >= 0 && ipnum.Cmp(to_teredo) <= 0 { + // Teredo so need to remap to ipv4 + iptype = 4 + ipnum.Not(ipnum) + ipnum.And(ipnum, last_32bits) + } } } } @@ -271,6 +294,10 @@ func readfloat(pos uint32) float32 { // initialize the component with the database path func Open(dbpath string) { max_ipv6_range.SetString("340282366920938463463374607431768211455", 10) + from_6to4.SetString("42545680458834377588178886921629466624", 10) + to_6to4.SetString("42550872755692912415807417417958686719", 10) + from_teredo.SetString("42540488161975842760550356425300246528", 10) + to_teredo.SetString("42540488241204005274814694018844196863", 10) var err error f, err = os.Open(dbpath) @@ -563,7 +590,7 @@ func query(ipaddress string, mode uint32) IP2Locationrecord { } if ipno.Cmp(maxip)>=0 { - ipno = ipno.Sub(ipno, big.NewInt(1)) + ipno.Sub(ipno, big.NewInt(1)) } for low <= high {