pydnspp.cc 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  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. // We want a lot of different parts of the DNS API in the python
  15. // module, but not one big 10000-line file.
  16. // So we split it up in several 'mini-modules'
  17. // These would be the same as a single module, except for
  18. // the init function, which has to be modified to a unique
  19. // name initModulePart_<name>, and return true/false instead of
  20. // NULL/*mod
  21. //
  22. // The big init function is split up into a separate initModulePart function
  23. // for each class we add.
  24. #define PY_SSIZE_T_CLEAN
  25. #include <Python.h>
  26. #include <structmember.h>
  27. #include <dns/message.h>
  28. #include <dns/opcode.h>
  29. #include <dns/tsig.h>
  30. #include <util/python/pycppwrapper_util.h>
  31. #include "pydnspp_common.h"
  32. #include "edns_python.h"
  33. #include "message_python.h"
  34. #include "messagerenderer_python.h"
  35. #include "name_python.h"
  36. #include "nsec3hash_python.h"
  37. #include "opcode_python.h"
  38. #include "pydnspp_common.h"
  39. #include "pydnspp_towire.h"
  40. #include "question_python.h"
  41. #include "rcode_python.h"
  42. #include "rdata_python.h"
  43. #include "rrclass_python.h"
  44. #include "rrset_python.h"
  45. #include "rrttl_python.h"
  46. #include "rrtype_python.h"
  47. #include "rrset_collection_python.h"
  48. #include "serial_python.h"
  49. #include "tsigerror_python.h"
  50. #include "tsigkey_python.h"
  51. #include "tsig_python.h"
  52. #include "tsig_rdata_python.h"
  53. #include "tsigrecord_python.h"
  54. #include "zone_checker_python.h"
  55. #include "zone_checker_python_inc.cc"
  56. using namespace isc::dns;
  57. using namespace isc::dns::python;
  58. using namespace isc::util::python;
  59. namespace {
  60. bool
  61. initModulePart_EDNS(PyObject* mod) {
  62. // After the type has been initialized, we initialize any exceptions
  63. // that are defined in the wrapper for this class, and add constants
  64. // to the type, if any
  65. if (!initClass(edns_type, "EDNS", mod)) {
  66. return (false);
  67. }
  68. addClassVariable(edns_type, "SUPPORTED_VERSION",
  69. Py_BuildValue("B", EDNS::SUPPORTED_VERSION));
  70. return (true);
  71. }
  72. bool
  73. initModulePart_Message(PyObject* mod) {
  74. if (!initClass(message_type, "Message", mod)) {
  75. return (false);
  76. }
  77. try {
  78. //
  79. // Constant class variables
  80. //
  81. // Parse mode
  82. installClassVariable(message_type, "PARSE",
  83. Py_BuildValue("I", Message::PARSE));
  84. installClassVariable(message_type, "RENDER",
  85. Py_BuildValue("I", Message::RENDER));
  86. // Parse options
  87. installClassVariable(message_type, "PARSE_DEFAULT",
  88. Py_BuildValue("I", Message::PARSE_DEFAULT));
  89. installClassVariable(message_type, "PRESERVE_ORDER",
  90. Py_BuildValue("I", Message::PRESERVE_ORDER));
  91. // Header flags
  92. installClassVariable(message_type, "HEADERFLAG_QR",
  93. Py_BuildValue("I", Message::HEADERFLAG_QR));
  94. installClassVariable(message_type, "HEADERFLAG_AA",
  95. Py_BuildValue("I", Message::HEADERFLAG_AA));
  96. installClassVariable(message_type, "HEADERFLAG_TC",
  97. Py_BuildValue("I", Message::HEADERFLAG_TC));
  98. installClassVariable(message_type, "HEADERFLAG_RD",
  99. Py_BuildValue("I", Message::HEADERFLAG_RD));
  100. installClassVariable(message_type, "HEADERFLAG_RA",
  101. Py_BuildValue("I", Message::HEADERFLAG_RA));
  102. installClassVariable(message_type, "HEADERFLAG_AD",
  103. Py_BuildValue("I", Message::HEADERFLAG_AD));
  104. installClassVariable(message_type, "HEADERFLAG_CD",
  105. Py_BuildValue("I", Message::HEADERFLAG_CD));
  106. // Sections
  107. installClassVariable(message_type, "SECTION_QUESTION",
  108. Py_BuildValue("I", Message::SECTION_QUESTION));
  109. installClassVariable(message_type, "SECTION_ANSWER",
  110. Py_BuildValue("I", Message::SECTION_ANSWER));
  111. installClassVariable(message_type, "SECTION_AUTHORITY",
  112. Py_BuildValue("I", Message::SECTION_AUTHORITY));
  113. installClassVariable(message_type, "SECTION_ADDITIONAL",
  114. Py_BuildValue("I", Message::SECTION_ADDITIONAL));
  115. // Protocol constant
  116. installClassVariable(message_type, "DEFAULT_MAX_UDPSIZE",
  117. Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
  118. /* Class-specific exceptions */
  119. po_MessageTooShort =
  120. PyErr_NewException("pydnspp.MessageTooShort", NULL, NULL);
  121. PyObjectContainer(po_MessageTooShort).installToModule(
  122. mod, "MessageTooShort");
  123. po_InvalidMessageSection =
  124. PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
  125. PyObjectContainer(po_InvalidMessageSection).installToModule(
  126. mod, "InvalidMessageSection");
  127. po_InvalidMessageOperation =
  128. PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
  129. PyObjectContainer(po_InvalidMessageOperation).installToModule(
  130. mod, "InvalidMessageOperation");
  131. po_InvalidMessageUDPSize =
  132. PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
  133. PyObjectContainer(po_InvalidMessageUDPSize).installToModule(
  134. mod, "InvalidMessageUDPSize");
  135. po_DNSMessageBADVERS =
  136. PyErr_NewException("pydnspp.DNSMessageBADVERS", NULL, NULL);
  137. PyObjectContainer(po_DNSMessageBADVERS).installToModule(
  138. mod, "DNSMessageBADVERS");
  139. po_UnknownNSEC3HashAlgorithm =
  140. PyErr_NewException("pydnspp.UnknownNSEC3HashAlgorithm", NULL, NULL);
  141. PyObjectContainer(po_UnknownNSEC3HashAlgorithm).installToModule(
  142. mod, "UnknownNSEC3HashAlgorithm");
  143. } catch (const std::exception& ex) {
  144. const std::string ex_what =
  145. "Unexpected failure in Message initialization: " +
  146. std::string(ex.what());
  147. PyErr_SetString(po_IscException, ex_what.c_str());
  148. return (false);
  149. } catch (...) {
  150. PyErr_SetString(PyExc_SystemError,
  151. "Unexpected failure in Message initialization");
  152. return (false);
  153. }
  154. return (true);
  155. }
  156. bool
  157. initModulePart_MessageRenderer(PyObject* mod) {
  158. if (!initClass(messagerenderer_type, "MessageRenderer", mod)) {
  159. return (false);
  160. }
  161. addClassVariable(messagerenderer_type, "CASE_INSENSITIVE",
  162. Py_BuildValue("I", MessageRenderer::CASE_INSENSITIVE));
  163. addClassVariable(messagerenderer_type, "CASE_SENSITIVE",
  164. Py_BuildValue("I", MessageRenderer::CASE_SENSITIVE));
  165. return (true);
  166. }
  167. bool
  168. initModulePart_NameComparisonResult(PyObject* mod) {
  169. if (!initClass(name_comparison_result_type,
  170. "NameComparisonResult", mod)) {
  171. return (false);
  172. }
  173. // Add the enums to the module
  174. po_NameRelation = Py_BuildValue("{i:s,i:s,i:s,i:s}",
  175. NameComparisonResult::SUPERDOMAIN, "SUPERDOMAIN",
  176. NameComparisonResult::SUBDOMAIN, "SUBDOMAIN",
  177. NameComparisonResult::EQUAL, "EQUAL",
  178. NameComparisonResult::COMMONANCESTOR, "COMMONANCESTOR");
  179. addClassVariable(name_comparison_result_type, "NameRelation",
  180. po_NameRelation);
  181. // Add the constants themselves too
  182. addClassVariable(name_comparison_result_type, "SUPERDOMAIN",
  183. Py_BuildValue("I", NameComparisonResult::SUPERDOMAIN));
  184. addClassVariable(name_comparison_result_type, "SUBDOMAIN",
  185. Py_BuildValue("I", NameComparisonResult::SUBDOMAIN));
  186. addClassVariable(name_comparison_result_type, "EQUAL",
  187. Py_BuildValue("I", NameComparisonResult::EQUAL));
  188. addClassVariable(name_comparison_result_type, "COMMONANCESTOR",
  189. Py_BuildValue("I", NameComparisonResult::COMMONANCESTOR));
  190. return (true);
  191. }
  192. bool
  193. initModulePart_Name(PyObject* mod) {
  194. if (!initClass(name_type, "Name", mod)) {
  195. return (false);
  196. }
  197. // Add the constants to the module
  198. addClassVariable(name_type, "MAX_WIRE",
  199. Py_BuildValue("I", Name::MAX_WIRE));
  200. addClassVariable(name_type, "MAX_LABELS",
  201. Py_BuildValue("I", Name::MAX_LABELS));
  202. addClassVariable(name_type, "MAX_LABELLEN",
  203. Py_BuildValue("I", Name::MAX_LABELLEN));
  204. addClassVariable(name_type, "MAX_COMPRESS_POINTER",
  205. Py_BuildValue("I", Name::MAX_COMPRESS_POINTER));
  206. addClassVariable(name_type, "COMPRESS_POINTER_MARK8",
  207. Py_BuildValue("I", Name::COMPRESS_POINTER_MARK8));
  208. addClassVariable(name_type, "COMPRESS_POINTER_MARK16",
  209. Py_BuildValue("I", Name::COMPRESS_POINTER_MARK16));
  210. addClassVariable(name_type, "ROOT_NAME",
  211. createNameObject(Name::ROOT_NAME()));
  212. // Add the exceptions to the module
  213. try {
  214. po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
  215. PyObjectContainer(po_EmptyLabel).installToModule(mod, "EmptyLabel");
  216. po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
  217. PyObjectContainer(po_TooLongName).installToModule(mod, "TooLongName");
  218. po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
  219. PyObjectContainer(po_TooLongLabel).installToModule(mod, "TooLongLabel");
  220. po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
  221. PyObjectContainer(po_BadLabelType).installToModule(mod, "BadLabelType");
  222. po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
  223. PyObjectContainer(po_BadEscape).installToModule(mod, "BadEscape");
  224. po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL,
  225. NULL);
  226. PyObjectContainer(po_IncompleteName).installToModule(mod, "IncompleteName");
  227. po_InvalidBufferPosition =
  228. PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
  229. PyObjectContainer(po_InvalidBufferPosition).installToModule(
  230. mod, "InvalidBufferPosition");
  231. // This one could have gone into the message_python.cc file, but is
  232. // already needed here.
  233. po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR",
  234. NULL, NULL);
  235. PyObjectContainer(po_DNSMessageFORMERR).installToModule(
  236. mod, "DNSMessageFORMERR");
  237. } catch (const std::exception& ex) {
  238. const std::string ex_what =
  239. "Unexpected failure in Name initialization: " +
  240. std::string(ex.what());
  241. PyErr_SetString(po_IscException, ex_what.c_str());
  242. return (false);
  243. } catch (...) {
  244. PyErr_SetString(PyExc_SystemError,
  245. "Unexpected failure in Name initialization");
  246. return (false);
  247. }
  248. return (true);
  249. }
  250. bool
  251. initModulePart_Opcode(PyObject* mod) {
  252. if (!initClass(opcode_type, "Opcode", mod)) {
  253. return (false);
  254. }
  255. addClassVariable(opcode_type, "QUERY_CODE",
  256. Py_BuildValue("h", Opcode::QUERY_CODE));
  257. addClassVariable(opcode_type, "IQUERY_CODE",
  258. Py_BuildValue("h", Opcode::IQUERY_CODE));
  259. addClassVariable(opcode_type, "STATUS_CODE",
  260. Py_BuildValue("h", Opcode::STATUS_CODE));
  261. addClassVariable(opcode_type, "RESERVED3_CODE",
  262. Py_BuildValue("h", Opcode::RESERVED3_CODE));
  263. addClassVariable(opcode_type, "NOTIFY_CODE",
  264. Py_BuildValue("h", Opcode::NOTIFY_CODE));
  265. addClassVariable(opcode_type, "UPDATE_CODE",
  266. Py_BuildValue("h", Opcode::UPDATE_CODE));
  267. addClassVariable(opcode_type, "RESERVED6_CODE",
  268. Py_BuildValue("h", Opcode::RESERVED6_CODE));
  269. addClassVariable(opcode_type, "RESERVED7_CODE",
  270. Py_BuildValue("h", Opcode::RESERVED7_CODE));
  271. addClassVariable(opcode_type, "RESERVED8_CODE",
  272. Py_BuildValue("h", Opcode::RESERVED8_CODE));
  273. addClassVariable(opcode_type, "RESERVED9_CODE",
  274. Py_BuildValue("h", Opcode::RESERVED9_CODE));
  275. addClassVariable(opcode_type, "RESERVED10_CODE",
  276. Py_BuildValue("h", Opcode::RESERVED10_CODE));
  277. addClassVariable(opcode_type, "RESERVED11_CODE",
  278. Py_BuildValue("h", Opcode::RESERVED11_CODE));
  279. addClassVariable(opcode_type, "RESERVED12_CODE",
  280. Py_BuildValue("h", Opcode::RESERVED12_CODE));
  281. addClassVariable(opcode_type, "RESERVED13_CODE",
  282. Py_BuildValue("h", Opcode::RESERVED13_CODE));
  283. addClassVariable(opcode_type, "RESERVED14_CODE",
  284. Py_BuildValue("h", Opcode::RESERVED14_CODE));
  285. addClassVariable(opcode_type, "RESERVED15_CODE",
  286. Py_BuildValue("h", Opcode::RESERVED15_CODE));
  287. return (true);
  288. }
  289. bool
  290. initModulePart_Question(PyObject* mod) {
  291. return (initClass(question_type, "Question", mod));
  292. }
  293. bool
  294. initModulePart_Rcode(PyObject* mod) {
  295. if (!initClass(rcode_type, "Rcode", mod)) {
  296. return (false);
  297. }
  298. addClassVariable(rcode_type, "NOERROR_CODE",
  299. Py_BuildValue("h", Rcode::NOERROR_CODE));
  300. addClassVariable(rcode_type, "FORMERR_CODE",
  301. Py_BuildValue("h", Rcode::FORMERR_CODE));
  302. addClassVariable(rcode_type, "SERVFAIL_CODE",
  303. Py_BuildValue("h", Rcode::SERVFAIL_CODE));
  304. addClassVariable(rcode_type, "NXDOMAIN_CODE",
  305. Py_BuildValue("h", Rcode::NXDOMAIN_CODE));
  306. addClassVariable(rcode_type, "NOTIMP_CODE",
  307. Py_BuildValue("h", Rcode::NOTIMP_CODE));
  308. addClassVariable(rcode_type, "REFUSED_CODE",
  309. Py_BuildValue("h", Rcode::REFUSED_CODE));
  310. addClassVariable(rcode_type, "YXDOMAIN_CODE",
  311. Py_BuildValue("h", Rcode::YXDOMAIN_CODE));
  312. addClassVariable(rcode_type, "YXRRSET_CODE",
  313. Py_BuildValue("h", Rcode::YXRRSET_CODE));
  314. addClassVariable(rcode_type, "NXRRSET_CODE",
  315. Py_BuildValue("h", Rcode::NXRRSET_CODE));
  316. addClassVariable(rcode_type, "NOTAUTH_CODE",
  317. Py_BuildValue("h", Rcode::NOTAUTH_CODE));
  318. addClassVariable(rcode_type, "NOTZONE_CODE",
  319. Py_BuildValue("h", Rcode::NOTZONE_CODE));
  320. addClassVariable(rcode_type, "RESERVED11_CODE",
  321. Py_BuildValue("h", Rcode::RESERVED11_CODE));
  322. addClassVariable(rcode_type, "RESERVED12_CODE",
  323. Py_BuildValue("h", Rcode::RESERVED12_CODE));
  324. addClassVariable(rcode_type, "RESERVED13_CODE",
  325. Py_BuildValue("h", Rcode::RESERVED13_CODE));
  326. addClassVariable(rcode_type, "RESERVED14_CODE",
  327. Py_BuildValue("h", Rcode::RESERVED14_CODE));
  328. addClassVariable(rcode_type, "RESERVED15_CODE",
  329. Py_BuildValue("h", Rcode::RESERVED15_CODE));
  330. addClassVariable(rcode_type, "BADVERS_CODE",
  331. Py_BuildValue("h", Rcode::BADVERS_CODE));
  332. return (true);
  333. }
  334. bool
  335. initModulePart_Rdata(PyObject* mod) {
  336. if (!initClass(rdata_type, "Rdata", mod)) {
  337. return (false);
  338. }
  339. // Add the exceptions to the class
  340. try {
  341. po_InvalidRdataLength =
  342. PyErr_NewException("pydnspp.InvalidRdataLength", NULL, NULL);
  343. PyObjectContainer(po_InvalidRdataLength).installToModule(
  344. mod, "InvalidRdataLength");
  345. po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText",
  346. NULL, NULL);
  347. PyObjectContainer(po_InvalidRdataText).installToModule(
  348. mod, "InvalidRdataText");
  349. po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong",
  350. NULL, NULL);
  351. PyObjectContainer(po_CharStringTooLong).installToModule(
  352. mod, "CharStringTooLong");
  353. } catch (const std::exception& ex) {
  354. const std::string ex_what =
  355. "Unexpected failure in Rdata initialization: " +
  356. std::string(ex.what());
  357. PyErr_SetString(po_IscException, ex_what.c_str());
  358. return (false);
  359. } catch (...) {
  360. PyErr_SetString(PyExc_SystemError,
  361. "Unexpected failure in Rdata initialization");
  362. return (false);
  363. }
  364. return (true);
  365. }
  366. bool
  367. initModulePart_RRClass(PyObject* mod) {
  368. if (!initClass(rrclass_type, "RRClass", mod)) {
  369. return (false);
  370. }
  371. try {
  372. po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass",
  373. NULL, NULL);
  374. PyObjectContainer(po_InvalidRRClass).installToModule(
  375. mod, "InvalidRRClass");
  376. po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass",
  377. NULL, NULL);
  378. PyObjectContainer(po_IncompleteRRClass).installToModule(
  379. mod, "IncompleteRRClass");
  380. // Incorporate auto-generated RRClass constants
  381. #include <dns/python/rrclass_constants_inc.cc>
  382. } catch (const std::exception& ex) {
  383. const std::string ex_what =
  384. "Unexpected failure in RRClass initialization: " +
  385. std::string(ex.what());
  386. PyErr_SetString(po_IscException, ex_what.c_str());
  387. return (false);
  388. } catch (...) {
  389. PyErr_SetString(PyExc_SystemError,
  390. "Unexpected failure in RRClass initialization");
  391. return (false);
  392. }
  393. return (true);
  394. }
  395. bool
  396. initModulePart_RRset(PyObject* mod) {
  397. if (!initClass(rrset_type, "RRset", mod)) {
  398. return (false);
  399. }
  400. try {
  401. po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
  402. PyObjectContainer(po_EmptyRRset).installToModule(mod, "EmptyRRset");
  403. } catch (const std::exception& ex) {
  404. const std::string ex_what =
  405. "Unexpected failure in RRset initialization: " +
  406. std::string(ex.what());
  407. PyErr_SetString(po_IscException, ex_what.c_str());
  408. return (false);
  409. } catch (...) {
  410. PyErr_SetString(PyExc_SystemError,
  411. "Unexpected failure in RRset initialization");
  412. return (false);
  413. }
  414. return (true);
  415. }
  416. bool
  417. initModulePart_RRTTL(PyObject* mod) {
  418. if (!initClass(rrttl_type, "RRTTL", mod)) {
  419. return (false);
  420. }
  421. try {
  422. po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL",
  423. NULL, NULL);
  424. PyObjectContainer(po_InvalidRRTTL).installToModule(mod,
  425. "InvalidRRTTL");
  426. po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL",
  427. NULL, NULL);
  428. PyObjectContainer(po_IncompleteRRTTL).installToModule(
  429. mod, "IncompleteRRTTL");
  430. } catch (const std::exception& ex) {
  431. const std::string ex_what =
  432. "Unexpected failure in RRTTL initialization: " +
  433. std::string(ex.what());
  434. PyErr_SetString(po_IscException, ex_what.c_str());
  435. return (false);
  436. } catch (...) {
  437. PyErr_SetString(PyExc_SystemError,
  438. "Unexpected failure in RRTTL initialization");
  439. return (false);
  440. }
  441. return (true);
  442. }
  443. bool
  444. initModulePart_RRType(PyObject* mod) {
  445. if (!initClass(rrtype_type, "RRType", mod)) {
  446. return (false);
  447. }
  448. try {
  449. po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType",
  450. NULL, NULL);
  451. PyObjectContainer(po_InvalidRRType).installToModule(mod,
  452. "InvalidRRType");
  453. po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType",
  454. NULL, NULL);
  455. PyObjectContainer(po_IncompleteRRType).installToModule(
  456. mod, "IncompleteRRType");
  457. // Incorporate auto-generated RRType constants
  458. #include <dns/python/rrtype_constants_inc.cc>
  459. // We still need to define some special types by hand (for now)
  460. installClassVariable(rrtype_type, "IXFR",
  461. createRRTypeObject(RRType::IXFR()));
  462. installClassVariable(rrtype_type, "AXFR",
  463. createRRTypeObject(RRType::AXFR()));
  464. installClassVariable(rrtype_type, "ANY",
  465. createRRTypeObject(RRType::ANY()));
  466. } catch (const std::exception& ex) {
  467. const std::string ex_what =
  468. "Unexpected failure in RRType initialization: " +
  469. std::string(ex.what());
  470. PyErr_SetString(po_IscException, ex_what.c_str());
  471. return (false);
  472. } catch (...) {
  473. PyErr_SetString(PyExc_SystemError,
  474. "Unexpected failure in RRType initialization");
  475. return (false);
  476. }
  477. return (true);
  478. }
  479. bool
  480. initModulePart_Serial(PyObject* mod) {
  481. return (initClass(serial_type, "Serial", mod));
  482. }
  483. bool
  484. initModulePart_TSIGError(PyObject* mod) {
  485. if (!initClass(tsigerror_type, "TSIGError", mod)) {
  486. return (false);
  487. }
  488. try {
  489. // Constant class variables
  490. // Error codes (bare values)
  491. installClassVariable(tsigerror_type, "BAD_SIG_CODE",
  492. Py_BuildValue("H", TSIGError::BAD_SIG_CODE));
  493. installClassVariable(tsigerror_type, "BAD_KEY_CODE",
  494. Py_BuildValue("H", TSIGError::BAD_KEY_CODE));
  495. installClassVariable(tsigerror_type, "BAD_TIME_CODE",
  496. Py_BuildValue("H", TSIGError::BAD_TIME_CODE));
  497. // Error codes (constant objects)
  498. installClassVariable(tsigerror_type, "NOERROR",
  499. createTSIGErrorObject(TSIGError::NOERROR()));
  500. installClassVariable(tsigerror_type, "FORMERR",
  501. createTSIGErrorObject(TSIGError::FORMERR()));
  502. installClassVariable(tsigerror_type, "SERVFAIL",
  503. createTSIGErrorObject(TSIGError::SERVFAIL()));
  504. installClassVariable(tsigerror_type, "NXDOMAIN",
  505. createTSIGErrorObject(TSIGError::NXDOMAIN()));
  506. installClassVariable(tsigerror_type, "NOTIMP",
  507. createTSIGErrorObject(TSIGError::NOTIMP()));
  508. installClassVariable(tsigerror_type, "REFUSED",
  509. createTSIGErrorObject(TSIGError::REFUSED()));
  510. installClassVariable(tsigerror_type, "YXDOMAIN",
  511. createTSIGErrorObject(TSIGError::YXDOMAIN()));
  512. installClassVariable(tsigerror_type, "YXRRSET",
  513. createTSIGErrorObject(TSIGError::YXRRSET()));
  514. installClassVariable(tsigerror_type, "NXRRSET",
  515. createTSIGErrorObject(TSIGError::NXRRSET()));
  516. installClassVariable(tsigerror_type, "NOTAUTH",
  517. createTSIGErrorObject(TSIGError::NOTAUTH()));
  518. installClassVariable(tsigerror_type, "NOTZONE",
  519. createTSIGErrorObject(TSIGError::NOTZONE()));
  520. installClassVariable(tsigerror_type, "RESERVED11",
  521. createTSIGErrorObject(TSIGError::RESERVED11()));
  522. installClassVariable(tsigerror_type, "RESERVED12",
  523. createTSIGErrorObject(TSIGError::RESERVED12()));
  524. installClassVariable(tsigerror_type, "RESERVED13",
  525. createTSIGErrorObject(TSIGError::RESERVED13()));
  526. installClassVariable(tsigerror_type, "RESERVED14",
  527. createTSIGErrorObject(TSIGError::RESERVED14()));
  528. installClassVariable(tsigerror_type, "RESERVED15",
  529. createTSIGErrorObject(TSIGError::RESERVED15()));
  530. installClassVariable(tsigerror_type, "BAD_SIG",
  531. createTSIGErrorObject(TSIGError::BAD_SIG()));
  532. installClassVariable(tsigerror_type, "BAD_KEY",
  533. createTSIGErrorObject(TSIGError::BAD_KEY()));
  534. installClassVariable(tsigerror_type, "BAD_TIME",
  535. createTSIGErrorObject(TSIGError::BAD_TIME()));
  536. } catch (const std::exception& ex) {
  537. const std::string ex_what =
  538. "Unexpected failure in TSIGError initialization: " +
  539. std::string(ex.what());
  540. PyErr_SetString(po_IscException, ex_what.c_str());
  541. return (false);
  542. } catch (...) {
  543. PyErr_SetString(PyExc_SystemError,
  544. "Unexpected failure in TSIGError initialization");
  545. return (false);
  546. }
  547. return (true);
  548. }
  549. bool
  550. initModulePart_TSIGKey(PyObject* mod) {
  551. if (!initClass(tsigkey_type, "TSIGKey", mod)) {
  552. return (false);
  553. }
  554. try {
  555. // Constant class variables
  556. installClassVariable(tsigkey_type, "HMACMD5_NAME",
  557. createNameObject(TSIGKey::HMACMD5_NAME()));
  558. installClassVariable(tsigkey_type, "HMACSHA1_NAME",
  559. createNameObject(TSIGKey::HMACSHA1_NAME()));
  560. installClassVariable(tsigkey_type, "HMACSHA256_NAME",
  561. createNameObject(TSIGKey::HMACSHA256_NAME()));
  562. installClassVariable(tsigkey_type, "HMACSHA224_NAME",
  563. createNameObject(TSIGKey::HMACSHA224_NAME()));
  564. installClassVariable(tsigkey_type, "HMACSHA384_NAME",
  565. createNameObject(TSIGKey::HMACSHA384_NAME()));
  566. installClassVariable(tsigkey_type, "HMACSHA512_NAME",
  567. createNameObject(TSIGKey::HMACSHA512_NAME()));
  568. } catch (const std::exception& ex) {
  569. const std::string ex_what =
  570. "Unexpected failure in TSIGKey initialization: " +
  571. std::string(ex.what());
  572. PyErr_SetString(po_IscException, ex_what.c_str());
  573. return (false);
  574. } catch (...) {
  575. PyErr_SetString(PyExc_SystemError,
  576. "Unexpected failure in TSIGKey initialization");
  577. return (false);
  578. }
  579. return (true);
  580. }
  581. bool
  582. initModulePart_TSIGKeyRing(PyObject* mod) {
  583. if (!initClass(tsigkeyring_type, "TSIGKeyRing", mod)) {
  584. return (false);
  585. }
  586. addClassVariable(tsigkeyring_type, "SUCCESS",
  587. Py_BuildValue("I", TSIGKeyRing::SUCCESS));
  588. addClassVariable(tsigkeyring_type, "EXIST",
  589. Py_BuildValue("I", TSIGKeyRing::EXIST));
  590. addClassVariable(tsigkeyring_type, "NOTFOUND",
  591. Py_BuildValue("I", TSIGKeyRing::NOTFOUND));
  592. return (true);
  593. }
  594. bool
  595. initModulePart_TSIGContext(PyObject* mod) {
  596. if (!initClass(tsigcontext_type, "TSIGContext", mod)) {
  597. return (false);
  598. }
  599. try {
  600. // Class specific exceptions
  601. po_TSIGContextError = PyErr_NewException("pydnspp.TSIGContextError",
  602. po_IscException, NULL);
  603. PyObjectContainer(po_TSIGContextError).installToModule(
  604. mod, "TSIGContextError");
  605. // Constant class variables
  606. installClassVariable(tsigcontext_type, "STATE_INIT",
  607. Py_BuildValue("I", TSIGContext::INIT));
  608. installClassVariable(tsigcontext_type, "STATE_SENT_REQUEST",
  609. Py_BuildValue("I", TSIGContext::SENT_REQUEST));
  610. installClassVariable(tsigcontext_type, "STATE_RECEIVED_REQUEST",
  611. Py_BuildValue("I", TSIGContext::RECEIVED_REQUEST));
  612. installClassVariable(tsigcontext_type, "STATE_SENT_RESPONSE",
  613. Py_BuildValue("I", TSIGContext::SENT_RESPONSE));
  614. installClassVariable(tsigcontext_type, "STATE_VERIFIED_RESPONSE",
  615. Py_BuildValue("I",
  616. TSIGContext::VERIFIED_RESPONSE));
  617. installClassVariable(tsigcontext_type, "DEFAULT_FUDGE",
  618. Py_BuildValue("H", TSIGContext::DEFAULT_FUDGE));
  619. } catch (const std::exception& ex) {
  620. const std::string ex_what =
  621. "Unexpected failure in TSIGContext initialization: " +
  622. std::string(ex.what());
  623. PyErr_SetString(po_IscException, ex_what.c_str());
  624. return (false);
  625. } catch (...) {
  626. PyErr_SetString(PyExc_SystemError,
  627. "Unexpected failure in TSIGContext initialization");
  628. return (false);
  629. }
  630. return (true);
  631. }
  632. bool
  633. initModulePart_TSIG(PyObject* mod) {
  634. return (initClass(tsig_type, "TSIG", mod));
  635. }
  636. bool
  637. initModulePart_TSIGRecord(PyObject* mod) {
  638. if (!initClass(tsigrecord_type, "TSIGRecord", mod)) {
  639. return (false);
  640. }
  641. try {
  642. // Constant class variables
  643. installClassVariable(tsigrecord_type, "TSIG_TTL",
  644. Py_BuildValue("I", 0));
  645. } catch (const std::exception& ex) {
  646. const std::string ex_what =
  647. "Unexpected failure in TSIGRecord initialization: " +
  648. std::string(ex.what());
  649. PyErr_SetString(po_IscException, ex_what.c_str());
  650. return (false);
  651. } catch (...) {
  652. PyErr_SetString(PyExc_SystemError,
  653. "Unexpected failure in TSIGRecord initialization");
  654. return (false);
  655. }
  656. return (true);
  657. }
  658. PyMethodDef methods[] = {
  659. { "check_zone", internal::pyCheckZone, METH_VARARGS, dns_checkZone_doc },
  660. { NULL, NULL, 0, NULL }
  661. };
  662. PyModuleDef pydnspp = {
  663. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  664. "pydnspp",
  665. "Python bindings for the classes in the isc::dns namespace.\n\n"
  666. "These bindings match the original C++ API as closely as possible, "
  667. "but are not complete. Some classes are unnecessary (InputBuffer "
  668. "and OutputBuffer for instance), and others may be necessary, but "
  669. "were not up to now.",
  670. -1,
  671. methods,
  672. NULL,
  673. NULL,
  674. NULL,
  675. NULL
  676. };
  677. } // unnamed namespace
  678. PyMODINIT_FUNC
  679. PyInit_pydnspp(void) {
  680. PyObject* mod = PyModule_Create(&pydnspp);
  681. if (mod == NULL) {
  682. return (NULL);
  683. }
  684. try {
  685. // Add the exceptions to the class
  686. po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
  687. PyObjectContainer(po_IscException).installToModule(mod, "IscException");
  688. po_InvalidOperation = PyErr_NewException("pydnspp.InvalidOperation",
  689. NULL, NULL);
  690. PyObjectContainer(po_InvalidOperation).installToModule(
  691. mod, "InvalidOperation");
  692. po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
  693. NULL, NULL);
  694. PyObjectContainer(po_InvalidParameter).installToModule(
  695. mod, "InvalidParameter");
  696. } catch (const std::exception& ex) {
  697. const std::string ex_what =
  698. "Unexpected failure in pydnspp initialization: " +
  699. std::string(ex.what());
  700. PyErr_SetString(po_IscException, ex_what.c_str());
  701. return (NULL);
  702. } catch (...) {
  703. PyErr_SetString(PyExc_SystemError,
  704. "Unexpected failure in pydnspp initialization");
  705. return (NULL);
  706. }
  707. // for each part included above, we call its specific initializer
  708. if (!initModulePart_NameComparisonResult(mod)) {
  709. return (NULL);
  710. }
  711. if (!initModulePart_Name(mod)) {
  712. return (NULL);
  713. }
  714. if (!initModulePart_MessageRenderer(mod)) {
  715. return (NULL);
  716. }
  717. if (!initModulePart_NSEC3Hash(mod)) {
  718. return (NULL);
  719. }
  720. if (!initModulePart_RRClass(mod)) {
  721. return (NULL);
  722. }
  723. if (!initModulePart_RRType(mod)) {
  724. return (NULL);
  725. }
  726. if (!initModulePart_RRTTL(mod)) {
  727. return (NULL);
  728. }
  729. if (!initModulePart_Rdata(mod)) {
  730. return (NULL);
  731. }
  732. if (!initModulePart_RRset(mod)) {
  733. return (NULL);
  734. }
  735. if (!initModulePart_Question(mod)) {
  736. return (NULL);
  737. }
  738. if (!initModulePart_Opcode(mod)) {
  739. return (NULL);
  740. }
  741. if (!initModulePart_Rcode(mod)) {
  742. return (NULL);
  743. }
  744. if (!initModulePart_Message(mod)) {
  745. return (NULL);
  746. }
  747. if (!initModulePart_EDNS(mod)) {
  748. return (NULL);
  749. }
  750. if (!initModulePart_Serial(mod)) {
  751. return (NULL);
  752. }
  753. if (!initModulePart_TSIGKey(mod)) {
  754. return (NULL);
  755. }
  756. if (!initModulePart_TSIGKeyRing(mod)) {
  757. return (NULL);
  758. }
  759. if (!initModulePart_TSIG(mod)) {
  760. return (NULL);
  761. }
  762. if (!initModulePart_TSIGError(mod)) {
  763. return (NULL);
  764. }
  765. if (!initModulePart_TSIGRecord(mod)) {
  766. return (NULL);
  767. }
  768. if (!initModulePart_TSIGContext(mod)) {
  769. return (NULL);
  770. }
  771. if (!initModulePart_RRsetCollectionBase(mod)) {
  772. return (NULL);
  773. }
  774. if (!initModulePart_RRsetCollection(mod)) {
  775. return (NULL);
  776. }
  777. return (mod);
  778. }