00001
00068 #include <stdio.h>
00069
00070 #include "../../mem/mem.h"
00071 #include "../../dprint.h"
00072 #include "../../action.h"
00073
00074 #include "mark.h"
00075 #include "sip.h"
00076 #include "mod.h"
00077
00078 extern str isc_my_uri;
00084 char *hexchars="0123456789abcdef";
00092 int bin_to_base16(char *from,int len, char *to)
00093 {
00094 int i,j;
00095 for(i=0,j=0;i<len;i++,j+=2){
00096 to[j] = hexchars[(((unsigned char)from[i]) >>4 )&0x0F];
00097 to[j+1] = hexchars[(((unsigned char)from[i]))&0x0F];
00098 }
00099 return 2*len;
00100 }
00101
00103 #define HEX_DIGIT(x) \
00104 ((x>='0'&&x<='9')?x-'0':((x>='a'&&x<='f')?x-'a'+10:((x>='A'&&x<='F')?x-'A'+10:0)))
00105
00112 int base16_to_bin(char *from,int len, char *to)
00113 {
00114 int i,j;
00115 for(i=0,j=0;j<len;i++,j+=2){
00116 to[i] = (unsigned char) ( HEX_DIGIT(from[j])<<4 | HEX_DIGIT(from[j+1]));
00117 }
00118 return i;
00119 }
00120
00130 int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark)
00131 {
00132 str route={0,0};
00133 str as={0,0};
00134 char chr_mark[256];
00135 char aor_hex[256];
00136 int len;
00137
00138
00139 isc_mark_drop_route(msg);
00140
00141 len = bin_to_base16(mark->aor.s,mark->aor.len,aor_hex);
00142
00143 sprintf(chr_mark,"%s@%.*s;lr;s=%d;h=%d;d=%d;a=%.*s",
00144 ISC_MARK_USERNAME,
00145 isc_my_uri.len,isc_my_uri.s,
00146 mark->skip,
00147 mark->handling,
00148 mark->direction,
00149 len,aor_hex
00150 );
00151
00152 route.s = chr_mark;
00153 route.len = strlen(chr_mark);
00154 if (match) as = match->server_name;
00155 isc_mark_write_route(msg,&as,&route);
00156 LOG(L_INFO,"INFO:"M_NAME":isc_mark_set: NEW mark <%s>\n",chr_mark);
00157
00158 return 1;
00159 }
00160
00161
00167 void isc_mark_get(str x,isc_mark *mark)
00168 {
00169 int i,j,k;
00170 str aor_hex={0,0};
00171 if (mark->aor.s) pkg_free(mark->aor.s);
00172 mark->aor=aor_hex;
00173 for(i=0;i<x.len&&x.s[i]!=';';i++);
00174 while(i<x.len){
00175 if (x.s[i+1]=='=') {
00176 k = 0;
00177 for(j=i+2;j<x.len && x.s[j]!=';';j++)
00178 k = k*10+(x.s[j]-'0');
00179 switch(x.s[i]){
00180 case 's':
00181 mark->skip = k;
00182 break;
00183 case 'h':
00184 mark->handling = k;
00185 break;
00186 case 'd':
00187 mark->direction = k;
00188 break;
00189 case 'a':
00190 aor_hex.s=x.s+i+2;
00191 aor_hex.len=0;
00192 for(j=i+2;j<x.len && x.s[j]!=';';j++)
00193 aor_hex.len++;
00194 mark->aor.len = aor_hex.len/2;
00195 mark->aor.s = pkg_malloc(mark->aor.len);
00196 if (!mark->aor.s){
00197 LOG(L_ERR, "ERR:"M_NAME":isc_mark_get: Error allocating %d bytes\n",mark->aor.len);
00198 mark->aor.len = 0;
00199 }else{
00200 mark->aor.len = base16_to_bin(aor_hex.s,aor_hex.len,mark->aor.s);
00201 }
00202 break;
00203 default:
00204 LOG(L_ERR,"INFO:"M_NAME":isc_mark_get: unkown parameter found: %c !\n",x.s[i]);
00205 }
00206 i = j+1;
00207 }
00208 else i++;
00209 }
00210 }
00211
00213 #define HEX_VAL(c) ( (c<='9')?(c-'0'):(c-'A'+10) )
00214
00222 int isc_mark_get_from_msg(struct sip_msg *msg,isc_mark *mark)
00223 {
00224 struct hdr_field *hdr;
00225 rr_t *rr;
00226 str x;
00227 LOG(L_INFO,"INFO:"M_NAME":isc_mark_get_from_msg: Trying to get the mark from the message \n");
00228
00229 memset(mark,0,sizeof(isc_mark));
00230
00231 parse_headers(msg,HDR_EOH_F,0);
00232 hdr = msg->headers;
00233 while(hdr){
00234 if (hdr->type == HDR_ROUTE_T){
00235 if (!hdr->parsed){
00236 if (parse_rr(hdr) < 0) {
00237 LOG(L_ERR, "ERROR:"M_NAME":isc_mark_get_from_msg: Error while parsing Route HF\n");
00238 hdr = hdr->next;
00239 continue;
00240 }
00241 }
00242 rr = (rr_t*)hdr->parsed;
00243 while(rr){
00244 x = rr->nameaddr.uri;
00245 if (x.len >= ISC_MARK_USERNAME_LEN + 1 + isc_my_uri.len &&
00246 strncasecmp(x.s,ISC_MARK_USERNAME,ISC_MARK_USERNAME_LEN)==0 &&
00247 strncasecmp(x.s+ISC_MARK_USERNAME_LEN+1,isc_my_uri.s,isc_my_uri.len)==0)
00248 {
00249 LOG(L_INFO,"INFO:"M_NAME":isc_mark_get_from_msg: Found <%.*s>\n",x.len,x.s);
00250 isc_mark_get(x,mark);
00251 return 1;
00252 }
00253 rr = rr->next;
00254 }
00255 }
00256 hdr = hdr->next;
00257 }
00258 return 0;
00259 }
00260
00270 int isc_mark_get_from_lump(struct sip_msg *msg,isc_mark *mark)
00271 {
00272 struct lump* lmp,*tmp;;
00273 struct lump* anchor;
00274 str x;
00275
00276 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
00277
00278 memset(mark,0,sizeof(isc_mark));
00279
00280 LOG(L_DBG,"DEBUG:"M_NAME":isc_mark_get_from_lump: Start --------- \n");
00281 lmp = msg->add_rm;
00282 while(lmp){
00283 tmp= lmp->before;
00284 if (tmp &&
00285 tmp->op==LUMP_ADD &&
00286 tmp->u.value &&
00287 strstr(tmp->u.value,ISC_MARK_USERNAME))
00288 {
00289 LOG(L_DBG,"DEBUG:"M_NAME":isc_mark_get_from_lump: Found lump %s ... dropping\n",tmp->u.value);
00290 x.s = lmp->u.value;
00291 x.len = lmp->len;
00292 isc_mark_get(x,mark);
00293 return 1;
00294 }
00295 lmp = lmp->next;
00296 }
00297 LOG(L_DBG,"DEBUG:"M_NAME":isc_mark_get_from_lump: ---------- End \n");
00298
00299 return 0;
00300 }
00301
00314 inline int isc_mark_write_route(struct sip_msg *msg,str *as,str *iscmark)
00315 {
00316 struct hdr_field *first;
00317 struct lump* anchor;
00318 str route;
00319
00320 parse_headers(msg,HDR_EOH_F,0);
00321 first = msg->headers;
00322 if (as && as->len) {
00323 route.s = pkg_malloc(21+as->len+iscmark->len);
00324 sprintf(route.s,"Route: <%.*s;lr>, <%.*s>\r\n",as->len,as->s,iscmark->len,iscmark->s);
00325 }else{
00326 route.s = pkg_malloc(18+iscmark->len);
00327 sprintf(route.s,"Route: <%.*s>\r\n",iscmark->len,iscmark->s);
00328 }
00329
00330 route.len =strlen(route.s);
00331 LOG(L_DBG,"DEBUG:"M_NAME":isc_mark_write_route: <%.*s>\n",route.len,route.s);
00332
00333 anchor = anchor_lump(msg, first->name.s - msg->buf, 0 , HDR_ROUTE_T);
00334 if (anchor == NULL) {
00335 LOG(L_ERR, "ERROR:"M_NAME":isc_mark_write_route: anchor_lump failed\n");
00336 return 0;
00337 }
00338
00339 if (!insert_new_lump_before(anchor, route.s,route.len,HDR_ROUTE_T)){
00340 LOG( L_ERR, "ERROR:"M_NAME":isc_mark_write_route: error creting lump for header_mark\n" );
00341 }
00342 return 1;
00343 }
00344
00345
00352 inline int isc_mark_drop_route(struct sip_msg *msg)
00353 {
00354 struct lump* lmp,*tmp;
00355 struct lump* anchor;
00356
00357 parse_headers(msg,HDR_EOH_F,0);
00358
00359 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
00360
00361 LOG(L_DBG,"DEBUG:"M_NAME":ifc_mark_drop_route: Start --------- \n");
00362 lmp = msg->add_rm;
00363 while(lmp){
00364 tmp= lmp->before;
00365 if (tmp &&
00366 tmp->op==LUMP_ADD &&
00367 tmp->u.value &&
00368 strstr(tmp->u.value,ISC_MARK_USERNAME))
00369 {
00370 LOG(L_DBG,"DEBUG:"M_NAME":ifc_mark_drop_route: Found lump %s ... dropping\n",tmp->u.value);
00371
00372 tmp->len = 0;
00373
00374
00375 }
00376 lmp = lmp->next;
00377 }
00378 LOG(L_DBG,"DEBUG:"M_NAME":ifc_mark_drop_route: ---------- End \n");
00379
00380 return 1;
00381 }