|
@@ -26,7 +26,6 @@ static PyObject* po_MessageTooShort;
|
|
|
static PyObject* po_InvalidMessageSection;
|
|
|
static PyObject* po_InvalidMessageOperation;
|
|
|
static PyObject* po_InvalidMessageUDPSize;
|
|
|
-static PyObject* po_DNSMessageBADVERS;
|
|
|
|
|
|
//
|
|
|
// Definition of the classes
|
|
@@ -120,7 +119,6 @@ static PyTypeObject messageflag_type = {
|
|
|
0 // tp_version_tag
|
|
|
};
|
|
|
|
|
|
-
|
|
|
static int
|
|
|
MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
|
|
|
PyObject* args UNUSED_PARAM)
|
|
@@ -191,585 +189,6 @@ MessageFlag_CD(s_MessageFlag* self UNUSED_PARAM) {
|
|
|
// End of MessageFlag wrapper
|
|
|
//
|
|
|
|
|
|
-
|
|
|
-//
|
|
|
-// Opcode
|
|
|
-//
|
|
|
-class s_Opcode : public PyObject {
|
|
|
-public:
|
|
|
- const Opcode* opcode;
|
|
|
-};
|
|
|
-
|
|
|
-static int Opcode_init(s_Opcode* self, PyObject* args);
|
|
|
-static void Opcode_destroy(s_Opcode* self);
|
|
|
-
|
|
|
-static PyObject* Opcode_getCode(s_Opcode* self);
|
|
|
-static PyObject* Opcode_toText(s_Opcode* self);
|
|
|
-static PyObject* Opcode_str(PyObject* self);
|
|
|
-static PyObject* Opcode_QUERY(s_Opcode* self);
|
|
|
-static PyObject* Opcode_IQUERY(s_Opcode* self);
|
|
|
-static PyObject* Opcode_STATUS(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED3(s_Opcode* self);
|
|
|
-static PyObject* Opcode_NOTIFY(s_Opcode* self);
|
|
|
-static PyObject* Opcode_UPDATE(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED6(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED7(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED8(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED9(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED10(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED11(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED12(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED13(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED14(s_Opcode* self);
|
|
|
-static PyObject* Opcode_RESERVED15(s_Opcode* self);
|
|
|
-static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
|
|
|
-
|
|
|
-static PyMethodDef Opcode_methods[] = {
|
|
|
- { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
|
|
|
- { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
|
|
|
- { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
|
|
|
- { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
|
|
|
- { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
|
|
|
- { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
|
|
|
- { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
|
|
|
- { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
|
|
|
- { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
|
|
|
- { NULL, NULL, 0, NULL }
|
|
|
-};
|
|
|
-
|
|
|
-static PyTypeObject opcode_type = {
|
|
|
- PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
- "pydnspp.Opcode",
|
|
|
- sizeof(s_Opcode), // tp_basicsize
|
|
|
- 0, // tp_itemsize
|
|
|
- (destructor)Opcode_destroy, // tp_dealloc
|
|
|
- NULL, // tp_print
|
|
|
- NULL, // tp_getattr
|
|
|
- NULL, // tp_setattr
|
|
|
- NULL, // tp_reserved
|
|
|
- NULL, // tp_repr
|
|
|
- NULL, // tp_as_number
|
|
|
- NULL, // tp_as_sequence
|
|
|
- NULL, // tp_as_mapping
|
|
|
- NULL, // tp_hash
|
|
|
- NULL, // tp_call
|
|
|
- Opcode_str, // tp_str
|
|
|
- NULL, // tp_getattro
|
|
|
- NULL, // tp_setattro
|
|
|
- NULL, // tp_as_buffer
|
|
|
- Py_TPFLAGS_DEFAULT, // tp_flags
|
|
|
- "The Opcode class objects represent standard OPCODEs "
|
|
|
- "of the header section of DNS messages.",
|
|
|
- NULL, // tp_traverse
|
|
|
- NULL, // tp_clear
|
|
|
- (richcmpfunc)Opcode_richcmp, // tp_richcompare
|
|
|
- 0, // tp_weaklistoffset
|
|
|
- NULL, // tp_iter
|
|
|
- NULL, // tp_iternext
|
|
|
- Opcode_methods, // tp_methods
|
|
|
- NULL, // tp_members
|
|
|
- NULL, // tp_getset
|
|
|
- NULL, // tp_base
|
|
|
- NULL, // tp_dict
|
|
|
- NULL, // tp_descr_get
|
|
|
- NULL, // tp_descr_set
|
|
|
- 0, // tp_dictoffset
|
|
|
- (initproc)Opcode_init, // tp_init
|
|
|
- NULL, // tp_alloc
|
|
|
- PyType_GenericNew, // tp_new
|
|
|
- NULL, // tp_free
|
|
|
- NULL, // tp_is_gc
|
|
|
- NULL, // tp_bases
|
|
|
- NULL, // tp_mro
|
|
|
- NULL, // tp_cache
|
|
|
- NULL, // tp_subclasses
|
|
|
- NULL, // tp_weaklist
|
|
|
- NULL, // tp_del
|
|
|
- 0 // tp_version_tag
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-static int
|
|
|
-Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
|
|
|
- PyErr_SetString(PyExc_NotImplementedError,
|
|
|
- "Opcode can't be built directly");
|
|
|
- return (-1);
|
|
|
-}
|
|
|
-
|
|
|
-static void
|
|
|
-Opcode_destroy(s_Opcode* self) {
|
|
|
- // We only use the consts from Opcode, so don't
|
|
|
- // delete self->opcode here
|
|
|
- self->opcode = NULL;
|
|
|
- Py_TYPE(self)->tp_free(self);
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_getCode(s_Opcode* self) {
|
|
|
- return (Py_BuildValue("I", self->opcode->getCode()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_toText(s_Opcode* self) {
|
|
|
- return (Py_BuildValue("s", self->opcode->toText().c_str()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_str(PyObject* self) {
|
|
|
- // Simply call the to_text method we already defined
|
|
|
- return (PyObject_CallMethod(self,
|
|
|
- const_cast<char*>("to_text"),
|
|
|
- const_cast<char*>("")));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_createStatic(const Opcode& opcode) {
|
|
|
- s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
|
|
|
- if (ret != NULL) {
|
|
|
- ret->opcode = &opcode;
|
|
|
- }
|
|
|
- return (ret);
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::QUERY()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::IQUERY()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::STATUS()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED3()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::NOTIFY()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::UPDATE()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED6()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED7()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED8()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED9()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED10()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED11()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED12()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED13()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED14()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
|
|
|
- return (Opcode_createStatic(Opcode::RESERVED15()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
|
|
|
- bool c = false;
|
|
|
-
|
|
|
- // Check for null and if the types match. If different type,
|
|
|
- // simply return False
|
|
|
- if (!other || (self->ob_type != other->ob_type)) {
|
|
|
- Py_RETURN_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // Only equals and not equals here, unorderable type
|
|
|
- switch (op) {
|
|
|
- case Py_LT:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_LE:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_EQ:
|
|
|
- c = (*self->opcode == *other->opcode);
|
|
|
- break;
|
|
|
- case Py_NE:
|
|
|
- c = (*self->opcode != *other->opcode);
|
|
|
- break;
|
|
|
- case Py_GT:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_GE:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- }
|
|
|
- if (c)
|
|
|
- Py_RETURN_TRUE;
|
|
|
- else
|
|
|
- Py_RETURN_FALSE;
|
|
|
-}
|
|
|
-
|
|
|
-//
|
|
|
-// End of Opcode wrapper
|
|
|
-//
|
|
|
-
|
|
|
-//
|
|
|
-// Rcode
|
|
|
-//
|
|
|
-
|
|
|
-// We added a helper variable static_code here
|
|
|
-// Since we can create Rcodes dynamically with Rcode(int), but also
|
|
|
-// use the static globals (Rcode::NOERROR() etc), we use this
|
|
|
-// variable to see if the code came from one of the latter, in which
|
|
|
-// case Rcode_destroy should not free it (the other option is to
|
|
|
-// allocate new Rcodes for every use of the static ones, but this
|
|
|
-// seems more efficient).
|
|
|
-class s_Rcode : public PyObject {
|
|
|
-public:
|
|
|
- const Rcode* rcode;
|
|
|
- bool static_code;
|
|
|
-};
|
|
|
-
|
|
|
-static int Rcode_init(s_Rcode* self, PyObject* args);
|
|
|
-static void Rcode_destroy(s_Rcode* self);
|
|
|
-
|
|
|
-static PyObject* Rcode_getCode(s_Rcode* self);
|
|
|
-static PyObject* Rcode_toText(s_Rcode* self);
|
|
|
-static PyObject* Rcode_str(PyObject* self);
|
|
|
-static PyObject* Rcode_NOERROR(s_Rcode* self);
|
|
|
-static PyObject* Rcode_FORMERR(s_Rcode* self);
|
|
|
-static PyObject* Rcode_SERVFAIL(s_Rcode* self);
|
|
|
-static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
|
|
|
-static PyObject* Rcode_NOTIMP(s_Rcode* self);
|
|
|
-static PyObject* Rcode_REFUSED(s_Rcode* self);
|
|
|
-static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
|
|
|
-static PyObject* Rcode_YXRRSET(s_Rcode* self);
|
|
|
-static PyObject* Rcode_NXRRSET(s_Rcode* self);
|
|
|
-static PyObject* Rcode_NOTAUTH(s_Rcode* self);
|
|
|
-static PyObject* Rcode_NOTZONE(s_Rcode* self);
|
|
|
-static PyObject* Rcode_RESERVED11(s_Rcode* self);
|
|
|
-static PyObject* Rcode_RESERVED12(s_Rcode* self);
|
|
|
-static PyObject* Rcode_RESERVED13(s_Rcode* self);
|
|
|
-static PyObject* Rcode_RESERVED14(s_Rcode* self);
|
|
|
-static PyObject* Rcode_RESERVED15(s_Rcode* self);
|
|
|
-static PyObject* Rcode_BADVERS(s_Rcode* self);
|
|
|
-static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
|
|
|
-
|
|
|
-static PyMethodDef Rcode_methods[] = {
|
|
|
- { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
|
|
|
- { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
|
|
|
- { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
|
|
|
- { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
|
|
|
- { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
|
|
|
- { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
|
|
|
- { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
|
|
|
- { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
|
|
|
- { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
|
|
|
- { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
|
|
|
- { NULL, NULL, 0, NULL }
|
|
|
-};
|
|
|
-
|
|
|
-static PyTypeObject rcode_type = {
|
|
|
- PyVarObject_HEAD_INIT(NULL, 0)
|
|
|
- "pydnspp.Rcode",
|
|
|
- sizeof(s_Rcode), // tp_basicsize
|
|
|
- 0, // tp_itemsize
|
|
|
- (destructor)Rcode_destroy, // tp_dealloc
|
|
|
- NULL, // tp_print
|
|
|
- NULL, // tp_getattr
|
|
|
- NULL, // tp_setattr
|
|
|
- NULL, // tp_reserved
|
|
|
- NULL, // tp_repr
|
|
|
- NULL, // tp_as_number
|
|
|
- NULL, // tp_as_sequence
|
|
|
- NULL, // tp_as_mapping
|
|
|
- NULL, // tp_hash
|
|
|
- NULL, // tp_call
|
|
|
- Rcode_str, // tp_str
|
|
|
- NULL, // tp_getattro
|
|
|
- NULL, // tp_setattro
|
|
|
- NULL, // tp_as_buffer
|
|
|
- Py_TPFLAGS_DEFAULT, // tp_flags
|
|
|
- "The Rcode class objects represent standard RCODEs"
|
|
|
- "of the header section of DNS messages.",
|
|
|
- NULL, // tp_traverse
|
|
|
- NULL, // tp_clear
|
|
|
- (richcmpfunc)Rcode_richcmp, // tp_richcompare
|
|
|
- 0, // tp_weaklistoffset
|
|
|
- NULL, // tp_iter
|
|
|
- NULL, // tp_iternext
|
|
|
- Rcode_methods, // tp_methods
|
|
|
- NULL, // tp_members
|
|
|
- NULL, // tp_getset
|
|
|
- NULL, // tp_base
|
|
|
- NULL, // tp_dict
|
|
|
- NULL, // tp_descr_get
|
|
|
- NULL, // tp_descr_set
|
|
|
- 0, // tp_dictoffset
|
|
|
- (initproc)Rcode_init, // tp_init
|
|
|
- NULL, // tp_alloc
|
|
|
- PyType_GenericNew, // tp_new
|
|
|
- NULL, // tp_free
|
|
|
- NULL, // tp_is_gc
|
|
|
- NULL, // tp_bases
|
|
|
- NULL, // tp_mro
|
|
|
- NULL, // tp_cache
|
|
|
- NULL, // tp_subclasses
|
|
|
- NULL, // tp_weaklist
|
|
|
- NULL, // tp_del
|
|
|
- 0 // tp_version_tag
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-static int
|
|
|
-Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
|
|
|
- uint16_t code = 0;
|
|
|
- if (PyArg_ParseTuple(args, "h", &code)) {
|
|
|
- try {
|
|
|
- self->rcode = new Rcode(code);
|
|
|
- self->static_code = false;
|
|
|
- } catch (const isc::OutOfRange&) {
|
|
|
- PyErr_SetString(PyExc_OverflowError,
|
|
|
- "rcode out of range");
|
|
|
- return (-1);
|
|
|
- }
|
|
|
- return (0);
|
|
|
- } else {
|
|
|
- return (-1);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void
|
|
|
-Rcode_destroy(s_Rcode* self) {
|
|
|
- // Depending on whether we created the rcode or are referring
|
|
|
- // to a global static one, we do or do not delete self->rcode here
|
|
|
- if (!self->static_code) {
|
|
|
- delete self->rcode;
|
|
|
- }
|
|
|
- self->rcode = NULL;
|
|
|
- Py_TYPE(self)->tp_free(self);
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_getCode(s_Rcode* self) {
|
|
|
- return (Py_BuildValue("I", self->rcode->getCode()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_toText(s_Rcode* self) {
|
|
|
- return (Py_BuildValue("s", self->rcode->toText().c_str()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_str(PyObject* self) {
|
|
|
- // Simply call the to_text method we already defined
|
|
|
- return (PyObject_CallMethod(self,
|
|
|
- const_cast<char*>("to_text"),
|
|
|
- const_cast<char*>("")));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_createStatic(const Rcode& rcode) {
|
|
|
- s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
|
|
|
- if (ret != NULL) {
|
|
|
- ret->rcode = &rcode;
|
|
|
- ret->static_code = true;
|
|
|
- }
|
|
|
- return (ret);
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NOERROR()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::FORMERR()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::SERVFAIL()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NXDOMAIN()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NOTIMP()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::REFUSED()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::YXDOMAIN()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::YXRRSET()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NXRRSET()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NOTAUTH()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::NOTZONE()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::RESERVED11()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::RESERVED12()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::RESERVED13()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::RESERVED14()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::RESERVED15()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
|
|
|
- return (Rcode_createStatic(Rcode::BADVERS()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
|
|
|
- bool c = false;
|
|
|
-
|
|
|
- // Check for null and if the types match. If different type,
|
|
|
- // simply return False
|
|
|
- if (!other || (self->ob_type != other->ob_type)) {
|
|
|
- Py_RETURN_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // Only equals and not equals here, unorderable type
|
|
|
- switch (op) {
|
|
|
- case Py_LT:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_LE:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_EQ:
|
|
|
- c = (*self->rcode == *other->rcode);
|
|
|
- break;
|
|
|
- case Py_NE:
|
|
|
- c = (*self->rcode != *other->rcode);
|
|
|
- break;
|
|
|
- case Py_GT:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- case Py_GE:
|
|
|
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
|
|
|
- return (NULL);
|
|
|
- break;
|
|
|
- }
|
|
|
- if (c)
|
|
|
- Py_RETURN_TRUE;
|
|
|
- else
|
|
|
- Py_RETURN_FALSE;
|
|
|
-}
|
|
|
-
|
|
|
-//
|
|
|
-// End of Rcode wrapper
|
|
|
-//
|
|
|
-
|
|
|
-
|
|
|
//
|
|
|
// Section
|
|
|
//
|
|
@@ -973,16 +392,14 @@ static void Message_destroy(s_Message* self);
|
|
|
static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
|
|
|
-static PyObject* Message_isDNSSECSupported(s_Message* self);
|
|
|
-static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
|
|
|
-static PyObject* Message_getUDPSize(s_Message* self);
|
|
|
-static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_getQid(s_Message* self);
|
|
|
static PyObject* Message_setQid(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_getRcode(s_Message* self);
|
|
|
static PyObject* Message_setRcode(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_getOpcode(s_Message* self);
|
|
|
static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
|
|
|
+static PyObject* Message_getEDNS(s_Message* self);
|
|
|
+static PyObject* Message_setEDNS(s_Message* self, PyObject* args);
|
|
|
static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
|
|
|
// use direct iterators for these? (or simply lists for now?)
|
|
|
static PyObject* Message_getQuestion(s_Message* self);
|
|
@@ -1019,35 +436,6 @@ static PyMethodDef Message_methods[] = {
|
|
|
"Sets the specified header flag bit to 0. The message must be in "
|
|
|
"RENDER mode. If not, an InvalidMessageOperation is raised. "
|
|
|
"Takes a MessageFlag object as the only argument." },
|
|
|
- { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
|
|
|
- "Returns True if the message sender indicates DNSSEC is supported. "
|
|
|
- "If EDNS is included, this corresponds to the value of the DO bit. "
|
|
|
- "Otherwise, DNSSEC is considered not supported." },
|
|
|
- { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
|
|
|
- "Specify whether DNSSEC is supported in the message. "
|
|
|
- "The message must be in RENDER mode. If not, an "
|
|
|
- "InvalidMessageOperation is raised."
|
|
|
- "If EDNS is included in the message, the DO bit is set or cleared "
|
|
|
- "according to given argument (True or False) of this method."},
|
|
|
- { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
|
|
|
- "Return the maximum buffer size of UDP messages for the sender "
|
|
|
- "of the message.\n\n"
|
|
|
- "The semantics of this value is different based on the mode:\n"
|
|
|
- "In the PARSE mode, it means the buffer size of the remote node;\n"
|
|
|
- "in the RENDER mode, it means the buffer size of the local node.\n\n"
|
|
|
- "In either case, its value is the value of the UDP payload size field "
|
|
|
- "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
|
|
|
- { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
|
|
|
- "Specify the maximum buffer size of UDP messages of the local "
|
|
|
- "node. If the message is not in RENDER mode, an "
|
|
|
- "InvalidMessageOperation is raised.\n\n"
|
|
|
- "If EDNS OPT RR is included in the message, its UDP payload size field "
|
|
|
- "will be set to the specified value.\n"
|
|
|
- "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
|
|
|
- "for the maximum buffer size, regardless of whether EDNS OPT RR is "
|
|
|
- "included or not. This means if an application wants to send a message "
|
|
|
- "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
|
|
|
- "specify the value using this method. "},
|
|
|
{ "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
|
|
|
"Returns the query id" },
|
|
|
{ "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
|
|
@@ -1066,6 +454,12 @@ static PyMethodDef Message_methods[] = {
|
|
|
"Sets the message opcode (an Opcode object).\n"
|
|
|
"If the message is not in RENDER mode, an "
|
|
|
"InvalidMessageOperation is raised."},
|
|
|
+ { "get_edns", reinterpret_cast<PyCFunction>(Message_getEDNS), METH_NOARGS,
|
|
|
+ "Return, if any, the EDNS associated with the message."
|
|
|
+ },
|
|
|
+ { "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
|
|
|
+ "Set EDNS for the message."
|
|
|
+ },
|
|
|
{ "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
|
|
|
"Returns the number of RRs contained in the given section." },
|
|
|
{ "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
|
|
@@ -1248,57 +642,6 @@ Message_clearHeaderFlag(s_Message* self, PyObject* args) {
|
|
|
}
|
|
|
|
|
|
static PyObject*
|
|
|
-Message_isDNSSECSupported(s_Message* self) {
|
|
|
- if (self->message->isDNSSECSupported()) {
|
|
|
- Py_RETURN_TRUE;
|
|
|
- } else {
|
|
|
- Py_RETURN_FALSE;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Message_setDNSSECSupported(s_Message* self, PyObject* args) {
|
|
|
- PyObject *b;
|
|
|
- if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
|
|
|
- return (NULL);
|
|
|
- }
|
|
|
- try {
|
|
|
- if (b == Py_True) {
|
|
|
- self->message->setDNSSECSupported(true);
|
|
|
- } else {
|
|
|
- self->message->setDNSSECSupported(false);
|
|
|
- }
|
|
|
- Py_RETURN_NONE;
|
|
|
- } catch (const InvalidMessageOperation& imo) {
|
|
|
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
- return (NULL);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Message_getUDPSize(s_Message* self) {
|
|
|
- return (Py_BuildValue("I", self->message->getUDPSize()));
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
-Message_setUDPSize(s_Message* self, PyObject* args) {
|
|
|
- uint16_t size;
|
|
|
- if (!PyArg_ParseTuple(args, "H", &size)) {
|
|
|
- return (NULL);
|
|
|
- }
|
|
|
- try {
|
|
|
- self->message->setUDPSize(size);
|
|
|
- Py_RETURN_NONE;
|
|
|
- } catch (const InvalidMessageUDPSize& imus) {
|
|
|
- PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
|
|
|
- return (NULL);
|
|
|
- } catch (const InvalidMessageOperation& imo) {
|
|
|
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
- return (NULL);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static PyObject*
|
|
|
Message_getQid(s_Message* self) {
|
|
|
return (Py_BuildValue("I", self->message->getQid()));
|
|
|
}
|
|
@@ -1324,12 +667,18 @@ Message_getRcode(s_Message* self) {
|
|
|
|
|
|
rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
|
|
|
if (rcode != NULL) {
|
|
|
- rcode->rcode = new Rcode(self->message->getRcode());
|
|
|
- if (rcode->rcode == NULL)
|
|
|
- {
|
|
|
+ rcode->rcode = NULL;
|
|
|
+ try {
|
|
|
+ rcode->rcode = new Rcode(self->message->getRcode());
|
|
|
+ } catch (const InvalidMessageOperation& imo) {
|
|
|
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
+ } catch (...) {
|
|
|
+ PyErr_SetString(po_IscException, "Unexpected exception");
|
|
|
+ }
|
|
|
+ if (rcode->rcode == NULL) {
|
|
|
Py_DECREF(rcode);
|
|
|
return (NULL);
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return (rcode);
|
|
@@ -1356,15 +705,18 @@ Message_getOpcode(s_Message* self) {
|
|
|
|
|
|
opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
|
|
|
if (opcode != NULL) {
|
|
|
- // Note that we do not new and delete for opcodes.
|
|
|
- // all rcodes point to the statics defined in
|
|
|
- // message.cc
|
|
|
- opcode->opcode = &self->message->getOpcode();
|
|
|
- if (opcode->opcode == NULL)
|
|
|
- {
|
|
|
+ opcode->opcode = NULL;
|
|
|
+ try {
|
|
|
+ opcode->opcode = new Opcode(self->message->getOpcode());
|
|
|
+ } catch (const InvalidMessageOperation& imo) {
|
|
|
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
+ } catch (...) {
|
|
|
+ PyErr_SetString(po_IscException, "Unexpected exception");
|
|
|
+ }
|
|
|
+ if (opcode->opcode == NULL) {
|
|
|
Py_DECREF(opcode);
|
|
|
return (NULL);
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return (opcode);
|
|
@@ -1386,6 +738,41 @@ Message_setOpcode(s_Message* self, PyObject* args) {
|
|
|
}
|
|
|
|
|
|
static PyObject*
|
|
|
+Message_getEDNS(s_Message* self) {
|
|
|
+ s_EDNS* edns;
|
|
|
+ EDNS* edns_body;
|
|
|
+ ConstEDNSPtr src = self->message->getEDNS();
|
|
|
+
|
|
|
+ if (!src) {
|
|
|
+ Py_RETURN_NONE;
|
|
|
+ }
|
|
|
+ if ((edns_body = new(nothrow) EDNS(*src)) == NULL) {
|
|
|
+ return (PyErr_NoMemory());
|
|
|
+ }
|
|
|
+ edns = static_cast<s_EDNS*>(opcode_type.tp_alloc(&edns_type, 0));
|
|
|
+ if (edns != NULL) {
|
|
|
+ edns->edns = edns_body;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (edns);
|
|
|
+}
|
|
|
+
|
|
|
+static PyObject*
|
|
|
+Message_setEDNS(s_Message* self, PyObject* args) {
|
|
|
+ s_EDNS* edns;
|
|
|
+ if (!PyArg_ParseTuple(args, "O!", &edns_type, &edns)) {
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ self->message->setEDNS(EDNSPtr(new EDNS(*edns->edns)));
|
|
|
+ Py_RETURN_NONE;
|
|
|
+ } catch (const InvalidMessageOperation& imo) {
|
|
|
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static PyObject*
|
|
|
Message_getRRCount(s_Message* self, PyObject* args) {
|
|
|
s_Section *section;
|
|
|
if (!PyArg_ParseTuple(args, "O!", §ion_type, §ion)) {
|
|
@@ -1520,7 +907,16 @@ Message_makeResponse(s_Message* self) {
|
|
|
static PyObject*
|
|
|
Message_toText(s_Message* self) {
|
|
|
// Py_BuildValue makes python objects from native data
|
|
|
- return (Py_BuildValue("s", self->message->toText().c_str()));
|
|
|
+ try {
|
|
|
+ return (Py_BuildValue("s", self->message->toText().c_str()));
|
|
|
+ } catch (const InvalidMessageOperation& imo) {
|
|
|
+ PyErr_Clear();
|
|
|
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
|
|
|
+ return (NULL);
|
|
|
+ } catch (...) {
|
|
|
+ PyErr_SetString(po_IscException, "Unexpected exception");
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static PyObject*
|
|
@@ -1535,7 +931,7 @@ static PyObject*
|
|
|
Message_toWire(s_Message* self, PyObject* args) {
|
|
|
s_MessageRenderer* mr;
|
|
|
|
|
|
- if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
|
|
|
+ if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
|
|
|
try {
|
|
|
self->message->toWire(*mr->messagerenderer);
|
|
|
// If we return NULL it is seen as an error, so use this for
|