00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00051 #include <stdlib.h>
00052
00053 #include "enum.h"
00054 #include "../../sr_module.h"
00055 #include "../../parser/parse_uri.h"
00056 #include "../../parser/parse_from.h"
00057 #include "../../ut.h"
00058 #include "../../resolve.h"
00059 #include "../../mem/mem.h"
00060 #include "../../dset.h"
00061 #include "../../qvalue.h"
00062 #include "enum_mod.h"
00063 #include "../../lib/kcore/regexp.h"
00064 #include "../../pvar.h"
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static int cclen(const char *number)
00079 {
00080 char d1,d2;
00081
00082 if (!number || (strlen(number) < 3))
00083 return(0);
00084
00085 d1 = number[0];
00086 d2 = number[1];
00087
00088 if (!isdigit((int)d2))
00089 return(0);
00090
00091 switch(d1) {
00092 case '1':
00093 case '7':
00094 return(1);
00095 case '2':
00096 if ((d2 == '0') || (d1 == '7'))
00097 return(2);
00098 break;
00099 case '3':
00100 if ((d2 >= '0') && (d1 <= '4'))
00101 return(2);
00102 if ((d2 == '6') || (d1 == '9'))
00103 return(2);
00104 break;
00105 case '4':
00106 if (d2 != '2')
00107 return(2);
00108 break;
00109 case '5':
00110 if ((d2 >= '1') && (d1 <= '8'))
00111 return(2);
00112 break;
00113 case '6':
00114 if (d1 <= '6')
00115 return(2);
00116 break;
00117 case '8':
00118 if ((d2 == '1') || (d1 == '2') || (d1 == '4') || (d1 == '6'))
00119 return(2);
00120 break;
00121 case '9':
00122 if (d1 <= '5')
00123 return(2);
00124 if (d2 == '8')
00125 return(2);
00126 break;
00127 default:
00128 return(0);
00129 }
00130
00131 return(3);
00132 }
00133
00134
00135
00136
00137 static inline int findchr(char* p, int c, unsigned int size)
00138 {
00139 int len=0;
00140
00141 for(;len<size;p++){
00142 if (*p==(unsigned char)c) {
00143 return len;
00144 }
00145 len++;
00146 }
00147 return len;
00148 }
00149
00150
00151
00152
00153
00154
00155 static inline int parse_naptr_regexp(char* first, int len, str* pattern,
00156 str* replacement)
00157 {
00158 char *second, *third;
00159
00160 if (len > 0) {
00161 if (*first == '!') {
00162 second = (char *)memchr((void *)(first + 1), '!', len - 1);
00163 if (second) {
00164 len = len - (second - first + 1);
00165 if (len > 0) {
00166 third = memchr(second + 1, '!', len);
00167 if (third) {
00168 pattern->len = second - first - 1;
00169 pattern->s = first + 1;
00170 replacement->len = third - second - 1;
00171 replacement->s = second + 1;
00172 return 1;
00173 } else {
00174 LM_ERR("Third ! missing from regexp\n");
00175 return -1;
00176 }
00177 } else {
00178 LM_ERR("Third ! missing from regexp\n");
00179 return -2;
00180 }
00181 } else {
00182 LM_ERR("Second ! missing from regexp\n");
00183 return -3;
00184 }
00185 } else {
00186 LM_ERR("First ! missing from regexp\n");
00187 return -4;
00188 }
00189 } else {
00190 LM_ERR("Regexp missing\n");
00191 return -5;
00192 }
00193 }
00194
00195
00196
00197
00198 static inline int sip_match( struct naptr_rdata* naptr, str* service)
00199 {
00200 if (service->len == 0) {
00201 return (naptr->flags_len == 1) &&
00202 ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) &&
00203 (naptr->services_len == 7) &&
00204 ((strncasecmp(naptr->services, "e2u+sip", 7) == 0) ||
00205 (strncasecmp(naptr->services, "sip+e2u", 7) == 0));
00206 } else if (service->s[0] != '+') {
00207 return (naptr->flags_len == 1) &&
00208 ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) &&
00209 (naptr->services_len == service->len + 8) &&
00210 (strncasecmp(naptr->services, "e2u+", 4) == 0) &&
00211 (strncasecmp(naptr->services + 4, service->s, service->len) == 0) &&
00212 (strncasecmp(naptr->services + 4 + service->len, ":sip", 4) == 0);
00213 } else {
00214 str bakservice, baknaptr;
00215 int naptrlen, len;
00216
00217
00218 if (strncasecmp(naptr->services, "e2u+", 4) != 0) {
00219 return 0;
00220 }
00221 baknaptr.s = naptr->services + 4;
00222 baknaptr.len = naptr->services_len - 4;
00223 for (;;) {
00224 bakservice.s = service->s + 1;
00225 bakservice.len = service->len - 1;
00226 naptrlen = findchr(baknaptr.s,'+',baknaptr.len);
00227
00228 for (;;) {
00229 len = findchr(bakservice.s,'+',bakservice.len);
00230 if ((naptrlen == len ) && !strncasecmp(baknaptr.s, bakservice.s, len)){
00231 return 1;
00232 }
00233 if ( (bakservice.len -= len+1) > 0) {
00234 bakservice.s += len+1;
00235 continue;
00236 }
00237 break;
00238 }
00239 if ( (baknaptr.len -= naptrlen+1) > 0) {
00240 baknaptr.s += naptrlen+1;
00241 continue;
00242 }
00243 break;
00244 }
00245
00246 return 0;
00247 }
00248 }
00249
00250
00251
00252
00253
00254 static inline int is_e164(str* _user)
00255 {
00256 int i;
00257 char c;
00258
00259 if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
00260 for (i = 1; i < _user->len; i++) {
00261 c = (_user->s)[i];
00262 if ((c < '0') || (c > '9')) return -1;
00263 }
00264 return 1;
00265 } else {
00266 return -1;
00267 }
00268 }
00269
00270
00271
00272
00273
00274 int is_from_user_enum_0(struct sip_msg* _msg, char* _str1, char* _str2)
00275 {
00276 return is_from_user_enum_2(_msg, (char *)(&suffix), (char *)(&service));
00277 }
00278
00279
00280
00281
00282 int is_from_user_enum_1(struct sip_msg* _msg, char* _suffix, char* _str2)
00283 {
00284 return is_from_user_enum_2(_msg, _suffix, (char *)(&service));
00285 }
00286
00287
00288
00289
00290
00291 int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service)
00292 {
00293 struct ip_addr addr;
00294 struct hostent* he;
00295 unsigned short zp;
00296 char proto;
00297 char *user_s;
00298 int user_len, i, j;
00299 char name[MAX_DOMAIN_SIZE];
00300 char uri[MAX_URI_SIZE];
00301 struct sip_uri *furi;
00302 struct sip_uri luri;
00303 struct rdata* head;
00304
00305 str* suffix;
00306 str* service;
00307
00308 struct rdata* l;
00309 struct naptr_rdata* naptr;
00310
00311 str pattern, replacement, result;
00312 char string[17];
00313
00314 if (parse_from_header(_msg) < 0) {
00315 LM_ERR("Failed to parse From header\n");
00316 return -1;
00317 }
00318
00319 if(_msg->from==NULL || get_from(_msg)==NULL) {
00320 LM_DBG("No From header\n");
00321 return -1;
00322 }
00323
00324 if ((furi = parse_from_uri(_msg)) == NULL) {
00325 LM_ERR("Failed to parse From URI\n");
00326 return -1;
00327 }
00328
00329 suffix = (str*)_suffix;
00330 service = (str*)_service;
00331
00332 if (is_e164(&(furi->user)) == -1) {
00333 LM_ERR("From URI user is not an E164 number\n");
00334 return -1;
00335 }
00336
00337
00338
00339 user_s = furi->user.s;
00340 user_len = furi->user.len;
00341
00342 j = 0;
00343 for (i = user_len - 1; i > 0; i--) {
00344 name[j] = user_s[i];
00345 name[j + 1] = '.';
00346 j = j + 2;
00347 }
00348
00349 memcpy(name + j, suffix->s, suffix->len + 1);
00350
00351 head = get_record(name, T_NAPTR, RES_ONLY_TYPE);
00352
00353 if (head == 0) {
00354 LM_DBG("No NAPTR record found for %s.\n", name);
00355 return -3;
00356 }
00357
00358
00359
00360
00361 for (l = head; l; l = l->next) {
00362
00363 if (l->type != T_NAPTR) continue;
00364 naptr = (struct naptr_rdata*)l->rdata;
00365 if (naptr == 0) {
00366 LM_ERR("Null rdata in DNS response\n");
00367 free_rdata_list(head);
00368 return -4;
00369 }
00370
00371 LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
00372 "'%.*s', slen %u, services '%.*s', rlen %u, "
00373 "regexp '%.*s'\n",
00374 name, naptr->order, naptr->pref,
00375 naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len,
00376 (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
00377 (int)(naptr->regexp_len), ZSW(naptr->regexp));
00378
00379 if (sip_match(naptr, service) != 0) {
00380 if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
00381 &pattern, &replacement) < 0) {
00382 free_rdata_list(head);
00383 LM_ERR("Parsing of NAPTR regexp failed\n");
00384 return -5;
00385 }
00386 #ifdef LATER
00387 if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) {
00388 LM_DBG("Resulted in replacement: '%.*s'\n",
00389 replacement.len, ZSW(replacement.s));
00390 retval = set_uri(_msg, replacement.s, replacement.len);
00391 free_rdata_list(head);
00392 return retval;
00393 }
00394 #endif
00395 result.s = &(uri[0]);
00396 result.len = MAX_URI_SIZE;
00397
00398 pattern.s[pattern.len] = (char)0;
00399 replacement.s[replacement.len] = (char)0;
00400
00401
00402 memcpy(&(string[0]), user_s, user_len);
00403 string[user_len] = (char)0;
00404 if (reg_replace(pattern.s, replacement.s, &(string[0]),
00405 &result) < 0) {
00406 pattern.s[pattern.len] = '!';
00407 replacement.s[replacement.len] = '!';
00408 LM_ERR("Regexp replace failed\n");
00409 free_rdata_list(head);
00410 return -6;
00411 }
00412 LM_DBG("Resulted in replacement: '%.*s'\n",
00413 result.len, ZSW(result.s));
00414
00415 if(parse_uri(result.s, result.len, &luri) < 0)
00416 {
00417 LM_ERR("Parsing of URI <%.*s> failed\n",
00418 result.len, result.s);
00419 free_rdata_list(head);
00420 return -7;
00421 }
00422
00423 pattern.s[pattern.len] = '!';
00424 replacement.s[replacement.len] = '!';
00425
00426 zp = 0;
00427 proto = PROTO_NONE;
00428 he = sip_resolvehost(&luri.host, &zp, &proto);
00429
00430 hostent2ip_addr(&addr, he, 0);
00431
00432 if(ip_addr_cmp(&addr, &_msg->rcv.src_ip))
00433 {
00434 free_rdata_list(head);
00435 return(1);
00436 }
00437 }
00438 }
00439 free_rdata_list(head);
00440 LM_DBG("FAIL\n");
00441
00442
00443 return(-8);
00444 }
00445
00446
00447
00448
00449
00450
00451 int add_uri_param(str *uri, str *param, str *new_uri)
00452 {
00453 struct sip_uri puri;
00454 char *at;
00455
00456 if (parse_uri(uri->s, uri->len, &puri) < 0) {
00457 return 0;
00458 }
00459
00460
00461 if (puri.headers.len == 0) {
00462 memcpy(uri->s + uri->len, param->s, param->len);
00463 uri->len = uri->len + param->len;
00464 new_uri->len = 0;
00465 return 1;
00466 }
00467
00468
00469 at = new_uri->s;
00470 switch (puri.type) {
00471 case SIP_URI_T:
00472 memcpy(at, "sip:", 4);
00473 at = at + 4;
00474 break;
00475 case SIPS_URI_T:
00476 memcpy(at, "sips:", 5);
00477 at = at + 5;
00478 break;
00479 case TEL_URI_T:
00480 memcpy(at, "tel:", 4);
00481 at = at + 4;
00482 break;
00483 case TELS_URI_T:
00484 memcpy(at, "tels:", 5);
00485 at = at + 5;
00486 break;
00487 default:
00488 LM_ERR("Unknown URI scheme <%d>\n", puri.type);
00489 return 0;
00490 }
00491 if (puri.user.len) {
00492 memcpy(at, puri.user.s, puri.user.len);
00493 at = at + puri.user.len;
00494 if (puri.passwd.len) {
00495 *at = ':';
00496 at = at + 1;
00497 memcpy(at, puri.passwd.s, puri.passwd.len);
00498 at = at + puri.passwd.len;
00499 };
00500 *at = '@';
00501 at = at + 1;
00502 }
00503 memcpy(at, puri.host.s, puri.host.len);
00504 at = at + puri.host.len;
00505 if (puri.port.len) {
00506 *at = ':';
00507 at = at + 1;
00508 memcpy(at, puri.port.s, puri.port.len);
00509 at = at + puri.port.len;
00510 }
00511 if (puri.params.len) {
00512 *at = ';';
00513 at = at + 1;
00514 memcpy(at, puri.params.s, puri.params.len);
00515 at = at + puri.params.len;
00516 }
00517 memcpy(at, param->s, param->len);
00518 at = at + param->len;
00519 *at = '?';
00520 at = at + 1;
00521 memcpy(at, puri.headers.s, puri.headers.len);
00522 at = at + puri.headers.len;
00523 new_uri->len = at - new_uri->s;
00524 return 1;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 static inline int naptr_greater(struct rdata* a, struct rdata* b)
00534 {
00535 struct naptr_rdata *na, *nb;
00536
00537 if (a->type != T_NAPTR) return 1;
00538 if (b->type != T_NAPTR) return 0;
00539
00540 na = (struct naptr_rdata*)a->rdata;
00541 if (na == 0) return 1;
00542
00543 nb = (struct naptr_rdata*)b->rdata;
00544 if (nb == 0) return 0;
00545
00546 return (((na->order) << 16) + na->pref) >
00547 (((nb->order) << 16) + nb->pref);
00548 }
00549
00550
00551
00552
00553
00554 static inline void naptr_sort(struct rdata** head)
00555 {
00556 struct rdata *p, *q, *r, *s, *temp, *start;
00557
00558
00559
00560
00561 s = NULL;
00562 start = *head;
00563 while ( s != start -> next ) {
00564 r = p = start ;
00565 q = p -> next ;
00566 while ( p != s ) {
00567 if ( naptr_greater(p, q) ) {
00568 if ( p == start ) {
00569 temp = q -> next ;
00570 q -> next = p ;
00571 p -> next = temp ;
00572 start = q ;
00573 r = q ;
00574 } else {
00575 temp = q -> next ;
00576 q -> next = p ;
00577 p -> next = temp ;
00578 r -> next = q ;
00579 r = q ;
00580 }
00581 } else {
00582 r = p ;
00583 p = p -> next ;
00584 }
00585 q = p -> next ;
00586 if ( q == s ) s = p ;
00587 }
00588 }
00589 *head = start;
00590 }
00591
00592
00593
00594
00595
00596
00597 int do_query(struct sip_msg* _msg, char *user, char *name, str *service) {
00598
00599 char uri[MAX_URI_SIZE];
00600 char new_uri[MAX_URI_SIZE];
00601 unsigned int priority, curr_prio, first;
00602 qvalue_t q;
00603 struct rdata* head;
00604 struct rdata* l;
00605 struct naptr_rdata* naptr;
00606 str pattern, replacement, result, new_result;
00607
00608 head = get_record(name, T_NAPTR, RES_ONLY_TYPE);
00609
00610 if (head == 0) {
00611 LM_DBG("No NAPTR record found for %s.\n", name);
00612 return -1;
00613 }
00614
00615 naptr_sort(&head);
00616
00617 q = MAX_Q - 10;
00618 curr_prio = 0;
00619 first = 1;
00620
00621 for (l = head; l; l = l->next) {
00622
00623 if (l->type != T_NAPTR) continue;
00624 naptr = (struct naptr_rdata*)l->rdata;
00625 if (naptr == 0) {
00626 LM_ERR("Null rdata in DNS response\n");
00627 continue;
00628 }
00629
00630 LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags '%.*s', "
00631 "slen %u, services '%.*s', rlen %u, regexp '%.*s'\n",
00632 name, naptr->order, naptr->pref,
00633 naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
00634 naptr->services_len,
00635 (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
00636 (int)(naptr->regexp_len), ZSW(naptr->regexp));
00637
00638 if (sip_match(naptr, service) == 0) continue;
00639
00640 if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
00641 &pattern, &replacement) < 0) {
00642 LM_ERR("Parsing of NAPTR regexp failed\n");
00643 continue;
00644 }
00645 result.s = &(uri[0]);
00646 result.len = MAX_URI_SIZE;
00647
00648 pattern.s[pattern.len] = (char)0;
00649 replacement.s[replacement.len] = (char)0;
00650 if (reg_replace(pattern.s, replacement.s, user, &result) < 0) {
00651 pattern.s[pattern.len] = '!';
00652 replacement.s[replacement.len] = '!';
00653 LM_ERR("Regexp replace failed\n");
00654 continue;
00655 }
00656 LM_DBG("Resulted in replacement: '%.*s'\n", result.len, ZSW(result.s));
00657 pattern.s[pattern.len] = '!';
00658 replacement.s[replacement.len] = '!';
00659
00660 if (param.len > 0) {
00661 if (result.len + param.len > MAX_URI_SIZE - 1) {
00662 LM_ERR("URI is too long\n");
00663 continue;
00664 }
00665 new_result.s = &(new_uri[0]);
00666 new_result.len = MAX_URI_SIZE;
00667 if (add_uri_param(&result, ¶m, &new_result) == 0) {
00668 LM_ERR("Parsing of URI <%.*s> failed\n",
00669 result.len, result.s);
00670 continue;
00671 }
00672 if (new_result.len > 0) {
00673 result = new_result;
00674 }
00675 }
00676
00677 if (first) {
00678 if (rewrite_uri(_msg, &result) == -1) {
00679 goto done;
00680 }
00681 set_ruri_q(q);
00682 first = 0;
00683 curr_prio = ((naptr->order) << 16) + naptr->pref;
00684 } else {
00685 priority = ((naptr->order) << 16) + naptr->pref;
00686 if (priority > curr_prio) {
00687 q = q - 10;
00688 curr_prio = priority;
00689 }
00690 if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
00691 goto done;
00692 }
00693 }
00694 }
00695
00696 done:
00697 free_rdata_list(head);
00698 return first ? -1 : 1;
00699 }
00700
00701
00702
00703
00704
00705 int enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2)
00706 {
00707 return enum_query(_msg, &suffix, &service);
00708 }
00709
00710
00711
00712
00713
00714 int enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2)
00715 {
00716 str suffix;
00717
00718 if (get_str_fparam(&suffix, _msg, (fparam_t*)_suffix) != 0) {
00719 LM_ERR("unable to get suffix\n");
00720 return -1;
00721 }
00722
00723 return enum_query(_msg, &suffix, &service);
00724 }
00725
00726
00727
00728
00729
00730 int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
00731 {
00732 str suffix, *service;
00733
00734 if (get_str_fparam(&suffix, _msg, (fparam_t*)_suffix) != 0) {
00735 LM_ERR("unable to get suffix\n");
00736 return -1;
00737 }
00738
00739 service = (str*)_service;
00740 if ((service == NULL) || (service->len == 0)) {
00741 LM_ERR("invalid service parameter");
00742 return -1;
00743 }
00744
00745 return enum_query(_msg, &suffix, service);
00746 }
00747
00748
00749
00750
00751
00752 int enum_query(struct sip_msg* _msg, str* suffix, str* service)
00753 {
00754 char *user_s;
00755 int user_len, i, j;
00756 char name[MAX_DOMAIN_SIZE];
00757 char string[17];
00758
00759 LM_DBG("enum_query on suffix <%.*s> service <%.*s>\n",
00760 suffix->len, suffix->s, service->len, service->s);
00761
00762 if (parse_sip_msg_uri(_msg) < 0) {
00763 LM_ERR("Parsing of R-URI failed\n");
00764 return -1;
00765 }
00766
00767 if (is_e164(&(_msg->parsed_uri.user)) == -1) {
00768 LM_ERR("R-URI user is not an E164 number\n");
00769 return -1;
00770 }
00771
00772 user_s = _msg->parsed_uri.user.s;
00773 user_len = _msg->parsed_uri.user.len;
00774
00775 memcpy(&(string[0]), user_s, user_len);
00776 string[user_len] = (char)0;
00777
00778 j = 0;
00779 for (i = user_len - 1; i > 0; i--) {
00780 name[j] = user_s[i];
00781 name[j + 1] = '.';
00782 j = j + 2;
00783 }
00784
00785 memcpy(name + j, suffix->s, suffix->len + 1);
00786
00787 return do_query(_msg, string, name, service);
00788 }
00789
00790
00791
00792
00793
00794
00795
00796 int i_enum_query_0(struct sip_msg* _msg, char* _suffix, char* _service)
00797 {
00798 return i_enum_query_2(_msg, (char *)(&i_suffix), (char *)(&service));
00799 }
00800
00801
00802
00803
00804 int i_enum_query_1(struct sip_msg* _msg, char* _suffix, char* _service)
00805 {
00806 return i_enum_query_2(_msg, _suffix, (char *)(&service));
00807 }
00808
00809
00810 int i_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
00811 {
00812 char *user_s;
00813 int user_len, i, j;
00814 char name[MAX_DOMAIN_SIZE];
00815 char apex[MAX_COMPONENT_SIZE + 1];
00816 char separator[MAX_COMPONENT_SIZE + 1];
00817 int sdl = 0;
00818 int cc_len;
00819 struct rdata* head;
00820
00821 char string[17];
00822
00823 str *suffix, *service;
00824
00825 suffix = (str*)_suffix;
00826 service = (str*)_service;
00827
00828 if (parse_sip_msg_uri(_msg) < 0) {
00829 LM_ERR("Parsing of R-URI failed\n");
00830 return -1;
00831 }
00832
00833 if (is_e164(&(_msg->parsed_uri.user)) == -1) {
00834 LM_ERR("R-URI user is not an E164 number\n");
00835 return -1;
00836 }
00837
00838 user_s = _msg->parsed_uri.user.s;
00839 user_len = _msg->parsed_uri.user.len;
00840
00841
00842 if (( 2*user_len + MAX_COMPONENT_SIZE + MAX_COMPONENT_SIZE + 4) > MAX_DOMAIN_SIZE) {
00843 LM_ERR("Strings too long\n");
00844 return -1;
00845 }
00846 if ( i_branchlabel.len > MAX_COMPONENT_SIZE ) {
00847 LM_ERR("i_branchlabel too long\n");
00848 return -1;
00849 }
00850 if ( suffix->len > MAX_COMPONENT_SIZE ) {
00851 LM_ERR("Suffix too long\n");
00852 return -1;
00853 }
00854
00855
00856 memcpy(&(string[0]), user_s, user_len);
00857 string[user_len] = (char)0;
00858
00859
00860 memcpy(apex, suffix->s , suffix->len);
00861 apex[suffix->len] = (char)0;
00862 sdl = 0;
00863 separator[0] = 0;
00864
00865 cc_len = cclen(string + 1);
00866
00867 if (!strncasecmp(i_bl_alg.s,"ebl",i_bl_alg.len)) {
00868 sdl = cc_len;
00869
00870 j = 0;
00871 memcpy(name, i_branchlabel.s, i_branchlabel.len);
00872 j += i_branchlabel.len;
00873 name[j++] = '.';
00874
00875 for (i = cc_len ; i > 0; i--) {
00876 name[j++] = user_s[i];
00877 name[j++] = '.';
00878 }
00879 memcpy(name + j, suffix->s, suffix->len + 1);
00880
00881 LM_DBG("Looking for EBL record for %s.\n", name);
00882 head = get_record(name, T_EBL, RES_ONLY_TYPE);
00883 if (head == 0) {
00884 LM_DBG("No EBL found for %s. Defaulting to user ENUM.\n",name);
00885 } else {
00886 struct ebl_rdata* ebl;
00887 ebl = (struct ebl_rdata *) head->rdata;
00888
00889 LM_DBG("EBL record for %s is %d / %.*s / %.*s.\n",
00890 name, ebl->position, (int)ebl->separator_len,
00891 ebl->separator,(int)ebl->apex_len, ebl->apex);
00892
00893 if ((ebl->apex_len > MAX_COMPONENT_SIZE) || (ebl->separator_len > MAX_COMPONENT_SIZE)) {
00894 LM_ERR("EBL strings too long\n");
00895 return -1;
00896 }
00897
00898 if (ebl->position > 15) {
00899 LM_ERR("EBL position too large (%d)\n",
00900 ebl->position);
00901 return -1;
00902 }
00903
00904 sdl = ebl->position;
00905
00906 memcpy(separator, ebl->separator, ebl->separator_len);
00907 separator[ebl->separator_len] = 0;
00908
00909 memcpy(apex, ebl->apex, ebl->apex_len);
00910 apex[ebl->apex_len] = 0;
00911 free_rdata_list(head);
00912 }
00913 } else if (!strncasecmp(i_bl_alg.s,"txt",i_bl_alg.len)) {
00914 sdl = cc_len;
00915 memcpy(separator, i_branchlabel.s, i_branchlabel.len);
00916 separator[i_branchlabel.len] = 0;
00917
00918
00919 j = 0;
00920 memcpy(name, i_branchlabel.s, i_branchlabel.len);
00921 j += i_branchlabel.len;
00922 name[j++] = '.';
00923
00924 for (i = cc_len ; i > 0; i--) {
00925 name[j++] = user_s[i];
00926 name[j++] = '.';
00927 }
00928 memcpy(name + j, suffix->s, suffix->len + 1);
00929
00930 head = get_record(name, T_TXT, RES_ONLY_TYPE);
00931 if (head == 0) {
00932 LM_DBG("TXT found for %s. Defaulting to %d\n",
00933 name, cc_len);
00934 } else {
00935 sdl = atoi(((struct txt_rdata*)head->rdata)->txt[0].cstr);
00936 LM_DBG("TXT record for %s is %d.\n", name, sdl);
00937
00938 if ((sdl < 0) || (sdl > 10)) {
00939 LM_ERR("Sdl %d out of bounds. Set back to cc_len.\n", sdl);
00940 sdl = cc_len;
00941 }
00942 free_rdata_list(head);
00943 }
00944 } else {
00945 sdl = cc_len;
00946 memcpy(separator, i_branchlabel.s, i_branchlabel.len);
00947 separator[i_branchlabel.len] = 0;
00948
00949 }
00950
00951 j = 0;
00952 sdl++;
00953 for (i = user_len - 1; i > 0; i--) {
00954 name[j] = user_s[i];
00955 name[j + 1] = '.';
00956 j = j + 2;
00957 if (separator[0] && (i == sdl)) {
00958 strcpy(name + j, separator);
00959 j += strlen(separator);
00960 name[j++] = '.';
00961 }
00962 }
00963
00964 memcpy(name + j, apex, strlen(apex)+1);
00965
00966 return do_query(_msg, string, name, service);
00967 }
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 int enum_pv_query_1(struct sip_msg* _msg, char* _sp)
00979 {
00980 return enum_pv_query_3(_msg, _sp, (char *)(&suffix), (char *)(&service));
00981 }
00982
00983
00984
00985
00986 int enum_pv_query_2(struct sip_msg* _msg, char* _sp, char* _suffix)
00987 {
00988 return enum_pv_query_3(_msg, _sp, _suffix, (char *)(&service));
00989 }
00990
00991
00992
00993
00994
00995 int enum_pv_query_3(struct sip_msg* _msg, char* _sp, char* _suffix,
00996 char* _service)
00997 {
00998 char *user_s;
00999 int user_len, i, j, first;
01000 char name[MAX_DOMAIN_SIZE];
01001 char uri[MAX_URI_SIZE];
01002 char new_uri[MAX_URI_SIZE];
01003 unsigned int priority, curr_prio;
01004 qvalue_t q;
01005 struct rdata* head;
01006 struct rdata* l;
01007 struct naptr_rdata* naptr;
01008 str pattern, replacement, result, new_result;
01009 str *suffix, *service;
01010 char string[17];
01011 pv_spec_t *sp;
01012 pv_value_t pv_val;
01013
01014 sp = (pv_spec_t *)_sp;
01015 suffix = (str*)_suffix;
01016 service = (str*)_service;
01017
01018
01019
01020
01021 if (sp && (pv_get_spec_value(_msg, sp, &pv_val) == 0)) {
01022 if (pv_val.flags & PV_VAL_STR) {
01023 if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
01024 LM_DBG("Missing E.164 number\n");
01025 return -1;
01026 }
01027 } else {
01028 LM_DBG("Pseudo variable value is not string\n");
01029 return -1;
01030 }
01031 } else {
01032 LM_DBG("Cannot get pseudo variable value\n");
01033 return -1;
01034 }
01035 if (is_e164(&(pv_val.rs)) == -1) {
01036 LM_ERR("pseudo variable does not contain an E164 number\n");
01037 return -1;
01038 }
01039
01040 user_s = pv_val.rs.s;
01041 user_len = pv_val.rs.len;
01042
01043 memcpy(&(string[0]), user_s, user_len);
01044 string[user_len] = (char)0;
01045
01046 j = 0;
01047 for (i = user_len - 1; i > 0; i--) {
01048 name[j] = user_s[i];
01049 name[j + 1] = '.';
01050 j = j + 2;
01051 }
01052
01053 memcpy(name + j, suffix->s, suffix->len + 1);
01054
01055 head = get_record(name, T_NAPTR, RES_ONLY_TYPE);
01056
01057 if (head == 0) {
01058 LM_DBG("No NAPTR record found for %s.\n", name);
01059 return -1;
01060 }
01061
01062 naptr_sort(&head);
01063
01064 q = MAX_Q - 10;
01065 curr_prio = 0;
01066 first = 1;
01067
01068 for (l = head; l; l = l->next) {
01069
01070 if (l->type != T_NAPTR) continue;
01071 naptr = (struct naptr_rdata*)l->rdata;
01072 if (naptr == 0) {
01073 LM_ERR("Null rdata in DNS response\n");
01074 continue;
01075 }
01076
01077 LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
01078 "'%.*s', slen %u, services '%.*s', rlen %u, "
01079 "regexp '%.*s'\n",
01080 name, naptr->order, naptr->pref,
01081 naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
01082 naptr->services_len,
01083 (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
01084 (int)(naptr->regexp_len), ZSW(naptr->regexp));
01085
01086 if (sip_match(naptr, service) == 0) continue;
01087
01088 if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
01089 &pattern, &replacement) < 0) {
01090 LM_ERR("Parsing of NAPTR regexp failed\n");
01091 continue;
01092 }
01093 result.s = &(uri[0]);
01094 result.len = MAX_URI_SIZE;
01095
01096 pattern.s[pattern.len] = (char)0;
01097 replacement.s[replacement.len] = (char)0;
01098 if (reg_replace(pattern.s, replacement.s, &(string[0]),
01099 &result) < 0) {
01100 pattern.s[pattern.len] = '!';
01101 replacement.s[replacement.len] = '!';
01102 LM_ERR("Regexp replace failed\n");
01103 continue;
01104 }
01105 LM_DBG("Resulted in replacement: '%.*s'\n",
01106 result.len, ZSW(result.s));
01107 pattern.s[pattern.len] = '!';
01108 replacement.s[replacement.len] = '!';
01109
01110 if (param.len > 0) {
01111 if (result.len + param.len > MAX_URI_SIZE - 1) {
01112 LM_ERR("URI is too long\n");
01113 continue;
01114 }
01115 new_result.s = &(new_uri[0]);
01116 new_result.len = MAX_URI_SIZE;
01117 if (add_uri_param(&result, ¶m, &new_result) == 0) {
01118 LM_ERR("Parsing of URI <%.*s> failed\n",
01119 result.len, result.s);
01120 continue;
01121 }
01122 if (new_result.len > 0) {
01123 result = new_result;
01124 }
01125 }
01126
01127 if (first) {
01128 if (rewrite_uri(_msg, &result) == -1) {
01129 goto done;
01130 }
01131 set_ruri_q(q);
01132 first = 0;
01133 curr_prio = ((naptr->order) << 16) + naptr->pref;
01134 } else {
01135 priority = ((naptr->order) << 16) + naptr->pref;
01136 if (priority > curr_prio) {
01137 q = q - 10;
01138 curr_prio = priority;
01139 }
01140 if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
01141 goto done;
01142 }
01143 }
01144 }
01145
01146 done:
01147 free_rdata_list(head);
01148 return first ? -1 : 1;
01149 }
01150