mark.c

Go to the documentation of this file.
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     /* Drop all the old Header Lump "Route: <as>, <my>" */
00139     isc_mark_drop_route(msg);
00140     
00141     len = bin_to_base16(mark->aor.s,mark->aor.len,aor_hex);
00142     /* Create the Marking */        
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     /* Add it in a lump */
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             //tmp->op=LUMP_NOP;         
00372             tmp->len = 0;
00373             /*lmp->before = tmp->before;
00374             free_lump(tmp); */
00375         }
00376         lmp = lmp->next;        
00377     }
00378     LOG(L_DBG,"DEBUG:"M_NAME":ifc_mark_drop_route: ---------- End \n");
00379     
00380     return 1;
00381 }

Generated on Thu Oct 23 04:14:38 2008 for Open IMS Core CSCFs by  doxygen 1.5.2