1.1 --- a/opensips/modules/enum/enum.c Wed Feb 10 21:25:01 2010 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,1196 +0,0 @@ 1.4 -/* 1.5 - * $Id: enum.c 5901 2009-07-21 07:45:05Z bogdan_iancu $ 1.6 - * 1.7 - * Enum and E164 related functions 1.8 - * 1.9 - * Copyright (C) 2002-2008 Juha Heinanen 1.10 - * 1.11 - * This file is part of opensips, a free SIP server. 1.12 - * 1.13 - * opensips is free software; you can redistribute it and/or modify 1.14 - * it under the terms of the GNU General Public License as published by 1.15 - * the Free Software Foundation; either version 2 of the License, or 1.16 - * (at your option) any later version 1.17 - * 1.18 - * opensips is distributed in the hope that it will be useful, 1.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.21 - * GNU General Public License for more details. 1.22 - * 1.23 - * You should have received a copy of the GNU General Public License 1.24 - * along with this program; if not, write to the Free Software 1.25 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.26 - * 1.27 - */ 1.28 - 1.29 -#include <stdlib.h> 1.30 - 1.31 -#include "enum.h" 1.32 -#include "../../parser/parse_uri.h" 1.33 -#include "../../parser/parse_from.h" 1.34 -#include "../../ut.h" 1.35 -#include "../../resolve.h" 1.36 -#include "../../mem/mem.h" 1.37 -#include "../../dset.h" 1.38 -#include "../../qvalue.h" 1.39 -#include "enum_mod.h" 1.40 -#include "../../regexp.h" 1.41 -#include "../../pvar.h" 1.42 - 1.43 -/* 1.44 - * Input: E.164 number w/o leading + 1.45 - * 1.46 - * Output: number of digits in the country code 1.47 - * 0 on invalid number 1.48 - * 1.49 - * convention: 1.50 - * 3 digits is the default length of a country code. 1.51 - * country codes 1 and 7 are a single digit. 1.52 - * the following country codes are two digits: 20, 27, 30-34, 36, 39, 1.53 - * 40, 41, 43-49, 51-58, 60-66, 81, 82, 84, 86, 90-95, 98. 1.54 - */ 1.55 -static int cclen(const char *number) 1.56 -{ 1.57 - char d1,d2; 1.58 - 1.59 - if (!number || (strlen(number) < 3)) 1.60 - return(0); 1.61 - 1.62 - d1 = number[0]; 1.63 - d2 = number[1]; 1.64 - 1.65 - if (!isdigit((int)d2)) 1.66 - return(0); 1.67 - 1.68 - switch(d1) { 1.69 - case '1': 1.70 - case '7': 1.71 - return(1); 1.72 - case '2': 1.73 - if ((d2 == '0') || (d1 == '7')) 1.74 - return(2); 1.75 - break; 1.76 - case '3': 1.77 - if ((d2 >= '0') && (d1 <= '4')) 1.78 - return(2); 1.79 - if ((d2 == '6') || (d1 == '9')) 1.80 - return(2); 1.81 - break; 1.82 - case '4': 1.83 - if (d2 != '2') 1.84 - return(2); 1.85 - break; 1.86 - case '5': 1.87 - if ((d2 >= '1') && (d1 <= '8')) 1.88 - return(2); 1.89 - break; 1.90 - case '6': 1.91 - if (d1 <= '6') 1.92 - return(2); 1.93 - break; 1.94 - case '8': 1.95 - if ((d2 == '1') || (d1 == '2') || (d1 == '4') || (d1 == '6')) 1.96 - return(2); 1.97 - break; 1.98 - case '9': 1.99 - if (d1 <= '5') 1.100 - return(2); 1.101 - if (d2 == '8') 1.102 - return(2); 1.103 - break; 1.104 - default: 1.105 - return(0); 1.106 - } 1.107 - 1.108 - return(3); 1.109 -} 1.110 - 1.111 - 1.112 - 1.113 -/* return the length of the string until c, if not found returns n */ 1.114 -static inline int findchr(char* p, int c, unsigned int size) 1.115 -{ 1.116 - int len=0; 1.117 - 1.118 - for(;len<size;p++){ 1.119 - if (*p==(unsigned char)c) { 1.120 - return len; 1.121 - } 1.122 - len++; 1.123 - } 1.124 - return len; 1.125 -} 1.126 - 1.127 - 1.128 -/* Parse NAPTR regexp field of the form !pattern!replacement! and return its 1.129 - * components in pattern and replacement parameters. Regexp field starts at 1.130 - * address first and is len characters long. 1.131 - */ 1.132 -static inline int parse_naptr_regexp(char* first, int len, str* pattern, 1.133 - str* replacement) 1.134 -{ 1.135 - char *second, *third; 1.136 - 1.137 - if (len > 0) { 1.138 - if (*first == '!') { 1.139 - second = (char *)memchr((void *)(first + 1), '!', len - 1); 1.140 - if (second) { 1.141 - len = len - (second - first + 1); 1.142 - if (len > 0) { 1.143 - third = memchr(second + 1, '!', len); 1.144 - if (third) { 1.145 - pattern->len = second - first - 1; 1.146 - pattern->s = first + 1; 1.147 - replacement->len = third - second - 1; 1.148 - replacement->s = second + 1; 1.149 - return 1; 1.150 - } else { 1.151 - LM_ERR("Third ! missing from regexp\n"); 1.152 - return -1; 1.153 - } 1.154 - } else { 1.155 - LM_ERR("Third ! missing from regexp\n"); 1.156 - return -2; 1.157 - } 1.158 - } else { 1.159 - LM_ERR("Second ! missing from regexp\n"); 1.160 - return -3; 1.161 - } 1.162 - } else { 1.163 - LM_ERR("First ! missing from regexp\n"); 1.164 - return -4; 1.165 - } 1.166 - } else { 1.167 - LM_ERR("Regexp missing\n"); 1.168 - return -5; 1.169 - } 1.170 -} 1.171 -/* Checks if NAPTR record has flag u and its services field 1.172 - * e2u+[service:]sip or 1.173 - * e2u+service[+service[+service[+...]]] 1.174 - */ 1.175 -static inline int sip_match( struct naptr_rdata* naptr, str* service) 1.176 -{ 1.177 - if (service->len == 0) { 1.178 - return (naptr->flags_len == 1) && 1.179 - ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) && 1.180 - (naptr->services_len == 7) && 1.181 - ((strncasecmp(naptr->services, "e2u+sip", 7) == 0) || 1.182 - (strncasecmp(naptr->services, "sip+e2u", 7) == 0)); 1.183 - } else if (service->s[0] != '+') { 1.184 - return (naptr->flags_len == 1) && 1.185 - ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) && 1.186 - (naptr->services_len == service->len + 8) && 1.187 - (strncasecmp(naptr->services, "e2u+", 4) == 0) && 1.188 - (strncasecmp(naptr->services + 4, service->s, service->len) == 0) && 1.189 - (strncasecmp(naptr->services + 4 + service->len, ":sip", 4) == 0); 1.190 - } else { /* handle compound NAPTRs and multiple services */ 1.191 - str bakservice, baknaptr; /* we bakup the str */ 1.192 - int naptrlen, len; /* length of the extracted service */ 1.193 - 1.194 - /* RFC 3761, NAPTR service field must start with E2U+ */ 1.195 - if (strncasecmp(naptr->services, "e2u+", 4) != 0) { 1.196 - return 0; 1.197 - } 1.198 - baknaptr.s = naptr->services + 4; /* leading 'e2u+' */ 1.199 - baknaptr.len = naptr->services_len - 4; 1.200 - for (;;) { /* iterate over services in NAPTR */ 1.201 - bakservice.s = service->s + 1; /* leading '+' */ 1.202 - bakservice.len = service->len - 1; 1.203 - naptrlen = findchr(baknaptr.s,'+',baknaptr.len); 1.204 - 1.205 - for (;;) { /* iterate over services in enum_query */ 1.206 - len = findchr(bakservice.s,'+',bakservice.len); 1.207 - if ((naptrlen == len ) && !strncasecmp(baknaptr.s, bakservice.s, len)){ 1.208 - return 1; 1.209 - } 1.210 - if ( (bakservice.len -= len+1) > 0) { 1.211 - bakservice.s += len+1; 1.212 - continue; 1.213 - } 1.214 - break; 1.215 - } 1.216 - if ( (baknaptr.len -= naptrlen+1) > 0) { 1.217 - baknaptr.s += naptrlen+1; 1.218 - continue; 1.219 - } 1.220 - break; 1.221 - } 1.222 - /* no matching service found */ 1.223 - return 0; 1.224 - } 1.225 -} 1.226 - 1.227 - 1.228 -/* 1.229 - * Checks if argument is an e164 number starting with + 1.230 - */ 1.231 -static inline int is_e164(str* _user) 1.232 -{ 1.233 - int i; 1.234 - char c; 1.235 - 1.236 - if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) { 1.237 - for (i = 1; i < _user->len; i++) { 1.238 - c = (_user->s)[i]; 1.239 - if ((c < '0') || (c > '9')) return -1; 1.240 - } 1.241 - return 1; 1.242 - } else { 1.243 - return -1; 1.244 - } 1.245 -} 1.246 - 1.247 - 1.248 -/* 1.249 - * Call is_from_user_enum_2 with module parameter suffix and default service. 1.250 - */ 1.251 -int is_from_user_enum_0(struct sip_msg* _msg, char* _str1, char* _str2) 1.252 -{ 1.253 - return is_from_user_enum_2(_msg, (char *)(&suffix), (char *)(&service)); 1.254 -} 1.255 - 1.256 -/* 1.257 - * Call is_from_user_enum_2 with given suffix and default service. 1.258 - */ 1.259 -int is_from_user_enum_1(struct sip_msg* _msg, char* _suffix, char* _str2) 1.260 -{ 1.261 - return is_from_user_enum_2(_msg, _suffix, (char *)(&service)); 1.262 -} 1.263 - 1.264 -/* 1.265 - * Check if from user is a valid enum based user, and check to make sure 1.266 - * that the src_ip == an srv record that maps to the enum from user. 1.267 - */ 1.268 -int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service) 1.269 -{ 1.270 - struct ip_addr addr; 1.271 - struct hostent* he; 1.272 - unsigned short zp; 1.273 - unsigned short proto; 1.274 - char *user_s; 1.275 - int user_len, i, j; 1.276 - char name[MAX_DOMAIN_SIZE]; 1.277 - char uri[MAX_URI_SIZE]; 1.278 - struct sip_uri *furi; 1.279 - struct sip_uri luri; 1.280 - struct rdata* head; 1.281 - 1.282 - str* suffix; 1.283 - str* service; 1.284 - 1.285 - struct rdata* l; 1.286 - struct naptr_rdata* naptr; 1.287 - 1.288 - str pattern, replacement, result; 1.289 - char string[17]; 1.290 - 1.291 - if (parse_from_header(_msg) < 0) { 1.292 - LM_ERR("Failed to parse From header\n"); 1.293 - return -1; 1.294 - } 1.295 - 1.296 - if(_msg->from==NULL || get_from(_msg)==NULL) { 1.297 - LM_DBG("No From header\n"); 1.298 - return -1; 1.299 - } 1.300 - 1.301 - if ((furi = parse_from_uri(_msg)) == NULL) { 1.302 - LM_ERR("Failed to parse From URI\n"); 1.303 - return -1; 1.304 - } 1.305 - 1.306 - suffix = (str*)_suffix; 1.307 - service = (str*)_service; 1.308 - 1.309 - if (is_e164(&(furi->user)) == -1) { 1.310 - LM_ERR("From URI user is not an E164 number\n"); 1.311 - return -1; 1.312 - } 1.313 - 1.314 - /* assert: the from user is a valid formatted e164 string */ 1.315 - 1.316 - user_s = furi->user.s; 1.317 - user_len = furi->user.len; 1.318 - 1.319 - j = 0; 1.320 - for (i = user_len - 1; i > 0; i--) { 1.321 - name[j] = user_s[i]; 1.322 - name[j + 1] = '.'; 1.323 - j = j + 2; 1.324 - } 1.325 - 1.326 - memcpy(name + j, suffix->s, suffix->len + 1); 1.327 - 1.328 - head = get_record(name, T_NAPTR); 1.329 - 1.330 - if (head == 0) { 1.331 - LM_DBG("No NAPTR record found for %s.\n", name); 1.332 - return -3; 1.333 - } 1.334 - 1.335 - /* we have the naptr records, loop and find an srv record with */ 1.336 - /* same ip address as source ip address, if we do then true is returned */ 1.337 - 1.338 - for (l = head; l; l = l->next) { 1.339 - 1.340 - if (l->type != T_NAPTR) continue; /*should never happen*/ 1.341 - naptr = (struct naptr_rdata*)l->rdata; 1.342 - if (naptr == 0) { 1.343 - LM_ERR("Null rdata in DNS response\n"); 1.344 - free_rdata_list(head); 1.345 - return -4; 1.346 - } 1.347 - 1.348 - LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags " 1.349 - "'%.*s', slen %u, services '%.*s', rlen %u, " 1.350 - "regexp '%.*s'\n", 1.351 - name, naptr->order, naptr->pref, 1.352 - naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len, 1.353 - (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, 1.354 - (int)(naptr->regexp_len), ZSW(naptr->regexp)); 1.355 - 1.356 - if (sip_match(naptr, service) != 0) { 1.357 - if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, 1.358 - &pattern, &replacement) < 0) { 1.359 - free_rdata_list(head); /*clean up*/ 1.360 - LM_ERR("Parsing of NAPTR regexp failed\n"); 1.361 - return -5; 1.362 - } 1.363 -#ifdef LATER 1.364 - if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) { 1.365 - LM_DBG("Resulted in replacement: '%.*s'\n", 1.366 - replacement.len, ZSW(replacement.s)); 1.367 - retval = set_uri(_msg, replacement.s, replacement.len); 1.368 - free_rdata_list(head); /*clean up*/ 1.369 - return retval; 1.370 - } 1.371 -#endif 1.372 - result.s = &(uri[0]); 1.373 - result.len = MAX_URI_SIZE; 1.374 - /* Avoid making copies of pattern and replacement */ 1.375 - pattern.s[pattern.len] = (char)0; 1.376 - replacement.s[replacement.len] = (char)0; 1.377 - /* We have already checked the size of 1.378 - _msg->parsed_uri.user.s */ 1.379 - memcpy(&(string[0]), user_s, user_len); 1.380 - string[user_len] = (char)0; 1.381 - if (reg_replace(pattern.s, replacement.s, &(string[0]), 1.382 - &result) < 0) { 1.383 - pattern.s[pattern.len] = '!'; 1.384 - replacement.s[replacement.len] = '!'; 1.385 - LM_ERR("Regexp replace failed\n"); 1.386 - free_rdata_list(head); /*clean up*/ 1.387 - return -6; 1.388 - } 1.389 - LM_DBG("Resulted in replacement: '%.*s'\n", 1.390 - result.len, ZSW(result.s)); 1.391 - 1.392 - if(parse_uri(result.s, result.len, &luri) < 0) 1.393 - { 1.394 - LM_ERR("Parsing of URI <%.*s> failed\n", 1.395 - result.len, result.s); 1.396 - free_rdata_list(head); /*clean up*/ 1.397 - return -7; 1.398 - } 1.399 - 1.400 - pattern.s[pattern.len] = '!'; 1.401 - replacement.s[replacement.len] = '!'; 1.402 - 1.403 - zp = 0; 1.404 - proto = PROTO_NONE; 1.405 - he = sip_resolvehost(&luri.host, &zp, &proto, 1.406 - (luri.type==SIPS_URI_T)?1:0 , 0); 1.407 - 1.408 - hostent2ip_addr(&addr, he, 0); 1.409 - 1.410 - if(ip_addr_cmp(&addr, &_msg->rcv.src_ip)) 1.411 - { 1.412 - free_rdata_list(head); 1.413 - return(1); 1.414 - } 1.415 - } 1.416 - } 1.417 - free_rdata_list(head); /*clean up*/ 1.418 - LM_DBG("FAIL\n"); 1.419 - 1.420 - /* must not have found the record */ 1.421 - return(-8); 1.422 -} 1.423 - 1.424 - 1.425 - 1.426 -/* 1.427 - * Add parameter to URI. 1.428 - */ 1.429 -int add_uri_param(str *uri, str *param, str *new_uri) 1.430 -{ 1.431 - struct sip_uri puri; 1.432 - char *at; 1.433 - 1.434 - if (parse_uri(uri->s, uri->len, &puri) < 0) { 1.435 - return 0; 1.436 - } 1.437 - 1.438 - /* if current uri has no headers, pad param to the end of uri */ 1.439 - if (puri.headers.len == 0) { 1.440 - memcpy(uri->s + uri->len, param->s, param->len); 1.441 - uri->len = uri->len + param->len; 1.442 - new_uri->len = 0; 1.443 - return 1; 1.444 - } 1.445 - 1.446 - /* otherwise take the long path and create new_uri */ 1.447 - at = new_uri->s; 1.448 - switch (puri.type) { 1.449 - case SIP_URI_T: 1.450 - memcpy(at, "sip:", 4); 1.451 - at = at + 4; 1.452 - break; 1.453 - case SIPS_URI_T: 1.454 - memcpy(at, "sips:", 5); 1.455 - at = at + 5; 1.456 - break; 1.457 - case TEL_URI_T: 1.458 - memcpy(at, "tel:", 4); 1.459 - at = at + 4; 1.460 - break; 1.461 - case TELS_URI_T: 1.462 - memcpy(at, "tels:", 5); 1.463 - at = at + 5; 1.464 - break; 1.465 - default: 1.466 - LM_ERR("Unknown URI scheme <%d>\n", puri.type); 1.467 - return 0; 1.468 - } 1.469 - if (puri.user.len) { 1.470 - memcpy(at, puri.user.s, puri.user.len); 1.471 - at = at + puri.user.len; 1.472 - if (puri.passwd.len) { 1.473 - *at = ':'; 1.474 - at = at + 1; 1.475 - memcpy(at, puri.passwd.s, puri.passwd.len); 1.476 - at = at + puri.passwd.len; 1.477 - }; 1.478 - *at = '@'; 1.479 - at = at + 1; 1.480 - } 1.481 - memcpy(at, puri.host.s, puri.host.len); 1.482 - at = at + puri.host.len; 1.483 - if (puri.port.len) { 1.484 - *at = ':'; 1.485 - at = at + 1; 1.486 - memcpy(at, puri.port.s, puri.port.len); 1.487 - at = at + puri.port.len; 1.488 - } 1.489 - if (puri.params.len) { 1.490 - *at = ';'; 1.491 - at = at + 1; 1.492 - memcpy(at, puri.params.s, puri.params.len); 1.493 - at = at + puri.params.len; 1.494 - } 1.495 - memcpy(at, param->s, param->len); 1.496 - at = at + param->len; 1.497 - *at = '?'; 1.498 - at = at + 1; 1.499 - memcpy(at, puri.headers.s, puri.headers.len); 1.500 - at = at + puri.headers.len; 1.501 - new_uri->len = at - new_uri->s; 1.502 - return 1; 1.503 -} 1.504 - 1.505 -/* 1.506 - * Tests if one result record is "greater" that the other. Non-NAPTR records 1.507 - * greater that NAPTR record. An invalid NAPTR record is greater than a 1.508 - * valid one. Valid NAPTR records are compared based on their 1.509 - * (order,preference). 1.510 - */ 1.511 -static inline int naptr_greater(struct rdata* a, struct rdata* b) 1.512 -{ 1.513 - struct naptr_rdata *na, *nb; 1.514 - 1.515 - if (a->type != T_NAPTR) return 1; 1.516 - if (b->type != T_NAPTR) return 0; 1.517 - 1.518 - na = (struct naptr_rdata*)a->rdata; 1.519 - if (na == 0) return 1; 1.520 - 1.521 - nb = (struct naptr_rdata*)b->rdata; 1.522 - if (nb == 0) return 0; 1.523 - 1.524 - return (((na->order) << 16) + na->pref) > 1.525 - (((nb->order) << 16) + nb->pref); 1.526 -} 1.527 - 1.528 - 1.529 -/* 1.530 - * Bubble sorts result record list according to naptr (order,preference). 1.531 - */ 1.532 -static inline void naptr_sort(struct rdata** head) 1.533 -{ 1.534 - struct rdata *p, *q, *r, *s, *temp, *start; 1.535 - 1.536 - /* r precedes p and s points to the node up to which comparisons 1.537 - are to be made */ 1.538 - 1.539 - s = NULL; 1.540 - start = *head; 1.541 - while ( s != start -> next ) { 1.542 - r = p = start ; 1.543 - q = p -> next ; 1.544 - while ( p != s ) { 1.545 - if ( naptr_greater(p, q) ) { 1.546 - if ( p == start ) { 1.547 - temp = q -> next ; 1.548 - q -> next = p ; 1.549 - p -> next = temp ; 1.550 - start = q ; 1.551 - r = q ; 1.552 - } else { 1.553 - temp = q -> next ; 1.554 - q -> next = p ; 1.555 - p -> next = temp ; 1.556 - r -> next = q ; 1.557 - r = q ; 1.558 - } 1.559 - } else { 1.560 - r = p ; 1.561 - p = p -> next ; 1.562 - } 1.563 - q = p -> next ; 1.564 - if ( q == s ) s = p ; 1.565 - } 1.566 - } 1.567 - *head = start; 1.568 -} 1.569 - 1.570 - 1.571 -/* 1.572 - * Makes enum query on name. On success, rewrites user part and 1.573 - * replaces Request-URI. 1.574 - */ 1.575 -int do_query(struct sip_msg* _msg, char *user, char *name, str *service) { 1.576 - 1.577 - char uri[MAX_URI_SIZE]; 1.578 - char new_uri[MAX_URI_SIZE]; 1.579 - unsigned int priority, curr_prio, first; 1.580 - qvalue_t q; 1.581 - struct rdata* head; 1.582 - struct rdata* l; 1.583 - struct naptr_rdata* naptr; 1.584 - str pattern, replacement, result, new_result; 1.585 - 1.586 - head = get_record(name, T_NAPTR); 1.587 - 1.588 - if (head == 0) { 1.589 - LM_DBG("No NAPTR record found for %s.\n", name); 1.590 - return -1; 1.591 - } 1.592 - 1.593 - naptr_sort(&head); 1.594 - 1.595 - q = MAX_Q - 10; 1.596 - curr_prio = 0; 1.597 - first = 1; 1.598 - 1.599 - for (l = head; l; l = l->next) { 1.600 - 1.601 - if (l->type != T_NAPTR) continue; /*should never happen*/ 1.602 - naptr = (struct naptr_rdata*)l->rdata; 1.603 - if (naptr == 0) { 1.604 - LM_ERR("Null rdata in DNS response\n"); 1.605 - continue; 1.606 - } 1.607 - 1.608 - LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags '%.*s', " 1.609 - "slen %u, services '%.*s', rlen %u, regexp '%.*s'\n", 1.610 - name, naptr->order, naptr->pref, 1.611 - naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), 1.612 - naptr->services_len, 1.613 - (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, 1.614 - (int)(naptr->regexp_len), ZSW(naptr->regexp)); 1.615 - 1.616 - if (sip_match(naptr, service) == 0) continue; 1.617 - 1.618 - if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, 1.619 - &pattern, &replacement) < 0) { 1.620 - LM_ERR("Parsing of NAPTR regexp failed\n"); 1.621 - continue; 1.622 - } 1.623 - result.s = &(uri[0]); 1.624 - result.len = MAX_URI_SIZE; 1.625 - /* Avoid making copies of pattern and replacement */ 1.626 - pattern.s[pattern.len] = (char)0; 1.627 - replacement.s[replacement.len] = (char)0; 1.628 - if (reg_replace(pattern.s, replacement.s, user, &result) < 0) { 1.629 - pattern.s[pattern.len] = '!'; 1.630 - replacement.s[replacement.len] = '!'; 1.631 - LM_ERR("Regexp replace failed\n"); 1.632 - continue; 1.633 - } 1.634 - LM_DBG("Resulted in replacement: '%.*s'\n", result.len, ZSW(result.s)); 1.635 - pattern.s[pattern.len] = '!'; 1.636 - replacement.s[replacement.len] = '!'; 1.637 - 1.638 - if (param.len > 0) { 1.639 - if (result.len + param.len > MAX_URI_SIZE - 1) { 1.640 - LM_ERR("URI is too long\n"); 1.641 - continue; 1.642 - } 1.643 - new_result.s = &(new_uri[0]); 1.644 - new_result.len = MAX_URI_SIZE; 1.645 - if (add_uri_param(&result, ¶m, &new_result) == 0) { 1.646 - LM_ERR("Parsing of URI <%.*s> failed\n", 1.647 - result.len, result.s); 1.648 - continue; 1.649 - } 1.650 - if (new_result.len > 0) { 1.651 - result = new_result; 1.652 - } 1.653 - } 1.654 - 1.655 - if (first) { 1.656 - if (set_ruri(_msg, &result) == -1) { 1.657 - goto done; 1.658 - } 1.659 - set_ruri_q(q); 1.660 - first = 0; 1.661 - curr_prio = ((naptr->order) << 16) + naptr->pref; 1.662 - } else { 1.663 - priority = ((naptr->order) << 16) + naptr->pref; 1.664 - if (priority > curr_prio) { 1.665 - q = q - 10; 1.666 - curr_prio = priority; 1.667 - } 1.668 - if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) { 1.669 - goto done; 1.670 - } 1.671 - } 1.672 - } 1.673 - 1.674 -done: 1.675 - free_rdata_list(head); 1.676 - return first ? -1 : 1; 1.677 -} 1.678 - 1.679 - 1.680 -/* 1.681 - * Call enum_query_2 with module parameter suffix and default service. 1.682 - */ 1.683 -int enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2) 1.684 -{ 1.685 - return enum_query_2(_msg, (char *)(&suffix), (char *)(&service)); 1.686 -} 1.687 - 1.688 - 1.689 -/* 1.690 - * Call enum_query_2 with given suffix and default service. 1.691 - */ 1.692 -int enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2) 1.693 -{ 1.694 - return enum_query_2(_msg, _suffix, (char *)(&service)); 1.695 -} 1.696 - 1.697 - 1.698 -/* 1.699 - * See documentation in README file. 1.700 - */ 1.701 -int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service) 1.702 -{ 1.703 - char *user_s; 1.704 - int user_len, i, j; 1.705 - char name[MAX_DOMAIN_SIZE]; 1.706 - char string[17]; 1.707 - 1.708 - str *suffix, *service; 1.709 - 1.710 - suffix = (str*)_suffix; 1.711 - service = (str*)_service; 1.712 - 1.713 - if (parse_sip_msg_uri(_msg) < 0) { 1.714 - LM_ERR("Parsing of R-URI failed\n"); 1.715 - return -1; 1.716 - } 1.717 - 1.718 - if (is_e164(&(_msg->parsed_uri.user)) == -1) { 1.719 - LM_ERR("R-URI user is not an E164 number\n"); 1.720 - return -1; 1.721 - } 1.722 - 1.723 - user_s = _msg->parsed_uri.user.s; 1.724 - user_len = _msg->parsed_uri.user.len; 1.725 - 1.726 - memcpy(&(string[0]), user_s, user_len); 1.727 - string[user_len] = (char)0; 1.728 - 1.729 - j = 0; 1.730 - for (i = user_len - 1; i > 0; i--) { 1.731 - name[j] = user_s[i]; 1.732 - name[j + 1] = '.'; 1.733 - j = j + 2; 1.734 - } 1.735 - 1.736 - memcpy(name + j, suffix->s, suffix->len + 1); 1.737 - 1.738 - return do_query(_msg, string, name, service); 1.739 -} 1.740 - 1.741 - 1.742 -/* 1.743 - * Call isn_query_2 with module parameter suffix and default service. 1.744 - */ 1.745 -int isn_query_0(struct sip_msg* _msg, char* _str1, char* _str2) 1.746 -{ 1.747 - return isn_query_2(_msg, (char *)(&isnsuffix), (char *)(&service)); 1.748 -} 1.749 - 1.750 - 1.751 -/* 1.752 - * Call isn_query_2 with given suffix and default service. 1.753 - */ 1.754 -int isn_query_1(struct sip_msg* _msg, char* _suffix, char* _str2) 1.755 -{ 1.756 - return isn_query_2(_msg, _suffix, (char *)(&service)); 1.757 -} 1.758 - 1.759 - 1.760 -/* 1.761 - * See documentation in README file. 1.762 - */ 1.763 -int isn_query_2(struct sip_msg* _msg, char* _suffix, char* _service) 1.764 -{ 1.765 - char *user_s = NULL; 1.766 - int user_len, i, j; 1.767 - char name[MAX_DOMAIN_SIZE] = {0}; 1.768 - char string[17] = {0}; 1.769 - char szItad[17] = {0}; 1.770 - size_t nItlen = 0; 1.771 - 1.772 - str *suffix, *service; 1.773 - 1.774 - suffix = (str*)_suffix; 1.775 - service = (str*)_service; 1.776 - 1.777 - if (parse_sip_msg_uri(_msg) < 0) { 1.778 - LM_ERR("Parsing of R-URI failed\n"); 1.779 - return -1; 1.780 - } 1.781 - 1.782 - user_s = _msg->parsed_uri.user.s; 1.783 - user_len = _msg->parsed_uri.user.len; 1.784 - 1.785 - memcpy(&(string[0]), user_s, user_len); 1.786 - string[user_len] = (char)0; 1.787 - 1.788 - /* Do primitive test for correct ISN format, */ 1.789 - /* and set szItad to the ISN ITAD (RFC 3872/2871). */ 1.790 - /* Correct ISN format guessed from freenum.org and IANA */ 1.791 - /* doc http://www.iana.org/assignments/trip-parameters/ */ 1.792 - { 1.793 - char *pAster = strchr(string, '*'); 1.794 - if (pAster && (nItlen = strspn(pAster + sizeof(char), "0123456789"))) 1.795 - strncpy(szItad, pAster + sizeof(char), nItlen); 1.796 - else { 1.797 - LM_ERR("R-URI user does not contain a valid ISN\n"); 1.798 - return -1; 1.799 - } 1.800 - } 1.801 - 1.802 - /* Ammend the original ENUM E.164 string logic to process */ 1.803 - /* ISN numbers instead, which include a nonreversed ITAD. */ 1.804 - i = user_len - nItlen - sizeof(char); /* Ex: *1212 */ 1.805 - j = 0; 1.806 - while (i--) { 1.807 - name[j] = user_s[i]; 1.808 - name[j + 1] = '.'; 1.809 - j = j + 2; 1.810 - } 1.811 - 1.812 - strcat(name + j, szItad); /* Copy the unreversed ITAD, */ 1.813 - name[j + nItlen] = '.'; /* and append a trailing dot. */ 1.814 - memcpy(name + j + nItlen + sizeof(char), suffix->s, suffix->len + 1); 1.815 - 1.816 - return do_query(_msg, string, name, service); 1.817 -} 1.818 - 1.819 - 1.820 -/*********** INFRASTRUCTURE ENUM ***************/ 1.821 - 1.822 -/* 1.823 - * Call enum_query_2 with default suffix and service. 1.824 - */ 1.825 -int i_enum_query_0(struct sip_msg* _msg, char* _suffix, char* _service) 1.826 -{ 1.827 - return i_enum_query_2(_msg, (char *)(&i_suffix), (char *)(&service)); 1.828 -} 1.829 - 1.830 -/* 1.831 - * Call enum_query_2 with given suffix and default service. 1.832 - */ 1.833 -int i_enum_query_1(struct sip_msg* _msg, char* _suffix, char* _service) 1.834 -{ 1.835 - return i_enum_query_2(_msg, _suffix, (char *)(&service)); 1.836 -} 1.837 - 1.838 - 1.839 -int i_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service) 1.840 -{ 1.841 - char *user_s; 1.842 - int user_len, i, j; 1.843 - char name[MAX_DOMAIN_SIZE]; 1.844 - char apex[MAX_COMPONENT_SIZE + 1]; 1.845 - char separator[MAX_COMPONENT_SIZE + 1]; 1.846 - int sdl = 0; /* subdomain location: infrastructure enum offset */ 1.847 - int cc_len; 1.848 - struct rdata* head; 1.849 - 1.850 - char string[17]; 1.851 - 1.852 - str *suffix, *service; 1.853 - 1.854 - suffix = (str*)_suffix; 1.855 - service = (str*)_service; 1.856 - 1.857 - if (parse_sip_msg_uri(_msg) < 0) { 1.858 - LM_ERR("Parsing of R-URI failed\n"); 1.859 - return -1; 1.860 - } 1.861 - 1.862 - if (is_e164(&(_msg->parsed_uri.user)) == -1) { 1.863 - LM_ERR("R-URI user is not an E164 number\n"); 1.864 - return -1; 1.865 - } 1.866 - 1.867 - user_s = _msg->parsed_uri.user.s; 1.868 - user_len = _msg->parsed_uri.user.len; 1.869 - 1.870 - /* make sure we don't run out of space in strings */ 1.871 - if (( 2*user_len + MAX_COMPONENT_SIZE + MAX_COMPONENT_SIZE + 4) > MAX_DOMAIN_SIZE) { 1.872 - LM_ERR("Strings too long\n"); 1.873 - return -1; 1.874 - } 1.875 - if ( i_branchlabel.len > MAX_COMPONENT_SIZE ) { 1.876 - LM_ERR("i_branchlabel too long\n"); 1.877 - return -1; 1.878 - } 1.879 - if ( suffix->len > MAX_COMPONENT_SIZE ) { 1.880 - LM_ERR("Suffix too long\n"); 1.881 - return -1; 1.882 - } 1.883 - 1.884 - 1.885 - memcpy(&(string[0]), user_s, user_len); 1.886 - string[user_len] = (char)0; 1.887 - 1.888 - /* Set up parameters as for user-enum */ 1.889 - memcpy(apex, suffix->s , suffix->len); 1.890 - apex[suffix->len] = (char)0; 1.891 - sdl = 0; /* where to insert i-enum separator */ 1.892 - separator[0] = 0; /* don't insert anything */ 1.893 - 1.894 - cc_len = cclen(string + 1); 1.895 - 1.896 - if (!strncasecmp(i_bl_alg.s,"ebl",i_bl_alg.len)) { 1.897 - sdl = cc_len; /* default */ 1.898 - 1.899 - j = 0; 1.900 - memcpy(name, i_branchlabel.s, i_branchlabel.len); 1.901 - j += i_branchlabel.len; 1.902 - name[j++] = '.'; 1.903 - 1.904 - for (i = cc_len ; i > 0; i--) { 1.905 - name[j++] = user_s[i]; 1.906 - name[j++] = '.'; 1.907 - } 1.908 - memcpy(name + j, suffix->s, suffix->len + 1); 1.909 - 1.910 - LM_DBG("Looking for EBL record for %s.\n", name); 1.911 - head = get_record(name, T_EBL); 1.912 - if (head == 0) { 1.913 - LM_DBG("No EBL found for %s. Defaulting to user ENUM.\n",name); 1.914 - } else { 1.915 - struct ebl_rdata* ebl; 1.916 - ebl = (struct ebl_rdata *) head->rdata; 1.917 - 1.918 - LM_DBG("EBL record for %s is %d / %.*s / %.*s.\n", 1.919 - name, ebl->position, (int)ebl->separator_len, 1.920 - ebl->separator,(int)ebl->apex_len, ebl->apex); 1.921 - 1.922 - if ((ebl->apex_len > MAX_COMPONENT_SIZE) || (ebl->separator_len > MAX_COMPONENT_SIZE)) { 1.923 - LM_ERR("EBL strings too long\n"); 1.924 - return -1; 1.925 - } 1.926 - 1.927 - if (ebl->position > 15) { 1.928 - LM_ERR("EBL position too large (%d)\n", 1.929 - ebl->position); 1.930 - return -1; 1.931 - } 1.932 - 1.933 - sdl = ebl->position; 1.934 - 1.935 - memcpy(separator, ebl->separator, ebl->separator_len); 1.936 - separator[ebl->separator_len] = 0; 1.937 - 1.938 - memcpy(apex, ebl->apex, ebl->apex_len); 1.939 - apex[ebl->apex_len] = 0; 1.940 - free_rdata_list(head); 1.941 - } 1.942 - } else if (!strncasecmp(i_bl_alg.s,"txt",i_bl_alg.len)) { 1.943 - sdl = cc_len; /* default */ 1.944 - memcpy(separator, i_branchlabel.s, i_branchlabel.len); 1.945 - separator[i_branchlabel.len] = 0; 1.946 - /* no change to apex */ 1.947 - 1.948 - j = 0; 1.949 - memcpy(name, i_branchlabel.s, i_branchlabel.len); 1.950 - j += i_branchlabel.len; 1.951 - name[j++] = '.'; 1.952 - 1.953 - for (i = cc_len ; i > 0; i--) { 1.954 - name[j++] = user_s[i]; 1.955 - name[j++] = '.'; 1.956 - } 1.957 - memcpy(name + j, suffix->s, suffix->len + 1); 1.958 - 1.959 - head = get_record(name, T_TXT); 1.960 - if (head == 0) { 1.961 - LM_DBG("TXT found for %s. Defaulting to %d\n", 1.962 - name, cc_len); 1.963 - } else { 1.964 - sdl = atoi(((struct txt_rdata*)head->rdata)->txt); 1.965 - LM_DBG("TXT record for %s is %d.\n", name, sdl); 1.966 - 1.967 - if ((sdl < 0) || (sdl > 10)) { 1.968 - LM_ERR("Sdl %d out of bounds. Set back to cc_len.\n", sdl); 1.969 - sdl = cc_len; 1.970 - } 1.971 - free_rdata_list(head); 1.972 - } 1.973 - } else { /* defaults to CC */ 1.974 - sdl = cc_len; 1.975 - memcpy(separator, i_branchlabel.s, i_branchlabel.len); 1.976 - separator[i_branchlabel.len] = 0; 1.977 - /* no change to apex */ 1.978 - } 1.979 - 1.980 - j = 0; 1.981 - sdl++; /* to avoid comparing i to (sdl+1) */ 1.982 - for (i = user_len - 1; i > 0; i--) { 1.983 - name[j] = user_s[i]; 1.984 - name[j + 1] = '.'; 1.985 - j = j + 2; 1.986 - if (separator[0] && (i == sdl)) { /* insert the I-ENUM separator here? */ 1.987 - strcpy(name + j, separator); /* we've checked string sizes. */ 1.988 - j += strlen(separator); 1.989 - name[j++] = '.'; 1.990 - } 1.991 - } 1.992 - 1.993 - memcpy(name + j, apex, strlen(apex)+1); 1.994 - 1.995 - return do_query(_msg, string, name, service); 1.996 -} 1.997 - 1.998 - 1.999 - 1.1000 -/******************* FQUERY *******************/ 1.1001 - 1.1002 - 1.1003 -/* 1.1004 - * Call enum_pv_query_3 with pv arg, module parameter suffix, 1.1005 - * and default service. 1.1006 - */ 1.1007 -int enum_pv_query_1(struct sip_msg* _msg, char* _sp) 1.1008 -{ 1.1009 - return enum_pv_query_3(_msg, _sp, (char *)(&suffix), (char *)(&service)); 1.1010 -} 1.1011 - 1.1012 -/* 1.1013 - * Call enum_pv_query_3 with pv and suffix args and default service. 1.1014 - */ 1.1015 -int enum_pv_query_2(struct sip_msg* _msg, char* _sp, char* _suffix) 1.1016 -{ 1.1017 - return enum_pv_query_3(_msg, _sp, _suffix, (char *)(&service)); 1.1018 -} 1.1019 - 1.1020 -/* 1.1021 - * See documentation in README file. 1.1022 - */ 1.1023 - 1.1024 -int enum_pv_query_3(struct sip_msg* _msg, char* _sp, char* _suffix, 1.1025 - char* _service) 1.1026 -{ 1.1027 - char *user_s; 1.1028 - int user_len, i, j, first; 1.1029 - char name[MAX_DOMAIN_SIZE]; 1.1030 - char uri[MAX_URI_SIZE]; 1.1031 - char new_uri[MAX_URI_SIZE]; 1.1032 - unsigned int priority, curr_prio; 1.1033 - qvalue_t q; 1.1034 - char tostring[17]; 1.1035 - struct rdata* head; 1.1036 - struct rdata* l; 1.1037 - struct naptr_rdata* naptr; 1.1038 - str pattern, replacement, result, new_result; 1.1039 - str *suffix, *service; 1.1040 - char string[17]; 1.1041 - pv_spec_t *sp; 1.1042 - pv_value_t pv_val; 1.1043 - 1.1044 - sp = (pv_spec_t *)_sp; 1.1045 - suffix = (str*)_suffix; 1.1046 - service = (str*)_service; 1.1047 - 1.1048 - /* 1.1049 - * Get R-URI user to tostring 1.1050 - */ 1.1051 - if (parse_sip_msg_uri(_msg) < 0) { 1.1052 - LM_ERR("R-URI parsing failed\n"); 1.1053 - return -1; 1.1054 - } 1.1055 - 1.1056 - if (is_e164(&(_msg->parsed_uri.user)) == -1) { 1.1057 - LM_ERR("R-URI user is not an E164 number\n"); 1.1058 - return -1; 1.1059 - } 1.1060 - 1.1061 - user_s = _msg->parsed_uri.user.s; 1.1062 - user_len = _msg->parsed_uri.user.len; 1.1063 - 1.1064 - memcpy(&(tostring[0]), user_s, user_len); 1.1065 - tostring[user_len] = (char)0; 1.1066 - 1.1067 - /* 1.1068 - * Get E.164 number from pseudo variable 1.1069 - */ 1.1070 - if (sp && (pv_get_spec_value(_msg, sp, &pv_val) == 0)) { 1.1071 - if (pv_val.flags & PV_VAL_STR) { 1.1072 - if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) { 1.1073 - LM_DBG("Missing E.164 number\n"); 1.1074 - return -1; 1.1075 - } 1.1076 - } else { 1.1077 - LM_DBG("Pseudo variable value is not string\n"); 1.1078 - return -1; 1.1079 - } 1.1080 - } else { 1.1081 - LM_DBG("Cannot get pseudo variable value\n"); 1.1082 - return -1; 1.1083 - } 1.1084 - if (is_e164(&(pv_val.rs)) == -1) { 1.1085 - LM_ERR("pseudo variable does not contain an E164 number\n"); 1.1086 - return -1; 1.1087 - } 1.1088 - 1.1089 - user_s = pv_val.rs.s; 1.1090 - user_len = pv_val.rs.len; 1.1091 - 1.1092 - memcpy(&(string[0]), user_s, user_len); 1.1093 - string[user_len] = (char)0; 1.1094 - 1.1095 - j = 0; 1.1096 - for (i = user_len - 1; i > 0; i--) { 1.1097 - name[j] = user_s[i]; 1.1098 - name[j + 1] = '.'; 1.1099 - j = j + 2; 1.1100 - } 1.1101 - 1.1102 - memcpy(name + j, suffix->s, suffix->len + 1); 1.1103 - 1.1104 - head = get_record(name, T_NAPTR); 1.1105 - 1.1106 - if (head == 0) { 1.1107 - LM_DBG("No NAPTR record found for %s.\n", name); 1.1108 - return -1; 1.1109 - } 1.1110 - 1.1111 - naptr_sort(&head); 1.1112 - 1.1113 - q = MAX_Q - 10; 1.1114 - curr_prio = 0; 1.1115 - first = 1; 1.1116 - 1.1117 - for (l = head; l; l = l->next) { 1.1118 - 1.1119 - if (l->type != T_NAPTR) continue; /*should never happen*/ 1.1120 - naptr = (struct naptr_rdata*)l->rdata; 1.1121 - if (naptr == 0) { 1.1122 - LM_ERR("Null rdata in DNS response\n"); 1.1123 - continue; 1.1124 - } 1.1125 - 1.1126 - LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags " 1.1127 - "'%.*s', slen %u, services '%.*s', rlen %u, " 1.1128 - "regexp '%.*s'\n", 1.1129 - name, naptr->order, naptr->pref, 1.1130 - naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), 1.1131 - naptr->services_len, 1.1132 - (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, 1.1133 - (int)(naptr->regexp_len), ZSW(naptr->regexp)); 1.1134 - 1.1135 - if (sip_match(naptr, service) == 0) continue; 1.1136 - 1.1137 - if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, 1.1138 - &pattern, &replacement) < 0) { 1.1139 - LM_ERR("Parsing of NAPTR regexp failed\n"); 1.1140 - continue; 1.1141 - } 1.1142 - result.s = &(uri[0]); 1.1143 - result.len = MAX_URI_SIZE; 1.1144 - /* Avoid making copies of pattern and replacement */ 1.1145 - pattern.s[pattern.len] = (char)0; 1.1146 - replacement.s[replacement.len] = (char)0; 1.1147 - if (reg_replace(pattern.s, replacement.s, &(tostring[0]), 1.1148 - &result) < 0) { 1.1149 - pattern.s[pattern.len] = '!'; 1.1150 - replacement.s[replacement.len] = '!'; 1.1151 - LM_ERR("Regexp replace failed\n"); 1.1152 - continue; 1.1153 - } 1.1154 - LM_DBG("Resulted in replacement: '%.*s'\n", 1.1155 - result.len, ZSW(result.s)); 1.1156 - pattern.s[pattern.len] = '!'; 1.1157 - replacement.s[replacement.len] = '!'; 1.1158 - 1.1159 - if (param.len > 0) { 1.1160 - if (result.len + param.len > MAX_URI_SIZE - 1) { 1.1161 - LM_ERR("URI is too long\n"); 1.1162 - continue; 1.1163 - } 1.1164 - new_result.s = &(new_uri[0]); 1.1165 - new_result.len = MAX_URI_SIZE; 1.1166 - if (add_uri_param(&result, ¶m, &new_result) == 0) { 1.1167 - LM_ERR("Parsing of URI <%.*s> failed\n", 1.1168 - result.len, result.s); 1.1169 - continue; 1.1170 - } 1.1171 - if (new_result.len > 0) { 1.1172 - result = new_result; 1.1173 - } 1.1174 - } 1.1175 - 1.1176 - if (first) { 1.1177 - if (set_ruri(_msg, &result) == -1) { 1.1178 - goto done; 1.1179 - } 1.1180 - set_ruri_q(q); 1.1181 - first = 0; 1.1182 - curr_prio = ((naptr->order) << 16) + naptr->pref; 1.1183 - } else { 1.1184 - priority = ((naptr->order) << 16) + naptr->pref; 1.1185 - if (priority > curr_prio) { 1.1186 - q = q - 10; 1.1187 - curr_prio = priority; 1.1188 - } 1.1189 - if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) { 1.1190 - goto done; 1.1191 - } 1.1192 - } 1.1193 - } 1.1194 - 1.1195 -done: 1.1196 - free_rdata_list(head); 1.1197 - return first ? -1 : 1; 1.1198 -} 1.1199 -