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