ipops_mod.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /*
  2. * ipops module - IPv4 and Ipv6 operations
  3. *
  4. * Copyright (C) 2011 Iñaki Baz Castillo
  5. *
  6. * This file is part of SIP Router, a free SIP server.
  7. *
  8. * SIP Router is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * SIP Router is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * History:
  23. * -------
  24. * 2011-07-29: Added a function to detect RFC1918 private IPv4 addresses (ibc)
  25. * 2011-04-27: Initial version (ibc)
  26. */
  27. /*!
  28. * \file
  29. * \brief SIP-router ipops :: Module interface
  30. * \ingroup ipops
  31. * Copyright (C) 2011 Iñaki Baz Castillo
  32. * Module: \ref ipops
  33. */
  34. /*! \defgroup ipops SIP-router ipops Module
  35. *
  36. * The ipops module provide IPv4 and IPv6 operations.
  37. */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <sys/types.h>
  42. #include <sys/socket.h>
  43. #include <netdb.h>
  44. #include <arpa/inet.h>
  45. #include "../../sr_module.h"
  46. #include "../../dprint.h"
  47. #include "../../str.h"
  48. #include "../../mod_fix.h"
  49. #include "../../pvar.h"
  50. #include "../../resolve.h"
  51. #include "api.h"
  52. #include "ipops_pv.h"
  53. #include "ip_parser.h"
  54. #include "rfc1918_parser.h"
  55. MODULE_VERSION
  56. /*
  57. * Module parameter variables
  58. */
  59. /*
  60. * Module core functions
  61. */
  62. /*
  63. * Module internal functions
  64. */
  65. int _compare_ips(char*, size_t, enum enum_ip_type, char*, size_t, enum enum_ip_type);
  66. int _ip_is_in_subnet(char *ip1, size_t len1, enum enum_ip_type ip1_type, char *ip2, size_t len2, enum enum_ip_type ip2_type, int netmask);
  67. /*
  68. * Script functions
  69. */
  70. static int w_is_ip(struct sip_msg*, char*);
  71. static int w_is_pure_ip(struct sip_msg*, char*);
  72. static int w_is_ipv4(struct sip_msg*, char*);
  73. static int w_is_ipv6(struct sip_msg*, char*);
  74. static int w_is_ipv6_reference(struct sip_msg*, char*);
  75. static int w_ip_type(struct sip_msg*, char*);
  76. static int w_compare_ips(struct sip_msg*, char*, char*);
  77. static int w_compare_pure_ips(struct sip_msg*, char*, char*);
  78. static int w_is_ip_rfc1918(struct sip_msg*, char*);
  79. static int w_ip_is_in_subnet(struct sip_msg*, char*, char*);
  80. static int w_dns_sys_match_ip(sip_msg_t*, char*, char*);
  81. static int w_dns_int_match_ip(sip_msg_t*, char*, char*);
  82. static int w_dns_query(struct sip_msg* msg, char* str1, char* str2);
  83. static pv_export_t mod_pvs[] = {
  84. { {"dns", sizeof("dns")-1}, PVT_OTHER, pv_get_dns, 0,
  85. pv_parse_dns_name, 0, 0, 0 },
  86. { {"HN", sizeof("HN")-1}, PVT_OTHER, pv_get_hn, 0,
  87. pv_parse_hn_name, 0, 0, 0 },
  88. { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
  89. };
  90. /*
  91. * Exported functions
  92. */
  93. static cmd_export_t cmds[] =
  94. {
  95. { "is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, 0,
  96. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  97. { "is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, 0,
  98. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  99. { "is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, 0,
  100. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  101. { "is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, 0,
  102. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  103. { "is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, fixup_spve_null, 0,
  104. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  105. { "ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, 0,
  106. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  107. { "compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, 0,
  108. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  109. { "compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, fixup_spve_spve, 0,
  110. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  111. { "is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, 0,
  112. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  113. { "is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, 0,
  114. REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
  115. { "dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, fixup_spve_spve, 0,
  116. ANY_ROUTE },
  117. { "dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, fixup_spve_spve, 0,
  118. ANY_ROUTE },
  119. { "dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, 0,
  120. ANY_ROUTE },
  121. { "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0},
  122. { 0, 0, 0, 0, 0, 0 }
  123. };
  124. /*
  125. * Module interface
  126. */
  127. struct module_exports exports = {
  128. "ipops", /*!< module name */
  129. DEFAULT_DLFLAGS, /*!< dlopen flags */
  130. cmds, /*!< exported functions */
  131. 0, /*!< exported parameters */
  132. 0, /*!< exported statistics */
  133. 0, /*!< exported MI functions */
  134. mod_pvs, /*!< exported pseudo-variables */
  135. 0, /*!< extra processes */
  136. 0, /*!< module initialization function */
  137. (response_function) 0, /*!< response handling function */
  138. 0, /*!< destroy function */
  139. 0 /*!< per-child init function */
  140. };
  141. /*
  142. * Module internal functions
  143. */
  144. /*! \brief Return 1 if both pure IP's are equal, 0 otherwise. */
  145. int _compare_ips(char *ip1, size_t len1, enum enum_ip_type ip1_type, char *ip2, size_t len2, enum enum_ip_type ip2_type)
  146. {
  147. struct in_addr in_addr1, in_addr2;
  148. struct in6_addr in6_addr1, in6_addr2;
  149. char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
  150. // Not same IP type, return false.
  151. if (ip1_type != ip2_type)
  152. return 0;
  153. memcpy(_ip1, ip1, len1);
  154. _ip1[len1] = '\0';
  155. memcpy(_ip2, ip2, len2);
  156. _ip2[len2] = '\0';
  157. switch(ip1_type) {
  158. // Comparing IPv4 with IPv4.
  159. case(ip_type_ipv4):
  160. if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
  161. if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
  162. if (in_addr1.s_addr == in_addr2.s_addr)
  163. return 1;
  164. else
  165. return 0;
  166. break;
  167. // Comparing IPv6 with IPv6.
  168. case(ip_type_ipv6):
  169. if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
  170. if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
  171. if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
  172. return 1;
  173. else
  174. return 0;
  175. break;
  176. default:
  177. return 0;
  178. break;
  179. }
  180. }
  181. /*! \brief Return 1 if IP1 is in the subnet given by IP2 and the netmask, 0 otherwise. */
  182. int _ip_is_in_subnet(char *ip1, size_t len1, enum enum_ip_type ip1_type, char *ip2, size_t len2, enum enum_ip_type ip2_type, int netmask)
  183. {
  184. struct in_addr in_addr1, in_addr2;
  185. struct in6_addr in6_addr1, in6_addr2;
  186. char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
  187. uint32_t ipv4_mask;
  188. uint8_t ipv6_mask[16];
  189. int i;
  190. // Not same IP type, return false.
  191. if (ip1_type != ip2_type)
  192. return 0;
  193. memcpy(_ip1, ip1, len1);
  194. _ip1[len1] = '\0';
  195. memcpy(_ip2, ip2, len2);
  196. _ip2[len2] = '\0';
  197. switch(ip1_type) {
  198. // Comparing IPv4 with IPv4.
  199. case(ip_type_ipv4):
  200. if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
  201. if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
  202. if (netmask <0 || netmask > 32) return 0;
  203. if (netmask == 32) ipv4_mask = 0xFFFFFFFF;
  204. else ipv4_mask = htonl(~(0xFFFFFFFF >> netmask));
  205. if ((in_addr1.s_addr & ipv4_mask) == in_addr2.s_addr)
  206. return 1;
  207. else
  208. return 0;
  209. break;
  210. // Comparing IPv6 with IPv6.
  211. case(ip_type_ipv6):
  212. if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
  213. if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
  214. if (netmask <0 || netmask > 128) return 0;
  215. for (i=0; i<16; i++)
  216. {
  217. if (netmask > ((i+1)*8)) ipv6_mask[i] = 0xFF;
  218. else if (netmask > (i*8)) ipv6_mask[i] = ~(0xFF >> (netmask-(i*8)));
  219. else ipv6_mask[i] = 0x00;
  220. }
  221. for (i=0; i<16; i++) in6_addr1.s6_addr[i] &= ipv6_mask[i];
  222. if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
  223. return 1;
  224. else
  225. return 0;
  226. break;
  227. default:
  228. return 0;
  229. break;
  230. }
  231. }
  232. /*
  233. * Script functions
  234. */
  235. /*! \brief Return true if the given argument (string or pv) is a valid IPv4, IPv6 or IPv6 reference. */
  236. static int w_is_ip(struct sip_msg* _msg, char* _s)
  237. {
  238. str string;
  239. if (_s == NULL) {
  240. LM_ERR("bad parameter\n");
  241. return -2;
  242. }
  243. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  244. {
  245. LM_ERR("cannot print the format for string\n");
  246. return -3;
  247. }
  248. if (ip_parser_execute(string.s, string.len) != ip_type_error)
  249. return 1;
  250. else
  251. return -1;
  252. }
  253. /*! \brief Return true if the given argument (string or pv) is a valid IPv4 or IPv6. */
  254. static int w_is_pure_ip(struct sip_msg* _msg, char* _s)
  255. {
  256. str string;
  257. if (_s == NULL) {
  258. LM_ERR("bad parameter\n");
  259. return -2;
  260. }
  261. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  262. {
  263. LM_ERR("cannot print the format for string\n");
  264. return -3;
  265. }
  266. switch(ip_parser_execute(string.s, string.len)) {
  267. case(ip_type_ipv4):
  268. return 1;
  269. break;
  270. case(ip_type_ipv6):
  271. return 1;
  272. break;
  273. default:
  274. return -1;
  275. break;
  276. }
  277. }
  278. /*! \brief Return true if the given argument (string or pv) is a valid IPv4. */
  279. static int w_is_ipv4(struct sip_msg* _msg, char* _s)
  280. {
  281. str string;
  282. if (_s == NULL) {
  283. LM_ERR("bad parameter\n");
  284. return -2;
  285. }
  286. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  287. {
  288. LM_ERR("cannot print the format for string\n");
  289. return -3;
  290. }
  291. if (ip_parser_execute(string.s, string.len) == ip_type_ipv4)
  292. return 1;
  293. else
  294. return -1;
  295. }
  296. /*! \brief Return true if the given argument (string or pv) is a valid IPv6. */
  297. static int w_is_ipv6(struct sip_msg* _msg, char* _s)
  298. {
  299. str string;
  300. if (_s == NULL) {
  301. LM_ERR("bad parameter\n");
  302. return -2;
  303. }
  304. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  305. {
  306. LM_ERR("cannot print the format for string\n");
  307. return -3;
  308. }
  309. if (ip_parser_execute(string.s, string.len) == ip_type_ipv6)
  310. return 1;
  311. else
  312. return -1;
  313. }
  314. /*! \brief Return true if the given argument (string or pv) is a valid IPv6 reference. */
  315. static int w_is_ipv6_reference(struct sip_msg* _msg, char* _s)
  316. {
  317. str string;
  318. if (_s == NULL) {
  319. LM_ERR("bad parameter\n");
  320. return -2;
  321. }
  322. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  323. {
  324. LM_ERR("cannot print the format for string\n");
  325. return -3;
  326. }
  327. if (ip_parser_execute(string.s, string.len) == ip_type_ipv6_reference)
  328. return 1;
  329. else
  330. return -1;
  331. }
  332. /*! \brief Return the IP type of the given argument (string or pv): 1 = IPv4, 2 = IPv6, 3 = IPv6 refenrece, -1 = invalid IP. */
  333. static int w_ip_type(struct sip_msg* _msg, char* _s)
  334. {
  335. str string;
  336. if (_s == NULL) {
  337. LM_ERR("bad parameter\n");
  338. return -2;
  339. }
  340. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  341. {
  342. LM_ERR("cannot print the format for string\n");
  343. return -3;
  344. }
  345. switch (ip_parser_execute(string.s, string.len)) {
  346. case(ip_type_ipv4):
  347. return 1;
  348. break;
  349. case(ip_type_ipv6):
  350. return 2;
  351. break;
  352. case(ip_type_ipv6_reference):
  353. return 3;
  354. break;
  355. default:
  356. return -1;
  357. break;
  358. }
  359. }
  360. /*! \brief Return true if both IP's (string or pv) are equal. This function also allows comparing an IPv6 with an IPv6 reference. */
  361. static int w_compare_ips(struct sip_msg* _msg, char* _s1, char* _s2)
  362. {
  363. str string1, string2;
  364. enum enum_ip_type ip1_type, ip2_type;
  365. if (_s1 == NULL || _s2 == NULL ) {
  366. LM_ERR("bad parameters\n");
  367. return -2;
  368. }
  369. if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
  370. {
  371. LM_ERR("cannot print the format for first string\n");
  372. return -3;
  373. }
  374. if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
  375. {
  376. LM_ERR("cannot print the format for second string\n");
  377. return -3;
  378. }
  379. switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
  380. case(ip_type_error):
  381. return -1;
  382. break;
  383. case(ip_type_ipv6_reference):
  384. string1.s += 1;
  385. string1.len -= 2;
  386. ip1_type = ip_type_ipv6;
  387. break;
  388. default:
  389. break;
  390. }
  391. switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
  392. case(ip_type_error):
  393. return -1;
  394. break;
  395. case(ip_type_ipv6_reference):
  396. string2.s += 1;
  397. string2.len -= 2;
  398. ip2_type = ip_type_ipv6;
  399. break;
  400. default:
  401. break;
  402. }
  403. if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
  404. return 1;
  405. else
  406. return -1;
  407. }
  408. /*! \brief Return true if both pure IP's (string or pv) are equal. IPv6 references not allowed. */
  409. static int w_compare_pure_ips(struct sip_msg* _msg, char* _s1, char* _s2)
  410. {
  411. str string1, string2;
  412. enum enum_ip_type ip1_type, ip2_type;
  413. if (_s1 == NULL || _s2 == NULL ) {
  414. LM_ERR("bad parameters\n");
  415. return -2;
  416. }
  417. if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
  418. {
  419. LM_ERR("cannot print the format for first string\n");
  420. return -3;
  421. }
  422. if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
  423. {
  424. LM_ERR("cannot print the format for second string\n");
  425. return -3;
  426. }
  427. switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
  428. case(ip_type_error):
  429. return -1;
  430. break;
  431. case(ip_type_ipv6_reference):
  432. return -1;
  433. break;
  434. default:
  435. break;
  436. }
  437. switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
  438. case(ip_type_error):
  439. return -1;
  440. break;
  441. case(ip_type_ipv6_reference):
  442. return -1;
  443. break;
  444. default:
  445. break;
  446. }
  447. if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
  448. return 1;
  449. else
  450. return -1;
  451. }
  452. /*! \brief Return true if the first IP (string or pv) is within the subnet defined by the second IP in CIDR notation. IPv6 references not allowed. */
  453. static int w_ip_is_in_subnet(struct sip_msg* _msg, char* _s1, char* _s2)
  454. {
  455. str string1, string2;
  456. enum enum_ip_type ip1_type, ip2_type;
  457. char *cidr_pos = NULL;
  458. int netmask = 0;
  459. if (_s1 == NULL || _s2 == NULL ) {
  460. LM_ERR("bad parameters\n");
  461. return -2;
  462. }
  463. if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
  464. {
  465. LM_ERR("cannot print the format for first string\n");
  466. return -3;
  467. }
  468. if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
  469. {
  470. LM_ERR("cannot print the format for second string\n");
  471. return -3;
  472. }
  473. switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
  474. case(ip_type_error):
  475. return -1;
  476. break;
  477. case(ip_type_ipv6_reference):
  478. return -1;
  479. break;
  480. default:
  481. break;
  482. }
  483. cidr_pos = string2.s + string2.len - 1;
  484. while (cidr_pos > string2.s)
  485. {
  486. if (*cidr_pos == '/')
  487. {
  488. string2.len = (cidr_pos - string2.s);
  489. netmask = atoi(cidr_pos+1);
  490. break;
  491. }
  492. cidr_pos--;
  493. }
  494. switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
  495. case(ip_type_error):
  496. return -1;
  497. break;
  498. case(ip_type_ipv6_reference):
  499. return -1;
  500. break;
  501. default:
  502. break;
  503. }
  504. if (netmask == 0)
  505. {
  506. if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
  507. return 1;
  508. else
  509. return -1;
  510. }
  511. else
  512. {
  513. if (_ip_is_in_subnet(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type, netmask))
  514. return 1;
  515. else
  516. return -1;
  517. }
  518. }
  519. /*! \brief Return true if the given argument (string or pv) is a valid RFC 1918 IPv4 (private address). */
  520. static int w_is_ip_rfc1918(struct sip_msg* _msg, char* _s)
  521. {
  522. str string;
  523. if (_s == NULL) {
  524. LM_ERR("bad parameter\n");
  525. return -2;
  526. }
  527. if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
  528. {
  529. LM_ERR("cannot print the format for string\n");
  530. return -3;
  531. }
  532. if (rfc1918_parser_execute(string.s, string.len) == 1)
  533. return 1;
  534. else
  535. return -1;
  536. }
  537. static inline ip_addr_t *strtoipX(str *ips)
  538. {
  539. /* try to figure out INET class */
  540. if(ips->s[0] == '[' || memchr(ips->s, ':', ips->len)!=NULL)
  541. {
  542. /* IPv6 */
  543. return str2ip6(ips);
  544. } else {
  545. /* IPv4 */
  546. return str2ip(ips);
  547. }
  548. }
  549. static int w_dns_sys_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
  550. {
  551. struct addrinfo hints, *res, *p;
  552. int status;
  553. ip_addr_t *ipa;
  554. void *addr;
  555. str hns;
  556. str ips;
  557. struct sockaddr_in *ipv4;
  558. struct sockaddr_in6 *ipv6;
  559. if (fixup_get_svalue(msg, (gparam_p)hnp, &hns))
  560. {
  561. LM_ERR("cannot evaluate hostname parameter\n");
  562. return -2;
  563. }
  564. if (fixup_get_svalue(msg, (gparam_p)ipp, &ips))
  565. {
  566. LM_ERR("cannot evaluate ip address parameter\n");
  567. return -2;
  568. }
  569. ipa = strtoipX(&ips);
  570. if(ipa==NULL)
  571. {
  572. LM_ERR("invalid ip address: %.*s\n", ips.len, ips.s);
  573. return -3;
  574. }
  575. memset(&hints, 0, sizeof(hints));
  576. hints.ai_family = AF_UNSPEC; /* allow any of AF_INET or AF_INET6 */
  577. // hints.ai_socktype = SOCK_STREAM;
  578. hints.ai_socktype = SOCK_DGRAM;
  579. if ((status = getaddrinfo(hns.s, NULL, &hints, &res)) != 0)
  580. {
  581. LM_ERR("getaddrinfo: %s\n", gai_strerror(status));
  582. return -4;
  583. }
  584. for(p = res;p != NULL; p = p->ai_next)
  585. {
  586. if(p->ai_family==ipa->af)
  587. {
  588. if (p->ai_family==AF_INET)
  589. {
  590. ipv4 = (struct sockaddr_in *)p->ai_addr;
  591. addr = &(ipv4->sin_addr);
  592. } else {
  593. ipv6 = (struct sockaddr_in6 *)p->ai_addr;
  594. addr = &(ipv6->sin6_addr);
  595. }
  596. if(memcmp(ipa->u.addr, addr, ipa->len)==0)
  597. {
  598. /* matched IP */
  599. freeaddrinfo(res);
  600. return 1;
  601. }
  602. }
  603. }
  604. freeaddrinfo(res);
  605. return -1;
  606. }
  607. static int w_dns_int_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
  608. {
  609. ip_addr_t *ipa;
  610. str hns;
  611. str ips;
  612. struct hostent* he;
  613. char ** h;
  614. if (fixup_get_svalue(msg, (gparam_p)hnp, &hns))
  615. {
  616. LM_ERR("cannot evaluate hostname parameter\n");
  617. return -2;
  618. }
  619. if (fixup_get_svalue(msg, (gparam_p)ipp, &ips))
  620. {
  621. LM_ERR("cannot evaluate ip address parameter\n");
  622. return -2;
  623. }
  624. ipa = strtoipX(&ips);
  625. if(ipa==NULL)
  626. {
  627. LM_ERR("invalid ip address: %.*s\n", ips.len, ips.s);
  628. return -3;
  629. }
  630. he=resolvehost(hns.s);
  631. if (he==0) {
  632. DBG("could not resolve %s\n", hns.s);
  633. return -4;
  634. }
  635. if (he->h_addrtype==ipa->af)
  636. {
  637. for(h=he->h_addr_list; (*h); h++)
  638. {
  639. if(memcmp(ipa->u.addr, *h, ipa->len)==0)
  640. {
  641. /* match */
  642. return 1;
  643. }
  644. }
  645. }
  646. /* no match */
  647. return -1;
  648. }
  649. /**
  650. *
  651. */
  652. static int w_dns_query(struct sip_msg* msg, char* str1, char* str2)
  653. {
  654. str hostname;
  655. str name;
  656. if(msg==NULL)
  657. {
  658. LM_ERR("received null msg\n");
  659. return -1;
  660. }
  661. if(fixup_get_svalue(msg, (gparam_t*)str1, &hostname)<0)
  662. {
  663. LM_ERR("cannot get the hostname\n");
  664. return -1;
  665. }
  666. if(fixup_get_svalue(msg, (gparam_t*)str2, &name)<0)
  667. {
  668. LM_ERR("cannot get the pv container name\n");
  669. return -1;
  670. }
  671. return dns_update_pv(&hostname, &name);
  672. }