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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define _GNU_SOURCE
00040 #include <string.h>
00041 #include <unistd.h>
00042 #include <netinet/in.h>
00043 #include "../../str.h"
00044 #include "../../parser/msg_parser.h"
00045 #include "../../parser/hf.h"
00046 #include "../../parser/contact/parse_contact.h"
00047 #include "../../parser/contact/contact.h"
00048 #include "../../parser/digest/digest.h"
00049 #include "../../parser/digest/digest_parser.h"
00050 #include "../../parser/parse_rr.h"
00051 #include "../../parser/parse_content.h"
00052 #include "../../parser/parse_cseq.h"
00053 #include "../../parser/parse_expires.h"
00054 #include "../../parser/parse_methods.h"
00055 #include "../../dprint.h"
00056 #include "../../mem/mem.h"
00057 #include "encode_to_body.h"
00058 #include "encode_contact.h"
00059 #include "encode_digest.h"
00060 #include "encode_via.h"
00061 #include "encode_cseq.h"
00062 #include "encode_route.h"
00063 #include "encode_content_length.h"
00064 #include "encode_content_type.h"
00065 #include "encode_expires.h"
00066 #include "encode_allow.h"
00067 #include "xaddress.h"
00068 #include "encode_msg.h"
00069 #include "encode_header.h"
00070
00071 #define REL_PTR(a,b) ((unsigned char)(b-a))
00072 #define MAX_CONTACT_LEN 50
00073 #define MAX_XHDR_LEN 255
00074
00075 #define SEGREGATE 0x02
00076 #define ONLY_URIS 0x01
00077 #define HEADER_OFFSET_IDX 0
00078 #define HEADER_LEN_IDX (HEADER_OFFSET_IDX+2)
00079 #define HEADER_NAME_LEN_IDX (HEADER_LEN_IDX+2)
00080 #define HEADER_PAYLOAD_IDX (HEADER_NAME_LEN_IDX+1)
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int encode_header(struct sip_msg *sipmsg,struct hdr_field *hdr,unsigned char *payload,int paylen)
00092 {
00093 int len=0;
00094 unsigned int integer,*methods=0;
00095 char *hdrstart,*tmp;
00096 unsigned short int ptr;
00097 struct to_body *tobody=0;
00098 struct via_body *viabody=0;
00099 struct cseq_body *cseqbody=0;
00100 char *msg,*myerror;
00101 int mlen;
00102
00103 msg=sipmsg->buf;
00104 mlen=sipmsg->len;
00105 hdrstart = hdr->name.s;
00106 if(hdrstart-msg<0){
00107 LM_ERR("header(%.*s) does not belong to sip_msg(hdrstart<msg)\n",
00108 hdr->name.len,hdr->name.s);
00109 return -1;
00110 }
00111 ptr=htons((short int)(hdrstart-msg));
00112 if((hdrstart-msg)>mlen){
00113 LM_ERR("out of the sip_msg bounds (%d>%d)\n",ntohs(ptr),mlen);
00114 return -1;
00115 }
00116 if(hdr->len>(1<<16)){
00117 LM_ERR("length of header too long\n");
00118 return -1;
00119 }
00120 memcpy(payload,&ptr,2);
00121 ptr=htons((short int)(hdr->len));
00122 memcpy(payload+HEADER_LEN_IDX,&ptr,2);
00123 payload[HEADER_NAME_LEN_IDX]=(unsigned char)hdr->name.len;
00124 switch(hdr->type){
00125 case HDR_FROM_T:
00126 case HDR_TO_T:
00127 case HDR_REFER_TO_T:
00128 case HDR_RPID_T:
00129 if(!hdr->parsed){
00130 if((tobody=pkg_malloc(sizeof(struct to_body)))==0){
00131 myerror="Out of memory !!\n";
00132 goto error;
00133 }
00134 memset(tobody,0,sizeof(struct to_body));
00135 parse_to(hdr->body.s,hdr->body.s+hdr->body.len+1,tobody);
00136 if (tobody->error == PARSE_ERROR) {
00137 myerror="bad (REFER,TO,FROM,RPID) header\n";
00138 pkg_free(tobody);
00139 return 5;
00140 goto error;
00141 }
00142 hdr->parsed=(struct to_body*)tobody;
00143 }else
00144 tobody=(struct to_body*)hdr->parsed;
00145 if((len=encode_to_body(hdr->name.s,hdr->len,tobody,payload+5))<0){
00146 myerror="parsing from or to header\n";
00147 goto error;
00148 }else{
00149 return 5+len;
00150 }
00151 break;
00152 case HDR_CONTACT_T:
00153 if(!hdr->parsed)
00154 if(parse_contact(hdr)<0){
00155 myerror="parsing contact\n";
00156 goto error;
00157 }
00158 if((len=encode_contact_body(hdr->name.s,hdr->len,(contact_body_t*)hdr->parsed,payload+5))<0){
00159 myerror="encoding contact header\n";
00160 goto error;
00161 }else{
00162 return 5+len;
00163 }
00164 break;
00165 case HDR_ROUTE_T:
00166 case HDR_RECORDROUTE_T:
00167 if(!hdr->parsed)
00168 if(parse_rr(hdr)<0){
00169 myerror="encoding route or recordroute\n";
00170 goto error;
00171 }
00172 if((len=encode_route_body(hdr->name.s,hdr->len,(rr_t*)hdr->parsed,payload+5))<0){
00173 myerror="encoding route or recordroute header\n";
00174 goto error;
00175 }else{
00176 return 5+len;
00177 }
00178 break;
00179 case HDR_CONTENTLENGTH_T:
00180 if(!hdr->parsed){
00181 tmp=parse_content_length(hdr->body.s,hdr->body.s+hdr->body.len+1,(int*)&integer);
00182 if (tmp==0){
00183 myerror="bad content_length header\n";
00184 goto error;
00185 }
00186 hdr->parsed=(void*)(long)integer;
00187 }
00188 if((len=encode_contentlength(hdr->name.s,hdr->len,(long int)hdr->parsed,(char*)(payload+5)))<0){
00189 myerror="encoding content-length header\n";
00190 goto error;
00191 }else{
00192 return 5+len;
00193 }
00194 break;
00195 case HDR_VIA_T:
00196 if(!hdr->parsed){
00197 if((viabody=pkg_malloc(sizeof(struct via_body)))==0){
00198 myerror="out of memory\n";
00199 goto error;
00200 }
00201 memset(viabody,0,sizeof(struct via_body));
00202 if(parse_via(hdr->body.s,hdr->body.s+hdr->body.len+1,viabody)==0){
00203 myerror="encoding via \n";
00204 goto error;
00205 }
00206 hdr->parsed=viabody;
00207 }
00208 if((len=encode_via_body(hdr->name.s,hdr->len,(struct via_body*)hdr->parsed,payload+5))<0){
00209 myerror="encoding via header\n";
00210 goto error;
00211 }else{
00212 return 5+len;
00213 }
00214 break;
00215 case HDR_ACCEPT_T:
00216 if(!hdr->parsed){
00217 if(parse_accept_hdr(sipmsg)<0){
00218 return 5;
00219 }
00220 }
00221 if((len=encode_accept(hdr->name.s,hdr->len,(unsigned int*)hdr->parsed,(char*)(payload+5)))<0){
00222 myerror="encoding via header\n";
00223 goto error;
00224 }else{
00225 return 5+len;
00226 }
00227 break;
00228 case HDR_CONTENTTYPE_T:
00229 if(!hdr->parsed){
00230 if(parse_content_type_hdr(sipmsg)<0){
00231 myerror="encoding content-type header\n";
00232 goto error;
00233 }
00234 }
00235 if((len=encode_content_type(hdr->name.s,hdr->len,(unsigned int)(long int)hdr->parsed,(char*)(payload+5)))<0){
00236 myerror="encoding via header\n";
00237 goto error;
00238 }else{
00239 return 5+len;
00240 }
00241 break;
00242 case HDR_CSEQ_T:
00243 if(!hdr->parsed){
00244 if((cseqbody=pkg_malloc(sizeof(struct cseq_body)))==0){
00245 myerror="out of memory\n";
00246 goto error;
00247 }
00248 memset(cseqbody,0,sizeof(struct cseq_body));
00249 if(parse_cseq(hdr->name.s,hdr->body.s+hdr->body.len+1,cseqbody)==0){
00250 myerror="encoding cseq header\n";
00251 goto error;
00252 }
00253 hdr->parsed=cseqbody;
00254 }
00255 if((len=encode_cseq(hdr->name.s,hdr->len,(struct cseq_body*)hdr->parsed,payload+5))<0){
00256 myerror="encoding via header\n";
00257 goto error;
00258 }else{
00259 return 5+len;
00260 }
00261 break;
00262 case HDR_EXPIRES_T:
00263 if(!hdr->parsed){
00264 if(parse_expires(hdr)<0){
00265 myerror="encoding expires header\n";
00266 goto error;
00267 }
00268 }
00269 if((len=encode_expires(hdr->name.s,hdr->len,(exp_body_t *)hdr->parsed,payload+5))<0){
00270 myerror="encoding expires header\n";
00271 goto error;
00272 }else{
00273 return 5+len;
00274 }
00275 break;
00276 case HDR_ALLOW_T:
00277 if(!hdr->parsed){
00278 if((methods=pkg_malloc(sizeof(unsigned int)))==0){
00279 myerror="out of memory\n";
00280 goto error;
00281 }
00282 *methods=0;
00283 if(parse_methods(&hdr->body,methods)!=0){
00284 myerror="encoding allow header\n";
00285 pkg_free(methods);
00286 return 5;
00287
00288 }
00289 hdr->parsed=methods;
00290 }
00291 if((len=encode_allow(hdr->name.s,hdr->len,(unsigned int*)hdr->parsed,(char*)(payload+5)))<0){
00292 myerror="encoding allow header\n";
00293 goto error;
00294 }else{
00295 return 5+len;
00296 }
00297 break;
00298 case HDR_AUTHORIZATION_T:
00299 case HDR_PROXYAUTH_T:
00300 if(!hdr->parsed){
00301 if(parse_credentials(hdr)<0){
00302 myerror="encoding a digest header\n";
00303 goto error;
00304 }
00305 }
00306 if((len=encode_digest(hdr->name.s,hdr->len,(dig_cred_t*)(&(((auth_body_t*)hdr->parsed)->digest)),payload+5))<0){
00307 myerror="encoding allow header\n";
00308 goto error;
00309 }else{
00310 return 5+len;
00311 }
00312 break;
00313 default:
00314 return 5;
00315 }
00316 return 1;
00317 error:
00318 if(tobody)
00319 pkg_free(tobody);
00320 if(cseqbody)
00321 pkg_free(cseqbody);
00322 if(viabody)
00323 free_via_list(viabody);
00324 if(methods)
00325 pkg_free(methods);
00326 LM_ERR("%s",myerror);
00327 return -1;
00328 }
00329
00330 int print_encoded_header(FILE *fd,char *msg,int msglen,unsigned char *payload,int len,char type,char *prefix)
00331 {
00332 char *hdr_start_ptr;
00333 short int start_idx,i;
00334
00335 memcpy(&start_idx,payload,2);
00336 start_idx=ntohs(start_idx);
00337
00338 hdr_start_ptr = &msg[start_idx];
00339 memcpy(&i,payload+HEADER_LEN_IDX,2);
00340 i=ntohs(i);
00341
00342 fprintf(fd,"%sHEADER NAME:[%.*s]\n",prefix,payload[HEADER_NAME_LEN_IDX],hdr_start_ptr);
00343 fprintf(fd,"%sHEADER:[%.*s]\n",prefix,i-2,hdr_start_ptr);
00344 fprintf(fd,"%sHEADER CODE=",prefix);
00345 for(i=0;i<len;i++)
00346 fprintf(fd,"%s%d%s",i==0?"[":":",payload[i],i==len-1?"]\n":"");
00347 if(len==4)
00348 return 1;
00349 switch(type){
00350 case HDR_FROM_T:
00351 case HDR_TO_T:
00352 case HDR_REFER_TO_T:
00353 case HDR_RPID_T:
00354 memcpy(&i,payload+HEADER_LEN_IDX,2);
00355 i=ntohs(i);
00356 print_encoded_to_body(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00357 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00358 prefix[strlen(prefix)-2]=0;
00359 break;
00360 case HDR_CONTACT_T:
00361 memcpy(&i,payload+HEADER_LEN_IDX,2);
00362 i=ntohs(i);
00363 print_encoded_contact_body(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00364 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00365 prefix[strlen(prefix)-2]=0;
00366 break;
00367 case HDR_ROUTE_T:
00368 case HDR_RECORDROUTE_T:
00369 memcpy(&i,payload+HEADER_LEN_IDX,2);
00370 i=ntohs(i);
00371 print_encoded_route_body(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00372 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00373 prefix[strlen(prefix)-2]=0;
00374 break;
00375 case HDR_CONTENTLENGTH_T:
00376 memcpy(&i,payload+HEADER_LEN_IDX,2);
00377 i=ntohs(i);
00378 print_encoded_contentlength(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00379 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00380 prefix[strlen(prefix)-2]=0;
00381 break;
00382 case HDR_VIA_T:
00383 case HDR_VIA2_T:
00384 memcpy(&i,payload+HEADER_LEN_IDX,2);
00385 i=ntohs(i);
00386 print_encoded_via_body(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00387 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00388 prefix[strlen(prefix)-2]=0;
00389 break;
00390 case HDR_ACCEPT_T:
00391 memcpy(&i,payload+HEADER_LEN_IDX,2);
00392 i=ntohs(i);
00393 print_encoded_accept(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00394 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00395 prefix[strlen(prefix)-2]=0;
00396 break;
00397 case HDR_CONTENTTYPE_T:
00398 memcpy(&i,payload+HEADER_LEN_IDX,2);
00399 i=ntohs(i);
00400 print_encoded_content_type(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00401 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00402 prefix[strlen(prefix)-2]=0;
00403 break;
00404 case HDR_CSEQ_T:
00405 memcpy(&i,payload+HEADER_LEN_IDX,2);
00406 i=ntohs(i);
00407 print_encoded_cseq(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00408 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00409 prefix[strlen(prefix)-2]=0;
00410 break;
00411 case HDR_EXPIRES_T:
00412 memcpy(&i,payload+HEADER_LEN_IDX,2);
00413 i=ntohs(i);
00414 print_encoded_expires(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00415 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00416 prefix[strlen(prefix)-2]=0;
00417 break;
00418 case HDR_ALLOW_T:
00419 memcpy(&i,payload+HEADER_LEN_IDX,2);
00420 i=ntohs(i);
00421 print_encoded_allow(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00422 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00423 prefix[strlen(prefix)-2]=0;
00424 break;
00425 case HDR_PROXYAUTH_T:
00426 case HDR_AUTHORIZATION_T:
00427
00428 memcpy(&i,payload+HEADER_LEN_IDX,2);
00429 i=ntohs(i);
00430 print_encoded_digest(fd,hdr_start_ptr,i,&payload[HEADER_PAYLOAD_IDX],
00431 len-HEADER_PAYLOAD_IDX,strcat(prefix," "));
00432 prefix[strlen(prefix)-2]=0;
00433 break;
00434 default:
00435 return 1;
00436 }
00437 return 1;
00438 }
00439
00440 int dump_headers_test(char *msg,int msglen,unsigned char *payload,int len,char type,FILE* fd,char segregationLevel)
00441 {
00442 char *hdr_start_ptr;
00443 short int start_idx;
00444
00445 memcpy(&start_idx,payload,2);
00446 start_idx=ntohs(start_idx);
00447
00448 hdr_start_ptr = &msg[start_idx];
00449
00450 switch(type){
00451 case 'f':
00452 case 't':
00453 case 'o':
00454 case 'p':
00455 dump_to_body_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00456 len-HEADER_PAYLOAD_IDX,fd,segregationLevel);
00457 break;
00458 case 'm':
00459 dump_contact_body_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00460 len-HEADER_PAYLOAD_IDX,fd,segregationLevel,"");
00461 break;
00462 case 'r':
00463 case 'R':
00464 dump_route_body_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00465 len-HEADER_PAYLOAD_IDX,fd,segregationLevel,"");
00466 break;
00467 case 'l':
00468 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00469 len-HEADER_PAYLOAD_IDX,fd);
00470 break;
00471 case 'v':
00472 dump_via_body_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00473 len-HEADER_PAYLOAD_IDX,fd,segregationLevel);
00474 break;
00475 case 'A':
00476 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00477 len-HEADER_PAYLOAD_IDX,fd);
00478 break;
00479 case 'c':
00480 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00481 len-HEADER_PAYLOAD_IDX,fd);
00482 break;
00483 case 'S':
00484 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00485 len-HEADER_PAYLOAD_IDX,fd);
00486 break;
00487 case 'P':
00488 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00489 len-HEADER_PAYLOAD_IDX,fd);
00490 break;
00491 case 'a':
00492 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00493 len-HEADER_PAYLOAD_IDX,fd);
00494 break;
00495 case 'h':
00496 case 'H':
00497 case 'z':
00498 dump_standard_hdr_test(hdr_start_ptr,payload[HEADER_LEN_IDX],&payload[HEADER_PAYLOAD_IDX],
00499 len-HEADER_PAYLOAD_IDX,fd);
00500 break;
00501 default:
00502 return 1;
00503 }
00504 return 1;
00505 }
00506
00507 int dump_standard_hdr_test(char *hdr,int hdrlen,unsigned char *payload,int paylen,FILE* fd)
00508 {
00509 int i;
00510 i=htonl(hdrlen);
00511 fwrite(&i,1,4,fd);
00512 fwrite(hdr,1,hdrlen,fd);
00513 i=htonl(paylen);
00514 fwrite(&i,1,4,fd);
00515 fwrite(payload,1,paylen,fd);
00516 fwrite(&theSignal,1,4,fd);
00517 return 0;
00518 }