|
@@ -21,6 +21,7 @@
|
|
|
*
|
|
|
* History:
|
|
|
* -------
|
|
|
+ * 2015-03-31: Added srv_query function (rboisvert)
|
|
|
* 2011-07-29: Added a function to detect RFC1918 private IPv4 addresses (ibc)
|
|
|
* 2011-04-27: Initial version (ibc)
|
|
|
*/
|
|
@@ -92,10 +93,13 @@ static int w_dns_sys_match_ip(sip_msg_t*, char*, char*);
|
|
|
static int w_dns_int_match_ip(sip_msg_t*, char*, char*);
|
|
|
|
|
|
static int w_dns_query(struct sip_msg* msg, char* str1, char* str2);
|
|
|
+static int w_srv_query(struct sip_msg* msg, char* str1, char* str2);
|
|
|
|
|
|
static pv_export_t mod_pvs[] = {
|
|
|
{ {"dns", sizeof("dns")-1}, PVT_OTHER, pv_get_dns, 0,
|
|
|
pv_parse_dns_name, 0, 0, 0 },
|
|
|
+ { {"srvquery", sizeof("srvquery")-1}, PVT_OTHER, pv_get_srv, 0,
|
|
|
+ pv_parse_srv_name, 0, 0, 0 },
|
|
|
{ {"HN", sizeof("HN")-1}, PVT_OTHER, pv_get_hn, 0,
|
|
|
pv_parse_hn_name, 0, 0, 0 },
|
|
|
{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
|
|
@@ -106,34 +110,36 @@ static pv_export_t mod_pvs[] = {
|
|
|
*/
|
|
|
static cmd_export_t cmds[] =
|
|
|
{
|
|
|
- { "is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, fixup_spve_spve, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, 0,
|
|
|
- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
- { "dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, fixup_spve_spve, 0,
|
|
|
- ANY_ROUTE },
|
|
|
- { "dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, fixup_spve_spve, 0,
|
|
|
- ANY_ROUTE },
|
|
|
- { "dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, 0,
|
|
|
- ANY_ROUTE },
|
|
|
- { "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0},
|
|
|
- { 0, 0, 0, 0, 0, 0 }
|
|
|
+ { "is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, fixup_spve_spve, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "is_in_subnet", (cmd_function)w_ip_is_in_subnet, 2, fixup_spve_spve, 0,
|
|
|
+ REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
|
|
|
+ { "dns_sys_match_ip", (cmd_function)w_dns_sys_match_ip, 2, fixup_spve_spve, 0,
|
|
|
+ ANY_ROUTE },
|
|
|
+ { "dns_int_match_ip", (cmd_function)w_dns_int_match_ip, 2, fixup_spve_spve, 0,
|
|
|
+ ANY_ROUTE },
|
|
|
+ { "dns_query", (cmd_function)w_dns_query, 2, fixup_spve_spve, 0,
|
|
|
+ ANY_ROUTE },
|
|
|
+ { "srv_query", (cmd_function)w_srv_query, 2, fixup_spve_spve, 0,
|
|
|
+ ANY_ROUTE },
|
|
|
+ { "bind_ipops", (cmd_function)bind_ipops, 0, 0, 0, 0},
|
|
|
+ { 0, 0, 0, 0, 0, 0 }
|
|
|
};
|
|
|
|
|
|
|
|
@@ -141,18 +147,18 @@ static cmd_export_t cmds[] =
|
|
|
* Module interface
|
|
|
*/
|
|
|
struct module_exports exports = {
|
|
|
- "ipops", /*!< module name */
|
|
|
- DEFAULT_DLFLAGS, /*!< dlopen flags */
|
|
|
- cmds, /*!< exported functions */
|
|
|
- 0, /*!< exported parameters */
|
|
|
- 0, /*!< exported statistics */
|
|
|
- 0, /*!< exported MI functions */
|
|
|
- mod_pvs, /*!< exported pseudo-variables */
|
|
|
- 0, /*!< extra processes */
|
|
|
- 0, /*!< module initialization function */
|
|
|
- (response_function) 0, /*!< response handling function */
|
|
|
- 0, /*!< destroy function */
|
|
|
- 0 /*!< per-child init function */
|
|
|
+ "ipops", /*!< module name */
|
|
|
+ DEFAULT_DLFLAGS, /*!< dlopen flags */
|
|
|
+ cmds, /*!< exported functions */
|
|
|
+ 0, /*!< exported parameters */
|
|
|
+ 0, /*!< exported statistics */
|
|
|
+ 0, /*!< exported MI functions */
|
|
|
+ mod_pvs, /*!< exported pseudo-variables */
|
|
|
+ 0, /*!< extra processes */
|
|
|
+ 0, /*!< module initialization function */
|
|
|
+ (response_function) 0, /*!< response handling function */
|
|
|
+ 0, /*!< destroy function */
|
|
|
+ 0 /*!< per-child init function */
|
|
|
};
|
|
|
|
|
|
|
|
@@ -163,97 +169,97 @@ struct module_exports exports = {
|
|
|
/*! \brief Return 1 if both pure IP's are equal, 0 otherwise. */
|
|
|
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)
|
|
|
{
|
|
|
- struct in_addr in_addr1, in_addr2;
|
|
|
- struct in6_addr in6_addr1, in6_addr2;
|
|
|
- char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
|
|
|
-
|
|
|
- // Not same IP type, return false.
|
|
|
- if (ip1_type != ip2_type)
|
|
|
- return 0;
|
|
|
-
|
|
|
- memcpy(_ip1, ip1, len1);
|
|
|
- _ip1[len1] = '\0';
|
|
|
- memcpy(_ip2, ip2, len2);
|
|
|
- _ip2[len2] = '\0';
|
|
|
-
|
|
|
- switch(ip1_type) {
|
|
|
- // Comparing IPv4 with IPv4.
|
|
|
- case(ip_type_ipv4):
|
|
|
- if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
|
|
|
- if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
|
|
|
- if (in_addr1.s_addr == in_addr2.s_addr)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- // Comparing IPv6 with IPv6.
|
|
|
- case(ip_type_ipv6):
|
|
|
- if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
|
|
|
- if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
|
|
|
- if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- }
|
|
|
+ struct in_addr in_addr1, in_addr2;
|
|
|
+ struct in6_addr in6_addr1, in6_addr2;
|
|
|
+ char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
|
|
|
+
|
|
|
+ // Not same IP type, return false.
|
|
|
+ if (ip1_type != ip2_type)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy(_ip1, ip1, len1);
|
|
|
+ _ip1[len1] = '\0';
|
|
|
+ memcpy(_ip2, ip2, len2);
|
|
|
+ _ip2[len2] = '\0';
|
|
|
+
|
|
|
+ switch(ip1_type) {
|
|
|
+ // Comparing IPv4 with IPv4.
|
|
|
+ case(ip_type_ipv4):
|
|
|
+ if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
|
|
|
+ if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
|
|
|
+ if (in_addr1.s_addr == in_addr2.s_addr)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ // Comparing IPv6 with IPv6.
|
|
|
+ case(ip_type_ipv6):
|
|
|
+ if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
|
|
|
+ if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
|
|
|
+ if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*! \brief Return 1 if IP1 is in the subnet given by IP2 and the netmask, 0 otherwise. */
|
|
|
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)
|
|
|
{
|
|
|
- struct in_addr in_addr1, in_addr2;
|
|
|
- struct in6_addr in6_addr1, in6_addr2;
|
|
|
- char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
|
|
|
- uint32_t ipv4_mask;
|
|
|
- uint8_t ipv6_mask[16];
|
|
|
- int i;
|
|
|
-
|
|
|
- // Not same IP type, return false.
|
|
|
- if (ip1_type != ip2_type)
|
|
|
- return 0;
|
|
|
-
|
|
|
- memcpy(_ip1, ip1, len1);
|
|
|
- _ip1[len1] = '\0';
|
|
|
- memcpy(_ip2, ip2, len2);
|
|
|
- _ip2[len2] = '\0';
|
|
|
-
|
|
|
- switch(ip1_type) {
|
|
|
- // Comparing IPv4 with IPv4.
|
|
|
- case(ip_type_ipv4):
|
|
|
- if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
|
|
|
- if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
|
|
|
- if (netmask <0 || netmask > 32) return 0;
|
|
|
- if (netmask == 32) ipv4_mask = 0xFFFFFFFF;
|
|
|
- else ipv4_mask = htonl(~(0xFFFFFFFF >> netmask));
|
|
|
- if ((in_addr1.s_addr & ipv4_mask) == in_addr2.s_addr)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- // Comparing IPv6 with IPv6.
|
|
|
- case(ip_type_ipv6):
|
|
|
- if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
|
|
|
- if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
|
|
|
- if (netmask <0 || netmask > 128) return 0;
|
|
|
- for (i=0; i<16; i++)
|
|
|
- {
|
|
|
- if (netmask > ((i+1)*8)) ipv6_mask[i] = 0xFF;
|
|
|
- else if (netmask > (i*8)) ipv6_mask[i] = ~(0xFF >> (netmask-(i*8)));
|
|
|
- else ipv6_mask[i] = 0x00;
|
|
|
- }
|
|
|
- for (i=0; i<16; i++) in6_addr1.s6_addr[i] &= ipv6_mask[i];
|
|
|
- if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- }
|
|
|
+ struct in_addr in_addr1, in_addr2;
|
|
|
+ struct in6_addr in6_addr1, in6_addr2;
|
|
|
+ char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
|
|
|
+ uint32_t ipv4_mask;
|
|
|
+ uint8_t ipv6_mask[16];
|
|
|
+ int i;
|
|
|
+
|
|
|
+ // Not same IP type, return false.
|
|
|
+ if (ip1_type != ip2_type)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy(_ip1, ip1, len1);
|
|
|
+ _ip1[len1] = '\0';
|
|
|
+ memcpy(_ip2, ip2, len2);
|
|
|
+ _ip2[len2] = '\0';
|
|
|
+
|
|
|
+ switch(ip1_type) {
|
|
|
+ // Comparing IPv4 with IPv4.
|
|
|
+ case(ip_type_ipv4):
|
|
|
+ if (inet_pton(AF_INET, _ip1, &in_addr1) == 0) return 0;
|
|
|
+ if (inet_pton(AF_INET, _ip2, &in_addr2) == 0) return 0;
|
|
|
+ if (netmask <0 || netmask > 32) return 0;
|
|
|
+ if (netmask == 32) ipv4_mask = 0xFFFFFFFF;
|
|
|
+ else ipv4_mask = htonl(~(0xFFFFFFFF >> netmask));
|
|
|
+ if ((in_addr1.s_addr & ipv4_mask) == in_addr2.s_addr)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ // Comparing IPv6 with IPv6.
|
|
|
+ case(ip_type_ipv6):
|
|
|
+ if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1) return 0;
|
|
|
+ if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1) return 0;
|
|
|
+ if (netmask <0 || netmask > 128) return 0;
|
|
|
+ for (i=0; i<16; i++)
|
|
|
+ {
|
|
|
+ if (netmask > ((i+1)*8)) ipv6_mask[i] = 0xFF;
|
|
|
+ else if (netmask > (i*8)) ipv6_mask[i] = ~(0xFF >> (netmask-(i*8)));
|
|
|
+ else ipv6_mask[i] = 0x00;
|
|
|
+ }
|
|
|
+ for (i=0; i<16; i++) in6_addr1.s6_addr[i] &= ipv6_mask[i];
|
|
|
+ if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -265,358 +271,358 @@ int _ip_is_in_subnet(char *ip1, size_t len1, enum enum_ip_type ip1_type, char *i
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid IPv4, IPv6 or IPv6 reference. */
|
|
|
static int w_is_ip(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (ip_parser_execute(string.s, string.len) != ip_type_error)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ip_parser_execute(string.s, string.len) != ip_type_error)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid IPv4 or IPv6. */
|
|
|
static int w_is_pure_ip(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- switch(ip_parser_execute(string.s, string.len)) {
|
|
|
- case(ip_type_ipv4):
|
|
|
- return 1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6):
|
|
|
- return 1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- }
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(ip_parser_execute(string.s, string.len)) {
|
|
|
+ case(ip_type_ipv4):
|
|
|
+ return 1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6):
|
|
|
+ return 1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid IPv4. */
|
|
|
static int w_is_ipv4(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (ip_parser_execute(string.s, string.len) == ip_type_ipv4)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ip_parser_execute(string.s, string.len) == ip_type_ipv4)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid IPv6. */
|
|
|
static int w_is_ipv6(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (ip_parser_execute(string.s, string.len) == ip_type_ipv6)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ip_parser_execute(string.s, string.len) == ip_type_ipv6)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid IPv6 reference. */
|
|
|
static int w_is_ipv6_reference(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (ip_parser_execute(string.s, string.len) == ip_type_ipv6_reference)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ip_parser_execute(string.s, string.len) == ip_type_ipv6_reference)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return the IP type of the given argument (string or pv): 1 = IPv4, 2 = IPv6, 3 = IPv6 refenrece, -1 = invalid IP. */
|
|
|
static int w_ip_type(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- switch (ip_parser_execute(string.s, string.len)) {
|
|
|
- case(ip_type_ipv4):
|
|
|
- return 1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6):
|
|
|
- return 2;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- return 3;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- }
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (ip_parser_execute(string.s, string.len)) {
|
|
|
+ case(ip_type_ipv4):
|
|
|
+ return 1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6):
|
|
|
+ return 2;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ return 3;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if both IP's (string or pv) are equal. This function also allows comparing an IPv6 with an IPv6 reference. */
|
|
|
static int w_compare_ips(struct sip_msg* _msg, char* _s1, char* _s2)
|
|
|
{
|
|
|
- str string1, string2;
|
|
|
- enum enum_ip_type ip1_type, ip2_type;
|
|
|
-
|
|
|
- if (_s1 == NULL || _s2 == NULL ) {
|
|
|
- LM_ERR("bad parameters\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for first string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for second string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- string1.s += 1;
|
|
|
- string1.len -= 2;
|
|
|
- ip1_type = ip_type_ipv6;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- string2.s += 1;
|
|
|
- string2.len -= 2;
|
|
|
- ip2_type = ip_type_ipv6;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string1, string2;
|
|
|
+ enum enum_ip_type ip1_type, ip2_type;
|
|
|
+
|
|
|
+ if (_s1 == NULL || _s2 == NULL ) {
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for first string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for second string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ string1.s += 1;
|
|
|
+ string1.len -= 2;
|
|
|
+ ip1_type = ip_type_ipv6;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ string2.s += 1;
|
|
|
+ string2.len -= 2;
|
|
|
+ ip2_type = ip_type_ipv6;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if both pure IP's (string or pv) are equal. IPv6 references not allowed. */
|
|
|
static int w_compare_pure_ips(struct sip_msg* _msg, char* _s1, char* _s2)
|
|
|
{
|
|
|
- str string1, string2;
|
|
|
- enum enum_ip_type ip1_type, ip2_type;
|
|
|
-
|
|
|
- if (_s1 == NULL || _s2 == NULL ) {
|
|
|
- LM_ERR("bad parameters\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for first string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for second string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string1, string2;
|
|
|
+ enum enum_ip_type ip1_type, ip2_type;
|
|
|
+
|
|
|
+ if (_s1 == NULL || _s2 == NULL ) {
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for first string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for second string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \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. */
|
|
|
static int w_ip_is_in_subnet(struct sip_msg* _msg, char* _s1, char* _s2)
|
|
|
{
|
|
|
- str string1, string2;
|
|
|
- enum enum_ip_type ip1_type, ip2_type;
|
|
|
- char *cidr_pos = NULL;
|
|
|
- int netmask = 0;
|
|
|
-
|
|
|
- if (_s1 == NULL || _s2 == NULL ) {
|
|
|
- LM_ERR("bad parameters\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for first string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for second string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- cidr_pos = string2.s + string2.len - 1;
|
|
|
- while (cidr_pos > string2.s)
|
|
|
- {
|
|
|
- if (*cidr_pos == '/')
|
|
|
- {
|
|
|
- string2.len = (cidr_pos - string2.s);
|
|
|
- netmask = atoi(cidr_pos+1);
|
|
|
- break;
|
|
|
- }
|
|
|
- cidr_pos--;
|
|
|
- }
|
|
|
- switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
- case(ip_type_error):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- case(ip_type_ipv6_reference):
|
|
|
- return -1;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (netmask == 0)
|
|
|
- {
|
|
|
- if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (_ip_is_in_subnet(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type, netmask))
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ str string1, string2;
|
|
|
+ enum enum_ip_type ip1_type, ip2_type;
|
|
|
+ char *cidr_pos = NULL;
|
|
|
+ int netmask = 0;
|
|
|
+
|
|
|
+ if (_s1 == NULL || _s2 == NULL ) {
|
|
|
+ LM_ERR("bad parameters\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for first string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for second string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ cidr_pos = string2.s + string2.len - 1;
|
|
|
+ while (cidr_pos > string2.s)
|
|
|
+ {
|
|
|
+ if (*cidr_pos == '/')
|
|
|
+ {
|
|
|
+ string2.len = (cidr_pos - string2.s);
|
|
|
+ netmask = atoi(cidr_pos+1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ cidr_pos--;
|
|
|
+ }
|
|
|
+ switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
|
|
|
+ case(ip_type_error):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ case(ip_type_ipv6_reference):
|
|
|
+ return -1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (netmask == 0)
|
|
|
+ {
|
|
|
+ if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (_ip_is_in_subnet(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type, netmask))
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
/*! \brief Return true if the given argument (string or pv) is a valid RFC 1918 IPv4 (private address). */
|
|
|
static int w_is_ip_rfc1918(struct sip_msg* _msg, char* _s)
|
|
|
{
|
|
|
- str string;
|
|
|
-
|
|
|
- if (_s == NULL) {
|
|
|
- LM_ERR("bad parameter\n");
|
|
|
- return -2;
|
|
|
- }
|
|
|
-
|
|
|
- if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
- {
|
|
|
- LM_ERR("cannot print the format for string\n");
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- if (rfc1918_parser_execute(string.s, string.len) == 1)
|
|
|
- return 1;
|
|
|
- else
|
|
|
- return -1;
|
|
|
+ str string;
|
|
|
+
|
|
|
+ if (_s == NULL) {
|
|
|
+ LM_ERR("bad parameter\n");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
|
|
|
+ {
|
|
|
+ LM_ERR("cannot print the format for string\n");
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rfc1918_parser_execute(string.s, string.len) == 1)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
static inline ip_addr_t *strtoipX(str *ips)
|
|
@@ -669,9 +675,9 @@ static int w_dns_sys_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
|
|
|
|
|
|
if ((status = getaddrinfo(hns.s, NULL, &hints, &res)) != 0)
|
|
|
{
|
|
|
- LM_ERR("getaddrinfo: %s\n", gai_strerror(status));
|
|
|
- return -4;
|
|
|
- }
|
|
|
+ LM_ERR("getaddrinfo: %s\n", gai_strerror(status));
|
|
|
+ return -4;
|
|
|
+ }
|
|
|
|
|
|
for(p = res;p != NULL; p = p->ai_next)
|
|
|
{
|
|
@@ -692,7 +698,7 @@ static int w_dns_sys_match_ip(sip_msg_t *msg, char *hnp, char *ipp)
|
|
|
return 1;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
freeaddrinfo(res);
|
|
|
|
|
|
return -1;
|
|
@@ -773,3 +779,31 @@ static int w_dns_query(struct sip_msg* msg, char* str1, char* str2)
|
|
|
|
|
|
return dns_update_pv(&hostname, &name);
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+static int w_srv_query(struct sip_msg* msg, char* str1, char* str2)
|
|
|
+{
|
|
|
+ str srvcname;
|
|
|
+ str name;
|
|
|
+
|
|
|
+ if(msg==NULL)
|
|
|
+ {
|
|
|
+ LM_ERR("received null msg\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(fixup_get_svalue(msg, (gparam_t*)str1, &srvcname)<0)
|
|
|
+ {
|
|
|
+ LM_ERR("cannot get the srvcname\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(fixup_get_svalue(msg, (gparam_t*)str2, &name)<0)
|
|
|
+ {
|
|
|
+ LM_ERR("cannot get the pvid name\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return srv_update_pv(&srvcname, &name);
|
|
|
+}
|