msg_parser.h

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * For a license to use the ser software under conditions
00014  * other than those described here, or to purchase support for this
00015  * software, please contact iptel.org by e-mail at the following addresses:
00016  *    info@iptel.org
00017  *
00018  * ser is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  * History
00028  * -------
00029  *  2003-01-28  removed scratchpad (jiri)
00030  *  2003-02-28  scratchpad compatibility abandoned (jiri)
00031  *  2003-03-06  enum_request_method changed to begin with 1;
00032  *               0 reserved for invalid values; (jiri)
00033  *  2003-03-31  removed sip_msg->repl_add_rm (andrei)
00034  *  2003-04-01  2 macros added: GET_NEXT_HOP and GET_RURI (janakj)
00035  *  2003-04-04  structure for parsed inbound uri added (jiri)
00036  *  2003-04-11  updated the  sip_uri structure (lots of fields added) (andrei)
00037  *  2003-04-12  added msg_flags to sip_msg (andrei)
00038  *  2003-11-02  added diversion header field to sip_msg (jh)
00039  *  2004-11-08  added force_send_socket (andrei)
00040  *  2005-02-25  uri types added (sip, sips & tel)  (andrei)
00041  *  2006-04-20  uri comp member (only if USE_COMP is defined) (andrei)
00042  *  2006-11-10  check_transaction_quadruple inlined (andrei)
00043  *  2007-01-26  added date, identity, identity_info header fields
00044  *              to sip_msg (gergo)
00045  *  2007-03-14  added SIP_MSG_START(msg) macro
00046  */
00047 
00055 #ifndef msg_parser_h
00056 #define msg_parser_h
00057 
00058 
00059 #include "../comp_defs.h"
00060 #include "../str.h"
00061 #include "../lump_struct.h"
00062 #include "../flags.h"
00063 #include "../ip_addr.h"
00064 #include "../md5utils.h"
00065 #include "../config.h"
00066 #include "parse_def.h"
00067 #include "parse_cseq.h"
00068 #include "parse_via.h"
00069 #include "parse_fline.h"
00070 #include "parse_retry_after.h"
00071 #include "hf.h"
00072 #include "../error.h"
00073 
00074 
00076 
00077 #define REQ_LINE(_msg) ((_msg)->first_line.u.request)
00078 #define REQ_METHOD first_line.u.request.method_value
00079 #define REPLY_STATUS first_line.u.reply.statuscode
00080 #define REPLY_CLASS(_reply) ((_reply)->REPLY_STATUS/100)
00081 
00084 #define SIP_MSG_START(m)        ((m)->first_line.u.request.method.s)
00085 
00087 enum request_method {
00088         METHOD_UNDEF=0,           
00089         METHOD_INVITE=1,          
00090         METHOD_CANCEL=2,          
00091         METHOD_ACK=4,             
00092         METHOD_BYE=8,             
00093         METHOD_INFO=16,           
00094         METHOD_REGISTER=32,       
00095         METHOD_SUBSCRIBE=64,      
00096         METHOD_NOTIFY=128,        
00097         METHOD_MESSAGE=256,       
00098         METHOD_OPTIONS=512,       
00099         METHOD_PRACK=1024,        
00100         METHOD_UPDATE=2048,       
00101         METHOD_REFER=4096,        
00102         METHOD_PUBLISH=8192,      
00103         METHOD_OTHER=16384        
00104 };
00105 
00106 #define FL_FORCE_RPORT  (1 << 0)  
00107 #define FL_FORCE_ACTIVE (1 << 1)  
00108 #define FL_SDP_IP_AFS   (1 << 2)  
00109 #define FL_SDP_PORT_AFS (1 << 3)  
00110 #define FL_SHM_CLONE    (1 << 4)  
00111 #define FL_TIMEOUT      (1 << 5)  
00113 #define FL_REPLIED      (1 << 6)  
00115 #define FL_HASH_INDEX   (1 << 7)  
00117 #define FL_MTU_TCP_FB   (1 << 8)
00118 #define FL_MTU_TLS_FB   (1 << 9)
00119 #define FL_MTU_SCTP_FB  (1 << 10)
00120 #define FL_ADD_LOCAL_RPORT  (1 << 11) 
00121 #define FL_SDP_BODY     (1 << 12)  
00122 #define FL_USE_UAC_FROM      (1<<13)  /* take FROM hdr from UAC instead of UAS*/
00123 #define FL_USE_UAC_TO        (1<<14)  /* take TO hdr from UAC instead of UAS */
00124 
00125 /* WARNING: Value (1 << 28) is temporarily reserved for use in kamailio call_control
00126  * module (flag  FL_USE_CALL_CONTROL )! */
00127 
00128 /* WARNING: Value (1 << 29) is temporarily reserved for use in kamailio acc
00129  * module (flag FL_REQ_UPSTREAM)! */
00130 
00131 /* WARNING: Value (1 << 30) is temporarily reserved for use in kamailio
00132  * media proxy module (flag FL_USE_MEDIA_PROXY)! */
00133 
00134 /* WARNING: Value (1 << 31) is temporarily reserved for use in kamailio
00135  * nat_traversal module (flag FL_DO_KEEPALIVE)! */
00136 
00137 #define FL_MTU_FB_MASK  (FL_MTU_TCP_FB|FL_MTU_TLS_FB|FL_MTU_SCTP_FB)
00138 
00139 
00140 #define IFISMETHOD(methodname,firstchar)                                  \
00141 if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
00142         strncasecmp( tmp+1, #methodname +1, methodname##_LEN-1)==0 &&     \
00143         *(tmp+methodname##_LEN)==' ') {                                   \
00144                 fl->type=SIP_REQUEST;                                     \
00145                 fl->u.request.method.len=methodname##_LEN;                \
00146                 fl->u.request.method_value=METHOD_##methodname;           \
00147                 tmp=buffer+methodname##_LEN;                              \
00148 }
00149 
00150 #define IS_HTTP(req)                                                \
00151     ((req)->first_line.u.request.version.len >= HTTP_VERSION_LEN && \
00152     !strncasecmp((req)->first_line.u.request.version.s,             \
00153                 HTTP_VERSION, HTTP_VERSION_LEN))
00154 
00155 #define IS_SIP(req)                                                \
00156     ((req)->first_line.u.request.version.len >= SIP_VERSION_LEN && \
00157     !strncasecmp((req)->first_line.u.request.version.s,             \
00158                 SIP_VERSION, SIP_VERSION_LEN))
00159 
00167 #define GET_NEXT_HOP(m) \
00168 (((m)->dst_uri.s && (m)->dst_uri.len) ? (&(m)->dst_uri) : \
00169 (((m)->new_uri.s && (m)->new_uri.len) ? (&(m)->new_uri) : (&(m)->first_line.u.request.uri)))
00170 
00171 
00178 #define GET_RURI(m) \
00179 (((m)->new_uri.s && (m)->new_uri.len) ? (&(m)->new_uri) : (&(m)->first_line.u.request.uri))
00180 
00181 
00182 enum _uri_type{ERROR_URI_T=0, SIP_URI_T, SIPS_URI_T, TEL_URI_T, TELS_URI_T, URN_URI_T};
00183 typedef enum _uri_type uri_type;
00184 enum _uri_flags{
00185         URI_USER_NORMALIZE=1,
00186         URI_SIP_USER_PHONE=2
00187 }; /* bit fields */
00188 typedef enum _uri_flags uri_flags;
00189 
00191 struct sip_uri {
00192         str user;     
00193         str passwd;   
00194         str host;     
00195         str port;     
00196         str params;   
00197         str sip_params; 
00202         str headers;
00203         unsigned short port_no;
00204         unsigned short proto; 
00205         uri_type type; 
00206         uri_flags flags;
00208         str transport;
00209         str ttl;
00210         str user_param;
00211         str maddr;
00212         str method;
00213         str lr;
00214         str r2; 
00215         str gr;
00216         str transport_val; 
00217         str ttl_val;     
00218         str user_param_val; 
00219         str maddr_val; 
00220         str method_val; 
00221         str lr_val; 
00222         str r2_val;
00223         str gr_val;
00224 #ifdef USE_COMP
00225         unsigned short comp;
00226 #endif
00227 };
00228 
00229 typedef struct sip_uri sip_uri_t;
00230 
00231 struct msg_body;
00232 
00233 typedef void (*free_msg_body_f)(struct msg_body** ptr);
00234 
00235 typedef enum msg_body_type {
00236         MSG_BODY_UNKNOWN = 0,
00237         MSG_BODY_SDP
00238 } msg_body_type_t;
00239 
00248 typedef struct msg_body {
00249         msg_body_type_t type;
00250         free_msg_body_f free;
00251 } msg_body_t;
00252 
00253 
00254 /* pre-declaration, to include sys/time.h in .c */
00255 struct timeval;
00256 
00258 typedef struct sip_msg {
00259         unsigned int id;               
00260         int pid;                       
00261         struct timeval tval;           
00262         snd_flags_t fwd_send_flags;    
00263         snd_flags_t rpl_send_flags;    
00264         struct msg_start first_line;   
00265         struct via_body* via1;         
00266         struct via_body* via2;         
00267         struct hdr_field* headers;     
00268         struct hdr_field* last_header; 
00269         hdr_flags_t parsed_flag;    
00271              /* Via, To, CSeq, Call-Id, From, end of header*/
00272              /* pointers to the first occurrences of these headers;
00273                   * everything is also saved in 'headers'
00274                   * (WARNING: do not deallocate them twice!)*/
00275 
00276         struct hdr_field* h_via1;
00277         struct hdr_field* h_via2;
00278         struct hdr_field* callid;
00279         struct hdr_field* to;
00280         struct hdr_field* cseq;
00281         struct hdr_field* from;
00282         struct hdr_field* contact;
00283         struct hdr_field* maxforwards;
00284         struct hdr_field* route;
00285         struct hdr_field* record_route;
00286         struct hdr_field* content_type;
00287         struct hdr_field* content_length;
00288         struct hdr_field* authorization;
00289         struct hdr_field* expires;
00290         struct hdr_field* proxy_auth;
00291         struct hdr_field* supported;
00292         struct hdr_field* require;
00293         struct hdr_field* proxy_require;
00294         struct hdr_field* unsupported;
00295         struct hdr_field* allow;
00296         struct hdr_field* event;
00297         struct hdr_field* accept;
00298         struct hdr_field* accept_language;
00299         struct hdr_field* organization;
00300         struct hdr_field* priority;
00301         struct hdr_field* subject;
00302         struct hdr_field* user_agent;
00303         struct hdr_field* server;
00304         struct hdr_field* content_disposition;
00305         struct hdr_field* diversion;
00306         struct hdr_field* rpid;
00307         struct hdr_field* refer_to;
00308         struct hdr_field* session_expires;
00309         struct hdr_field* min_se;
00310         struct hdr_field* sipifmatch;
00311         struct hdr_field* subscription_state;
00312         struct hdr_field* date;
00313         struct hdr_field* identity;
00314         struct hdr_field* identity_info;
00315         struct hdr_field* pai;
00316         struct hdr_field* ppi;
00317         struct hdr_field* path;
00318         struct hdr_field* privacy;
00319 
00320         struct msg_body* body;
00321 
00322         char* eoh;        
00323         char* unparsed;   
00325         struct receive_info rcv; 
00327         char* buf;        
00329         unsigned int len; 
00331              /* modifications */
00332 
00333         str new_uri; 
00336         str dst_uri; 
00338         /* current uri */
00339         int parsed_uri_ok; 
00341         struct sip_uri parsed_uri; 
00342         int parsed_orig_ruri_ok; 
00344         struct sip_uri parsed_orig_ruri; 
00346         struct lump* add_rm;       
00347         struct lump* body_lumps;     
00348         struct lump_rpl *reply_lump; 
00353         char add_to_branch_s[MAX_BRANCH_PARAM_LEN];
00354         int add_to_branch_len;
00355 
00356         unsigned int  hash_index; 
00357         unsigned int msg_flags; 
00358              /* allows to set various flags on the message; may be used for
00359               * simple inter-module communication or remembering processing state
00360               * reached
00361               */
00362         flag_t flags;
00363         str set_global_address;
00364         str set_global_port;
00365         struct socket_info* force_send_socket; /* force sending on this socket,
00366                                                                                           if ser */
00367         str path_vec;
00368 } sip_msg_t;
00369 
00374 #define FAKED_REPLY     ((struct sip_msg *) -1)
00375 
00376 extern int via_cnt;
00382 extern unsigned int global_req_flags;
00383 
00384 
00385 int parse_msg(char* buf, unsigned int len, struct sip_msg* msg);
00386 
00387 int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next);
00388 
00389 char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr);
00390 
00391 void free_sip_msg(struct sip_msg* msg);
00392 
00396 inline static int check_transaction_quadruple( struct sip_msg* msg )
00397 {
00398         if ( parse_headers(msg, HDR_FROM_F|HDR_TO_F|HDR_CALLID_F|HDR_CSEQ_F,0)!=-1
00399                 && msg->from && msg->to && msg->callid && msg->cseq ) {
00400                 return 1;
00401         } else {
00402                 ser_error=E_BAD_TUPEL;
00403                 return 0;
00404         }
00405 }
00406 
00407 
00408 
00411 inline static char* get_body(struct sip_msg *msg)
00412 {
00413         int offset;
00414         unsigned int len;
00415 
00416         if ( parse_headers(msg, HDR_EOH_F, 0)==-1 )
00417                 return 0;
00418 
00419         if (msg->unparsed){
00420                 len=(unsigned int)(msg->unparsed-msg->buf);
00421         }else return 0;
00422         if ((len+2<=msg->len) && (strncmp(CRLF,msg->unparsed,CRLF_LEN)==0) )
00423                 offset = CRLF_LEN;
00424         else if ( (len+1<=msg->len) &&
00425                                 (*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' ) )
00426                 offset = 1;
00427         else
00428                 return 0;
00429 
00430         return msg->unparsed + offset;
00431 }
00432 
00433 
00437 int set_dst_uri(struct sip_msg* msg, str* uri);
00438 
00440 void reset_dst_uri(struct sip_msg* msg);
00441 
00442 hdr_field_t* get_hdr(sip_msg_t *msg, enum _hdr_types_t ht);
00443 hdr_field_t* next_sibling_hdr(hdr_field_t *hf);
00444 hdr_field_t* get_hdr_by_name(sip_msg_t *msg, char *name, int name_len);
00445 hdr_field_t* next_sibling_hdr_by_name(hdr_field_t *hf);
00446 
00447 int set_path_vector(struct sip_msg* msg, str* path);
00448 
00449 void reset_path_vector(struct sip_msg* msg);
00450 
00451 
00457 #define set_force_socket(msg, fsocket) \
00458         do { \
00459                 (msg)->force_send_socket=(fsocket); \
00460                 if ((msg)->force_send_socket) \
00461                         (msg)->fwd_send_flags.f |= SND_F_FORCE_SOCKET; \
00462                 else \
00463                         (msg)->fwd_send_flags.f &= ~SND_F_FORCE_SOCKET; \
00464         } while (0)
00465 
00467 #define reset_force_socket(msg) set_force_socket(msg, 0)
00468 
00473 typedef struct msg_ctx_id {
00474         int pid;
00475         int msgid;
00476 } msg_ctx_id_t;
00477 
00482 int msg_ctx_id_set(sip_msg_t *msg, msg_ctx_id_t *mid);
00483 
00488 int msg_ctx_id_match(sip_msg_t *msg, msg_ctx_id_t *mid);
00489 
00493 int msg_set_time(sip_msg_t *msg);
00494 
00495 #endif