msg_parser.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * sip msg. header proxy parser
00005  *
00006  *
00007  * Copyright (C) 2001-2003 FhG Fokus
00008  *
00009  * This file is part of ser, a free SIP server.
00010  *
00011  * ser is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version
00015  *
00016  * For a license to use the ser software under conditions
00017  * other than those described here, or to purchase support for this
00018  * software, please contact iptel.org by e-mail at the following addresses:
00019  *    info@iptel.org
00020  *
00021  * ser is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  * GNU General Public License for more details.
00025  *
00026  * You should have received a copy of the GNU General Public License
00027  * along with this program; if not, write to the Free Software
00028  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00029  *
00030  * History:
00031  * ---------
00032  *  2003-02-28  scratchpad compatibility abandoned (jiri)
00033  *  2003-01-29  scrathcpad removed (jiri)
00034  *  2003-01-27  next baby-step to removing ZT - PRESERVE_ZT (jiri)
00035  *  2003-03-31  removed msg->repl_add_rm (andrei)
00036  *  2003-04-26 ZSW (jiri)
00037  *  2003-05-01  parser extended to support Accept header field (janakj)
00038  *  2005-02-23  parse_headers uses hdr_flags_t now (andrei)
00039  *  2005-03-02  free_via_list(vb) on via parse error (andrei)
00040  *  2007-01-26  parser extended to support Identity, Identity-info and Date
00041  *              header fields (gergo)
00042  */
00043 
00056 #include <string.h>
00057 #include <stdlib.h>
00058 #include <sys/time.h>
00059 
00060 #include "../comp_defs.h"
00061 #include "msg_parser.h"
00062 #include "parser_f.h"
00063 #include "../ut.h"
00064 #include "../error.h"
00065 #include "../dprint.h"
00066 #include "../data_lump_rpl.h"
00067 #include "../mem/mem.h"
00068 #include "../error.h"
00069 #include "../core_stats.h"
00070 #include "../globals.h"
00071 #include "parse_hname2.h"
00072 #include "parse_uri.h"
00073 #include "parse_content.h"
00074 #include "parse_to.h"
00075 #include "../compiler_opt.h"
00076 
00077 #ifdef DEBUG_DMALLOC
00078 #include <mem/dmalloc.h>
00079 #endif
00080 
00081 
00082 #define parse_hname(_b,_e,_h) parse_hname2((_b),(_e),(_h))
00083 
00084 /* number of via's encountered */
00085 int via_cnt;
00086 /* global request flags */
00087 unsigned int global_req_flags = 0;
00088 
00089 /* returns pointer to next header line, and fill hdr_f ;
00090  * if at end of header returns pointer to the last crlf  (always buf)*/
00091 char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
00092 {
00093 
00094         char* tmp;
00095         char *match;
00096         struct via_body *vb;
00097         struct cseq_body* cseq_b;
00098         struct to_body* to_b;
00099         int integer, err;
00100         unsigned uval;
00101 
00102         if ((*buf)=='\n' || (*buf)=='\r'){
00103                 /* double crlf or lflf or crcr */
00104                 DBG("found end of header\n");
00105                 hdr->type=HDR_EOH_T;
00106                 return buf;
00107         }
00108 
00109         tmp=parse_hname(buf, end, hdr);
00110         if (hdr->type==HDR_ERROR_T){
00111                 LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
00112                 goto error;
00113         }
00114 
00115         /* eliminate leading whitespace */
00116         tmp=eat_lws_end(tmp, end);
00117         if (tmp>=end) {
00118                 LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n");
00119                 goto error;
00120         }
00121 
00122         /* if header-field well-known, parse it, find its end otherwise ;
00123          * after leaving the hdr->type switch, tmp should be set to the
00124          * next header field
00125          */
00126         switch(hdr->type){
00127                 case HDR_VIA_T:
00128                         /* keep number of vias parsed -- we want to report it in
00129                            replies for diagnostic purposes */
00130                         via_cnt++;
00131                         vb=pkg_malloc(sizeof(struct via_body));
00132                         if (vb==0){
00133                                 LOG(L_ERR, "get_hdr_field: out of memory\n");
00134                                 goto error;
00135                         }
00136                         memset(vb,0,sizeof(struct via_body));
00137                         hdr->body.s=tmp;
00138                         tmp=parse_via(tmp, end, vb);
00139                         if (vb->error==PARSE_ERROR){
00140                                 LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
00141                                 free_via_list(vb);
00142                                 goto error;
00143                         }
00144                         hdr->parsed=vb;
00145                         vb->hdr.s=hdr->name.s;
00146                         vb->hdr.len=hdr->name.len;
00147                         hdr->body.len=tmp-hdr->body.s;
00148                         break;
00149                 case HDR_CSEQ_T:
00150                         cseq_b=pkg_malloc(sizeof(struct cseq_body));
00151                         if (cseq_b==0){
00152                                 LOG(L_ERR, "get_hdr_field: out of memory\n");
00153                                 goto error;
00154                         }
00155                         memset(cseq_b, 0, sizeof(struct cseq_body));
00156                         hdr->body.s=tmp;
00157                         tmp=parse_cseq(tmp, end, cseq_b);
00158                         if (cseq_b->error==PARSE_ERROR){
00159                                 LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
00160                                 free_cseq(cseq_b);
00161                                 goto error;
00162                         }
00163                         hdr->parsed=cseq_b;
00164                         hdr->body.len=tmp-hdr->body.s;
00165                         DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n",
00166                                         hdr->name.len, ZSW(hdr->name.s),
00167                                         cseq_b->number.len, ZSW(cseq_b->number.s),
00168                                         cseq_b->method.len, cseq_b->method.s);
00169                         break;
00170                 case HDR_TO_T:
00171                         to_b=pkg_malloc(sizeof(struct to_body));
00172                         if (to_b==0){
00173                                 LOG(L_ERR, "get_hdr_field: out of memory\n");
00174                                 goto error;
00175                         }
00176                         memset(to_b, 0, sizeof(struct to_body));
00177                         hdr->body.s=tmp;
00178                         tmp=parse_to(tmp, end,to_b);
00179                         if (to_b->error==PARSE_ERROR){
00180                                 LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n");
00181                                 free_to(to_b);
00182                                 goto error;
00183                         }
00184                         hdr->parsed=to_b;
00185                         hdr->body.len=tmp-hdr->body.s;
00186                         DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n",
00187                                 hdr->name.len, ZSW(hdr->name.s),
00188                                 hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
00189                         DBG("DEBUG: to body [%.*s]\n",to_b->body.len,
00190                                 ZSW(to_b->body.s));
00191                         break;
00192                 case HDR_CONTENTLENGTH_T:
00193                         hdr->body.s=tmp;
00194                         tmp=parse_content_length(tmp,end, &integer);
00195                         if (tmp==0){
00196                                 LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n");
00197                                 goto error;
00198                         }
00199                         hdr->parsed=(void*)(long)integer;
00200                         hdr->body.len=tmp-hdr->body.s;
00201                         DBG("DEBUG: get_hdr_body : content_length=%d\n",
00202                                         (int)(long)hdr->parsed);
00203                         break;
00204                 case HDR_RETRY_AFTER_T:
00205                         hdr->body.s=tmp;
00206                         tmp=parse_retry_after(tmp,end, &uval, &err);
00207                         if (err){
00208                                 LOG(L_ERR, "ERROR:get_hdr_field: bad retry_after header\n");
00209                                 goto error;
00210                         }
00211                         hdr->parsed=(void*)(unsigned long)uval;
00212                         hdr->body.len=tmp-hdr->body.s;
00213                         DBG("DEBUG: get_hdr_body : retry_after=%d\n",
00214                                         (unsigned)(long)hdr->parsed);
00215                         break;
00216                 case HDR_IDENTITY_T:
00217                 case HDR_DATE_T:
00218                 case HDR_IDENTITY_INFO_T:
00219                 case HDR_SUPPORTED_T:
00220                 case HDR_REQUIRE_T:
00221                 case HDR_CONTENTTYPE_T:
00222                 case HDR_FROM_T:
00223                 case HDR_CALLID_T:
00224                 case HDR_CONTACT_T:
00225                 case HDR_ROUTE_T:
00226                 case HDR_RECORDROUTE_T:
00227                 case HDR_MAXFORWARDS_T:
00228                 case HDR_AUTHORIZATION_T:
00229                 case HDR_EXPIRES_T:
00230                 case HDR_PROXYAUTH_T:
00231                 case HDR_PROXYREQUIRE_T:
00232                 case HDR_UNSUPPORTED_T:
00233                 case HDR_ALLOW_T:
00234                 case HDR_EVENT_T:
00235                 case HDR_ACCEPT_T:
00236                 case HDR_ACCEPTLANGUAGE_T:
00237                 case HDR_ORGANIZATION_T:
00238                 case HDR_PRIORITY_T:
00239                 case HDR_SUBJECT_T:
00240                 case HDR_USERAGENT_T:
00241                 case HDR_SERVER_T:
00242                 case HDR_CONTENTDISPOSITION_T:
00243                 case HDR_DIVERSION_T:
00244                 case HDR_RPID_T:
00245                 case HDR_SIPIFMATCH_T:
00246                 case HDR_REFER_TO_T:
00247                 case HDR_SESSIONEXPIRES_T:
00248                 case HDR_MIN_SE_T:
00249                 case HDR_SUBSCRIPTION_STATE_T:
00250                 case HDR_ACCEPTCONTACT_T:
00251                 case HDR_ALLOWEVENTS_T:
00252                 case HDR_CONTENTENCODING_T:
00253                 case HDR_REFERREDBY_T:
00254                 case HDR_REJECTCONTACT_T:
00255                 case HDR_REQUESTDISPOSITION_T:
00256                 case HDR_WWW_AUTHENTICATE_T:
00257                 case HDR_PROXY_AUTHENTICATE_T:
00258                 case HDR_PATH_T:
00259                 case HDR_PRIVACY_T:
00260                 case HDR_PAI_T:
00261                 case HDR_PPI_T:
00262                 case HDR_REASON_T:
00263                 case HDR_OTHER_T:
00264                         /* just skip over it */
00265                         hdr->body.s=tmp;
00266                         /* find end of header */
00267                         /* find lf */
00268                         do{
00269                                 match=q_memchr(tmp, '\n', end-tmp);
00270                                 if (match){
00271                                         match++;
00272                                 }else {
00273                                         LOG(L_ERR,
00274                                                         "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
00275                                                         hdr->name.s, hdr->type);
00276                                         /* abort(); */
00277                                         tmp=end;
00278                                         goto error;
00279                                 }
00280                                 tmp=match;
00281                         }while( match<end &&( (*match==' ')||(*match=='\t') ) );
00282                         tmp=match;
00283                         hdr->body.len=match-hdr->body.s;
00284                         break;
00285                 default:
00286                         LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
00287                                         hdr->type);
00288                         goto error;
00289         }
00290         /* jku: if \r covered by current length, shrink it */
00291         trim_r( hdr->body );
00292         hdr->len=tmp-hdr->name.s;
00293         return tmp;
00294 error:
00295         DBG("get_hdr_field: error exit\n");
00296         STATS_BAD_MSG_HDR();
00297         hdr->type=HDR_ERROR_T;
00298         hdr->len=tmp-hdr->name.s;
00299         return tmp;
00300 }
00301 
00302 
00303 
00304 /* parse the headers and adds them to msg->headers and msg->to, from etc.
00305  * It stops when all the headers requested in flags were parsed, on error
00306  * (bad header) or end of headers
00307  * WARNING: parse_headers was changed to use hdr_flags_t (the flags are now
00308  *          different from the header types). Don't call it with a header type
00309  *          (HDR_xxx_T), only with header flags (HDR_xxx_F)!*/
00310 /* note: it continues where it previously stopped and goes ahead until
00311    end is encountered or desired HFs are found; if you call it twice
00312    for the same HF which is present only once, it will fail the second
00313    time; if you call it twice and the HF is found on second time too,
00314    it's not replaced in the well-known HF pointer but just added to
00315    header list; if you want to use a dumb convenience function which will
00316    give you the first occurrence of a header you are interested in,
00317    look at check_transaction_quadruple
00318 */
00319 int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next)
00320 {
00321         struct hdr_field* hf;
00322         char* tmp;
00323         char* rest;
00324         char* end;
00325         hdr_flags_t orig_flag;
00326 
00327         end=msg->buf+msg->len;
00328         tmp=msg->unparsed;
00329 
00330         if (unlikely(next)) {
00331                 orig_flag = msg->parsed_flag;
00332                 msg->parsed_flag &= ~flags;
00333         }else
00334                 orig_flag=0;
00335 
00336 #ifdef EXTRA_DEBUG
00337         DBG("parse_headers: flags=%llx\n", (unsigned long long)flags);
00338 #endif
00339         while( tmp<end && (flags & msg->parsed_flag) != flags){
00340                 prefetch_loc_r(tmp+64, 1);
00341                 hf=pkg_malloc(sizeof(struct hdr_field));
00342                 if (unlikely(hf==0)){
00343                         ser_error=E_OUT_OF_MEM;
00344                         LOG(L_ERR, "ERROR:parse_headers: memory allocation error\n");
00345                         goto error;
00346                 }
00347                 memset(hf,0, sizeof(struct hdr_field));
00348                 hf->type=HDR_ERROR_T;
00349                 rest=get_hdr_field(tmp, end, hf);
00350                 switch (hf->type){
00351                         case HDR_ERROR_T:
00352                                 LOG(L_INFO,"ERROR: bad header field [%.*s]\n",
00353                                         (end-tmp>20)?20:(int)(end-tmp), tmp);
00354                                 goto  error;
00355                         case HDR_EOH_T:
00356                                 msg->eoh=tmp; /* or rest?*/
00357                                 msg->parsed_flag|=HDR_EOH_F;
00358                                 pkg_free(hf);
00359                                 goto skip;
00360                         case HDR_ACCEPTCONTACT_T:
00361                         case HDR_ALLOWEVENTS_T:
00362                         case HDR_CONTENTENCODING_T:
00363                         case HDR_REFERREDBY_T:
00364                         case HDR_REJECTCONTACT_T:
00365                         case HDR_REQUESTDISPOSITION_T:
00366                         case HDR_WWW_AUTHENTICATE_T:
00367                         case HDR_PROXY_AUTHENTICATE_T:
00368                         case HDR_RETRY_AFTER_T:
00369                         case HDR_OTHER_T: /* mark the type as found/parsed*/
00370                                 msg->parsed_flag|=HDR_T2F(hf->type);
00371                                 break;
00372                         case HDR_CALLID_T:
00373                                 if (msg->callid==0) msg->callid=hf;
00374                                 msg->parsed_flag|=HDR_CALLID_F;
00375                                 break;
00376                         case HDR_SIPIFMATCH_T:
00377                                 if (msg->sipifmatch==0) msg->sipifmatch=hf;
00378                                 msg->parsed_flag|=HDR_SIPIFMATCH_F;
00379                                 break;
00380                         case HDR_TO_T:
00381                                 if (msg->to==0) msg->to=hf;
00382                                 msg->parsed_flag|=HDR_TO_F;
00383                                 break;
00384                         case HDR_CSEQ_T:
00385                                 if (msg->cseq==0) msg->cseq=hf;
00386                                 msg->parsed_flag|=HDR_CSEQ_F;
00387                                 break;
00388                         case HDR_FROM_T:
00389                                 if (msg->from==0) msg->from=hf;
00390                                 msg->parsed_flag|=HDR_FROM_F;
00391                                 break;
00392                         case HDR_CONTACT_T:
00393                                 if (msg->contact==0) msg->contact=hf;
00394                                 msg->parsed_flag|=HDR_CONTACT_F;
00395                                 break;
00396                         case HDR_MAXFORWARDS_T:
00397                                 if(msg->maxforwards==0) msg->maxforwards=hf;
00398                                 msg->parsed_flag|=HDR_MAXFORWARDS_F;
00399                                 break;
00400                         case HDR_ROUTE_T:
00401                                 if (msg->route==0) msg->route=hf;
00402                                 msg->parsed_flag|=HDR_ROUTE_F;
00403                                 break;
00404                         case HDR_RECORDROUTE_T:
00405                                 if (msg->record_route==0) msg->record_route = hf;
00406                                 msg->parsed_flag|=HDR_RECORDROUTE_F;
00407                                 break;
00408                         case HDR_CONTENTTYPE_T:
00409                                 if (msg->content_type==0) msg->content_type = hf;
00410                                 msg->parsed_flag|=HDR_CONTENTTYPE_F;
00411                                 break;
00412                         case HDR_CONTENTLENGTH_T:
00413                                 if (msg->content_length==0) msg->content_length = hf;
00414                                 msg->parsed_flag|=HDR_CONTENTLENGTH_F;
00415                                 break;
00416                         case HDR_AUTHORIZATION_T:
00417                                 if (msg->authorization==0) msg->authorization = hf;
00418                                 msg->parsed_flag|=HDR_AUTHORIZATION_F;
00419                                 break;
00420                         case HDR_EXPIRES_T:
00421                                 if (msg->expires==0) msg->expires = hf;
00422                                 msg->parsed_flag|=HDR_EXPIRES_F;
00423                                 break;
00424                         case HDR_PROXYAUTH_T:
00425                                 if (msg->proxy_auth==0) msg->proxy_auth = hf;
00426                                 msg->parsed_flag|=HDR_PROXYAUTH_F;
00427                                 break;
00428                         case HDR_PROXYREQUIRE_T:
00429                                 if (msg->proxy_require==0) msg->proxy_require = hf;
00430                                 msg->parsed_flag|=HDR_PROXYREQUIRE_F;
00431                                 break;
00432                         case HDR_SUPPORTED_T:
00433                                 if (msg->supported==0) msg->supported=hf;
00434                                 msg->parsed_flag|=HDR_SUPPORTED_F;
00435                                 break;
00436                         case HDR_REQUIRE_T:
00437                                 if (msg->require==0) msg->require=hf;
00438                                 msg->parsed_flag|=HDR_REQUIRE_F;
00439                                 break;
00440                         case HDR_UNSUPPORTED_T:
00441                                 if (msg->unsupported==0) msg->unsupported=hf;
00442                                 msg->parsed_flag|=HDR_UNSUPPORTED_F;
00443                                 break;
00444                         case HDR_ALLOW_T:
00445                                 if (msg->allow==0) msg->allow = hf;
00446                                 msg->parsed_flag|=HDR_ALLOW_F;
00447                                 break;
00448                         case HDR_EVENT_T:
00449                                 if (msg->event==0) msg->event = hf;
00450                                 msg->parsed_flag|=HDR_EVENT_F;
00451                                 break;
00452                         case HDR_ACCEPT_T:
00453                                 if (msg->accept==0) msg->accept = hf;
00454                                 msg->parsed_flag|=HDR_ACCEPT_F;
00455                                 break;
00456                         case HDR_ACCEPTLANGUAGE_T:
00457                                 if (msg->accept_language==0) msg->accept_language = hf;
00458                                 msg->parsed_flag|=HDR_ACCEPTLANGUAGE_F;
00459                                 break;
00460                         case HDR_ORGANIZATION_T:
00461                                 if (msg->organization==0) msg->organization = hf;
00462                                 msg->parsed_flag|=HDR_ORGANIZATION_F;
00463                                 break;
00464                         case HDR_PRIORITY_T:
00465                                 if (msg->priority==0) msg->priority = hf;
00466                                 msg->parsed_flag|=HDR_PRIORITY_F;
00467                                 break;
00468                         case HDR_SUBJECT_T:
00469                                 if (msg->subject==0) msg->subject = hf;
00470                                 msg->parsed_flag|=HDR_SUBJECT_F;
00471                                 break;
00472                         case HDR_USERAGENT_T:
00473                                 if (msg->user_agent==0) msg->user_agent = hf;
00474                                 msg->parsed_flag|=HDR_USERAGENT_F;
00475                                 break;
00476                         case HDR_SERVER_T:
00477                                 if (msg->server==0) msg->server = hf;
00478                                 msg->parsed_flag|=HDR_SERVER_F;
00479                                 break;
00480                         case HDR_CONTENTDISPOSITION_T:
00481                                 if (msg->content_disposition==0) msg->content_disposition = hf;
00482                                 msg->parsed_flag|=HDR_CONTENTDISPOSITION_F;
00483                                 break;
00484                         case HDR_DIVERSION_T:
00485                                 if (msg->diversion==0) msg->diversion = hf;
00486                                 msg->parsed_flag|=HDR_DIVERSION_F;
00487                                 break;
00488                         case HDR_RPID_T:
00489                                 if (msg->rpid==0) msg->rpid = hf;
00490                                 msg->parsed_flag|=HDR_RPID_F;
00491                                 break;
00492                         case HDR_REFER_TO_T:
00493                                 if (msg->refer_to==0) msg->refer_to = hf;
00494                                 msg->parsed_flag|=HDR_REFER_TO_F;
00495                                 break;
00496                         case HDR_SESSIONEXPIRES_T:
00497                                 if (msg->session_expires==0) msg->session_expires = hf;
00498                                 msg->parsed_flag|=HDR_SESSIONEXPIRES_F;
00499                                 break;
00500                         case HDR_MIN_SE_T:
00501                                 if (msg->min_se==0) msg->min_se = hf;
00502                                 msg->parsed_flag|=HDR_MIN_SE_F;
00503                                 break;
00504                         case HDR_SUBSCRIPTION_STATE_T:
00505                                 if (msg->subscription_state==0) msg->subscription_state = hf;
00506                                 msg->parsed_flag|=HDR_SUBSCRIPTION_STATE_F;
00507                                 break;
00508                         case HDR_VIA_T:
00509                                 msg->parsed_flag|=HDR_VIA_F;
00510                                 DBG("parse_headers: Via found, flags=%llx\n",
00511                                                 (unsigned long long)flags);
00512                                 if (msg->via1==0) {
00513                                         DBG("parse_headers: this is the first via\n");
00514                                         msg->h_via1=hf;
00515                                         msg->via1=hf->parsed;
00516                                         if (msg->via1->next){
00517                                                 msg->via2=msg->via1->next;
00518                                                 msg->parsed_flag|=HDR_VIA2_F;
00519                                         }
00520                                 }else if (msg->via2==0){
00521                                         msg->h_via2=hf;
00522                                         msg->via2=hf->parsed;
00523                                         msg->parsed_flag|=HDR_VIA2_F;
00524                                         DBG("parse_headers: this is the second via\n");
00525                                 }
00526                                 break;
00527                         case HDR_DATE_T:
00528                                 if (msg->date==0) msg->date=hf;
00529                                 msg->parsed_flag|=HDR_DATE_F;
00530                                 break;
00531                         case HDR_IDENTITY_T:
00532                                 if (msg->identity==0) msg->identity=hf;
00533                                 msg->parsed_flag|=HDR_IDENTITY_F;
00534                                 break;
00535                         case HDR_IDENTITY_INFO_T:
00536                                 if (msg->identity_info==0) msg->identity_info=hf;
00537                                 msg->parsed_flag|=HDR_IDENTITY_INFO_F;
00538                                 break;
00539                     case HDR_PATH_T:
00540                                 if (msg->path==0) msg->path=hf;
00541                                 msg->parsed_flag|=HDR_PATH_F;
00542                                 break;
00543                     case HDR_PRIVACY_T:
00544                                 if (msg->privacy==0) msg->privacy=hf;
00545                                 msg->parsed_flag|=HDR_PRIVACY_F;
00546                                 break;
00547                     case HDR_PAI_T:
00548                                 if (msg->pai==0) msg->pai=hf;
00549                                 msg->parsed_flag|=HDR_PAI_F;
00550                                 break;
00551                     case HDR_PPI_T:
00552                                 if (msg->ppi==0) msg->ppi=hf;
00553                                 msg->parsed_flag|=HDR_PPI_F;
00554                                 break;
00555                     case HDR_REASON_T:
00556                                 msg->parsed_flag|=HDR_REASON_F;
00557                                 break;
00558                         default:
00559                                 LOG(L_CRIT, "BUG: parse_headers: unknown header type %d\n",
00560                                                         hf->type);
00561                                 goto error;
00562                 }
00563                 /* add the header to the list*/
00564                 if (msg->last_header==0){
00565                         msg->headers=hf;
00566                         msg->last_header=hf;
00567                 }else{
00568                         msg->last_header->next=hf;
00569                         msg->last_header=hf;
00570                 }
00571 #ifdef EXTRA_DEBUG
00572                 DBG("header field type %d, name=<%.*s>, body=<%.*s>\n",
00573                         hf->type,
00574                         hf->name.len, ZSW(hf->name.s),
00575                         hf->body.len, ZSW(hf->body.s));
00576 #endif
00577                 tmp=rest;
00578         }
00579 skip:
00580         msg->unparsed=tmp;
00581         /* restore original flags */
00582         msg->parsed_flag |= orig_flag;
00583         return 0;
00584 
00585 error:
00586         ser_error=E_BAD_REQ;
00587         if (hf) pkg_free(hf);
00588         /* restore original flags */
00589         msg->parsed_flag |= orig_flag;
00590         return -1;
00591 }
00592 
00593 
00594 
00595 
00596 
00597 /* returns 0 if ok, -1 for errors */
00598 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
00599 {
00600 
00601         char *tmp;
00602         char* rest;
00603         struct msg_start *fl;
00604         int offset;
00605         hdr_flags_t flags;
00606 
00607         /* eat crlf from the beginning */
00608         for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&
00609                         tmp-buf < len ; tmp++);
00610         offset=tmp-buf;
00611         fl=&(msg->first_line);
00612         rest=parse_first_line(tmp, len-offset, fl);
00613 #if 0
00614         rest=parse_fline(tmp, buf+len, fl);
00615 #endif
00616         offset+=rest-tmp;
00617         tmp=rest;
00618         switch(fl->type){
00619                 case SIP_INVALID:
00620                         DBG("parse_msg: invalid message\n");
00621                         goto error;
00622                         break;
00623                 case SIP_REQUEST:
00624                         DBG("SIP Request:\n");
00625                         DBG(" method:  <%.*s>\n",fl->u.request.method.len,
00626                                 ZSW(fl->u.request.method.s));
00627                         DBG(" uri:     <%.*s>\n",fl->u.request.uri.len,
00628                                 ZSW(fl->u.request.uri.s));
00629                         DBG(" version: <%.*s>\n",fl->u.request.version.len,
00630                                 ZSW(fl->u.request.version.s));
00631                         flags=HDR_VIA_F;
00632                         break;
00633                 case SIP_REPLY:
00634                         DBG("SIP Reply  (status):\n");
00635                         DBG(" version: <%.*s>\n",fl->u.reply.version.len,
00636                                         ZSW(fl->u.reply.version.s));
00637                         DBG(" status:  <%.*s>\n", fl->u.reply.status.len,
00638                                         ZSW(fl->u.reply.status.s));
00639                         DBG(" reason:  <%.*s>\n", fl->u.reply.reason.len,
00640                                         ZSW(fl->u.reply.reason.s));
00641                         /* flags=HDR_VIA | HDR_VIA2; */
00642                         /* we don't try to parse VIA2 for local messages; -Jiri */
00643                         flags=HDR_VIA_F;
00644                         break;
00645                 default:
00646                         DBG("unknown type %d\n",fl->type);
00647                         goto error;
00648         }
00649         msg->unparsed=tmp;
00650         /*find first Via: */
00651         if (parse_headers(msg, flags, 0)==-1) goto error;
00652 
00653 #ifdef EXTRA_DEBUG
00654         /* dump parsed data */
00655         if (msg->via1){
00656                 DBG("first via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
00657                         msg->via1->name.len,
00658                         ZSW(msg->via1->name.s),
00659                         msg->via1->version.len,
00660                         ZSW(msg->via1->version.s),
00661                         msg->via1->transport.len,
00662                         ZSW(msg->via1->transport.s),
00663                         msg->via1->host.len,
00664                         ZSW(msg->via1->host.s),
00665                         msg->via1->port_str.len,
00666                         ZSW(msg->via1->port_str.s),
00667                         msg->via1->port);
00668                 if (msg->via1->params.s)  DBG(";<%.*s>",
00669                                 msg->via1->params.len, ZSW(msg->via1->params.s));
00670                 if (msg->via1->comment.s)
00671                                 DBG(" <%.*s>",
00672                                         msg->via1->comment.len, ZSW(msg->via1->comment.s));
00673                 DBG ("\n");
00674         }
00675         if (msg->via2){
00676                 DBG("second via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>",
00677                         msg->via2->name.len,
00678                         ZSW(msg->via2->name.s),
00679                         msg->via2->version.len,
00680                         ZSW(msg->via2->version.s),
00681                         msg->via2->transport.len,
00682                         ZSW(msg->via2->transport.s),
00683                         msg->via2->host.len,
00684                         ZSW(msg->via2->host.s),
00685                         msg->via2->port_str.len,
00686                         ZSW(msg->via2->port_str.s),
00687                         msg->via2->port);
00688                 if (msg->via2->params.s)  DBG(";<%.*s>",
00689                                 msg->via2->params.len, ZSW(msg->via2->params.s));
00690                 if (msg->via2->comment.s) DBG(" <%.*s>",
00691                                 msg->via2->comment.len, ZSW(msg->via2->comment.s));
00692                 DBG ("\n");
00693         }
00694 #endif
00695 
00696 
00697 #ifdef EXTRA_DEBUG
00698         DBG("exiting parse_msg\n");
00699 #endif
00700 
00701         return 0;
00702 
00703 error:
00704         /* more debugging, msg->orig is/should be null terminated*/
00705         LOG(cfg_get(core, core_cfg, corelog), "ERROR: parse_msg: message=<%.*s>\n",
00706                         (int)msg->len, ZSW(msg->buf));
00707         return -1;
00708 }
00709 
00710 
00711 
00712 void free_reply_lump( struct lump_rpl *lump)
00713 {
00714         struct lump_rpl *foo, *bar;
00715         for(foo=lump;foo;)
00716         {
00717                 bar=foo->next;
00718                 free_lump_rpl(foo);
00719                 foo = bar;
00720         }
00721 }
00722 
00723 
00724 /*only the content*/
00725 void free_sip_msg(struct sip_msg* msg)
00726 {
00727         if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
00728         if (msg->dst_uri.s) { pkg_free(msg->dst_uri.s); msg->dst_uri.len=0; }
00729         if (msg->path_vec.s) { pkg_free(msg->path_vec.s); msg->path_vec.len=0; }
00730         if (msg->headers)     free_hdr_field_lst(msg->headers);
00731         if (msg->body && msg->body->free) msg->body->free(&msg->body);
00732         if (msg->add_rm)      free_lump_list(msg->add_rm);
00733         if (msg->body_lumps)  free_lump_list(msg->body_lumps);
00734         if (msg->reply_lump)   free_reply_lump(msg->reply_lump);
00735         /* don't free anymore -- now a pointer to a static buffer */
00736 #       ifdef DYN_BUF
00737         pkg_free(msg->buf);
00738 #       endif
00739 }
00740 
00741 
00742 /*
00743  * Make a private copy of the string and assign it to dst_uri
00744  */
00745 int set_dst_uri(struct sip_msg* msg, str* uri)
00746 {
00747         char* ptr;
00748 
00749         if (unlikely(!msg || !uri)) {
00750                 LOG(L_ERR, "set_dst_uri: Invalid parameter value\n");
00751                 return -1;
00752         }
00753 
00754         if (unlikely(uri->len == 0)) {
00755                 reset_dst_uri(msg);
00756         }else if (msg->dst_uri.s && (msg->dst_uri.len >= uri->len)) {
00757                 memcpy(msg->dst_uri.s, uri->s, uri->len);
00758                 msg->dst_uri.len = uri->len;
00759         } else {
00760                 ptr = (char*)pkg_malloc(uri->len);
00761                 if (!ptr) {
00762                         LOG(L_ERR, "set_dst_uri: Not enough memory\n");
00763                         return -1;
00764                 }
00765 
00766                 memcpy(ptr, uri->s, uri->len);
00767                 if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);
00768                 msg->dst_uri.s = ptr;
00769                 msg->dst_uri.len = uri->len;
00770         }
00771         return 0;
00772 }
00773 
00774 
00775 void reset_dst_uri(struct sip_msg* msg)
00776 {
00777         if(msg->dst_uri.s != 0) {
00778                 pkg_free(msg->dst_uri.s);
00779         }
00780         msg->dst_uri.s = 0;
00781         msg->dst_uri.len = 0;
00782 }
00783 
00784 int set_path_vector(struct sip_msg* msg, str* path)
00785 {
00786         char* ptr;
00787 
00788         if (unlikely(!msg || !path)) {
00789                 LM_ERR("invalid parameter value\n");
00790                 return -1;
00791         }
00792 
00793         if (unlikely(path->len == 0)) {
00794                 reset_path_vector(msg);
00795         } else if (msg->path_vec.s && (msg->path_vec.len >= path->len)) {
00796                 memcpy(msg->path_vec.s, path->s, path->len);
00797                 msg->path_vec.len = path->len;
00798         } else {
00799                 ptr = (char*)pkg_malloc(path->len);
00800                 if (!ptr) {
00801                         LM_ERR("not enough pkg memory\n");
00802                         return -1;
00803                 }
00804 
00805                 memcpy(ptr, path->s, path->len);
00806                 if (msg->path_vec.s) pkg_free(msg->path_vec.s);
00807                 msg->path_vec.s = ptr;
00808                 msg->path_vec.len = path->len;
00809         }
00810         return 0;
00811 }
00812 
00813 
00814 void reset_path_vector(struct sip_msg* msg)
00815 {
00816         if(msg->path_vec.s != 0) {
00817                 pkg_free(msg->path_vec.s);
00818         }
00819         msg->path_vec.s = 0;
00820         msg->path_vec.len = 0;
00821 }
00822 
00823 
00824 hdr_field_t* get_hdr(sip_msg_t *msg, enum _hdr_types_t ht)
00825 {
00826         hdr_field_t *hdr;
00827 
00828         if (msg->parsed_flag & HDR_T2F(ht))
00829                 for(hdr = msg->headers; hdr; hdr = hdr->next) {
00830                         if(hdr->type == ht) return hdr;
00831                 }
00832         return NULL;
00833 }
00834 
00835 
00836 hdr_field_t* next_sibling_hdr(hdr_field_t *hf)
00837 {
00838         hdr_field_t *hdr;
00839 
00840         for(hdr = hf->next; hdr; hdr = hdr->next) {
00841                 if(hdr->type == hf->type) return hdr;
00842         }
00843         return NULL;
00844 }
00845 
00846 hdr_field_t* get_hdr_by_name(sip_msg_t *msg, char *name, int name_len)
00847 {
00848         hdr_field_t *hdr;
00849 
00850         for(hdr = msg->headers; hdr; hdr = hdr->next) {
00851                 if(hdr->name.len == name_len && *hdr->name.s==*name
00852                                 && strncmp(hdr->name.s, name, name_len)==0)
00853                         return hdr;
00854         }
00855         return NULL;
00856 }
00857 
00858 
00859 hdr_field_t* next_sibling_hdr_by_name(hdr_field_t *hf)
00860 {
00861         hdr_field_t *hdr;
00862 
00863         for(hdr = hf->next; hdr; hdr = hdr->next) {
00864                 if(hdr->name.len == hf->name.len && *hdr->name.s==*hf->name.s
00865                                 && strncmp(hdr->name.s, hf->name.s, hf->name.len)==0)
00866                         return hdr;
00867         }
00868         return NULL;
00869 }
00870 
00875 int msg_ctx_id_set(sip_msg_t *msg, msg_ctx_id_t *mid)
00876 {
00877         if(msg==NULL || mid==NULL)
00878                 return -1;
00879         mid->msgid = msg->id;
00880         mid->pid = msg->pid;
00881         return 0;
00882 }
00883 
00888 int msg_ctx_id_match(sip_msg_t *msg, msg_ctx_id_t *mid)
00889 {
00890         if(msg==NULL || mid==NULL)
00891                 return -1;
00892         if(msg->id != mid->msgid || msg->pid!=mid->pid)
00893                 return 0;
00894         return 1;
00895 }
00896 
00900 int msg_set_time(sip_msg_t *msg)
00901 {
00902         if(unlikely(msg==NULL))
00903                 return -2;
00904         if(msg->tval.tv_sec!=0)
00905                 return 0;
00906         return gettimeofday(&msg->tval, NULL);
00907 }