message_python.cc 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952
  1. // Copyright (C) 2009 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. // Constants
  29. //
  30. static PyObject* po_MessagePARSE;
  31. static PyObject* po_MessageRENDER;
  32. static PyObject* po_MessageDefaultMaxUDPSize;
  33. //
  34. // Definition of the classes
  35. //
  36. // For each class, we need a struct, a helper functions (init, destroy,
  37. // and static wrappers around the methods we export), a list of methods,
  38. // and a type description
  39. //
  40. // MessageFlag
  41. //
  42. typedef struct {
  43. PyObject_HEAD
  44. const MessageFlag* messageflag;
  45. } s_MessageFlag;
  46. static int MessageFlag_init(s_MessageFlag* self, PyObject* args);
  47. static void MessageFlag_destroy(s_MessageFlag* self);
  48. static PyObject* MessageFlag_getBit(s_MessageFlag* self);
  49. static PyObject* MessageFlag_QR(s_MessageFlag* self);
  50. static PyObject* MessageFlag_AA(s_MessageFlag* self);
  51. static PyObject* MessageFlag_TC(s_MessageFlag* self);
  52. static PyObject* MessageFlag_RD(s_MessageFlag* self);
  53. static PyObject* MessageFlag_RA(s_MessageFlag* self);
  54. static PyObject* MessageFlag_AD(s_MessageFlag* self);
  55. static PyObject* MessageFlag_CD(s_MessageFlag* self);
  56. static PyMethodDef MessageFlag_methods[] = {
  57. { "get_bit", (PyCFunction)MessageFlag_getBit, METH_NOARGS, "Return the flag bit" },
  58. { "QR", (PyCFunction)MessageFlag_QR, METH_NOARGS | METH_STATIC, "Create a QR MessageFlag" },
  59. { "AA", (PyCFunction)MessageFlag_AA, METH_NOARGS | METH_STATIC, "Create a AA MessageFlag" },
  60. { "TC", (PyCFunction)MessageFlag_TC, METH_NOARGS | METH_STATIC, "Create a TC MessageFlag" },
  61. { "RD", (PyCFunction)MessageFlag_RD, METH_NOARGS | METH_STATIC, "Create a RD MessageFlag" },
  62. { "RA", (PyCFunction)MessageFlag_RA, METH_NOARGS | METH_STATIC, "Create a RA MessageFlag" },
  63. { "AD", (PyCFunction)MessageFlag_AD, METH_NOARGS | METH_STATIC, "Create a AD MessageFlag" },
  64. { "CD", (PyCFunction)MessageFlag_CD, METH_NOARGS | METH_STATIC, "Create a CD MessageFlag" },
  65. { NULL, NULL, 0, NULL }
  66. };
  67. static PyTypeObject messageflag_type = {
  68. PyVarObject_HEAD_INIT(NULL, 0)
  69. "libdns_python.MessageFlag",
  70. sizeof(s_MessageFlag), /* tp_basicsize */
  71. 0, /* tp_itemsize */
  72. (destructor)MessageFlag_destroy, /* tp_dealloc */
  73. NULL, /* tp_print */
  74. NULL, /* tp_getattr */
  75. NULL, /* tp_setattr */
  76. NULL, /* tp_reserved */
  77. NULL, /* tp_repr */
  78. NULL, /* tp_as_number */
  79. NULL, /* tp_as_sequence */
  80. NULL, /* tp_as_mapping */
  81. NULL, /* tp_hash */
  82. NULL, /* tp_call */
  83. NULL, /* tp_str */
  84. NULL, /* tp_getattro */
  85. NULL, /* tp_setattro */
  86. NULL, /* tp_as_buffer */
  87. Py_TPFLAGS_DEFAULT, /* tp_flags */
  88. "C++ MessageFlag Object", /* tp_doc */
  89. NULL, /* tp_traverse */
  90. NULL, /* tp_clear */
  91. NULL, /* tp_richcompare */
  92. 0, /* tp_weaklistoffset */
  93. NULL, /* tp_iter */
  94. NULL, /* tp_iternext */
  95. MessageFlag_methods, /* tp_methods */
  96. NULL, /* tp_members */
  97. NULL, /* tp_getset */
  98. NULL, /* tp_base */
  99. NULL, /* tp_dict */
  100. NULL, /* tp_descr_get */
  101. NULL, /* tp_descr_set */
  102. 0, /* tp_dictoffset */
  103. // TODO: Can we make this NULL? (no direct constructor)
  104. (initproc)MessageFlag_init, /* tp_init */
  105. NULL, /* tp_alloc */
  106. PyType_GenericNew, /* tp_new */
  107. NULL, /* tp_free */
  108. NULL, /* tp_is_gc */
  109. NULL, /* tp_bases */
  110. NULL, /* tp_mro */
  111. NULL, /* tp_cache */
  112. NULL, /* tp_subclasses */
  113. NULL, /* tp_weaklist */
  114. // Note: not sure if the following are correct. Added them just to
  115. // make the compiler happy.
  116. NULL, /* tp_del */
  117. 0 /* tp_version_tag */
  118. };
  119. static int
  120. MessageFlag_init(s_MessageFlag* self UNUSED_PARAM, PyObject* args UNUSED_PARAM)
  121. {
  122. PyErr_SetString(PyExc_NotImplementedError,
  123. "MessageFlag can't be built directly");
  124. return -1;
  125. }
  126. static void
  127. MessageFlag_destroy(s_MessageFlag* self)
  128. {
  129. // We only use the consts from MessageFlag, so don't
  130. // delete self->messageflag here
  131. self->messageflag = NULL;
  132. Py_TYPE(self)->tp_free(self);
  133. }
  134. static PyObject*
  135. MessageFlag_getBit(s_MessageFlag* self)
  136. {
  137. return Py_BuildValue("I", self->messageflag->getBit());
  138. }
  139. static PyObject*
  140. MessageFlag_QR(s_MessageFlag* self UNUSED_PARAM)
  141. {
  142. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  143. if (ret != NULL) {
  144. ret->messageflag = &MessageFlag::QR();
  145. if (ret->messageflag == NULL) {
  146. Py_DECREF(ret);
  147. return NULL;
  148. }
  149. }
  150. return (PyObject*) ret;
  151. }
  152. static PyObject*
  153. MessageFlag_AA(s_MessageFlag* self UNUSED_PARAM)
  154. {
  155. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  156. if (ret != NULL) {
  157. ret->messageflag = &MessageFlag::AA();
  158. if (ret->messageflag == NULL) {
  159. Py_DECREF(ret);
  160. return NULL;
  161. }
  162. }
  163. return (PyObject*) ret;
  164. }
  165. static PyObject*
  166. MessageFlag_TC(s_MessageFlag* self UNUSED_PARAM)
  167. {
  168. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  169. if (ret != NULL) {
  170. ret->messageflag = &MessageFlag::TC();
  171. if (ret->messageflag == NULL) {
  172. Py_DECREF(ret);
  173. return NULL;
  174. }
  175. }
  176. return (PyObject*) ret;
  177. }
  178. static PyObject*
  179. MessageFlag_RD(s_MessageFlag* self UNUSED_PARAM)
  180. {
  181. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  182. if (ret != NULL) {
  183. ret->messageflag = &MessageFlag::RD();
  184. if (ret->messageflag == NULL) {
  185. Py_DECREF(ret);
  186. return NULL;
  187. }
  188. }
  189. return (PyObject*) ret;
  190. }
  191. static PyObject*
  192. MessageFlag_RA(s_MessageFlag* self UNUSED_PARAM)
  193. {
  194. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  195. if (ret != NULL) {
  196. ret->messageflag = &MessageFlag::RA();
  197. if (ret->messageflag == NULL) {
  198. Py_DECREF(ret);
  199. return NULL;
  200. }
  201. }
  202. return (PyObject*) ret;
  203. }
  204. static PyObject*
  205. MessageFlag_AD(s_MessageFlag* self UNUSED_PARAM)
  206. {
  207. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  208. if (ret != NULL) {
  209. ret->messageflag = &MessageFlag::AD();
  210. if (ret->messageflag == NULL) {
  211. Py_DECREF(ret);
  212. return NULL;
  213. }
  214. }
  215. return (PyObject*) ret;
  216. }
  217. static PyObject*
  218. MessageFlag_CD(s_MessageFlag* self UNUSED_PARAM)
  219. {
  220. s_MessageFlag* ret = PyObject_New(s_MessageFlag, &messageflag_type);
  221. if (ret != NULL) {
  222. ret->messageflag = &MessageFlag::CD();
  223. if (ret->messageflag == NULL) {
  224. Py_DECREF(ret);
  225. return NULL;
  226. }
  227. }
  228. return (PyObject*) ret;
  229. }
  230. //
  231. // End of MessageFlag wrapper
  232. //
  233. //
  234. // Opcode
  235. //
  236. typedef struct {
  237. PyObject_HEAD
  238. const Opcode* opcode;
  239. } s_Opcode;
  240. static int Opcode_init(s_Opcode* self, PyObject* args);
  241. static void Opcode_destroy(s_Opcode* self);
  242. static PyObject* Opcode_getCode(s_Opcode* self);
  243. static PyObject* Opcode_toText(s_Opcode* self);
  244. static PyObject* Opcode_str(PyObject* self);
  245. static PyObject* Opcode_QUERY(s_Opcode* self);
  246. static PyObject* Opcode_IQUERY(s_Opcode* self);
  247. static PyObject* Opcode_STATUS(s_Opcode* self);
  248. static PyObject* Opcode_RESERVED3(s_Opcode* self);
  249. static PyObject* Opcode_NOTIFY(s_Opcode* self);
  250. static PyObject* Opcode_UPDATE(s_Opcode* self);
  251. static PyObject* Opcode_RESERVED6(s_Opcode* self);
  252. static PyObject* Opcode_RESERVED7(s_Opcode* self);
  253. static PyObject* Opcode_RESERVED8(s_Opcode* self);
  254. static PyObject* Opcode_RESERVED9(s_Opcode* self);
  255. static PyObject* Opcode_RESERVED10(s_Opcode* self);
  256. static PyObject* Opcode_RESERVED11(s_Opcode* self);
  257. static PyObject* Opcode_RESERVED12(s_Opcode* self);
  258. static PyObject* Opcode_RESERVED13(s_Opcode* self);
  259. static PyObject* Opcode_RESERVED14(s_Opcode* self);
  260. static PyObject* Opcode_RESERVED15(s_Opcode* self);
  261. static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
  262. static PyMethodDef Opcode_methods[] = {
  263. { "get_code", (PyCFunction)Opcode_getCode, METH_NOARGS, "Return the code value" },
  264. { "to_text", (PyCFunction)Opcode_toText, METH_NOARGS, "Return the text representation" },
  265. { "QUERY", (PyCFunction)Opcode_QUERY, METH_NOARGS | METH_STATIC, "Create a QUERY Opcode" },
  266. { "IQUERY", (PyCFunction)Opcode_IQUERY, METH_NOARGS | METH_STATIC, "Create a IQUERY Opcode" },
  267. { "STATUS", (PyCFunction)Opcode_STATUS, METH_NOARGS | METH_STATIC, "Create a STATUS Opcode" },
  268. { "RESERVED3", (PyCFunction)Opcode_RESERVED3, METH_NOARGS | METH_STATIC, "Create a RESERVED3 Opcode" },
  269. { "NOTIFY", (PyCFunction)Opcode_NOTIFY, METH_NOARGS | METH_STATIC, "Create a NOTIFY Opcode" },
  270. { "UPDATE", (PyCFunction)Opcode_UPDATE, METH_NOARGS | METH_STATIC, "Create a UPDATE Opcode" },
  271. { "RESERVED6", (PyCFunction)Opcode_RESERVED6, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  272. { "RESERVED7", (PyCFunction)Opcode_RESERVED7, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  273. { "RESERVED8", (PyCFunction)Opcode_RESERVED8, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  274. { "RESERVED9", (PyCFunction)Opcode_RESERVED9, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  275. { "RESERVED10", (PyCFunction)Opcode_RESERVED10, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  276. { "RESERVED11", (PyCFunction)Opcode_RESERVED11, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  277. { "RESERVED12", (PyCFunction)Opcode_RESERVED12, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  278. { "RESERVED13", (PyCFunction)Opcode_RESERVED13, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  279. { "RESERVED14", (PyCFunction)Opcode_RESERVED14, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  280. { "RESERVED15", (PyCFunction)Opcode_RESERVED15, METH_NOARGS | METH_STATIC, "Create a RESERVED Opcode" },
  281. { NULL, NULL, 0, NULL }
  282. };
  283. static PyTypeObject opcode_type = {
  284. PyVarObject_HEAD_INIT(NULL, 0)
  285. "libdns_python.Opcode",
  286. sizeof(s_Opcode), /* tp_basicsize */
  287. 0, /* tp_itemsize */
  288. (destructor)Opcode_destroy, /* tp_dealloc */
  289. NULL, /* tp_print */
  290. NULL, /* tp_getattr */
  291. NULL, /* tp_setattr */
  292. NULL, /* tp_reserved */
  293. NULL, /* tp_repr */
  294. NULL, /* tp_as_number */
  295. NULL, /* tp_as_sequence */
  296. NULL, /* tp_as_mapping */
  297. NULL, /* tp_hash */
  298. NULL, /* tp_call */
  299. Opcode_str, /* tp_str */
  300. NULL, /* tp_getattro */
  301. NULL, /* tp_setattro */
  302. NULL, /* tp_as_buffer */
  303. Py_TPFLAGS_DEFAULT, /* tp_flags */
  304. "C++ Opcode Object", /* tp_doc */
  305. NULL, /* tp_traverse */
  306. NULL, /* tp_clear */
  307. (richcmpfunc)Opcode_richcmp, /* tp_richcompare */
  308. 0, /* tp_weaklistoffset */
  309. NULL, /* tp_iter */
  310. NULL, /* tp_iternext */
  311. Opcode_methods, /* tp_methods */
  312. NULL, /* tp_members */
  313. NULL, /* tp_getset */
  314. NULL, /* tp_base */
  315. NULL, /* tp_dict */
  316. NULL, /* tp_descr_get */
  317. NULL, /* tp_descr_set */
  318. 0, /* tp_dictoffset */
  319. // TODO: Can we make this NULL? (no direct constructor)
  320. (initproc)Opcode_init, /* tp_init */
  321. NULL, /* tp_alloc */
  322. PyType_GenericNew, /* tp_new */
  323. NULL, /* tp_free */
  324. NULL, /* tp_is_gc */
  325. NULL, /* tp_bases */
  326. NULL, /* tp_mro */
  327. NULL, /* tp_cache */
  328. NULL, /* tp_subclasses */
  329. NULL, /* tp_weaklist */
  330. // Note: not sure if the following are correct. Added them just to
  331. // make the compiler happy.
  332. NULL, /* tp_del */
  333. 0 /* tp_version_tag */
  334. };
  335. static int
  336. Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM)
  337. {
  338. PyErr_SetString(PyExc_NotImplementedError,
  339. "Opcode can't be built directly");
  340. return -1;
  341. }
  342. static void
  343. Opcode_destroy(s_Opcode* self)
  344. {
  345. // We only use the consts from Opcode, so don't
  346. // delete self->opcode here
  347. self->opcode = NULL;
  348. Py_TYPE(self)->tp_free(self);
  349. }
  350. static PyObject*
  351. Opcode_getCode(s_Opcode* self)
  352. {
  353. return Py_BuildValue("I", self->opcode->getCode());
  354. }
  355. static PyObject*
  356. Opcode_toText(s_Opcode* self)
  357. {
  358. return Py_BuildValue("s", self->opcode->toText().c_str());
  359. }
  360. static PyObject*
  361. Opcode_str(PyObject* self)
  362. {
  363. // Simply call the to_text method we already defined
  364. return PyObject_CallMethod(self, (char*)"to_text", (char*)"");
  365. }
  366. static PyObject*
  367. Opcode_QUERY(s_Opcode* self UNUSED_PARAM)
  368. {
  369. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  370. if (ret != NULL) {
  371. ret->opcode = &Opcode::QUERY();
  372. if (ret->opcode == NULL) {
  373. Py_DECREF(ret);
  374. return NULL;
  375. }
  376. }
  377. return (PyObject*) ret;
  378. }
  379. static PyObject*
  380. Opcode_IQUERY(s_Opcode* self UNUSED_PARAM)
  381. {
  382. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  383. if (ret != NULL) {
  384. ret->opcode = &Opcode::IQUERY();
  385. if (ret->opcode == NULL) {
  386. Py_DECREF(ret);
  387. return NULL;
  388. }
  389. }
  390. return (PyObject*) ret;
  391. }
  392. static PyObject*
  393. Opcode_STATUS(s_Opcode* self UNUSED_PARAM)
  394. {
  395. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  396. if (ret != NULL) {
  397. ret->opcode = &Opcode::STATUS();
  398. if (ret->opcode == NULL) {
  399. Py_DECREF(ret);
  400. return NULL;
  401. }
  402. }
  403. return (PyObject*) ret;
  404. }
  405. static PyObject*
  406. Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM)
  407. {
  408. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  409. if (ret != NULL) {
  410. ret->opcode = &Opcode::RESERVED3();
  411. if (ret->opcode == NULL) {
  412. Py_DECREF(ret);
  413. return NULL;
  414. }
  415. }
  416. return (PyObject*) ret;
  417. }
  418. static PyObject*
  419. Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM)
  420. {
  421. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  422. if (ret != NULL) {
  423. ret->opcode = &Opcode::NOTIFY();
  424. if (ret->opcode == NULL) {
  425. Py_DECREF(ret);
  426. return NULL;
  427. }
  428. }
  429. return (PyObject*) ret;
  430. }
  431. static PyObject*
  432. Opcode_UPDATE(s_Opcode* self UNUSED_PARAM)
  433. {
  434. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  435. if (ret != NULL) {
  436. ret->opcode = &Opcode::UPDATE();
  437. if (ret->opcode == NULL) {
  438. Py_DECREF(ret);
  439. return NULL;
  440. }
  441. }
  442. return (PyObject*) ret;
  443. }
  444. static PyObject*
  445. Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM)
  446. {
  447. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  448. if (ret != NULL) {
  449. ret->opcode = &Opcode::RESERVED6();
  450. if (ret->opcode == NULL) {
  451. Py_DECREF(ret);
  452. return NULL;
  453. }
  454. }
  455. return (PyObject*) ret;
  456. }
  457. static PyObject*
  458. Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM)
  459. {
  460. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  461. if (ret != NULL) {
  462. ret->opcode = &Opcode::RESERVED7();
  463. if (ret->opcode == NULL) {
  464. Py_DECREF(ret);
  465. return NULL;
  466. }
  467. }
  468. return (PyObject*) ret;
  469. }
  470. static PyObject*
  471. Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM)
  472. {
  473. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  474. if (ret != NULL) {
  475. ret->opcode = &Opcode::RESERVED8();
  476. if (ret->opcode == NULL) {
  477. Py_DECREF(ret);
  478. return NULL;
  479. }
  480. }
  481. return (PyObject*) ret;
  482. }
  483. static PyObject*
  484. Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM)
  485. {
  486. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  487. if (ret != NULL) {
  488. ret->opcode = &Opcode::RESERVED9();
  489. if (ret->opcode == NULL) {
  490. Py_DECREF(ret);
  491. return NULL;
  492. }
  493. }
  494. return (PyObject*) ret;
  495. }
  496. static PyObject*
  497. Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM)
  498. {
  499. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  500. if (ret != NULL) {
  501. ret->opcode = &Opcode::RESERVED10();
  502. if (ret->opcode == NULL) {
  503. Py_DECREF(ret);
  504. return NULL;
  505. }
  506. }
  507. return (PyObject*) ret;
  508. }
  509. static PyObject*
  510. Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM)
  511. {
  512. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  513. if (ret != NULL) {
  514. ret->opcode = &Opcode::RESERVED11();
  515. if (ret->opcode == NULL) {
  516. Py_DECREF(ret);
  517. return NULL;
  518. }
  519. }
  520. return (PyObject*) ret;
  521. }
  522. static PyObject*
  523. Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM)
  524. {
  525. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  526. if (ret != NULL) {
  527. ret->opcode = &Opcode::RESERVED12();
  528. if (ret->opcode == NULL) {
  529. Py_DECREF(ret);
  530. return NULL;
  531. }
  532. }
  533. return (PyObject*) ret;
  534. }
  535. static PyObject*
  536. Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM)
  537. {
  538. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  539. if (ret != NULL) {
  540. ret->opcode = &Opcode::RESERVED13();
  541. if (ret->opcode == NULL) {
  542. Py_DECREF(ret);
  543. return NULL;
  544. }
  545. }
  546. return (PyObject*) ret;
  547. }
  548. static PyObject*
  549. Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM)
  550. {
  551. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  552. if (ret != NULL) {
  553. ret->opcode = &Opcode::RESERVED14();
  554. if (ret->opcode == NULL) {
  555. Py_DECREF(ret);
  556. return NULL;
  557. }
  558. }
  559. return (PyObject*) ret;
  560. }
  561. static PyObject*
  562. Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM)
  563. {
  564. s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
  565. if (ret != NULL) {
  566. ret->opcode = &Opcode::RESERVED15();
  567. if (ret->opcode == NULL) {
  568. Py_DECREF(ret);
  569. return NULL;
  570. }
  571. }
  572. return (PyObject*) ret;
  573. }
  574. static PyObject*
  575. Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op)
  576. {
  577. bool c = false;
  578. // Only equals and not equals here, unorderable type
  579. switch (op) {
  580. case Py_LT:
  581. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  582. return NULL;
  583. break;
  584. case Py_LE:
  585. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  586. return NULL;
  587. break;
  588. case Py_EQ:
  589. c = (*self->opcode == *other->opcode);
  590. break;
  591. case Py_NE:
  592. c = (*self->opcode != *other->opcode);
  593. break;
  594. case Py_GT:
  595. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  596. return NULL;
  597. break;
  598. case Py_GE:
  599. PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
  600. return NULL;
  601. break;
  602. }
  603. if (c)
  604. Py_RETURN_TRUE;
  605. else
  606. Py_RETURN_FALSE;
  607. }
  608. //
  609. // End of Opcode wrapper
  610. //
  611. //
  612. // Rcode
  613. //
  614. // We added a helper variable static_code here
  615. // Since we can create Rcodes dynamically with Rcode(int), but also
  616. // use the static globals (Rcode::NOERROR() etc), we use this
  617. // variable to see if the code came from one of the latter, in which
  618. // case Rcode_destroy should not free it (the other option is to
  619. // allocate new Rcodes for every use of the static ones, but this
  620. // seems more efficient).
  621. typedef struct {
  622. PyObject_HEAD
  623. const Rcode* rcode;
  624. bool static_code;
  625. } s_Rcode;
  626. static int Rcode_init(s_Rcode* self, PyObject* args);
  627. static void Rcode_destroy(s_Rcode* self);
  628. static PyObject* Rcode_getCode(s_Rcode* self);
  629. static PyObject* Rcode_toText(s_Rcode* self);
  630. static PyObject* Rcode_str(PyObject* self);
  631. static PyObject* Rcode_NOERROR(s_Rcode* self);
  632. static PyObject* Rcode_FORMERR(s_Rcode* self);
  633. static PyObject* Rcode_SERVFAIL(s_Rcode* self);
  634. static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
  635. static PyObject* Rcode_NOTIMP(s_Rcode* self);
  636. static PyObject* Rcode_REFUSED(s_Rcode* self);
  637. static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
  638. static PyObject* Rcode_YXRRSET(s_Rcode* self);
  639. static PyObject* Rcode_NXRRSET(s_Rcode* self);
  640. static PyObject* Rcode_NOTAUTH(s_Rcode* self);
  641. static PyObject* Rcode_NOTZONE(s_Rcode* self);
  642. static PyObject* Rcode_RESERVED11(s_Rcode* self);
  643. static PyObject* Rcode_RESERVED12(s_Rcode* self);
  644. static PyObject* Rcode_RESERVED13(s_Rcode* self);
  645. static PyObject* Rcode_RESERVED14(s_Rcode* self);
  646. static PyObject* Rcode_RESERVED15(s_Rcode* self);
  647. static PyObject* Rcode_BADVERS(s_Rcode* self);
  648. static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
  649. static PyMethodDef Rcode_methods[] = {
  650. { "get_code", (PyCFunction)Rcode_getCode, METH_NOARGS, "Return the code value" },
  651. { "to_text", (PyCFunction)Rcode_toText, METH_NOARGS, "Return the text representation" },
  652. { "NOERROR", (PyCFunction)Rcode_NOERROR, METH_NOARGS | METH_STATIC, "Create a NOERROR Rcode" },
  653. { "FORMERR", (PyCFunction)Rcode_FORMERR, METH_NOARGS | METH_STATIC, "Create a FORMERR Rcode" },
  654. { "SERVFAIL", (PyCFunction)Rcode_SERVFAIL, METH_NOARGS | METH_STATIC, "Create a SERVFAIL Rcode" },
  655. { "NXDOMAIN", (PyCFunction)Rcode_NXDOMAIN, METH_NOARGS | METH_STATIC, "Create a NXDOMAIN Rcode" },
  656. { "NOTIMP", (PyCFunction)Rcode_NOTIMP, METH_NOARGS | METH_STATIC, "Create a NOTIMP Rcode" },
  657. { "REFUSED", (PyCFunction)Rcode_REFUSED, METH_NOARGS | METH_STATIC, "Create a REFUSED Rcode" },
  658. { "YXDOMAIN", (PyCFunction)Rcode_YXDOMAIN, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  659. { "YXRRSET", (PyCFunction)Rcode_YXRRSET, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  660. { "NXRRSET", (PyCFunction)Rcode_NXRRSET, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  661. { "NOTAUTH", (PyCFunction)Rcode_NOTAUTH, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  662. { "NOTZONE", (PyCFunction)Rcode_NOTZONE, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  663. { "RESERVED11", (PyCFunction)Rcode_RESERVED11, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  664. { "RESERVED12", (PyCFunction)Rcode_RESERVED12, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  665. { "RESERVED13", (PyCFunction)Rcode_RESERVED13, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  666. { "RESERVED14", (PyCFunction)Rcode_RESERVED14, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  667. { "RESERVED15", (PyCFunction)Rcode_RESERVED15, METH_NOARGS | METH_STATIC, "Create a RESERVED Rcode" },
  668. { "BADVERS", (PyCFunction)Rcode_BADVERS, METH_NOARGS | METH_STATIC, "Create a BADVERS Rcode" },
  669. { NULL, NULL, 0, NULL }
  670. };
  671. static PyTypeObject rcode_type = {
  672. PyVarObject_HEAD_INIT(NULL, 0)
  673. "libdns_python.Rcode",
  674. sizeof(s_Rcode), /* tp_basicsize */
  675. 0, /* tp_itemsize */
  676. (destructor)Rcode_destroy, /* tp_dealloc */
  677. NULL, /* tp_print */
  678. NULL, /* tp_getattr */
  679. NULL, /* tp_setattr */
  680. NULL, /* tp_reserved */
  681. NULL, /* tp_repr */
  682. NULL, /* tp_as_number */
  683. NULL, /* tp_as_sequence */
  684. NULL, /* tp_as_mapping */
  685. NULL, /* tp_hash */
  686. NULL, /* tp_call */
  687. Rcode_str, /* tp_str */
  688. NULL, /* tp_getattro */
  689. NULL, /* tp_setattro */
  690. NULL, /* tp_as_buffer */
  691. Py_TPFLAGS_DEFAULT, /* tp_flags */
  692. "C++ Rcode Object", /* tp_doc */
  693. NULL, /* tp_traverse */
  694. NULL, /* tp_clear */
  695. (richcmpfunc)Rcode_richcmp, /* tp_richcompare */
  696. 0, /* tp_weaklistoffset */
  697. NULL, /* tp_iter */
  698. NULL, /* tp_iternext */
  699. Rcode_methods, /* tp_methods */
  700. NULL, /* tp_members */
  701. NULL, /* tp_getset */
  702. NULL, /* tp_base */
  703. NULL, /* tp_dict */
  704. NULL, /* tp_descr_get */
  705. NULL, /* tp_descr_set */
  706. 0, /* tp_dictoffset */
  707. // TODO: Can we make this NULL? (no direct constructor)
  708. (initproc)Rcode_init, /* tp_init */
  709. NULL, /* tp_alloc */
  710. PyType_GenericNew, /* tp_new */
  711. NULL, /* tp_free */
  712. NULL, /* tp_is_gc */
  713. NULL, /* tp_bases */
  714. NULL, /* tp_mro */
  715. NULL, /* tp_cache */
  716. NULL, /* tp_subclasses */
  717. NULL, /* tp_weaklist */
  718. // Note: not sure if the following are correct. Added them just to
  719. // make the compiler happy.
  720. NULL, /* tp_del */
  721. 0 /* tp_version_tag */
  722. };
  723. static int
  724. Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM)
  725. {
  726. uint16_t code = 0;
  727. if (PyArg_ParseTuple(args, "h", &code)) {
  728. try {
  729. self->rcode = new Rcode(code);
  730. self->static_code = false;
  731. } catch (isc::OutOfRange) {
  732. PyErr_SetString(PyExc_OverflowError,
  733. "rcode out of range");
  734. return -1;
  735. }
  736. return 0;
  737. } else {
  738. return -1;
  739. }
  740. }
  741. static void
  742. Rcode_destroy(s_Rcode* self)
  743. {
  744. // We only use the consts from Rcode, so don't
  745. // delete self->rcode here
  746. if (!self->static_code) {
  747. delete self->rcode;
  748. }
  749. self->rcode = NULL;
  750. Py_TYPE(self)->tp_free(self);
  751. }
  752. static PyObject*
  753. Rcode_getCode(s_Rcode* self)
  754. {
  755. return Py_BuildValue("I", self->rcode->getCode());
  756. }
  757. static PyObject*
  758. Rcode_toText(s_Rcode* self)
  759. {
  760. return Py_BuildValue("s", self->rcode->toText().c_str());
  761. }
  762. static PyObject*
  763. Rcode_str(PyObject* self)
  764. {
  765. // Simply call the to_text method we already defined
  766. return PyObject_CallMethod(self, (char*)"to_text", (char*)"");
  767. }
  768. static PyObject*
  769. Rcode_NOERROR(s_Rcode* self UNUSED_PARAM)
  770. {
  771. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  772. if (ret != NULL) {
  773. ret->rcode = &Rcode::NOERROR();
  774. ret->static_code = true;
  775. if (ret->rcode == NULL) {
  776. Py_DECREF(ret);
  777. return NULL;
  778. }
  779. }
  780. return (PyObject*) ret;
  781. }
  782. static PyObject*
  783. Rcode_FORMERR(s_Rcode* self UNUSED_PARAM)
  784. {
  785. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  786. if (ret != NULL) {
  787. ret->rcode = &Rcode::FORMERR();
  788. ret->static_code = true;
  789. if (ret->rcode == NULL) {
  790. Py_DECREF(ret);
  791. return NULL;
  792. }
  793. }
  794. return (PyObject*) ret;
  795. }
  796. static PyObject*
  797. Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM)
  798. {
  799. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  800. if (ret != NULL) {
  801. ret->rcode = &Rcode::SERVFAIL();
  802. ret->static_code = true;
  803. if (ret->rcode == NULL) {
  804. Py_DECREF(ret);
  805. return NULL;
  806. }
  807. }
  808. return (PyObject*) ret;
  809. }
  810. static PyObject*
  811. Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM)
  812. {
  813. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  814. if (ret != NULL) {
  815. ret->rcode = &Rcode::NXDOMAIN();
  816. ret->static_code = true;
  817. if (ret->rcode == NULL) {
  818. Py_DECREF(ret);
  819. return NULL;
  820. }
  821. }
  822. return (PyObject*) ret;
  823. }
  824. static PyObject*
  825. Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM)
  826. {
  827. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  828. if (ret != NULL) {
  829. ret->rcode = &Rcode::NOTIMP();
  830. ret->static_code = true;
  831. if (ret->rcode == NULL) {
  832. Py_DECREF(ret);
  833. return NULL;
  834. }
  835. }
  836. return (PyObject*) ret;
  837. }
  838. static PyObject*
  839. Rcode_REFUSED(s_Rcode* self UNUSED_PARAM)
  840. {
  841. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  842. if (ret != NULL) {
  843. ret->rcode = &Rcode::REFUSED();
  844. ret->static_code = true;
  845. if (ret->rcode == NULL) {
  846. Py_DECREF(ret);
  847. return NULL;
  848. }
  849. }
  850. return (PyObject*) ret;
  851. }
  852. static PyObject*
  853. Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM)
  854. {
  855. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  856. if (ret != NULL) {
  857. ret->rcode = &Rcode::YXDOMAIN();
  858. ret->static_code = true;
  859. if (ret->rcode == NULL) {
  860. Py_DECREF(ret);
  861. return NULL;
  862. }
  863. }
  864. return (PyObject*) ret;
  865. }
  866. static PyObject*
  867. Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM)
  868. {
  869. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  870. if (ret != NULL) {
  871. ret->rcode = &Rcode::YXRRSET();
  872. ret->static_code = true;
  873. if (ret->rcode == NULL) {
  874. Py_DECREF(ret);
  875. return NULL;
  876. }
  877. }
  878. return (PyObject*) ret;
  879. }
  880. static PyObject*
  881. Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM)
  882. {
  883. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  884. if (ret != NULL) {
  885. ret->rcode = &Rcode::NXRRSET();
  886. ret->static_code = true;
  887. if (ret->rcode == NULL) {
  888. Py_DECREF(ret);
  889. return NULL;
  890. }
  891. }
  892. return (PyObject*) ret;
  893. }
  894. static PyObject*
  895. Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM)
  896. {
  897. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  898. if (ret != NULL) {
  899. ret->rcode = &Rcode::NOTAUTH();
  900. ret->static_code = true;
  901. if (ret->rcode == NULL) {
  902. Py_DECREF(ret);
  903. return NULL;
  904. }
  905. }
  906. return (PyObject*) ret;
  907. }
  908. static PyObject*
  909. Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM)
  910. {
  911. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  912. if (ret != NULL) {
  913. ret->rcode = &Rcode::NOTZONE();
  914. ret->static_code = true;
  915. if (ret->rcode == NULL) {
  916. Py_DECREF(ret);
  917. return NULL;
  918. }
  919. }
  920. return (PyObject*) ret;
  921. }
  922. static PyObject*
  923. Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM)
  924. {
  925. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  926. if (ret != NULL) {
  927. ret->rcode = &Rcode::RESERVED11();
  928. ret->static_code = true;
  929. if (ret->rcode == NULL) {
  930. Py_DECREF(ret);
  931. return NULL;
  932. }
  933. }
  934. return (PyObject*) ret;
  935. }
  936. static PyObject*
  937. Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM)
  938. {
  939. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  940. if (ret != NULL) {
  941. ret->rcode = &Rcode::RESERVED12();
  942. ret->static_code = true;
  943. if (ret->rcode == NULL) {
  944. Py_DECREF(ret);
  945. return NULL;
  946. }
  947. }
  948. return (PyObject*) ret;
  949. }
  950. static PyObject*
  951. Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM)
  952. {
  953. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  954. if (ret != NULL) {
  955. ret->rcode = &Rcode::RESERVED13();
  956. ret->static_code = true;
  957. if (ret->rcode == NULL) {
  958. Py_DECREF(ret);
  959. return NULL;
  960. }
  961. }
  962. return (PyObject*) ret;
  963. }
  964. static PyObject*
  965. Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM)
  966. {
  967. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  968. if (ret != NULL) {
  969. ret->rcode = &Rcode::RESERVED14();
  970. ret->static_code = true;
  971. if (ret->rcode == NULL) {
  972. Py_DECREF(ret);
  973. return NULL;
  974. }
  975. }
  976. return (PyObject*) ret;
  977. }
  978. static PyObject*
  979. Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM)
  980. {
  981. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  982. if (ret != NULL) {
  983. ret->rcode = &Rcode::RESERVED15();
  984. ret->static_code = true;
  985. if (ret->rcode == NULL) {
  986. Py_DECREF(ret);
  987. return NULL;
  988. }
  989. }
  990. return (PyObject*) ret;
  991. }
  992. static PyObject*
  993. Rcode_BADVERS(s_Rcode* self UNUSED_PARAM)
  994. {
  995. s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
  996. if (ret != NULL) {
  997. ret->rcode = &Rcode::BADVERS();
  998. ret->static_code = true;
  999. if (ret->rcode == NULL) {
  1000. Py_DECREF(ret);
  1001. return NULL;
  1002. }
  1003. }
  1004. return (PyObject*) ret;
  1005. }
  1006. static PyObject*
  1007. Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op)
  1008. {
  1009. bool c;
  1010. // Only equals and not equals here, unorderable type
  1011. switch (op) {
  1012. case Py_LT:
  1013. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  1014. return NULL;
  1015. break;
  1016. case Py_LE:
  1017. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  1018. return NULL;
  1019. break;
  1020. case Py_EQ:
  1021. c = (*self->rcode == *other->rcode);
  1022. break;
  1023. case Py_NE:
  1024. c = (*self->rcode != *other->rcode);
  1025. break;
  1026. case Py_GT:
  1027. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  1028. return NULL;
  1029. break;
  1030. case Py_GE:
  1031. PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
  1032. return NULL;
  1033. break;
  1034. default:
  1035. assert(0); // XXX: should trigger an exception
  1036. }
  1037. if (c)
  1038. Py_RETURN_TRUE;
  1039. else
  1040. Py_RETURN_FALSE;
  1041. }
  1042. //
  1043. // End of Rcode wrapper
  1044. //
  1045. //
  1046. // Section
  1047. //
  1048. // TODO: iterator?
  1049. typedef struct {
  1050. PyObject_HEAD
  1051. const Section* section;
  1052. } s_Section;
  1053. static int Section_init(s_Section* self, PyObject* args);
  1054. static void Section_destroy(s_Section* self);
  1055. static PyObject* Section_getCode(s_Section* self);
  1056. static PyObject* Section_QUESTION(s_Section* self);
  1057. static PyObject* Section_ANSWER(s_Section* self);
  1058. static PyObject* Section_AUTHORITY(s_Section* self);
  1059. static PyObject* Section_ADDITIONAL(s_Section* self);
  1060. static PyObject* Section_richcmp(s_Section* self, s_Section* other, int op);
  1061. static PyMethodDef Section_methods[] = {
  1062. { "get_code", (PyCFunction)Section_getCode, METH_NOARGS, "Return the code value" },
  1063. { "QUESTION", (PyCFunction)Section_QUESTION, METH_NOARGS | METH_STATIC, "Create a QUESTION Section" },
  1064. { "ANSWER", (PyCFunction)Section_ANSWER, METH_NOARGS | METH_STATIC, "Create a ANSWER Section" },
  1065. { "AUTHORITY", (PyCFunction)Section_AUTHORITY, METH_NOARGS | METH_STATIC, "Create a AUTHORITY Section" },
  1066. { "ADDITIONAL", (PyCFunction)Section_ADDITIONAL, METH_NOARGS | METH_STATIC, "Create a ADDITIONAL Section" },
  1067. { NULL, NULL, 0, NULL }
  1068. };
  1069. static PyTypeObject section_type = {
  1070. PyVarObject_HEAD_INIT(NULL, 0)
  1071. "libdns_python.Section",
  1072. sizeof(s_Section), /* tp_basicsize */
  1073. 0, /* tp_itemsize */
  1074. (destructor)Section_destroy, /* tp_dealloc */
  1075. NULL, /* tp_print */
  1076. NULL, /* tp_getattr */
  1077. NULL, /* tp_setattr */
  1078. NULL, /* tp_reserved */
  1079. NULL, /* tp_repr */
  1080. NULL, /* tp_as_number */
  1081. NULL, /* tp_as_sequence */
  1082. NULL, /* tp_as_mapping */
  1083. NULL, /* tp_hash */
  1084. NULL, /* tp_call */
  1085. NULL, /* tp_str */
  1086. NULL, /* tp_getattro */
  1087. NULL, /* tp_setattro */
  1088. NULL, /* tp_as_buffer */
  1089. Py_TPFLAGS_DEFAULT, /* tp_flags */
  1090. "C++ Section Object", /* tp_doc */
  1091. NULL, /* tp_traverse */
  1092. NULL, /* tp_clear */
  1093. (richcmpfunc)Section_richcmp, /* tp_richcompare */
  1094. 0, /* tp_weaklistoffset */
  1095. NULL, /* tp_iter */
  1096. NULL, /* tp_iternext */
  1097. Section_methods, /* tp_methods */
  1098. NULL, /* tp_members */
  1099. NULL, /* tp_getset */
  1100. NULL, /* tp_base */
  1101. NULL, /* tp_dict */
  1102. NULL, /* tp_descr_get */
  1103. NULL, /* tp_descr_set */
  1104. 0, /* tp_dictoffset */
  1105. // TODO: Can we make this NULL? (no direct constructor)
  1106. (initproc)Section_init, /* tp_init */
  1107. NULL, /* tp_alloc */
  1108. PyType_GenericNew, /* tp_new */
  1109. NULL, /* tp_free */
  1110. NULL, /* tp_is_gc */
  1111. NULL, /* tp_bases */
  1112. NULL, /* tp_mro */
  1113. NULL, /* tp_cache */
  1114. NULL, /* tp_subclasses */
  1115. NULL, /* tp_weaklist */
  1116. // Note: not sure if the following are correct. Added them just to
  1117. // make the compiler happy.
  1118. NULL, /* tp_del */
  1119. 0 /* tp_version_tag */
  1120. };
  1121. static int
  1122. Section_init(s_Section* self UNUSED_PARAM, PyObject* args UNUSED_PARAM)
  1123. {
  1124. PyErr_SetString(PyExc_NotImplementedError,
  1125. "Section can't be built directly");
  1126. return -1;
  1127. }
  1128. static void
  1129. Section_destroy(s_Section* self)
  1130. {
  1131. // We only use the consts from Section, so don't
  1132. // delete self->section here
  1133. self->section = NULL;
  1134. Py_TYPE(self)->tp_free(self);
  1135. }
  1136. static PyObject*
  1137. Section_getCode(s_Section* self)
  1138. {
  1139. return Py_BuildValue("I", self->section->getCode());
  1140. }
  1141. static PyObject*
  1142. Section_QUESTION(s_Section* self UNUSED_PARAM)
  1143. {
  1144. s_Section* ret = PyObject_New(s_Section, &section_type);
  1145. if (ret != NULL) {
  1146. ret->section = &Section::QUESTION();
  1147. if (ret->section == NULL) {
  1148. Py_DECREF(ret);
  1149. return NULL;
  1150. }
  1151. }
  1152. return (PyObject*) ret;
  1153. }
  1154. static PyObject*
  1155. Section_ANSWER(s_Section* self UNUSED_PARAM)
  1156. {
  1157. s_Section* ret = PyObject_New(s_Section, &section_type);
  1158. if (ret != NULL) {
  1159. ret->section = &Section::ANSWER();
  1160. if (ret->section == NULL) {
  1161. Py_DECREF(ret);
  1162. return NULL;
  1163. }
  1164. }
  1165. return (PyObject*) ret;
  1166. }
  1167. static PyObject*
  1168. Section_AUTHORITY(s_Section* self UNUSED_PARAM)
  1169. {
  1170. s_Section* ret = PyObject_New(s_Section, &section_type);
  1171. if (ret != NULL) {
  1172. ret->section = &Section::AUTHORITY();
  1173. if (ret->section == NULL) {
  1174. Py_DECREF(ret);
  1175. return NULL;
  1176. }
  1177. }
  1178. return (PyObject*) ret;
  1179. }
  1180. static PyObject*
  1181. Section_ADDITIONAL(s_Section* self UNUSED_PARAM)
  1182. {
  1183. s_Section* ret = PyObject_New(s_Section, &section_type);
  1184. if (ret != NULL) {
  1185. ret->section = &Section::ADDITIONAL();
  1186. if (ret->section == NULL) {
  1187. Py_DECREF(ret);
  1188. return NULL;
  1189. }
  1190. }
  1191. return (PyObject*) ret;
  1192. }
  1193. static PyObject*
  1194. Section_richcmp(s_Section* self, s_Section* other, int op)
  1195. {
  1196. bool c;
  1197. // Only equals and not equals here, unorderable type
  1198. switch (op) {
  1199. case Py_LT:
  1200. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  1201. return NULL;
  1202. break;
  1203. case Py_LE:
  1204. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  1205. return NULL;
  1206. break;
  1207. case Py_EQ:
  1208. c = (*self->section == *other->section);
  1209. break;
  1210. case Py_NE:
  1211. c = (*self->section != *other->section);
  1212. break;
  1213. case Py_GT:
  1214. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  1215. return NULL;
  1216. break;
  1217. case Py_GE:
  1218. PyErr_SetString(PyExc_TypeError, "Unorderable type; Section");
  1219. return NULL;
  1220. break;
  1221. default:
  1222. assert(0); // XXX: should trigger an exception
  1223. }
  1224. if (c)
  1225. Py_RETURN_TRUE;
  1226. else
  1227. Py_RETURN_FALSE;
  1228. }
  1229. //
  1230. // End of Section wrapper
  1231. //
  1232. //
  1233. // Message
  1234. //
  1235. // The s_* Class simply coverst one instantiation of the object
  1236. typedef struct {
  1237. PyObject_HEAD
  1238. Message* message;
  1239. } s_Message;
  1240. //
  1241. // We declare the functions here, the definitions are below
  1242. // the type definition of the object, since both can use the other
  1243. //
  1244. // General creation and destruction
  1245. static int Message_init(s_Message* self, PyObject* args);
  1246. static void Message_destroy(s_Message* self);
  1247. static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
  1248. static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
  1249. static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
  1250. static PyObject* Message_isDNSSECSupported(s_Message* self);
  1251. static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
  1252. static PyObject* Message_getUDPSize(s_Message* self);
  1253. static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
  1254. static PyObject* Message_getQid(s_Message* self);
  1255. static PyObject* Message_setQid(s_Message* self, PyObject* args);
  1256. static PyObject* Message_getRcode(s_Message* self);
  1257. static PyObject* Message_setRcode(s_Message* self, PyObject* args);
  1258. static PyObject* Message_getOpcode(s_Message* self);
  1259. static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
  1260. static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
  1261. // use direct iterators for these? (or simply lists for now?)
  1262. static PyObject* Message_getQuestion(s_Message* self);
  1263. static PyObject* Message_getSection(s_Message* self, PyObject* args);
  1264. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  1265. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  1266. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  1267. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  1268. // TODO: Question not wrapped yet
  1269. static PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  1270. static PyObject* Message_addRRset(s_Message* self, PyObject* args);
  1271. static PyObject* Message_clear(s_Message* self, PyObject* args);
  1272. static PyObject* Message_makeResponse(s_Message* self);
  1273. static PyObject* Message_toText(s_Message* self);
  1274. static PyObject* Message_str(PyObject* self);
  1275. static PyObject* Message_toWire(s_Message* self, PyObject* args);
  1276. static PyObject* Message_fromWire(s_Message* self, PyObject* args);
  1277. // This list contains the actual set of functions we have in
  1278. // python. Each entry has
  1279. // 1. Python method name
  1280. // 2. Our static function here
  1281. // 3. Argument type
  1282. // 4. Documentation
  1283. static PyMethodDef Message_methods[] = {
  1284. { "get_header_flag", (PyCFunction)Message_getHeaderFlag, METH_VARARGS, "" },
  1285. { "set_header_flag", (PyCFunction)Message_setHeaderFlag, METH_VARARGS, "" },
  1286. { "clear_header_flag", (PyCFunction)Message_clearHeaderFlag, METH_VARARGS, "" },
  1287. { "is_dnssec_supported", (PyCFunction)Message_isDNSSECSupported, METH_NOARGS, "" },
  1288. { "set_dnssec_supported", (PyCFunction)Message_setDNSSECSupported, METH_VARARGS, "" },
  1289. { "get_udp_size", (PyCFunction)Message_getUDPSize, METH_NOARGS, "" },
  1290. { "set_udp_size", (PyCFunction)Message_setUDPSize, METH_VARARGS, "" },
  1291. { "get_qid", (PyCFunction)Message_getQid, METH_NOARGS, "" },
  1292. { "set_qid", (PyCFunction)Message_setQid, METH_VARARGS, "" },
  1293. { "get_rcode", (PyCFunction)Message_getRcode, METH_NOARGS, "" },
  1294. { "set_rcode", (PyCFunction)Message_setRcode, METH_VARARGS, "" },
  1295. { "get_opcode", (PyCFunction)Message_getOpcode, METH_NOARGS, "" },
  1296. { "set_opcode", (PyCFunction)Message_setOpcode, METH_VARARGS, "" },
  1297. { "get_rr_count", (PyCFunction)Message_getRRCount, METH_VARARGS, "" },
  1298. { "get_question", (PyCFunction)Message_getQuestion, METH_NOARGS, "Returns a list of all Question object in the message (should be 0 or 1)" },
  1299. { "get_section", (PyCFunction)Message_getSection, METH_VARARGS, "Returns a list of all RRset objects in the given section of the message" },
  1300. { "add_question", (PyCFunction)Message_addQuestion, METH_VARARGS, "" },
  1301. { "add_rrset", (PyCFunction)Message_addRRset, METH_VARARGS, "" },
  1302. { "clear", (PyCFunction)Message_clear, METH_VARARGS, "" },
  1303. { "make_response", (PyCFunction)Message_makeResponse, METH_NOARGS, "" },
  1304. { "to_text", (PyCFunction)Message_toText, METH_NOARGS, "Return the string representation" },
  1305. { "to_wire", (PyCFunction)Message_toWire, METH_VARARGS, "to wire format" },
  1306. { "from_wire", (PyCFunction)Message_fromWire, METH_VARARGS, "to wire format" },
  1307. { NULL, NULL, 0, NULL }
  1308. };
  1309. // This defines the complete type for reflection in python and
  1310. // parsing of PyObject* to s_Message
  1311. // Most of the functions are not actually implemented and NULL here.
  1312. static PyTypeObject message_type = {
  1313. PyVarObject_HEAD_INIT(NULL, 0)
  1314. "libdns_python.Message",
  1315. sizeof(s_Message), /* tp_basicsize */
  1316. 0, /* tp_itemsize */
  1317. (destructor)Message_destroy, /* tp_dealloc */
  1318. NULL, /* tp_print */
  1319. NULL, /* tp_getattr */
  1320. NULL, /* tp_setattr */
  1321. NULL, /* tp_reserved */
  1322. NULL, /* tp_repr */
  1323. NULL, /* tp_as_number */
  1324. NULL, /* tp_as_sequence */
  1325. NULL, /* tp_as_mapping */
  1326. NULL, /* tp_hash */
  1327. NULL, /* tp_call */
  1328. Message_str, /* tp_str */
  1329. NULL, /* tp_getattro */
  1330. NULL, /* tp_setattro */
  1331. NULL, /* tp_as_buffer */
  1332. Py_TPFLAGS_DEFAULT, /* tp_flags */
  1333. "C++ Message Object", /* tp_doc */
  1334. NULL, /* tp_traverse */
  1335. NULL, /* tp_clear */
  1336. NULL, /* tp_richcompare */
  1337. 0, /* tp_weaklistoffset */
  1338. NULL, /* tp_iter */
  1339. NULL, /* tp_iternext */
  1340. Message_methods, /* tp_methods */
  1341. NULL, /* tp_members */
  1342. NULL, /* tp_getset */
  1343. NULL, /* tp_base */
  1344. NULL, /* tp_dict */
  1345. NULL, /* tp_descr_get */
  1346. NULL, /* tp_descr_set */
  1347. 0, /* tp_dictoffset */
  1348. (initproc)Message_init, /* tp_init */
  1349. NULL, /* tp_alloc */
  1350. PyType_GenericNew, /* tp_new */
  1351. NULL, /* tp_free */
  1352. NULL, /* tp_is_gc */
  1353. NULL, /* tp_bases */
  1354. NULL, /* tp_mro */
  1355. NULL, /* tp_cache */
  1356. NULL, /* tp_subclasses */
  1357. NULL, /* tp_weaklist */
  1358. // Note: not sure if the following are correct. Added them just to
  1359. // make the compiler happy.
  1360. NULL, /* tp_del */
  1361. 0 /* tp_version_tag */
  1362. };
  1363. static int
  1364. Message_init(s_Message* self, PyObject* args)
  1365. {
  1366. unsigned int i;
  1367. // The constructor argument can be a string ("IN"), an integer (1),
  1368. // or a sequence of numbers between 0 and 255 (wire code)
  1369. if (PyArg_ParseTuple(args, "I", &i)) {
  1370. PyErr_Clear();
  1371. if (i == Message::PARSE) {
  1372. self->message = new Message(Message::PARSE);
  1373. return 0;
  1374. } else if (i == Message::RENDER) {
  1375. self->message = new Message(Message::RENDER);
  1376. return 0;
  1377. } else {
  1378. PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
  1379. return -1;
  1380. }
  1381. }
  1382. PyErr_Clear();
  1383. PyErr_SetString(PyExc_TypeError,
  1384. "no valid type in constructor argument");
  1385. return -1;
  1386. }
  1387. static void
  1388. Message_destroy(s_Message* self)
  1389. {
  1390. if (self->message != NULL)
  1391. delete self->message;
  1392. self->message = NULL;
  1393. Py_TYPE(self)->tp_free(self);
  1394. }
  1395. static PyObject*
  1396. Message_getHeaderFlag(s_Message* self, PyObject* args)
  1397. {
  1398. s_MessageFlag* messageflag;
  1399. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1400. return NULL;
  1401. }
  1402. if (self->message->getHeaderFlag(*messageflag->messageflag)) {
  1403. Py_RETURN_TRUE;
  1404. } else {
  1405. Py_RETURN_FALSE;
  1406. }
  1407. }
  1408. static PyObject*
  1409. Message_setHeaderFlag(s_Message* self, PyObject* args)
  1410. {
  1411. s_MessageFlag* messageflag;
  1412. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1413. return NULL;
  1414. }
  1415. self->message->setHeaderFlag(*messageflag->messageflag);
  1416. Py_RETURN_NONE;
  1417. }
  1418. static PyObject*
  1419. Message_clearHeaderFlag(s_Message* self, PyObject* args)
  1420. {
  1421. s_MessageFlag* messageflag;
  1422. if (!PyArg_ParseTuple(args, "O!", &messageflag_type, &messageflag)) {
  1423. return NULL;
  1424. }
  1425. self->message->clearHeaderFlag(*messageflag->messageflag);
  1426. Py_RETURN_NONE;
  1427. }
  1428. static PyObject*
  1429. Message_isDNSSECSupported(s_Message* self)
  1430. {
  1431. if (self->message->isDNSSECSupported()) {
  1432. Py_RETURN_TRUE;
  1433. } else {
  1434. Py_RETURN_FALSE;
  1435. }
  1436. }
  1437. static PyObject*
  1438. Message_setDNSSECSupported(s_Message* self, PyObject* args)
  1439. {
  1440. PyObject *b;
  1441. if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
  1442. return NULL;
  1443. }
  1444. try {
  1445. if (b == Py_True) {
  1446. self->message->setDNSSECSupported(true);
  1447. } else {
  1448. self->message->setDNSSECSupported(false);
  1449. }
  1450. Py_RETURN_NONE;
  1451. } catch (isc::dns::InvalidMessageOperation imo) {
  1452. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1453. return NULL;
  1454. }
  1455. }
  1456. static PyObject*
  1457. Message_getUDPSize(s_Message* self)
  1458. {
  1459. return Py_BuildValue("I", self->message->getUDPSize());
  1460. }
  1461. static PyObject*
  1462. Message_setUDPSize(s_Message* self, PyObject* args)
  1463. {
  1464. uint16_t size;
  1465. if (!PyArg_ParseTuple(args, "I", &size)) {
  1466. return NULL;
  1467. }
  1468. try {
  1469. self->message->setUDPSize(size);
  1470. Py_RETURN_NONE;
  1471. } catch (isc::dns::InvalidMessageUDPSize imus) {
  1472. PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
  1473. return NULL;
  1474. } catch (isc::dns::InvalidMessageOperation imo) {
  1475. PyErr_SetString(po_InvalidMessageOperation, imo.what());
  1476. return NULL;
  1477. }
  1478. }
  1479. static PyObject*
  1480. Message_getQid(s_Message* self)
  1481. {
  1482. return Py_BuildValue("I", self->message->getQid());
  1483. }
  1484. static PyObject*
  1485. Message_setQid(s_Message* self, PyObject* args)
  1486. {
  1487. uint16_t id;
  1488. if (!PyArg_ParseTuple(args, "I", &id)) {
  1489. return NULL;
  1490. }
  1491. self->message->setQid(id);
  1492. Py_RETURN_NONE;
  1493. }
  1494. static PyObject*
  1495. Message_getRcode(s_Message* self)
  1496. {
  1497. s_Rcode* rcode;
  1498. rcode = (s_Rcode*)rcode_type.tp_alloc(&rcode_type, 0);
  1499. if (rcode != NULL) {
  1500. rcode->rcode = new Rcode(self->message->getRcode());
  1501. if (rcode->rcode == NULL)
  1502. {
  1503. Py_DECREF(rcode);
  1504. return NULL;
  1505. }
  1506. }
  1507. return (PyObject*)rcode;
  1508. }
  1509. static PyObject*
  1510. Message_setRcode(s_Message* self, PyObject* args)
  1511. {
  1512. s_Rcode* rcode;
  1513. if (!PyArg_ParseTuple(args, "O!", &rcode_type, &rcode)) {
  1514. return NULL;
  1515. }
  1516. self->message->setRcode(*rcode->rcode);
  1517. Py_RETURN_NONE;
  1518. }
  1519. static PyObject*
  1520. Message_getOpcode(s_Message* self)
  1521. {
  1522. s_Opcode* opcode;
  1523. opcode = (s_Opcode*)opcode_type.tp_alloc(&opcode_type, 0);
  1524. if (opcode != NULL) {
  1525. // Note that we do not new and delete for opcodes.
  1526. // all rcodes point to the statics defined in
  1527. // message.cc
  1528. opcode->opcode = &self->message->getOpcode();
  1529. if (opcode->opcode == NULL)
  1530. {
  1531. Py_DECREF(opcode);
  1532. return NULL;
  1533. }
  1534. }
  1535. return (PyObject*)opcode;
  1536. }
  1537. static PyObject*
  1538. Message_setOpcode(s_Message* self, PyObject* args)
  1539. {
  1540. s_Opcode* opcode;
  1541. if (!PyArg_ParseTuple(args, "O!", &opcode_type, &opcode)) {
  1542. return NULL;
  1543. }
  1544. self->message->setOpcode(*opcode->opcode);
  1545. Py_RETURN_NONE;
  1546. }
  1547. static PyObject*
  1548. Message_getRRCount(s_Message* self, PyObject* args)
  1549. {
  1550. s_Section *section;
  1551. if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
  1552. return NULL;
  1553. }
  1554. return Py_BuildValue("I", self->message->getRRCount(*section->section));
  1555. }
  1556. // TODO use direct iterators for these? (or simply lists for now?)
  1557. static PyObject*
  1558. Message_getQuestion(s_Message* self)
  1559. {
  1560. PyObject* list = PyList_New(0);
  1561. for (QuestionIterator qi = self->message->beginQuestion();
  1562. qi != self->message->endQuestion();
  1563. ++qi) {
  1564. s_Question *question = (s_Question*)question_type.tp_alloc(&question_type, 0);
  1565. if (question != NULL) {
  1566. question->question = *qi;
  1567. if (question->question == NULL)
  1568. {
  1569. Py_DECREF(question);
  1570. return NULL;
  1571. }
  1572. }
  1573. PyList_Append(list, (PyObject*) question);
  1574. }
  1575. return list;
  1576. }
  1577. static PyObject*
  1578. Message_getSection(s_Message* self, PyObject* args)
  1579. {
  1580. s_Section *section;
  1581. if (!PyArg_ParseTuple(args, "O!", &section_type, &section)) {
  1582. return NULL;
  1583. }
  1584. PyObject* list = PyList_New(0);
  1585. for (RRsetIterator rrsi = self->message->beginSection(*section->section);
  1586. rrsi != self->message->endSection(*section->section);
  1587. ++rrsi) {
  1588. s_RRset *rrset = (s_RRset*)rrset_type.tp_alloc(&rrset_type, 0);
  1589. if (rrset != NULL) {
  1590. rrset->rrset = *rrsi;
  1591. if (rrset->rrset == NULL)
  1592. {
  1593. Py_DECREF(rrset);
  1594. Py_DECREF(list);
  1595. return NULL;
  1596. }
  1597. }
  1598. PyList_Append(list, (PyObject*) rrset);
  1599. // PyList_Append increases refcount, so we remove ours since
  1600. // we don't need it anymore
  1601. Py_DECREF(rrset);
  1602. }
  1603. return list;
  1604. }
  1605. //static PyObject* Message_beginQuestion(s_Message* self, PyObject* args);
  1606. //static PyObject* Message_endQuestion(s_Message* self, PyObject* args);
  1607. //static PyObject* Message_beginSection(s_Message* self, PyObject* args);
  1608. //static PyObject* Message_endSection(s_Message* self, PyObject* args);
  1609. //static PyObject* Message_addQuestion(s_Message* self, PyObject* args);
  1610. static PyObject*
  1611. Message_addQuestion(s_Message* self, PyObject* args)
  1612. {
  1613. s_Question *question;
  1614. if (!PyArg_ParseTuple(args, "O!", &question_type, &question)) {
  1615. return NULL;
  1616. }
  1617. self->message->addQuestion(question->question);
  1618. Py_RETURN_NONE;
  1619. }
  1620. static PyObject*
  1621. Message_addRRset(s_Message* self, PyObject* args)
  1622. {
  1623. PyObject *sign = Py_False;
  1624. s_Section* section;
  1625. s_RRset* rrset;
  1626. if (!PyArg_ParseTuple(args, "O!O!|O!", &section_type, &section,
  1627. &rrset_type, &rrset,
  1628. &PyBool_Type, &sign)) {
  1629. return NULL;
  1630. }
  1631. if (sign == Py_True) {
  1632. self->message->addRRset(*section->section, rrset->rrset, true);
  1633. } else {
  1634. self->message->addRRset(*section->section, rrset->rrset, false);
  1635. }
  1636. Py_RETURN_NONE;
  1637. }
  1638. static PyObject*
  1639. Message_clear(s_Message* self, PyObject* args)
  1640. {
  1641. unsigned int i;
  1642. // The constructor argument can be a string ("IN"), an integer (1),
  1643. // or a sequence of numbers between 0 and 255 (wire code)
  1644. if (PyArg_ParseTuple(args, "I", &i)) {
  1645. PyErr_Clear();
  1646. if (i == Message::PARSE) {
  1647. self->message->clear(Message::PARSE);
  1648. Py_RETURN_NONE;
  1649. } else if (i == Message::RENDER) {
  1650. self->message->clear(Message::RENDER);
  1651. Py_RETURN_NONE;
  1652. } else {
  1653. PyErr_SetString(PyExc_TypeError, "Message mode must be Message.PARSE or Message.RENDER");
  1654. return NULL;
  1655. }
  1656. } else {
  1657. return NULL;
  1658. }
  1659. }
  1660. static PyObject*
  1661. Message_makeResponse(s_Message* self)
  1662. {
  1663. self->message->makeResponse();
  1664. Py_RETURN_NONE;
  1665. }
  1666. static PyObject*
  1667. Message_toText(s_Message* self)
  1668. {
  1669. // Py_BuildValue makes python objects from native data
  1670. return Py_BuildValue("s", self->message->toText().c_str());
  1671. }
  1672. static PyObject*
  1673. Message_str(PyObject* self)
  1674. {
  1675. // Simply call the to_text method we already defined
  1676. return PyObject_CallMethod(self, (char*)"to_text", (char*)"");
  1677. }
  1678. static PyObject*
  1679. Message_toWire(s_Message* self, PyObject* args)
  1680. {
  1681. s_MessageRenderer* mr;
  1682. if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
  1683. self->message->toWire(*mr->messagerenderer);
  1684. // If we return NULL it is seen as an error, so use this for
  1685. // None returns
  1686. Py_RETURN_NONE;
  1687. }
  1688. PyErr_Clear();
  1689. PyErr_SetString(PyExc_TypeError,
  1690. "toWire argument must be a sequence object or a MessageRenderer");
  1691. return NULL;
  1692. }
  1693. static PyObject*
  1694. Message_fromWire(s_Message* self, PyObject* args)
  1695. {
  1696. const char* b;
  1697. Py_ssize_t len;
  1698. if (!PyArg_ParseTuple(args, "y#", &b, &len)) {
  1699. return NULL;
  1700. }
  1701. InputBuffer inbuf(b, len);
  1702. try {
  1703. self->message->fromWire(inbuf);
  1704. Py_RETURN_NONE;
  1705. } catch (isc::dns::DNSMessageFORMERR dmfe) {
  1706. PyErr_SetString(po_DNSMessageFORMERR, dmfe.what());
  1707. return NULL;
  1708. } catch (isc::dns::DNSMessageBADVERS dmfe) {
  1709. PyErr_SetString(po_DNSMessageBADVERS, dmfe.what());
  1710. return NULL;
  1711. }
  1712. }
  1713. // end of Message
  1714. // Module Initialization, all statics are initialized here
  1715. bool
  1716. initModulePart_Message(PyObject* mod)
  1717. {
  1718. // Add the exceptions to the module
  1719. po_MessageTooShort = PyErr_NewException("libdns_python.MessageTooShort", NULL, NULL);
  1720. Py_INCREF(po_MessageTooShort);
  1721. PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
  1722. po_InvalidMessageSection = PyErr_NewException("libdns_python.InvalidMessageSection", NULL, NULL);
  1723. Py_INCREF(po_InvalidMessageSection);
  1724. PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
  1725. po_InvalidMessageOperation = PyErr_NewException("libdns_python.InvalidMessageOperation", NULL, NULL);
  1726. Py_INCREF(po_InvalidMessageOperation);
  1727. PyModule_AddObject(mod, "InvalidMessageOperation", po_InvalidMessageOperation);
  1728. po_InvalidMessageUDPSize = PyErr_NewException("libdns_python.InvalidMessageUDPSize", NULL, NULL);
  1729. Py_INCREF(po_InvalidMessageUDPSize);
  1730. PyModule_AddObject(mod, "InvalidMessageUDPSize", po_InvalidMessageUDPSize);
  1731. po_DNSMessageBADVERS = PyErr_NewException("libdns_python.DNSMessageBADVERS", NULL, NULL);
  1732. Py_INCREF(po_DNSMessageBADVERS);
  1733. PyModule_AddObject(mod, "DNSMessageBADVERS", po_DNSMessageBADVERS);
  1734. // Constants. These should probably go into the Message class, but need to find out how first
  1735. po_MessagePARSE = Py_BuildValue("I", Message::PARSE);
  1736. Py_INCREF(po_MessagePARSE);
  1737. PyModule_AddObject(mod, "PARSE", po_MessagePARSE);
  1738. po_MessageRENDER = Py_BuildValue("I", Message::RENDER);
  1739. Py_INCREF(po_MessageRENDER);
  1740. PyModule_AddObject(mod, "RENDER", po_MessageRENDER);
  1741. po_MessageDefaultMaxUDPSize = Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE);
  1742. Py_INCREF(po_MessageDefaultMaxUDPSize);
  1743. PyModule_AddObject(mod, "DEFAULT_MAX_UDPSIZE", po_MessageDefaultMaxUDPSize);
  1744. /* add methods to class */
  1745. if (PyType_Ready(&messageflag_type) < 0) {
  1746. return false;
  1747. }
  1748. Py_INCREF(&messageflag_type);
  1749. PyModule_AddObject(mod, "MessageFlag",
  1750. (PyObject*) &messageflag_type);
  1751. if (PyType_Ready(&opcode_type) < 0) {
  1752. return false;
  1753. }
  1754. Py_INCREF(&opcode_type);
  1755. PyModule_AddObject(mod, "Opcode",
  1756. (PyObject*) &opcode_type);
  1757. if (PyType_Ready(&rcode_type) < 0) {
  1758. return false;
  1759. }
  1760. Py_INCREF(&rcode_type);
  1761. PyModule_AddObject(mod, "Rcode",
  1762. (PyObject*) &rcode_type);
  1763. if (PyType_Ready(&section_type) < 0) {
  1764. return false;
  1765. }
  1766. Py_INCREF(&section_type);
  1767. PyModule_AddObject(mod, "Section",
  1768. (PyObject*) &section_type);
  1769. if (PyType_Ready(&message_type) < 0) {
  1770. return false;
  1771. }
  1772. Py_INCREF(&message_type);
  1773. PyModule_AddObject(mod, "Message",
  1774. (PyObject*) &message_type);
  1775. return true;
  1776. }