message_python.cc 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id: message_python.cc 1711 2010-04-14 15:14:53Z jelte $
  15. #include <dns/message.h>
  16. using namespace isc::dns;
  17. //
  18. // Declaration of the custom exceptions
  19. // Initialization and addition of these go in the initModulePart
  20. // function at the end of this file
  21. //
  22. static PyObject* po_MessageTooShort;
  23. static PyObject* po_InvalidMessageSection;
  24. static PyObject* po_InvalidMessageOperation;
  25. static PyObject* po_InvalidMessageUDPSize;
  26. static PyObject* po_DNSMessageBADVERS;
  27. //
  28. // Definition of the classes
  29. //
  30. // For each class, we need a struct, a helper functions (init, destroy,
  31. // and static wrappers around the methods we export), a list of methods,
  32. // and a type description
  33. //
  34. // MessageFlag
  35. //
  36. class s_MessageFlag : public PyObject {
  37. public:
  38. const MessageFlag* messageflag;
  39. };
  40. static int MessageFlag_init(s_MessageFlag* self, PyObject* args);
  41. static void MessageFlag_destroy(s_MessageFlag* self);
  42. static PyObject* MessageFlag_getBit(s_MessageFlag* self);
  43. static PyObject* MessageFlag_QR(s_MessageFlag* self);
  44. static PyObject* MessageFlag_AA(s_MessageFlag* self);
  45. static PyObject* MessageFlag_TC(s_MessageFlag* self);
  46. static PyObject* MessageFlag_RD(s_MessageFlag* self);
  47. static PyObject* MessageFlag_RA(s_MessageFlag* self);
  48. static PyObject* MessageFlag_AD(s_MessageFlag* self);
  49. static PyObject* MessageFlag_CD(s_MessageFlag* self);
  50. static PyMethodDef MessageFlag_methods[] = {
  51. { "get_bit", reinterpret_cast<PyCFunction>(MessageFlag_getBit), METH_NOARGS, "Returns the flag bit" },
  52. { "QR", reinterpret_cast<PyCFunction>(MessageFlag_QR), METH_NOARGS | METH_STATIC, "Creates a QR MessageFlag" },
  53. { "AA", reinterpret_cast<PyCFunction>(MessageFlag_AA), METH_NOARGS | METH_STATIC, "Creates a AA MessageFlag" },
  54. { "TC", reinterpret_cast<PyCFunction>(MessageFlag_TC), METH_NOARGS | METH_STATIC, "Creates a TC MessageFlag" },
  55. { "RD", reinterpret_cast<PyCFunction>(MessageFlag_RD), METH_NOARGS | METH_STATIC, "Creates a RD MessageFlag" },
  56. { "RA", reinterpret_cast<PyCFunction>(MessageFlag_RA), METH_NOARGS | METH_STATIC, "Creates a RA MessageFlag" },
  57. { "AD", reinterpret_cast<PyCFunction>(MessageFlag_AD), METH_NOARGS | METH_STATIC, "Creates a AD MessageFlag" },
  58. { "CD", reinterpret_cast<PyCFunction>(MessageFlag_CD), METH_NOARGS | METH_STATIC, "Creates a CD MessageFlag" },
  59. { NULL, NULL, 0, NULL }
  60. };
  61. static PyTypeObject messageflag_type = {
  62. PyVarObject_HEAD_INIT(NULL, 0)
  63. "libdns_python.MessageFlag",
  64. sizeof(s_MessageFlag), // tp_basicsize
  65. 0, // tp_itemsize
  66. (destructor)MessageFlag_destroy, // tp_dealloc
  67. NULL, // tp_print
  68. NULL, // tp_getattr
  69. NULL, // tp_setattr
  70. NULL, // tp_reserved
  71. NULL, // tp_repr
  72. NULL, // tp_as_number
  73. NULL, // tp_as_sequence
  74. NULL, // tp_as_mapping
  75. NULL, // tp_hash
  76. NULL, // tp_call
  77. NULL, // tp_str
  78. NULL, // tp_getattro
  79. NULL, // tp_setattro
  80. NULL, // tp_as_buffer
  81. Py_TPFLAGS_DEFAULT, // tp_flags
  82. "The MessageFlag class objects represent standard "
  83. "flag bits of the header section of DNS messages.",
  84. NULL, // tp_traverse
  85. NULL, // tp_clear
  86. NULL, // tp_richcompare
  87. 0, // tp_weaklistoffset
  88. NULL, // tp_iter
  89. NULL, // tp_iternext
  90. MessageFlag_methods, // tp_methods
  91. NULL, // tp_members
  92. NULL, // tp_getset
  93. NULL, // tp_base
  94. NULL, // tp_dict
  95. NULL, // tp_descr_get
  96. NULL, // tp_descr_set
  97. 0, // tp_dictoffset
  98. (initproc)MessageFlag_init, // tp_init
  99. NULL, // tp_alloc
  100. PyType_GenericNew, // tp_new
  101. NULL, // tp_free
  102. NULL, // tp_is_gc
  103. NULL, // tp_bases
  104. NULL, // tp_mro
  105. NULL, // tp_cache
  106. NULL, // tp_subclasses
  107. NULL, // tp_weaklist
  108. NULL, // tp_del
  109. 0 // tp_version_tag
  110. };
  111. static int
  112. MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
  113. PyObject* args UNUSED_PARAM)
  114. {
  115. PyErr_SetString(PyExc_NotImplementedError,
  116. "MessageFlag can't be built directly");
  117. return (-1);
  118. }
  119. static void
  120. MessageFlag_destroy(s_MessageFlag* self) {
  121. // We only use the consts from MessageFlag, so don't
  122. // delete self->messageflag here
  123. self->messageflag = NULL;
  124. Py_TYPE(self)->tp_free(self);
  125. }
  126. static PyObject*
  127. MessageFlag_getBit(s_MessageFlag* self) {
  128. return (Py_BuildValue("I", self->messageflag->getBit()));
  129. }
  130. static PyObject*
  131. MessageFlag_createStatic(const MessageFlag& flag) {
  132. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  133. if (ret != NULL) {
  134. ret->messageflag = &flag;
  135. }
  136. return (ret);
  137. }
  138. static PyObject*
  139. MessageFlag_QR(s_MessageFlag* self UNUSED_PARAM) {
  140. return (MessageFlag_createStatic(MessageFlag::QR()));
  141. }
  142. static PyObject*
  143. MessageFlag_AA(s_MessageFlag* self UNUSED_PARAM) {
  144. return (MessageFlag_createStatic(MessageFlag::AA()));
  145. }
  146. static PyObject*
  147. MessageFlag_TC(s_MessageFlag* self UNUSED_PARAM) {
  148. return (MessageFlag_createStatic(MessageFlag::TC()));
  149. }
  150. static PyObject*
  151. MessageFlag_RD(s_MessageFlag* self UNUSED_PARAM) {
  152. return (MessageFlag_createStatic(MessageFlag::RD()));
  153. }
  154. static PyObject*
  155. MessageFlag_RA(s_MessageFlag* self UNUSED_PARAM) {
  156. return (MessageFlag_createStatic(MessageFlag::RA()));
  157. }
  158. static PyObject*
  159. MessageFlag_AD(s_MessageFlag* self UNUSED_PARAM) {
  160. return (MessageFlag_createStatic(MessageFlag::AD()));
  161. }
  162. static PyObject*
  163. MessageFlag_CD(s_MessageFlag* self UNUSED_PARAM) {
  164. return (MessageFlag_createStatic(MessageFlag::CD()));
  165. }
  166. //
  167. // End of MessageFlag wrapper
  168. //
  169. //
  170. // Opcode
  171. //
  172. class s_Opcode : public PyObject {
  173. public:
  174. const Opcode* opcode;
  175. };
  176. static int Opcode_init(s_Opcode* self, PyObject* args);
  177. static void Opcode_destroy(s_Opcode* self);
  178. static PyObject* Opcode_getCode(s_Opcode* self);
  179. static PyObject* Opcode_toText(s_Opcode* self);
  180. static PyObject* Opcode_str(PyObject* self);
  181. static PyObject* Opcode_QUERY(s_Opcode* self);
  182. static PyObject* Opcode_IQUERY(s_Opcode* self);
  183. static PyObject* Opcode_STATUS(s_Opcode* self);
  184. static PyObject* Opcode_RESERVED3(s_Opcode* self);
  185. static PyObject* Opcode_NOTIFY(s_Opcode* self);
  186. static PyObject* Opcode_UPDATE(s_Opcode* self);
  187. static PyObject* Opcode_RESERVED6(s_Opcode* self);
  188. static PyObject* Opcode_RESERVED7(s_Opcode* self);
  189. static PyObject* Opcode_RESERVED8(s_Opcode* self);
  190. static PyObject* Opcode_RESERVED9(s_Opcode* self);
  191. static PyObject* Opcode_RESERVED10(s_Opcode* self);
  192. static PyObject* Opcode_RESERVED11(s_Opcode* self);
  193. static PyObject* Opcode_RESERVED12(s_Opcode* self);
  194. static PyObject* Opcode_RESERVED13(s_Opcode* self);
  195. static PyObject* Opcode_RESERVED14(s_Opcode* self);
  196. static PyObject* Opcode_RESERVED15(s_Opcode* self);
  197. static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
  198. static PyMethodDef Opcode_methods[] = {
  199. { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
  200. { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
  201. { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
  202. { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
  203. { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
  204. { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
  205. { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
  206. { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
  207. { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  208. { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  209. { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  210. { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  211. { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  212. { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  213. { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  214. { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  215. { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  216. { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
  217. { NULL, NULL, 0, NULL }
  218. };
  219. static PyTypeObject opcode_type = {
  220. PyVarObject_HEAD_INIT(NULL, 0)
  221. "libdns_python.Opcode",
  222. sizeof(s_Opcode), // tp_basicsize
  223. 0, // tp_itemsize
  224. (destructor)Opcode_destroy, // tp_dealloc
  225. NULL, // tp_print
  226. NULL, // tp_getattr
  227. NULL, // tp_setattr
  228. NULL, // tp_reserved
  229. NULL, // tp_repr
  230. NULL, // tp_as_number
  231. NULL, // tp_as_sequence
  232. NULL, // tp_as_mapping
  233. NULL, // tp_hash
  234. NULL, // tp_call
  235. Opcode_str, // tp_str
  236. NULL, // tp_getattro
  237. NULL, // tp_setattro
  238. NULL, // tp_as_buffer
  239. Py_TPFLAGS_DEFAULT, // tp_flags
  240. "The Opcode class objects represent standard OPCODEs "
  241. "of the header section of DNS messages.",
  242. NULL, // tp_traverse
  243. NULL, // tp_clear
  244. (richcmpfunc)Opcode_richcmp, // tp_richcompare
  245. 0, // tp_weaklistoffset
  246. NULL, // tp_iter
  247. NULL, // tp_iternext
  248. Opcode_methods, // tp_methods
  249. NULL, // tp_members
  250. NULL, // tp_getset
  251. NULL, // tp_base
  252. NULL, // tp_dict
  253. NULL, // tp_descr_get
  254. NULL, // tp_descr_set
  255. 0, // tp_dictoffset
  256. (initproc)Opcode_init, // tp_init
  257. NULL, // tp_alloc
  258. PyType_GenericNew, // tp_new
  259. NULL, // tp_free
  260. NULL, // tp_is_gc
  261. NULL, // tp_bases
  262. NULL, // tp_mro
  263. NULL, // tp_cache
  264. NULL, // tp_subclasses
  265. NULL, // tp_weaklist
  266. NULL, // tp_del
  267. 0 // tp_version_tag
  268. };
  269. static int
  270. Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
  271. PyErr_SetString(PyExc_NotImplementedError,
  272. "Opcode can't be built directly");
  273. return (-1);
  274. }
  275. static void
  276. Opcode_destroy(s_Opcode* self) {
  277. // We only use the consts from Opcode, so don't
  278. // delete self->opcode here
  279. self->opcode = NULL;
  280. Py_TYPE(self)->tp_free(self);
  281. }
  282. static PyObject*
  283. Opcode_getCode(s_Opcode* self) {
  284. return (Py_BuildValue("I", self->opcode->getCode()));
  285. }
  286. static PyObject*
  287. Opcode_toText(s_Opcode* self) {
  288. return (Py_BuildValue("s", self->opcode->toText().c_str()));
  289. }
  290. static PyObject*
  291. Opcode_str(PyObject* self) {
  292. // Simply call the to_text method we already defined
  293. return PyObject_CallMethod(self,
  294. const_cast<char*>("to_text"),
  295. const_cast<char*>(""));
  296. }
  297. static PyObject*
  298. Opcode_createStatic(const Opcode& opcode) {
  299. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  300. if (ret != NULL) {
  301. ret->opcode = &opcode;
  302. }
  303. return (ret);
  304. }
  305. static PyObject*
  306. Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
  307. return (Opcode_createStatic(Opcode::QUERY()));
  308. }
  309. static PyObject*
  310. Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
  311. return (Opcode_createStatic(Opcode::IQUERY()));
  312. }
  313. static PyObject*
  314. Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
  315. return (Opcode_createStatic(Opcode::STATUS()));
  316. }
  317. static PyObject*
  318. Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
  319. return (Opcode_createStatic(Opcode::RESERVED3()));
  320. }
  321. static PyObject*
  322. Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
  323. return (Opcode_createStatic(Opcode::NOTIFY()));
  324. }
  325. static PyObject*
  326. Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
  327. return (Opcode_createStatic(Opcode::UPDATE()));
  328. }
  329. static PyObject*
  330. Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
  331. return (Opcode_createStatic(Opcode::RESERVED6()));
  332. }
  333. static PyObject*
  334. Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
  335. return (Opcode_createStatic(Opcode::RESERVED7()));
  336. }
  337. static PyObject*
  338. Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
  339. return (Opcode_createStatic(Opcode::RESERVED8()));
  340. }
  341. static PyObject*
  342. Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
  343. return (Opcode_createStatic(Opcode::RESERVED9()));
  344. }
  345. static PyObject*
  346. Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
  347. return (Opcode_createStatic(Opcode::RESERVED10()));
  348. }
  349. static PyObject*
  350. Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
  351. return (Opcode_createStatic(Opcode::RESERVED11()));
  352. }
  353. static PyObject*
  354. Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
  355. return (Opcode_createStatic(Opcode::RESERVED12()));
  356. }
  357. static PyObject*
  358. Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
  359. return (Opcode_createStatic(Opcode::RESERVED13()));
  360. }
  361. static PyObject*
  362. Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
  363. return (Opcode_createStatic(Opcode::RESERVED14()));
  364. }
  365. static PyObject*
  366. Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
  367. return (Opcode_createStatic(Opcode::RESERVED15()));
  368. }
  369. static PyObject*
  370. Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
  371. bool c = false;
  372. // Check for null and if the types match. If different type,
  373. // simply return False
  374. if (!other || (self->ob_type != other->ob_type)) {
  375. Py_RETURN_FALSE;
  376. }
  377. // Only equals and not equals here, unorderable type
  378. switch (op) {
  379. case Py_LT:
  380. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  381. return (NULL);
  382. break;
  383. case Py_LE:
  384. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  385. return (NULL);
  386. break;
  387. case Py_EQ:
  388. c = (*self->opcode == *other->opcode);
  389. break;
  390. case Py_NE:
  391. c = (*self->opcode != *other->opcode);
  392. break;
  393. case Py_GT:
  394. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  395. return (NULL);
  396. break;
  397. case Py_GE:
  398. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  399. return (NULL);
  400. break;
  401. }
  402. if (c)
  403. Py_RETURN_TRUE;
  404. else
  405. Py_RETURN_FALSE;
  406. }
  407. //
  408. // End of Opcode wrapper
  409. //
  410. //
  411. // Rcode
  412. //
  413. // We added a helper variable static_code here
  414. // Since we can create Rcodes dynamically with Rcode(int), but also
  415. // use the static globals (Rcode::NOERROR() etc), we use this
  416. // variable to see if the code came from one of the latter, in which
  417. // case Rcode_destroy should not free it (the other option is to
  418. // allocate new Rcodes for every use of the static ones, but this
  419. // seems more efficient).
  420. class s_Rcode : public PyObject {
  421. public:
  422. const Rcode* rcode;
  423. bool static_code;
  424. };
  425. static int Rcode_init(s_Rcode* self, PyObject* args);
  426. static void Rcode_destroy(s_Rcode* self);
  427. static PyObject* Rcode_getCode(s_Rcode* self);
  428. static PyObject* Rcode_toText(s_Rcode* self);
  429. static PyObject* Rcode_str(PyObject* self);
  430. static PyObject* Rcode_NOERROR(s_Rcode* self);
  431. static PyObject* Rcode_FORMERR(s_Rcode* self);
  432. static PyObject* Rcode_SERVFAIL(s_Rcode* self);
  433. static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
  434. static PyObject* Rcode_NOTIMP(s_Rcode* self);
  435. static PyObject* Rcode_REFUSED(s_Rcode* self);
  436. static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
  437. static PyObject* Rcode_YXRRSET(s_Rcode* self);
  438. static PyObject* Rcode_NXRRSET(s_Rcode* self);
  439. static PyObject* Rcode_NOTAUTH(s_Rcode* self);
  440. static PyObject* Rcode_NOTZONE(s_Rcode* self);
  441. static PyObject* Rcode_RESERVED11(s_Rcode* self);
  442. static PyObject* Rcode_RESERVED12(s_Rcode* self);
  443. static PyObject* Rcode_RESERVED13(s_Rcode* self);
  444. static PyObject* Rcode_RESERVED14(s_Rcode* self);
  445. static PyObject* Rcode_RESERVED15(s_Rcode* self);
  446. static PyObject* Rcode_BADVERS(s_Rcode* self);
  447. static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
  448. static PyMethodDef Rcode_methods[] = {
  449. { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
  450. { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
  451. { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
  452. { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
  453. { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
  454. { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
  455. { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
  456. { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
  457. { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  458. { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  459. { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  460. { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  461. { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  462. { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  463. { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  464. { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  465. { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  466. { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
  467. { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
  468. { NULL, NULL, 0, NULL }
  469. };
  470. static PyTypeObject rcode_type = {
  471. PyVarObject_HEAD_INIT(NULL, 0)
  472. "libdns_python.Rcode",
  473. sizeof(s_Rcode), // tp_basicsize
  474. 0, // tp_itemsize
  475. (destructor)Rcode_destroy, // tp_dealloc
  476. NULL, // tp_print
  477. NULL, // tp_getattr
  478. NULL, // tp_setattr
  479. NULL, // tp_reserved
  480. NULL, // tp_repr
  481. NULL, // tp_as_number
  482. NULL, // tp_as_sequence
  483. NULL, // tp_as_mapping
  484. NULL, // tp_hash
  485. NULL, // tp_call
  486. Rcode_str, // tp_str
  487. NULL, // tp_getattro
  488. NULL, // tp_setattro
  489. NULL, // tp_as_buffer
  490. Py_TPFLAGS_DEFAULT, // tp_flags
  491. "The Rcode class objects represent standard RCODEs"
  492. "of the header section of DNS messages.",
  493. NULL, // tp_traverse
  494. NULL, // tp_clear
  495. (richcmpfunc)Rcode_richcmp, // tp_richcompare
  496. 0, // tp_weaklistoffset
  497. NULL, // tp_iter
  498. NULL, // tp_iternext
  499. Rcode_methods, // tp_methods
  500. NULL, // tp_members
  501. NULL, // tp_getset
  502. NULL, // tp_base
  503. NULL, // tp_dict
  504. NULL, // tp_descr_get
  505. NULL, // tp_descr_set
  506. 0, // tp_dictoffset
  507. (initproc)Rcode_init, // tp_init
  508. NULL, // tp_alloc
  509. PyType_GenericNew, // tp_new
  510. NULL, // tp_free
  511. NULL, // tp_is_gc
  512. NULL, // tp_bases
  513. NULL, // tp_mro
  514. NULL, // tp_cache
  515. NULL, // tp_subclasses
  516. NULL, // tp_weaklist
  517. NULL, // tp_del
  518. 0 // tp_version_tag
  519. };
  520. static int
  521. Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
  522. uint16_t code = 0;
  523. if (PyArg_ParseTuple(args, "h", &code)) {
  524. try {
  525. self->rcode = new Rcode(code);
  526. self->static_code = false;
  527. } catch (isc::OutOfRange) {
  528. PyErr_SetString(PyExc_OverflowError,
  529. "rcode out of range");
  530. return (-1);
  531. }
  532. return (0);
  533. } else {
  534. return (-1);
  535. }
  536. }
  537. static void
  538. Rcode_destroy(s_Rcode* self) {
  539. // Depending on whether we created the rcode or are referring
  540. // to a global static one, we do or do not delete self->rcode here
  541. if (!self->static_code) {
  542. delete self->rcode;
  543. }
  544. self->rcode = NULL;
  545. Py_TYPE(self)->tp_free(self);
  546. }
  547. static PyObject*
  548. Rcode_getCode(s_Rcode* self) {
  549. return (Py_BuildValue("I", self->rcode->getCode()));
  550. }
  551. static PyObject*
  552. Rcode_toText(s_Rcode* self) {
  553. return (Py_BuildValue("s", self->rcode->toText().c_str()));
  554. }
  555. static PyObject*
  556. Rcode_str(PyObject* self) {
  557. // Simply call the to_text method we already defined
  558. return PyObject_CallMethod(self,
  559. const_cast<char*>("to_text"),
  560. const_cast<char*>(""));
  561. }
  562. static PyObject*
  563. Rcode_createStatic(const Rcode& rcode) {
  564. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  565. if (ret != NULL) {
  566. ret->rcode = &rcode;
  567. ret->static_code = true;
  568. }
  569. return (ret);
  570. }
  571. static PyObject*
  572. Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
  573. return (Rcode_createStatic(Rcode::NOERROR()));
  574. }
  575. static PyObject*
  576. Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
  577. return (Rcode_createStatic(Rcode::FORMERR()));
  578. }
  579. static PyObject*
  580. Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
  581. return (Rcode_createStatic(Rcode::SERVFAIL()));
  582. }
  583. static PyObject*
  584. Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
  585. return (Rcode_createStatic(Rcode::NXDOMAIN()));
  586. }
  587. static PyObject*
  588. Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
  589. return (Rcode_createStatic(Rcode::NOTIMP()));
  590. }
  591. static PyObject*
  592. Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
  593. return (Rcode_createStatic(Rcode::REFUSED()));
  594. }
  595. static PyObject*
  596. Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
  597. return (Rcode_createStatic(Rcode::YXDOMAIN()));
  598. }
  599. static PyObject*
  600. Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
  601. return (Rcode_createStatic(Rcode::YXRRSET()));
  602. }
  603. static PyObject*
  604. Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
  605. return (Rcode_createStatic(Rcode::NXRRSET()));
  606. }
  607. static PyObject*
  608. Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
  609. return (Rcode_createStatic(Rcode::NOTAUTH()));
  610. }
  611. static PyObject*
  612. Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
  613. return (Rcode_createStatic(Rcode::NOTZONE()));
  614. }
  615. static PyObject*
  616. Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
  617. return (Rcode_createStatic(Rcode::RESERVED11()));
  618. }
  619. static PyObject*
  620. Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
  621. return (Rcode_createStatic(Rcode::RESERVED12()));
  622. }
  623. static PyObject*
  624. Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
  625. return (Rcode_createStatic(Rcode::RESERVED13()));
  626. }
  627. static PyObject*
  628. Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
  629. return (Rcode_createStatic(Rcode::RESERVED14()));
  630. }
  631. static PyObject*
  632. Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
  633. return (Rcode_createStatic(Rcode::RESERVED15()));
  634. }
  635. static PyObject*
  636. Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
  637. return (Rcode_createStatic(Rcode::BADVERS()));
  638. }
  639. static PyObject*
  640. Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
  641. bool c = false;
  642. // Check for null and if the types match. If different type,
  643. // simply return False
  644. if (!other || (self->ob_type != other->ob_type)) {
  645. Py_RETURN_FALSE;
  646. }
  647. // Only equals and not equals here, unorderable type
  648. switch (op) {
  649. case Py_LT:
  650. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  651. return (NULL);
  652. break;
  653. case Py_LE:
  654. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  655. return (NULL);
  656. break;
  657. case Py_EQ:
  658. c = (*self->rcode == *other->rcode);
  659. break;
  660. case Py_NE:
  661. c = (*self->rcode != *other->rcode);
  662. break;
  663. case Py_GT:
  664. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  665. return (NULL);
  666. break;
  667. case Py_GE:
  668. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  669. return (NULL);
  670. break;
  671. }
  672. if (c)
  673. Py_RETURN_TRUE;
  674. else
  675. Py_RETURN_FALSE;
  676. }
  677. //
  678. // End of Rcode wrapper
  679. //
  680. //
  681. // Section
  682. //
  683. // TODO: iterator?
  684. class s_Section : public PyObject {
  685. public:
  686. const Section* section;
  687. };
  688. static int Section_init(s_Section* self, PyObject* args);
  689. static void Section_destroy(s_Section* self);
  690. static PyObject* Section_getCode(s_Section* self);
  691. static PyObject* Section_QUESTION(s_Section* self);
  692. static PyObject* Section_ANSWER(s_Section* self);
  693. static PyObject* Section_AUTHORITY(s_Section* self);
  694. static PyObject* Section_ADDITIONAL(s_Section* self);
  695. static PyObject* Section_richcmp(s_Section* self, s_Section* other, int op);
  696. static PyMethodDef Section_methods[] = {
  697. { "get_code", reinterpret_cast<PyCFunction>(Section_getCode), METH_NOARGS, "Returns the code value" },
  698. { "QUESTION", reinterpret_cast<PyCFunction>(Section_QUESTION), METH_NOARGS | METH_STATIC, "Creates a QUESTION Section" },
  699. { "ANSWER", reinterpret_cast<PyCFunction>(Section_ANSWER), METH_NOARGS | METH_STATIC, "Creates an ANSWER Section" },
  700. { "AUTHORITY", reinterpret_cast<PyCFunction>(Section_AUTHORITY), METH_NOARGS | METH_STATIC, "Creates an AUTHORITY Section" },
  701. { "ADDITIONAL", reinterpret_cast<PyCFunction>(Section_ADDITIONAL), METH_NOARGS | METH_STATIC, "Creates an ADDITIONAL Section" },
  702. { NULL, NULL, 0, NULL }
  703. };
  704. static PyTypeObject section_type = {
  705. PyVarObject_HEAD_INIT(NULL, 0)
  706. "libdns_python.Section",
  707. sizeof(s_Section), // tp_basicsize
  708. 0, // tp_itemsize
  709. (destructor)Section_destroy, // tp_dealloc
  710. NULL, // tp_print
  711. NULL, // tp_getattr
  712. NULL, // tp_setattr
  713. NULL, // tp_reserved
  714. NULL, // tp_repr
  715. NULL, // tp_as_number
  716. NULL, // tp_as_sequence
  717. NULL, // tp_as_mapping
  718. NULL, // tp_hash
  719. NULL, // tp_call
  720. NULL, // tp_str
  721. NULL, // tp_getattro
  722. NULL, // tp_setattro
  723. NULL, // tp_as_buffer
  724. Py_TPFLAGS_DEFAULT, // tp_flags
  725. "The Section class objects represent DNS message sections such "
  726. "as the header, question, or answer.",
  727. NULL, // tp_traverse
  728. NULL, // tp_clear
  729. (richcmpfunc)Section_richcmp, // tp_richcompare
  730. 0, // tp_weaklistoffset
  731. NULL, // tp_iter
  732. NULL, // tp_iternext
  733. Section_methods, // tp_methods
  734. NULL, // tp_members
  735. NULL, // tp_getset
  736. NULL, // tp_base
  737. NULL, // tp_dict
  738. NULL, // tp_descr_get
  739. NULL, // tp_descr_set
  740. 0, // tp_dictoffset
  741. (initproc)Section_init, // tp_init
  742. NULL, // tp_alloc
  743. PyType_GenericNew, // tp_new
  744. NULL, // tp_free
  745. NULL, // tp_is_gc
  746. NULL, // tp_bases
  747. NULL, // tp_mro
  748. NULL, // tp_cache
  749. NULL, // tp_subclasses
  750. NULL, // tp_weaklist
  751. NULL, // tp_del
  752. 0 // tp_version_tag
  753. };
  754. static int
  755. Section_init(s_Section* self UNUSED_PARAM,
  756. PyObject* args UNUSED_PARAM)
  757. {
  758. PyErr_SetString(PyExc_NotImplementedError,
  759. "Section can't be built directly");
  760. return (-1);
  761. }
  762. static void
  763. Section_destroy(s_Section* self) {
  764. // We only use the consts from Section, so don't
  765. // delete self->section here
  766. self->section = NULL;
  767. Py_TYPE(self)->tp_free(self);
  768. }
  769. static PyObject*
  770. Section_getCode(s_Section* self) {
  771. return (Py_BuildValue("I", self->section->getCode()));
  772. }
  773. static PyObject*
  774. Section_createStatic(const Section& section) {
  775. s_Section* ret = PyObject_New(s_Section, &section_type);
  776. if (ret != NULL) {
  777. ret->section = &section;
  778. }
  779. return (ret);
  780. }
  781. static PyObject*
  782. Section_QUESTION(s_Section* self UNUSED_PARAM) {
  783. return Section_createStatic(Section::QUESTION());
  784. }
  785. static PyObject*
  786. Section_ANSWER(s_Section* self UNUSED_PARAM) {
  787. return Section_createStatic(Section::ANSWER());
  788. }
  789. static PyObject*
  790. Section_AUTHORITY(s_Section* self UNUSED_PARAM) {
  791. return Section_createStatic(Section::AUTHORITY());
  792. }
  793. static PyObject*
  794. Section_ADDITIONAL(s_Section* self UNUSED_PARAM) {
  795. return Section_createStatic(Section::ADDITIONAL());
  796. }
  797. static PyObject*
  798. Section_richcmp(s_Section* self, s_Section* other, int op) {
  799. bool c = false;
  800. // Check for null and if the types match. If different type,
  801. // simply return False
  802. if (!other || (self->ob_type != other->ob_type)) {
  803. Py_RETURN_FALSE;
  804. }
  805. // Only equals and not equals here, unorderable type
  806. switch (op) {
  807. case Py_LT:
  808. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  809. return (NULL);
  810. break;
  811. case Py_LE:
  812. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  813. return (NULL);
  814. break;
  815. case Py_EQ:
  816. c = (*self->section == *other->section);
  817. break;
  818. case Py_NE:
  819. c = (*self->section != *other->section);
  820. break;
  821. case Py_GT:
  822. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  823. return (NULL);
  824. break;
  825. case Py_GE:
  826. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  827. return (NULL);
  828. break;
  829. }
  830. if (c)
  831. Py_RETURN_TRUE;
  832. else
  833. Py_RETURN_FALSE;
  834. }
  835. //
  836. // End of Section wrapper
  837. //
  838. //
  839. // Message
  840. //
  841. // The s_* Class simply coverst one instantiation of the object
  842. class s_Message : public PyObject {
  843. public:
  844. Message* message;
  845. };
  846. //
  847. // We declare the functions here, the definitions are below
  848. // the type definition of the object, since both can use the other
  849. //
  850. // General creation and destruction
  851. static int Message_init(s_Message* self, PyObject* args);
  852. static void Message_destroy(s_Message* self);
  853. static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
  854. static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
  855. static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
  856. static PyObject* Message_isDNSSECSupported(s_Message* self);
  857. static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
  858. static PyObject* Message_getUDPSize(s_Message* self);
  859. static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
  860. static PyObject* Message_getQid(s_Message* self);
  861. static PyObject* Message_setQid(s_Message* self, PyObject* args);
  862. static PyObject* Message_getRcode(s_Message* self);
  863. static PyObject* Message_setRcode(s_Message* self, PyObject* args);
  864. static PyObject* Message_getOpcode(s_Message* self);
  865. static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
  866. static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
  867. // use direct iterators for these? (or simply lists for now?)
  868. static PyObject* Message_getQuestion(s_Message* self);
  869. static PyObject* Message_getSection(s_Message* self, PyObject* args);
  870. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  871. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  872. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  873. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  874. static PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  875. static PyObject* Message_addRRset(s_Message* self, PyObject* args);
  876. static PyObject* Message_clear(s_Message* self, PyObject* args);
  877. static PyObject* Message_makeResponse(s_Message* self);
  878. static PyObject* Message_toText(s_Message* self);
  879. static PyObject* Message_str(PyObject* self);
  880. static PyObject* Message_toWire(s_Message* self, PyObject* args);
  881. static PyObject* Message_fromWire(s_Message* self, PyObject* args);
  882. // This list contains the actual set of functions we have in
  883. // python. Each entry has
  884. // 1. Python method name
  885. // 2. Our static function here
  886. // 3. Argument type
  887. // 4. Documentation
  888. static PyMethodDef Message_methods[] = {
  889. { "get_header_flag", reinterpret_cast<PyCFunction>(Message_getHeaderFlag), METH_VARARGS,
  890. "Return whether the specified header flag bit is set in the "
  891. "header section. Takes a MessageFlag object as the only argument." },
  892. { "set_header_flag", reinterpret_cast<PyCFunction>(Message_setHeaderFlag), METH_VARARGS,
  893. "Sets the specified header flag bit to 1. The message must be in "
  894. "RENDER mode. If not, an InvalidMessageOperation is raised. "
  895. "Takes a MessageFlag object as the only argument." },
  896. { "clear_header_flag", reinterpret_cast<PyCFunction>(Message_clearHeaderFlag), METH_VARARGS,
  897. "Sets the specified header flag bit to 0. The message must be in "
  898. "RENDER mode. If not, an InvalidMessageOperation is raised. "
  899. "Takes a MessageFlag object as the only argument." },
  900. { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
  901. "Returns True if the message sender indicates DNSSEC is supported. "
  902. "If EDNS is included, this corresponds to the value of the DO bit. "
  903. "Otherwise, DNSSEC is considered not supported." },
  904. { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
  905. "Specify whether DNSSEC is supported in the message. "
  906. "The message must be in RENDER mode. If not, an "
  907. "InvalidMessageOperation is raised."
  908. "If EDNS is included in the message, the DO bit is set or cleared "
  909. "according to given argument (True or False) of this method."},
  910. { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
  911. "Return the maximum buffer size of UDP messages for the sender "
  912. "of the message.\n\n"
  913. "The semantics of this value is different based on the mode:\n"
  914. "In the PARSE mode, it means the buffer size of the remote node;\n"
  915. "in the RENDER mode, it means the buffer size of the local node.\n\n"
  916. "In either case, its value is the value of the UDP payload size field "
  917. "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
  918. { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
  919. "Specify the maximum buffer size of UDP messages of the local "
  920. "node. If the message is not in RENDER mode, an "
  921. "InvalidMessageOperation is raised.\n\n"
  922. "If EDNS OPT RR is included in the message, its UDP payload size field "
  923. "will be set to the specified value.\n"
  924. "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
  925. "for the maximum buffer size, regardless of whether EDNS OPT RR is "
  926. "included or not. This means if an application wants to send a message "
  927. "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
  928. "specify the value using this method. "},
  929. { "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
  930. "Returns the query id" },
  931. { "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
  932. "Sets the query id. If the message is not in RENDER mode, an "
  933. "InvalidMessageOperation is raised.\n"
  934. "The argument must be an integer" },
  935. { "get_rcode", reinterpret_cast<PyCFunction>(Message_getRcode), METH_NOARGS,
  936. "Returns the message Response code (an Rcode object)" },
  937. { "set_rcode", reinterpret_cast<PyCFunction>(Message_setRcode), METH_VARARGS,
  938. "Sets the message Response code (an Rcode object).\n"
  939. "If the message is not in RENDER mode, an "
  940. "InvalidMessageOperation is raised."},
  941. { "get_opcode", reinterpret_cast<PyCFunction>(Message_getOpcode), METH_NOARGS,
  942. "Returns the message opcode (an Opcode object)" },
  943. { "set_opcode", reinterpret_cast<PyCFunction>(Message_setOpcode), METH_VARARGS,
  944. "Sets the message opcode (an Opcode object).\n"
  945. "If the message is not in RENDER mode, an "
  946. "InvalidMessageOperation is raised."},
  947. { "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
  948. "Returns the number of RRs contained in the given section." },
  949. { "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
  950. "Returns a list of all Question objects in the message "
  951. "(should be either 0 or 1)" },
  952. { "get_section", reinterpret_cast<PyCFunction>(Message_getSection), METH_VARARGS,
  953. "Returns a list of all RRset objects in the given section of the message\n"
  954. "The argument must be of type Section" },
  955. { "add_question", reinterpret_cast<PyCFunction>(Message_addQuestion), METH_VARARGS,
  956. "Add a Question to the message."
  957. "If the message is not in RENDER mode, an "
  958. "InvalidMessageOperation is raised."},
  959. { "add_rrset", reinterpret_cast<PyCFunction>(Message_addRRset), METH_VARARGS,
  960. "Add an RRset to the given section of the message.\n"
  961. "The first argument is of type Section\n"
  962. "The second is of type RRset\n"
  963. "The third argument is an optional Boolean specifying whether "
  964. "the RRset is signed"},
  965. { "clear", reinterpret_cast<PyCFunction>(Message_clear), METH_VARARGS,
  966. "Clears the message content (if any) and reinitialize the "
  967. "message in the given mode\n"
  968. "The argument must be either Message.PARSE or Message.RENDER"},
  969. { "make_response", reinterpret_cast<PyCFunction>(Message_makeResponse), METH_NOARGS,
  970. "Prepare for making a response from a request.\n"
  971. "This will clear the DNS header except those fields that should be kept "
  972. "for the response, and clear answer and the following sections. "
  973. "See also dns_message_reply() of BIND9."},
  974. { "to_text", reinterpret_cast<PyCFunction>(Message_toText), METH_NOARGS,
  975. "Returns the string representation of the message" },
  976. { "to_wire", reinterpret_cast<PyCFunction>(Message_toWire), METH_VARARGS,
  977. "Render the message in wire format.\n"
  978. "The argument must be a MessageRenderer.\n"
  979. "If the given message is not in RENDER mode, an "
  980. "InvalidMessageOperation is raised.\n"
  981. },
  982. { "from_wire", reinterpret_cast<PyCFunction>(Message_fromWire), METH_VARARGS,
  983. "Parses the given wire format to a Message object.\n"
  984. "The first argument is a Message to parse the data into.\n"
  985. "The second argument must implement the buffer interface.\n"
  986. "If the given message is not in PARSE mode, an "
  987. "InvalidMessageOperation is raised.\n"
  988. "Raises MessageTooShort, DNSMessageFORMERR or DNSMessageBADVERS "
  989. " if there is a problem parsing the message." },
  990. { NULL, NULL, 0, NULL }
  991. };
  992. // This defines the complete type for reflection in python and
  993. // parsing of PyObject* to s_Message
  994. // Most of the functions are not actually implemented and NULL here.
  995. static PyTypeObject message_type = {
  996. PyVarObject_HEAD_INIT(NULL, 0)
  997. "libdns_python.Message",
  998. sizeof(s_Message), // tp_basicsize
  999. 0, // tp_itemsize
  1000. (destructor)Message_destroy, // tp_dealloc
  1001. NULL, // tp_print
  1002. NULL, // tp_getattr
  1003. NULL, // tp_setattr
  1004. NULL, // tp_reserved
  1005. NULL, // tp_repr
  1006. NULL, // tp_as_number
  1007. NULL, // tp_as_sequence
  1008. NULL, // tp_as_mapping
  1009. NULL, // tp_hash
  1010. NULL, // tp_call
  1011. Message_str, // tp_str
  1012. NULL, // tp_getattro
  1013. NULL, // tp_setattro
  1014. NULL, // tp_as_buffer
  1015. Py_TPFLAGS_DEFAULT, // tp_flags
  1016. "The Message class encapsulates a standard DNS message.",
  1017. NULL, // tp_traverse
  1018. NULL, // tp_clear
  1019. NULL, // tp_richcompare
  1020. 0, // tp_weaklistoffset
  1021. NULL, // tp_iter
  1022. NULL, // tp_iternext
  1023. Message_methods, // tp_methods
  1024. NULL, // tp_members
  1025. NULL, // tp_getset
  1026. NULL, // tp_base
  1027. NULL, // tp_dict
  1028. NULL, // tp_descr_get
  1029. NULL, // tp_descr_set
  1030. 0, // tp_dictoffset
  1031. (initproc)Message_init, // tp_init
  1032. NULL, // tp_alloc
  1033. PyType_GenericNew, // tp_new
  1034. NULL, // tp_free
  1035. NULL, // tp_is_gc
  1036. NULL, // tp_bases
  1037. NULL, // tp_mro
  1038. NULL, // tp_cache
  1039. NULL, // tp_subclasses
  1040. NULL, // tp_weaklist
  1041. NULL, // tp_del
  1042. 0 // tp_version_tag
  1043. };
  1044. static int
  1045. Message_init(s_Message* self, PyObject* args) {
  1046. unsigned int i;
  1047. // The constructor argument can be a string ("IN"), an integer (1),
  1048. // or a sequence of numbers between 0 and 255 (wire code)
  1049. if (PyArg_ParseTuple(args, "I", &i)) {
  1050. PyErr_Clear();
  1051. if (i == Message::PARSE) {
  1052. self->message = new Message(Message::PARSE);
  1053. return (0);
  1054. } else if (i == Message::RENDER) {
  1055. self->message = new Message(Message::RENDER);
  1056. return (0);
  1057. } else {
  1058. PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
  1059. return (-1);
  1060. }
  1061. }
  1062. PyErr_Clear();
  1063. PyErr_SetString(PyExc_TypeError,
  1064. "no valid type in constructor argument");
  1065. return (-1);
  1066. }
  1067. static void
  1068. Message_destroy(s_Message* self) {
  1069. delete self->message;
  1070. self->message = NULL;
  1071. Py_TYPE(self)->tp_free(self);
  1072. }
  1073. static PyObject*
  1074. Message_getHeaderFlag(s_Message* self, PyObject* args) {
  1075. s_MessageFlag* messageflag;
  1076. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1077. return (NULL);
  1078. }
  1079. if (self->message->getHeaderFlag(*messageflag->messageflag)) {
  1080. Py_RETURN_TRUE;
  1081. } else {
  1082. Py_RETURN_FALSE;
  1083. }
  1084. }
  1085. static PyObject*
  1086. Message_setHeaderFlag(s_Message* self, PyObject* args) {
  1087. s_MessageFlag* messageflag;
  1088. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1089. return (NULL);
  1090. }
  1091. try {
  1092. self->message->setHeaderFlag(*messageflag->messageflag);
  1093. Py_RETURN_NONE;
  1094. } catch (isc::dns::InvalidMessageOperation imo) {
  1095. PyErr_Clear();
  1096. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1097. return (NULL);
  1098. }
  1099. }
  1100. static PyObject*
  1101. Message_clearHeaderFlag(s_Message* self, PyObject* args) {
  1102. s_MessageFlag* messageflag;
  1103. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1104. return (NULL);
  1105. }
  1106. try {
  1107. self->message->clearHeaderFlag(*messageflag->messageflag);
  1108. Py_RETURN_NONE;
  1109. } catch (isc::dns::InvalidMessageOperation imo) {
  1110. PyErr_Clear();
  1111. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1112. return (NULL);
  1113. }
  1114. Py_RETURN_NONE;
  1115. }
  1116. static PyObject*
  1117. Message_isDNSSECSupported(s_Message* self) {
  1118. if (self->message->isDNSSECSupported()) {
  1119. Py_RETURN_TRUE;
  1120. } else {
  1121. Py_RETURN_FALSE;
  1122. }
  1123. }
  1124. static PyObject*
  1125. Message_setDNSSECSupported(s_Message* self, PyObject* args) {
  1126. PyObject *b;
  1127. if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
  1128. return (NULL);
  1129. }
  1130. try {
  1131. if (b == Py_True) {
  1132. self->message->setDNSSECSupported(true);
  1133. } else {
  1134. self->message->setDNSSECSupported(false);
  1135. }
  1136. Py_RETURN_NONE;
  1137. } catch (isc::dns::InvalidMessageOperation imo) {
  1138. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1139. return (NULL);
  1140. }
  1141. }
  1142. static PyObject*
  1143. Message_getUDPSize(s_Message* self) {
  1144. return (Py_BuildValue("I", self->message->getUDPSize()));
  1145. }
  1146. static PyObject*
  1147. Message_setUDPSize(s_Message* self, PyObject* args) {
  1148. uint16_t size;
  1149. if (!PyArg_ParseTuple(args, "H", &size)) {
  1150. return (NULL);
  1151. }
  1152. try {
  1153. self->message->setUDPSize(size);
  1154. Py_RETURN_NONE;
  1155. } catch (isc::dns::InvalidMessageUDPSize imus) {
  1156. PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
  1157. return (NULL);
  1158. } catch (isc::dns::InvalidMessageOperation imo) {
  1159. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1160. return (NULL);
  1161. }
  1162. }
  1163. static PyObject*
  1164. Message_getQid(s_Message* self) {
  1165. return (Py_BuildValue("I", self->message->getQid()));
  1166. }
  1167. static PyObject*
  1168. Message_setQid(s_Message* self, PyObject* args) {
  1169. uint16_t id;
  1170. if (!PyArg_ParseTuple(args, "H", &id)) {
  1171. return (NULL);
  1172. }
  1173. try {
  1174. self->message->setQid(id);
  1175. Py_RETURN_NONE;
  1176. } catch (InvalidMessageOperation imo) {
  1177. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1178. return (NULL);
  1179. }
  1180. }
  1181. static PyObject*
  1182. Message_getRcode(s_Message* self) {
  1183. s_Rcode* rcode;
  1184. rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
  1185. if (rcode != NULL) {
  1186. rcode->rcode = new Rcode(self->message->getRcode());
  1187. if (rcode->rcode == NULL)
  1188. {
  1189. Py_DECREF(rcode);
  1190. return (NULL);
  1191. }
  1192. }
  1193. return (rcode);
  1194. }
  1195. static PyObject*
  1196. Message_setRcode(s_Message* self, PyObject* args) {
  1197. s_Rcode* rcode;
  1198. if (!PyArg_ParseTuple(args, "O!", &rcode_type, &rcode)) {
  1199. return (NULL);
  1200. }
  1201. try {
  1202. self->message->setRcode(*rcode->rcode);
  1203. Py_RETURN_NONE;
  1204. } catch (InvalidMessageOperation imo) {
  1205. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1206. return (NULL);
  1207. }
  1208. }
  1209. static PyObject*
  1210. Message_getOpcode(s_Message* self) {
  1211. s_Opcode* opcode;
  1212. opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
  1213. if (opcode != NULL) {
  1214. // Note that we do not new and delete for opcodes.
  1215. // all rcodes point to the statics defined in
  1216. // message.cc
  1217. opcode->opcode = &self->message->getOpcode();
  1218. if (opcode->opcode == NULL)
  1219. {
  1220. Py_DECREF(opcode);
  1221. return (NULL);
  1222. }
  1223. }
  1224. return (opcode);
  1225. }
  1226. static PyObject*
  1227. Message_setOpcode(s_Message* self, PyObject* args) {
  1228. s_Opcode* opcode;
  1229. if (!PyArg_ParseTuple(args, "O!", &opcode_type, &opcode)) {
  1230. return (NULL);
  1231. }
  1232. try {
  1233. self->message->setOpcode(*opcode->opcode);
  1234. Py_RETURN_NONE;
  1235. } catch (InvalidMessageOperation imo) {
  1236. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1237. return (NULL);
  1238. }
  1239. }
  1240. static PyObject*
  1241. Message_getRRCount(s_Message* self, PyObject* args) {
  1242. s_Section *section;
  1243. if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
  1244. return (NULL);
  1245. }
  1246. return (Py_BuildValue("I", self->message->getRRCount(*section->section)));
  1247. }
  1248. // TODO use direct iterators for these? (or simply lists for now?)
  1249. static PyObject*
  1250. Message_getQuestion(s_Message* self) {
  1251. PyObject* list = PyList_New(0);
  1252. for (QuestionIterator qi = self->message->beginQuestion();
  1253. qi != self->message->endQuestion();
  1254. ++qi) {
  1255. s_Question *question = static_cast<s_Question*>(question_type.tp_alloc(&question_type, 0));
  1256. if (question != NULL) {
  1257. question->question = *qi;
  1258. if (question->question == NULL)
  1259. {
  1260. Py_DECREF(question);
  1261. return (NULL);
  1262. }
  1263. }
  1264. PyList_Append(list, question);
  1265. }
  1266. return (list);
  1267. }
  1268. static PyObject*
  1269. Message_getSection(s_Message* self, PyObject* args) {
  1270. s_Section *section;
  1271. if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
  1272. return (NULL);
  1273. }
  1274. PyObject* list = PyList_New(0);
  1275. for (RRsetIterator rrsi = self->message->beginSection(*section->section);
  1276. rrsi != self->message->endSection(*section->section);
  1277. ++rrsi) {
  1278. s_RRset *rrset = static_cast<s_RRset*>(rrset_type.tp_alloc(&rrset_type, 0));
  1279. if (rrset != NULL) {
  1280. rrset->rrset = *rrsi;
  1281. if (rrset->rrset == NULL)
  1282. {
  1283. Py_DECREF(rrset);
  1284. Py_DECREF(list);
  1285. return (NULL);
  1286. }
  1287. }
  1288. PyList_Append(list, rrset);
  1289. // PyList_Append increases refcount, so we remove ours since
  1290. // we don't need it anymore
  1291. Py_DECREF(rrset);
  1292. }
  1293. return (list);
  1294. }
  1295. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  1296. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  1297. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  1298. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  1299. //static PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  1300. static PyObject*
  1301. Message_addQuestion(s_Message* self, PyObject* args) {
  1302. s_Question *question;
  1303. if (!PyArg_ParseTuple(args, "O!", &question_type, &question)) {
  1304. return (NULL);
  1305. }
  1306. self->message->addQuestion(question->question);
  1307. Py_RETURN_NONE;
  1308. }
  1309. static PyObject*
  1310. Message_addRRset(s_Message* self, PyObject* args) {
  1311. PyObject *sign = Py_False;
  1312. s_Section* section;
  1313. s_RRset* rrset;
  1314. if (!PyArg_ParseTuple(args, "O!O!|O!", &section_type, &section,
  1315. &rrset_type, &rrset,
  1316. &PyBool_Type, &sign)) {
  1317. return (NULL);
  1318. }
  1319. try {
  1320. if (sign == Py_True) {
  1321. self->message->addRRset(*section->section, rrset->rrset, true);
  1322. } else {
  1323. self->message->addRRset(*section->section, rrset->rrset, false);
  1324. }
  1325. Py_RETURN_NONE;
  1326. } catch (InvalidMessageOperation imo) {
  1327. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1328. return (NULL);
  1329. }
  1330. }
  1331. static PyObject*
  1332. Message_clear(s_Message* self, PyObject* args) {
  1333. unsigned int i;
  1334. // The constructor argument can be a string ("IN"), an integer (1),
  1335. // or a sequence of numbers between 0 and 255 (wire code)
  1336. if (PyArg_ParseTuple(args, "I", &i)) {
  1337. PyErr_Clear();
  1338. if (i == Message::PARSE) {
  1339. self->message->clear(Message::PARSE);
  1340. Py_RETURN_NONE;
  1341. } else if (i == Message::RENDER) {
  1342. self->message->clear(Message::RENDER);
  1343. Py_RETURN_NONE;
  1344. } else {
  1345. PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
  1346. return (NULL);
  1347. }
  1348. } else {
  1349. return (NULL);
  1350. }
  1351. }
  1352. static PyObject*
  1353. Message_makeResponse(s_Message* self) {
  1354. self->message->makeResponse();
  1355. Py_RETURN_NONE;
  1356. }
  1357. static PyObject*
  1358. Message_toText(s_Message* self) {
  1359. // Py_BuildValue makes python objects from native data
  1360. return (Py_BuildValue("s", self->message->toText().c_str()));
  1361. }
  1362. static PyObject*
  1363. Message_str(PyObject* self) {
  1364. // Simply call the to_text method we already defined
  1365. return PyObject_CallMethod(self,
  1366. const_cast<char*>("to_text"),
  1367. const_cast<char*>(""));
  1368. }
  1369. static PyObject*
  1370. Message_toWire(s_Message* self, PyObject* args) {
  1371. s_MessageRenderer* mr;
  1372. if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
  1373. try {
  1374. self->message->toWire(*mr->messagerenderer);
  1375. // If we return NULL it is seen as an error, so use this for
  1376. // None returns
  1377. Py_RETURN_NONE;
  1378. } catch (isc::dns::InvalidMessageOperation imo) {
  1379. PyErr_Clear();
  1380. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1381. return (NULL);
  1382. }
  1383. }
  1384. PyErr_Clear();
  1385. PyErr_SetString(PyExc_TypeError,
  1386. "toWire argument must be a MessageRenderer");
  1387. return (NULL);
  1388. }
  1389. static PyObject*
  1390. Message_fromWire(s_Message* self, PyObject* args) {
  1391. const char* b;
  1392. Py_ssize_t len;
  1393. if (!PyArg_ParseTuple(args, "y#", &b, &len)) {
  1394. return (NULL);
  1395. }
  1396. InputBuffer inbuf(b, len);
  1397. try {
  1398. self->message->fromWire(inbuf);
  1399. Py_RETURN_NONE;
  1400. } catch (isc::dns::InvalidMessageOperation imo) {
  1401. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1402. return (NULL);
  1403. } catch (isc::dns::DNSMessageFORMERR dmfe) {
  1404. PyErr_SetString(po_DNSMessageFORMERR, dmfe.what());
  1405. return (NULL);
  1406. } catch (isc::dns::DNSMessageBADVERS dmfe) {
  1407. PyErr_SetString(po_DNSMessageBADVERS, dmfe.what());
  1408. return (NULL);
  1409. } catch (isc::dns::MessageTooShort mts) {
  1410. PyErr_SetString(po_MessageTooShort, mts.what());
  1411. return (NULL);
  1412. }
  1413. }
  1414. // Module Initialization, all statics are initialized here
  1415. bool
  1416. initModulePart_Message(PyObject* mod) {
  1417. // add methods to class
  1418. if (PyType_Ready(&messageflag_type) < 0) {
  1419. return (false);
  1420. }
  1421. Py_INCREF(&messageflag_type);
  1422. PyModule_AddObject(mod, "MessageFlag",
  1423. reinterpret_cast<PyObject*>(&messageflag_type));
  1424. if (PyType_Ready(&opcode_type) < 0) {
  1425. return (false);
  1426. }
  1427. Py_INCREF(&opcode_type);
  1428. PyModule_AddObject(mod, "Opcode",
  1429. reinterpret_cast<PyObject*>(&opcode_type));
  1430. if (PyType_Ready(&rcode_type) < 0) {
  1431. return (false);
  1432. }
  1433. Py_INCREF(&rcode_type);
  1434. PyModule_AddObject(mod, "Rcode",
  1435. reinterpret_cast<PyObject*>(&rcode_type));
  1436. if (PyType_Ready(&section_type) < 0) {
  1437. return (false);
  1438. }
  1439. Py_INCREF(&section_type);
  1440. PyModule_AddObject(mod, "Section",
  1441. reinterpret_cast<PyObject*>(&section_type));
  1442. if (PyType_Ready(&message_type) < 0) {
  1443. return (false);
  1444. }
  1445. // Class variables
  1446. // These are added to the tp_dict of the type object
  1447. //
  1448. addClassVariable(message_type, "PARSE", Py_BuildValue("I", Message::PARSE));
  1449. addClassVariable(message_type, "RENDER", Py_BuildValue("I", Message::RENDER));
  1450. addClassVariable(message_type, "DEFAULT_MAX_UDPSIZE", Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
  1451. /* Class-specific exceptions */
  1452. po_MessageTooShort = PyErr_NewException("libdns_python.MessageTooShort", NULL, NULL);
  1453. PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
  1454. po_InvalidMessageSection = PyErr_NewException("libdns_python.InvalidMessageSection", NULL, NULL);
  1455. PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
  1456. po_InvalidMessageOperation = PyErr_NewException("libdns_python.InvalidMessageOperation", NULL, NULL);
  1457. PyModule_AddObject(mod, "InvalidMessageOperation", po_InvalidMessageOperation);
  1458. po_InvalidMessageUDPSize = PyErr_NewException("libdns_python.InvalidMessageUDPSize", NULL, NULL);
  1459. PyModule_AddObject(mod, "InvalidMessageUDPSize", po_InvalidMessageUDPSize);
  1460. po_DNSMessageBADVERS = PyErr_NewException("libdns_python.DNSMessageBADVERS", NULL, NULL);
  1461. PyModule_AddObject(mod, "DNSMessageBADVERS", po_DNSMessageBADVERS);
  1462. Py_INCREF(&message_type);
  1463. PyModule_AddObject(mod, "Message",
  1464. reinterpret_cast<PyObject*>(&message_type));
  1465. return (true);
  1466. }