From a1a00053300cff3c0f690d52377c76c83c2a08b2 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 19 Nov 2020 12:34:11 +0000 Subject: [PATCH] python: Add property to return IP addresses as bytes This avoids calling inet_pton to parse IP addresses from string Signed-off-by: Michael Tremer --- src/libloc.sym | 2 ++ src/loc/network.h | 2 ++ src/network.c | 8 ++++++++ src/python/database.c | 2 +- src/python/export.py | 7 ++----- src/python/network.c | 40 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/libloc.sym b/src/libloc.sym index 53273cd..406dd15 100644 --- a/src/libloc.sym +++ b/src/libloc.sym @@ -113,6 +113,8 @@ global: loc_network_format_last_address; loc_network_get_asn; loc_network_get_country_code; + loc_network_get_first_address; + loc_network_get_last_address; loc_network_gt; loc_network_has_flag; loc_network_is_subnet; diff --git a/src/loc/network.h b/src/loc/network.h index d86b685..4b7410c 100644 --- a/src/loc/network.h +++ b/src/loc/network.h @@ -39,7 +39,9 @@ struct loc_network* loc_network_unref(struct loc_network* network); char* loc_network_str(struct loc_network* network); int loc_network_address_family(struct loc_network* network); +const struct in6_addr* loc_network_get_first_address(struct loc_network* network); char* loc_network_format_first_address(struct loc_network* network); +const struct in6_addr* loc_network_get_last_address(struct loc_network* network); char* loc_network_format_last_address(struct loc_network* network); int loc_network_match_address(struct loc_network* network, const struct in6_addr* address); diff --git a/src/network.c b/src/network.c index 28ca2df..4c8787a 100644 --- a/src/network.c +++ b/src/network.c @@ -343,10 +343,18 @@ static char* loc_network_format_address(struct loc_network* network, const struc return string; } +LOC_EXPORT const struct in6_addr* loc_network_get_first_address(struct loc_network* network) { + return &network->first_address; +} + LOC_EXPORT char* loc_network_format_first_address(struct loc_network* network) { return loc_network_format_address(network, &network->first_address); } +LOC_EXPORT const struct in6_addr* loc_network_get_last_address(struct loc_network* network) { + return &network->last_address; +} + LOC_EXPORT char* loc_network_format_last_address(struct loc_network* network) { return loc_network_format_address(network, &network->last_address); } diff --git a/src/python/database.c b/src/python/database.c index ed22275..f385c61 100644 --- a/src/python/database.c +++ b/src/python/database.c @@ -329,7 +329,7 @@ static PyObject* Database_search_networks(DatabaseObject* self, PyObject* args, if (r) { PyErr_SetFromErrno(PyExc_SystemError); - loc_as_list_unref(countries); + loc_country_list_unref(countries); return NULL; } diff --git a/src/python/export.py b/src/python/export.py index 5bc9f30..6b39878 100644 --- a/src/python/export.py +++ b/src/python/export.py @@ -142,11 +142,8 @@ class XTGeoIPOutputWriter(OutputWriter): mode = "wb" def _write_network(self, network): - for address in (network.first_address, network.last_address): - # Convert this into a string of bits - bytes = socket.inet_pton(network.family, address) - - self.f.write(bytes) + for address in (network._first_address, network._last_address): + self.f.write(address) formats = { diff --git a/src/python/network.c b/src/python/network.c index ed91d65..742b472 100644 --- a/src/python/network.c +++ b/src/python/network.c @@ -215,6 +215,26 @@ static PyObject* Network_get_first_address(NetworkObject* self) { return obj; } +static PyObject* PyBytes_FromAddress(const struct in6_addr* address6) { + struct in_addr address4; + + // Convert IPv4 addresses to struct in_addr + if (IN6_IS_ADDR_V4MAPPED(address6)) { + address4.s_addr = address6->s6_addr32[3]; + + return PyBytes_FromStringAndSize((const char*)&address4, sizeof(address4)); + } + + // Return IPv6 addresses as they are + return PyBytes_FromStringAndSize((const char*)address6, sizeof(*address6)); +} + +static PyObject* Network_get__first_address(NetworkObject* self) { + const struct in6_addr* address = loc_network_get_first_address(self->network); + + return PyBytes_FromAddress(address); +} + static PyObject* Network_get_last_address(NetworkObject* self) { char* address = loc_network_format_last_address(self->network); @@ -224,6 +244,12 @@ static PyObject* Network_get_last_address(NetworkObject* self) { return obj; } +static PyObject* Network_get__last_address(NetworkObject* self) { + const struct in6_addr* address = loc_network_get_last_address(self->network); + + return PyBytes_FromAddress(address); +} + static struct PyMethodDef Network_methods[] = { { "exclude", @@ -281,6 +307,13 @@ static struct PyGetSetDef Network_getsetters[] = { NULL, NULL, }, + { + "_first_address", + (getter)Network_get__first_address, + NULL, + NULL, + NULL, + }, { "last_address", (getter)Network_get_last_address, @@ -288,6 +321,13 @@ static struct PyGetSetDef Network_getsetters[] = { NULL, NULL, }, + { + "_last_address", + (getter)Network_get__last_address, + NULL, + NULL, + NULL, + }, { NULL }, }; -- 2.39.5