2 libloc - A library to determine the location of someone on the Internet
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
21 #include <loc/libloc.h>
22 #include <loc/network.h>
23 #include <loc/network-list.h>
25 #include "locationmodule.h"
28 static PyObject
* PyList_FromNetworkList(struct loc_network_list
* networks
) {
29 PyObject
* list
= PyList_New(0);
33 while (!loc_network_list_empty(networks
)) {
34 struct loc_network
* network
= loc_network_list_pop(networks
);
36 PyObject
* n
= new_network(&NetworkType
, network
);
37 PyList_Append(list
, n
);
39 loc_network_unref(network
);
46 PyObject
* new_network(PyTypeObject
* type
, struct loc_network
* network
) {
47 NetworkObject
* self
= (NetworkObject
*)type
->tp_alloc(type
, 0);
49 self
->network
= loc_network_ref(network
);
52 return (PyObject
*)self
;
55 static PyObject
* Network_new(PyTypeObject
* type
, PyObject
* args
, PyObject
* kwds
) {
56 NetworkObject
* self
= (NetworkObject
*)type
->tp_alloc(type
, 0);
58 return (PyObject
*)self
;
61 static void Network_dealloc(NetworkObject
* self
) {
63 loc_network_unref(self
->network
);
65 Py_TYPE(self
)->tp_free((PyObject
* )self
);
68 static int Network_init(NetworkObject
* self
, PyObject
* args
, PyObject
* kwargs
) {
69 const char* network
= NULL
;
71 if (!PyArg_ParseTuple(args
, "s", &network
))
75 int r
= loc_network_new_from_string(loc_ctx
, &self
->network
, network
);
77 PyErr_Format(PyExc_ValueError
, "Invalid network: %s", network
);
84 static PyObject
* Network_repr(NetworkObject
* self
) {
85 char* network
= loc_network_str(self
->network
);
87 PyObject
* obj
= PyUnicode_FromFormat("<location.Network %s>", network
);
93 static PyObject
* Network_str(NetworkObject
* self
) {
94 char* network
= loc_network_str(self
->network
);
96 PyObject
* obj
= PyUnicode_FromString(network
);
102 static PyObject
* Network_get_country_code(NetworkObject
* self
) {
103 const char* country_code
= loc_network_get_country_code(self
->network
);
105 return PyUnicode_FromString(country_code
);
108 static int Network_set_country_code(NetworkObject
* self
, PyObject
* value
) {
109 const char* country_code
= PyUnicode_AsUTF8(value
);
111 int r
= loc_network_set_country_code(self
->network
, country_code
);
114 PyErr_Format(PyExc_ValueError
,
115 "Invalid country code: %s", country_code
);
123 static PyObject
* Network_get_asn(NetworkObject
* self
) {
124 uint32_t asn
= loc_network_get_asn(self
->network
);
127 return PyLong_FromLong(asn
);
132 static int Network_set_asn(NetworkObject
* self
, PyObject
* value
) {
133 long int asn
= PyLong_AsLong(value
);
135 // Check if the ASN is within the valid range
136 if (asn
<= 0 || asn
> UINT32_MAX
) {
137 PyErr_Format(PyExc_ValueError
, "Invalid ASN %ld", asn
);
141 int r
= loc_network_set_asn(self
->network
, asn
);
148 static PyObject
* Network_has_flag(NetworkObject
* self
, PyObject
* args
) {
149 enum loc_network_flags flag
= 0;
151 if (!PyArg_ParseTuple(args
, "i", &flag
))
154 if (loc_network_has_flag(self
->network
, flag
))
160 static PyObject
* Network_set_flag(NetworkObject
* self
, PyObject
* args
) {
161 enum loc_network_flags flag
= 0;
163 if (!PyArg_ParseTuple(args
, "i", &flag
))
166 int r
= loc_network_set_flag(self
->network
, flag
);
169 // What exception to throw here?
176 static PyObject
* Network_exclude(NetworkObject
* self
, PyObject
* args
) {
177 NetworkObject
* other
= NULL
;
179 if (!PyArg_ParseTuple(args
, "O!", &NetworkType
, &other
))
182 struct loc_network_list
* list
= loc_network_exclude(self
->network
, other
->network
);
184 // Convert to Python objects
185 PyObject
* obj
= PyList_FromNetworkList(list
);
186 loc_network_list_unref(list
);
191 static PyObject
* Network_is_subnet_of(NetworkObject
* self
, PyObject
* args
) {
192 NetworkObject
* other
= NULL
;
194 if (!PyArg_ParseTuple(args
, "O!", &NetworkType
, &other
))
197 if (loc_network_is_subnet_of(self
->network
, other
->network
))
203 static PyObject
* Network_get_family(NetworkObject
* self
) {
204 int family
= loc_network_address_family(self
->network
);
206 return PyLong_FromLong(family
);
209 static PyObject
* Network_get_first_address(NetworkObject
* self
) {
210 char* address
= loc_network_format_first_address(self
->network
);
212 PyObject
* obj
= PyUnicode_FromString(address
);
218 static PyObject
* Network_get_last_address(NetworkObject
* self
) {
219 char* address
= loc_network_format_last_address(self
->network
);
221 PyObject
* obj
= PyUnicode_FromString(address
);
227 static struct PyMethodDef Network_methods
[] = {
230 (PyCFunction
)Network_exclude
,
236 (PyCFunction
)Network_has_flag
,
242 (PyCFunction
)Network_is_subnet_of
,
248 (PyCFunction
)Network_set_flag
,
255 static struct PyGetSetDef Network_getsetters
[] = {
258 (getter
)Network_get_asn
,
259 (setter
)Network_set_asn
,
265 (getter
)Network_get_country_code
,
266 (setter
)Network_set_country_code
,
272 (getter
)Network_get_family
,
279 (getter
)Network_get_first_address
,
286 (getter
)Network_get_last_address
,
294 PyTypeObject NetworkType
= {
295 PyVarObject_HEAD_INIT(NULL
, 0)
296 .tp_name
= "location.Network",
297 .tp_basicsize
= sizeof(NetworkObject
),
298 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
299 .tp_new
= Network_new
,
300 .tp_dealloc
= (destructor
)Network_dealloc
,
301 .tp_init
= (initproc
)Network_init
,
302 .tp_doc
= "Network object",
303 .tp_methods
= Network_methods
,
304 .tp_getset
= Network_getsetters
,
305 .tp_repr
= (reprfunc
)Network_repr
,
306 .tp_str
= (reprfunc
)Network_str
,