diff options
Diffstat (limited to 'rpkid/ext/POW.c')
-rw-r--r-- | rpkid/ext/POW.c | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/rpkid/ext/POW.c b/rpkid/ext/POW.c index 5ff31812..0411014a 100644 --- a/rpkid/ext/POW.c +++ b/rpkid/ext/POW.c @@ -942,6 +942,8 @@ ipaddress_object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) int version = 0; const char *s = NULL; + ENTERING(ipaddress_object_new); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i", kwlist, &init, &version) || (self = (ipaddress_object *) type->tp_alloc(type, 0)) == NULL) goto error; @@ -995,6 +997,8 @@ ipaddress_object_str(ipaddress_object *self) { char addrstr[sizeof("aaaa:bbbb:cccc:dddd:eeee:ffff:255.255.255.255") + 1]; + ENTERING(ipaddress_object_str); + if (!inet_ntop(self->af, self->address, addrstr, sizeof(addrstr))) lose("Couldn't convert IP address"); @@ -1009,6 +1013,8 @@ ipaddress_object_repr(ipaddress_object *self) { char addrstr[sizeof("aaaa:bbbb:cccc:dddd:eeee:ffff:255.255.255.255") + 1]; + ENTERING(ipaddress_object_repr); + if (!inet_ntop(self->af, self->address, addrstr, sizeof(addrstr))) lose("Couldn't convert IP address"); @@ -1026,6 +1032,8 @@ ipaddress_object_compare(PyObject *arg1, PyObject *arg2) PyObject *obj2 = PyNumber_Long(arg2); int cmp = -1; + ENTERING(ipaddress_object_compare); + if (obj1 != NULL && obj2 != NULL) cmp = PyObject_Compare(obj1, obj2); @@ -1041,6 +1049,8 @@ ipaddress_object_richcompare(PyObject *arg1, PyObject *arg2, int op) PyObject *obj2 = PyNumber_Long(arg2); PyObject *result = NULL; + ENTERING(ipaddress_object_richcompare); + if (obj1 != NULL && obj2 != NULL) result = PyObject_RichCompare(obj1, obj2, op); @@ -1055,19 +1065,77 @@ ipaddress_object_hash(ipaddress_object *self) unsigned long h = 0; int i; + ENTERING(ipaddress_object_hash); + for (i = 0; i < self->length; i++) h ^= self->address[i] << ((i & 3) << 3); return (long) h == -1 ? 0 : (long) h; } +static char ipaddress_object_from_bytes__doc__[] = + "Construct an IPAddress object from a sequence of bytes.\n" + "\n" + "Argument must be a Python string of exactly 4 or 16 bytes.\n" + ; + +static PyObject * +ipaddress_object_from_bytes(PyTypeObject *type, PyObject *args) +{ + ipaddress_object *result = NULL; + char *bytes = NULL; + size_t len; + + ENTERING(ipaddress_object_from_bytes); + + if (!PyArg_ParseTuple(args, "s#", &bytes, &len)) + goto error; + + if (len != 4 && len != 16) + lose("Argument must be a string of exactly 4 or 16 bytes"); + + if ((result = (ipaddress_object *) type->tp_alloc(type, 0)) == NULL) + goto error; + + memcpy(result->address, bytes, len); + result->length = len; + + switch (len) { + case 4: result->version = 4; result->af = AF_INET; break; + case 16: result->version = 6; result->af = AF_INET6; break; + } + + error: + return (PyObject *) result; +} + +static char ipaddress_object_to_bytes__doc__[] = + "Returns a Python string of exactly 4 or 16 bytes representing\n" + "the binary value of this IPAddress.\n" + ; + +static PyObject * +ipaddress_object_to_bytes(ipaddress_object *self) +{ + ENTERING(ipaddress_object_from_bytes); + return PyString_FromStringAndSize(self->address, self->length); +} + static PyObject * ipaddress_object_get_bits(ipaddress_object *self, void *closure) { + ENTERING(ipaddress_object_get_bits); return PyInt_FromLong(self->length * 8); } static PyObject * +ipaddress_object_get_version(ipaddress_object *self, void *closure) +{ + ENTERING(ipaddress_object_get_version); + return PyInt_FromLong(self->version); +} + +static PyObject * ipaddress_object_number_binary_helper(binaryfunc function, PyObject *arg1, PyObject *arg2) { ipaddress_object *addr = NULL; @@ -1127,6 +1195,8 @@ ipaddress_object_number_long(PyObject *arg) { ipaddress_object *addr = (ipaddress_object *) arg; + ENTERING(ipaddress_object_number_long); + if (!POW_IPAddress_Check(arg)) return Py_NotImplemented; @@ -1136,48 +1206,56 @@ ipaddress_object_number_long(PyObject *arg) static PyObject * ipaddress_object_number_int(PyObject *arg) { + ENTERING(ipaddress_object_number_int); return ipaddress_object_number_long(arg); } static PyObject * ipaddress_object_number_add(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_add); return ipaddress_object_number_binary_helper(PyNumber_Add, arg1, arg2); } static PyObject * ipaddress_object_number_subtract(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_subtract); return ipaddress_object_number_binary_helper(PyNumber_Subtract, arg1, arg2); } static PyObject * ipaddress_object_number_lshift(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_lshift); return ipaddress_object_number_binary_helper(PyNumber_Lshift, arg1, arg2); } static PyObject * ipaddress_object_number_rshift(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_rshift); return ipaddress_object_number_binary_helper(PyNumber_Rshift, arg1, arg2); } static PyObject * ipaddress_object_number_and(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_and); return ipaddress_object_number_binary_helper(PyNumber_And, arg1, arg2); } static PyObject * ipaddress_object_number_xor(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_xor); return ipaddress_object_number_binary_helper(PyNumber_Xor, arg1, arg2); } static PyObject * ipaddress_object_number_or(PyObject *arg1, PyObject *arg2) { + ENTERING(ipaddress_object_number_or); return ipaddress_object_number_binary_helper(PyNumber_Or, arg1, arg2); } @@ -1186,6 +1264,8 @@ ipaddress_object_number_nonzero(ipaddress_object *self) { int i; + ENTERING(ipaddress_object_number_nonzero); + for (i = 0; i < self->length; i++) if (self->address[i] != 0) return 1; @@ -1198,6 +1278,8 @@ ipaddress_object_number_invert(ipaddress_object *self) ipaddress_object *result = NULL; int i; + ENTERING(ipaddress_object_number_invert); + if ((result = (ipaddress_object *) self->ob_type->tp_alloc(self->ob_type, 0)) == NULL) goto error; @@ -1212,8 +1294,15 @@ ipaddress_object_number_invert(ipaddress_object *self) return (PyObject *) result; } -static PyGetSetDef ipaddress_getsetters[] = { - {"bits", (getter) ipaddress_object_get_bits}, +static struct PyMethodDef ipaddress_object_methods[] = { + Define_Method(toBytes, ipaddress_object_to_bytes, METH_NOARGS), + Define_Class_Method(fromBytes, ipaddress_object_from_bytes, METH_VARARGS), + {NULL} +}; + +static PyGetSetDef ipaddress_object_getsetters[] = { + {"bits", (getter) ipaddress_object_get_bits}, + {"version", (getter) ipaddress_object_get_version}, {NULL} }; @@ -1288,9 +1377,9 @@ static PyTypeObject POW_IPAddress_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + ipaddress_object_methods, /* tp_methods */ 0, /* tp_members */ - ipaddress_getsetters, /* tp_getset */ + ipaddress_object_getsetters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ |