int th_add_hdr_cookie(sip_msg_t *msg) { struct lump* anchor; str h; h.len = th_cookie_name.len + 2 + th_cookie_value.len + 1 + CRLF_LEN; h.s = (char*)pkg_malloc(h.len+1); if(h.s == 0) { LM_ERR("no more pkg\n"); return -1; } anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); if(anchor == 0) { LM_ERR("can't get anchor\n"); pkg_free(h.s); return -1; } memcpy(h.s, th_cookie_name.s, th_cookie_name.len); memcpy(h.s+th_cookie_name.len, ": ", 2); memcpy(h.s+th_cookie_name.len+2, th_cookie_value.s, th_cookie_value.len); memcpy(h.s+th_cookie_name.len+2+th_cookie_value.len+1, CRLF, CRLF_LEN); h.s[h.len-1-CRLF_LEN] = 'h'; h.s[h.len] = '\0'; if (insert_new_lump_before(anchor, h.s, h.len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(h.s); return -1; } LM_DBG("+++++++++++++ added cookie header [%s]\n", h.s); return 0; }
int _test_insert_to_reply( struct sip_msg *msg, char *str ) { struct lump* anchor; char *buf; int len; len=strlen( str ); buf=pkg_malloc( len ); if (!buf) { LOG(L_ERR, "_test_insert_to_reply: no mem\n"); return 0; } memcpy( buf, str, len ); anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0); if (anchor == NULL) { LOG(L_ERR, "_test_insert_to_reply: anchor_lump failed\n"); return 0; } if (insert_new_lump_before(anchor,buf, len, 0)==0) { LOG(L_ERR, "_test_insert_to_reply: inser_new_lump failed\n"); return 0; } return 1; }
static int lua_sr_hdr_insert (lua_State *L) { struct lump* anchor; struct hdr_field *hf; char *txt; int len; char *hdr; sr_lua_env_t *env_L; env_L = sr_lua_env_get(); txt = (char*)lua_tostring(L, -1); if(txt==NULL || env_L->msg==NULL) return 0; LM_DBG("insert hf: %s\n", txt); hf = env_L->msg->headers; len = strlen(txt); hdr = (char*)pkg_malloc(len); if(hdr==NULL) { LM_ERR("no pkg memory left\n"); return 0; } memcpy(hdr, txt, len); anchor = anchor_lump(env_L->msg, hf->name.s + hf->len - env_L->msg->buf, 0, 0); if(insert_new_lump_before(anchor, hdr, len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(hdr); return 0; } return 0; }
/** * Given some header text, append it to the passed in message. * * @param msg The message to append the header text to. * @param header The header text to append. * * @return 0 on success, non-zero on failure. */ static int append_header(struct sip_msg *msg, const char *header) { struct lump* anchor = NULL; char *s = NULL; int len = 0; LM_DBG("Appending header: %s", header); if (parse_headers(msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse headers in message.\n"); return(1); } if ((anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0)) == 0) { LM_ERR("failed to get anchor to append header\n"); return(1); } len = strlen(header); if ((s = (char *)pkg_malloc(len)) == 0) { LM_ERR("No more pkg memory. (size requested = %d)\n", len); return(1); } memcpy(s, header, len); if (insert_new_lump_before(anchor, s, len, 0) == 0) { LM_ERR("failed to insert lump\n"); pkg_free(s); return(1); } LM_DBG("Done appending header successfully.\n"); return(0); }
static int insert_header_lump(struct sip_msg* msg, char* msg_position, int lump_before, str* hname, str *val) { struct lump* anchor; char *s; int len; anchor = anchor_lump(msg, msg_position - msg->buf, 0, 0); if (anchor == 0) { LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't get anchor\n"); return -1; } len=hname->len+2+val->len+2; s = (char*)pkg_malloc(len); if (!s) { LOG(L_ERR, "ERROR: textops: insert_header_lump(): not enough memory\n"); return -1; } memcpy(s, hname->s, hname->len); s[hname->len] = ':'; s[hname->len+1] = ' '; memcpy(s+hname->len+2, val->s, val->len); s[hname->len+2+val->len] = '\r'; s[hname->len+2+val->len+1] = '\n'; if ( (lump_before?insert_new_lump_before(anchor, s, len, 0):insert_new_lump_after(anchor, s, len, 0)) == 0) { LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't insert lump\n"); pkg_free(s); return -1; } return 1; }
/** * Inserts the Route header for marking, before first header. * - the marking will be in a header like below * - if the "as" parameter is empty: \code Route: <[iscmark]> \endcode * - else: \code Route: <sip:[email protected];lr>, <[iscmark]> \endcode * * * @param msg - SIP mesage to mark * @param as - SIP addres of the application server to forward to * @param iscmark - the mark to write * @returns 1 on success, else 0 */ inline int isc_mark_write_route(struct sip_msg *msg, str *as, str *iscmark) { struct hdr_field *first; struct lump* anchor; str route; parse_headers(msg, HDR_EOH_F, 0); first = msg->headers; if (as && as->len) { route.s = pkg_malloc(21+as->len+iscmark->len); sprintf(route.s, "Route: <%.*s;lr>, <%.*s>\r\n", as->len, as->s, iscmark->len, iscmark->s); } else { route.s = pkg_malloc(18+iscmark->len); sprintf(route.s, "Route: <%.*s>\r\n", iscmark->len, iscmark->s); } route.len = strlen(route.s); LM_DBG("isc_mark_write_route: <%.*s>\n", route.len, route.s); anchor = anchor_lump(msg, first->name.s - msg->buf, 0, HDR_ROUTE_T); if (anchor == NULL) { LM_ERR("isc_mark_write_route: anchor_lump failed\n"); return 0; } if (!insert_new_lump_before(anchor, route.s, route.len, HDR_ROUTE_T)) { LM_ERR("isc_mark_write_route: error creating lump for header_mark\n"); } return 1; }
static inline int add_diversion_helper(struct sip_msg* msg, str* s) { char *ptr; int is_ref; struct lump* anchor = 0; if (!msg->diversion && parse_headers(msg, HDR_DIVERSION_F, 0) == -1) { LM_ERR("header parsing failed\n"); return -1; } if (msg->diversion) { /* Insert just before the topmost Diversion header */ ptr = msg->diversion->name.s; } else { /* Insert at the end */ ptr = msg->unparsed; } anchor = anchor_lump2(msg, ptr - msg->buf, 0, 0, &is_ref); if (!anchor) { LM_ERR("can't get anchor\n"); return -2; } if (!insert_new_lump_before(anchor, s->s, s->len, 0)) { LM_ERR("can't insert lump\n"); return -3; } return 0; }
static int ki_add_sock_hdr(sip_msg_t* msg, str *hdr_name) { struct socket_info* si; struct lump* anchor; str hdr; char *p; if(hdr_name==NULL || hdr_name->s==NULL || hdr_name->len<=0) { LM_ERR("invalid header name parameter\n"); return -1; } si = msg->rcv.bind_address; if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); goto error; } anchor = anchor_lump( msg, msg->unparsed-msg->buf, 0, 0); if (anchor==0) { LM_ERR("can't get anchor\n"); goto error; } hdr.len = hdr_name->len + 2 + si->sock_str.len + CRLF_LEN; if ( (hdr.s=(char*)pkg_malloc(hdr.len))==0 ) { LM_ERR("no more pkg mem\n"); goto error; } p = hdr.s; memcpy( p, hdr_name->s, hdr_name->len); p += hdr_name->len; *(p++) = ':'; *(p++) = ' '; memcpy( p, si->sock_str.s, si->sock_str.len); p += si->sock_str.len; memcpy( p, CRLF, CRLF_LEN); p += CRLF_LEN; if ( p-hdr.s!=hdr.len ) { LM_CRIT("buffer overflow (%d!=%d)\n", (int)(long)(p-hdr.s),hdr.len); goto error1; } if (insert_new_lump_before( anchor, hdr.s, hdr.len, 0) == 0) { LM_ERR("can't insert lump\n"); goto error1; } return 1; error1: pkg_free(hdr.s); error: return -1; }
/** * Adds a received parameter to the first via with the source IP of the message. * @param req - the SIP request * @param str1 - not used * @param str2 - not used * @returns true if ok, false if not or error */ int P_add_via_received(struct sip_msg *msg,char *str1, char *str2) { struct via_body *via; struct via_param *vp; str received={0,0}; struct ip_addr *src_ip; char *src_ip_ch; int len; struct lump* anchor,*l; char *x; /* first add a received parameter */ via = msg->via1; /* if we already have a received header, SER will take care of it and put the right value */ if (via->received) goto delete_others; x = via->port_str.s+via->port_str.len; if (!x) x= via->host.s+via->host.len; anchor = anchor_lump(msg, x-msg->buf, 0 , 0 ); if (anchor == NULL) { LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): anchor_lump failed\n"); return 0; } src_ip = &(msg->rcv.src_ip); src_ip_ch = ip_addr2a(src_ip); len = strlen(src_ip_ch); received.len = s_received.len+len; received.s = pkg_malloc(received.len); if (!received.s){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): allocating %d bytes\n",received.len); return CSCF_RETURN_ERROR; } memcpy(received.s,s_received.s,s_received.len); memcpy(received.s+s_received.len,src_ip_ch,len); if (!(l=insert_new_lump_before(anchor, received.s,received.len,0))){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): error creating lump for received parameter\n" ); return CSCF_RETURN_ERROR; } /* then remove the old received params*/ delete_others: for(vp = via->param_lst; vp; vp = vp->next) if (vp->name.len == s_received2.len && strncasecmp(vp->name.s,s_received2.s,s_received2.len)==0){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): Found old received parameter!! This might indicate an attack.\n" ); if (!del_lump(msg,vp->start-msg->buf-1,vp->size+1,0)){ LOG(L_ERR,"ERR:"M_NAME":P_add_via_received(): Error deleting old received parameter from first via\n"); return CSCF_RETURN_ERROR; } } return CSCF_RETURN_TRUE; }
int add_maxfwd_header( struct sip_msg* msg , unsigned int val ) { unsigned int len; char *buf; struct lump* anchor; /* double check just to be sure */ if ( msg->maxforwards ) { LOG( L_ERR , "ERROR: add_maxfwd_header :" " MAX_FORWARDS header already exists (%p) !\n",msg->maxforwards); goto error; } /* constructing the header */ len = 14 /*"MAX-FORWARDS: "*/+ CRLF_LEN + 3/*val max on 3 digits*/; buf = (char*)pkg_malloc( len ); if (!buf) { LOG(L_ERR, "ERROR : add_maxfwd_header : " "No memory left\n"); return -1; } memcpy( buf , "Max-Forwards: ", 14 ); len = 14 ; len += btostr( buf+len , val ); memcpy( buf+len , CRLF , CRLF_LEN ); len +=CRLF_LEN; /*inserts the header at the begining of the message*/ anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0); if (anchor == 0) { LOG(L_ERR, "ERROR: add_maxfwd_header :" " Error, can't get anchor\n"); goto error1; } if (insert_new_lump_before(anchor, buf, len, 0) == 0) { LOG(L_ERR, "ERROR: add_maxfwd_header : " "Error, can't insert MAX-FORWARDS\n"); goto error1; } return 1; error1: pkg_free( buf ); error: return -1; }
int tps_add_headers(sip_msg_t *msg, str *hname, str *hbody, int hpos) { struct lump* anchor; str hs; if(hname==NULL || hname->len<=0 || hbody==NULL || hbody->len<=0) return 0; parse_headers(msg, HDR_EOH_F, 0); if(hpos == 0) { /* append */ /* after last header */ anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); } else { /* insert */ /* before first header */ anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0); } if(anchor == 0) { LM_ERR("can't get anchor\n"); return -1; } hs.len = hname->len + 2 + hbody->len; hs.s = (char*)pkg_malloc(hs.len + 3); if (hs.s==NULL) { LM_ERR("no pkg memory left (%.*s - %d)\n", hname->len, hname->s, hs.len); return -1; } memcpy(hs.s, hname->s, hname->len); hs.s[hname->len] = ':'; hs.s[hname->len+1] = ' '; memcpy(hs.s + hname->len + 2, hbody->s, hbody->len); /* add end of header if not present */ if(hs.s[hname->len + 2 + hbody->len]!='\n') { hs.s[hname->len + 2 + hbody->len] = '\r'; hs.s[hname->len + 2 + hbody->len+1] = '\n'; hs.len += 2; } if (insert_new_lump_before(anchor, hs.s, hs.len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(hs.s); return -1; } return 0; }
static inline int apply_urihdr_changes( struct sip_msg *req, str *uri, str *hdr) { struct lump* anchor; /* add the uri - move it to branch directly FIXME (bogdan)*/ if (req->new_uri.s) { pkg_free(req->new_uri.s); req->new_uri.len=0; } req->parsed_uri_ok=0; req->new_uri.s = (char*)pkg_malloc(uri->len+1); if (req->new_uri.s==0) { LM_ERR("no more pkg\n"); goto error; } memcpy( req->new_uri.s, uri->s, uri->len); req->new_uri.s[uri->len]=0; req->new_uri.len=uri->len; ruri_mark_new(); /* add the header */ if (parse_headers(req, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); goto error; } anchor = anchor_lump(req, req->unparsed - req->buf, 0, 0); if (anchor==0) { LM_ERR("failed to get anchor\n"); goto error; } if (insert_new_lump_before(anchor, hdr->s, hdr->len, 0) == 0) { LM_ERR("faield to insert lump\n"); goto error; } return 0; error: pkg_free( hdr->s ); return -1; }
/*! * \brief Set Request-URI as last Route header of a SIP * * Set Request-URI as last Route header of a SIP message, * this is necessary when forwarding to a strict router. * Allocates memory for message lump in private memory. * \param _m SIP message * \return negative on failure, 0 on success */ static inline int save_ruri(struct sip_msg* _m) { struct lump* anchor; char *s; int len; /* We must parse the whole message header here, because * the Request-URI must be saved in last Route HF in the message */ if (parse_headers(_m, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return -1; } /* Create an anchor */ anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0); if (anchor == 0) { LM_ERR("failed to get anchor\n"); return -2; } /* Create buffer for new lump */ len = RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len + ROUTE_SUFFIX_LEN; s = (char*)pkg_malloc(len); if (!s) { LM_ERR("No memory pkg left\n"); return -3; } /* Create new header field */ memcpy(s, RR_ROUTE_PREFIX, RR_ROUTE_PREFIX_LEN); memcpy(s + RR_ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len); memcpy(s + RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len, ROUTE_SUFFIX, ROUTE_SUFFIX_LEN); LM_DBG("New header: '%.*s'\n", len, ZSW(s)); /* Insert it */ if (insert_new_lump_before(anchor, s, len, 0) == 0) { pkg_free(s); LM_ERR("failed to insert lump\n"); return -4; } return 0; }
static int sr_mono_hdr_append (MonoString *hv) { struct lump* anchor; struct hdr_field *hf; char *hdr; str txt = {0}; sr_mono_env_t *env_M; env_M = sr_mono_env_get(); txt.s = mono_string_to_utf8(hv); if(txt.s==NULL || env_M->msg==NULL) goto error; txt.len = strlen(txt.s); LM_DBG("append hf: %s\n", txt.s); if (parse_headers(env_M->msg, HDR_EOH_F, 0) == -1) { LM_ERR("error while parsing message\n"); goto error; } hf = env_M->msg->last_header; hdr = (char*)pkg_malloc(txt.len+1); if(hdr==NULL) { PKG_MEM_ERROR; goto error; } memcpy(hdr, txt.s, txt.len); hdr[txt.len] = '\0'; anchor = anchor_lump(env_M->msg, hf->name.s + hf->len - env_M->msg->buf, 0, 0); if(insert_new_lump_before(anchor, hdr, txt.len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(hdr); goto error; } mono_free(txt.s); return 0; error: if(txt.s!=NULL) mono_free(txt.s); return -1; }
static int lua_sr_hdr_append (lua_State *L) { struct lump* anchor; struct hdr_field *hf; char *txt; int len; char *hdr; sr_lua_env_t *env_L; env_L = sr_lua_env_get(); txt = (char*)lua_tostring(L, -1); if(txt==NULL || env_L->msg==NULL) return 0; LM_DBG("append hf: %s\n", txt); if (parse_headers(env_L->msg, HDR_EOH_F, 0) == -1) { LM_ERR("error while parsing message\n"); return 0; } hf = env_L->msg->last_header; len = strlen(txt); hdr = (char*)pkg_malloc(len); if(hdr==NULL) { LM_ERR("no pkg memory left\n"); return 0; } memcpy(hdr, txt, len); anchor = anchor_lump(env_L->msg, hf->name.s + hf->len - env_L->msg->buf, 0, 0); if(anchor==NULL) { LM_ERR("unable to get the anchor\n"); pkg_free(hdr); return 0; } if(insert_new_lump_before(anchor, hdr, len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(hdr); return 0; } return 0; }
/** * Adds a header to the message as the first one in the message * @param msg - the message to add a header to * @param content - the str containing the new header * @returns 1 on succes, 0 on failure */ int cscf_add_header_first(struct sip_msg *msg, str *hdr,int type) { struct hdr_field *first; struct lump* anchor,*l; first = msg->headers; anchor = anchor_lump(msg, first->name.s - msg->buf, 0 , 0 ); if (anchor == NULL) { LM_DBG( "cscf_add_header_first: anchor_lump failed\n"); return 0; } if (!(l=insert_new_lump_before(anchor, hdr->s,hdr->len,type))){ LM_ERR( "cscf_add_header_first: error creating lump for header\n" ); return 0; } return 1; }
static inline int add_diversion_helper(struct sip_msg* msg, str* s) { char *ptr; static struct lump* anchor = 0; static int msg_id = 0; if (msg_id != msg->id) { msg_id = msg->id; anchor = 0; } if (!msg->diversion && parse_headers(msg, HDR_DIVERSION_F, 0) == -1) { LOG(L_ERR, "add_diversion_helper: Header parsing failed\n"); return -1; } if (msg->diversion) { /* Insert just before the topmost Diversion header */ ptr = msg->diversion->name.s; } else { /* Insert at the end */ ptr = msg->unparsed; } if (!anchor) { anchor = anchor_lump(msg, ptr - msg->buf, 0, 0); if (!anchor) { LOG(L_ERR, "add_diversion_helper: Can't get anchor\n"); return -2; } } if (!insert_new_lump_before(anchor, s->s, s->len, 0)) { LOG(L_ERR, "add_diversion_helper: Can't insert lump\n"); return -3; } return 0; }
int add_maxfwd_header( struct sip_msg* msg , unsigned int val ) { unsigned int len; char *buf; struct lump* anchor; /* constructing the header */ len = MF_HDR_LEN /*"MAX-FORWARDS: "*/+ CRLF_LEN + 3/*val max on 3 digits*/; buf = (char*)pkg_malloc( len ); if (!buf) { LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: no more pkg memory\n"); goto error; } memcpy( buf , MF_HDR, MF_HDR_LEN ); len = MF_HDR_LEN ; len += btostr( buf+len , val ); memcpy( buf+len , CRLF , CRLF_LEN ); len +=CRLF_LEN; /*inserts the header at the beginning of the message*/ anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0); if (anchor == 0) { LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: failed to get anchor\n"); goto error1; } if (insert_new_lump_before(anchor, buf, len, 0) == 0) { LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: failed to insert " "MAX-FORWARDS lump\n"); goto error1; } return 1; error1: pkg_free( buf ); error: return -1; }
static int append_hf_helper(struct sip_msg* msg, str *str1, str *str2) { struct lump* anchor; char *s; int len; if (parse_headers(msg, HDR_EOH_F, 0) == -1) { LOG(L_ERR, "append_hf(): Error while parsing message\n"); return -1; } anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); if (anchor == 0) { LOG(L_ERR, "append_hf(): Can't get anchor\n"); return -1; } len=str1->len; if (str2) len+= str2->len + REQ_LINE(msg).uri.len; s = (char*)pkg_malloc(len); if (!s) { LOG(L_ERR, "append_hf(): No memory left\n"); return -1; } memcpy(s, str1->s, str1->len); if (str2) { memcpy(s+str1->len, REQ_LINE(msg).uri.s, REQ_LINE(msg).uri.len); memcpy(s+str1->len+REQ_LINE(msg).uri.len, str2->s, str2->len ); } if (insert_new_lump_before(anchor, s, len, 0) == 0) { LOG(L_ERR, "append_hf(): Can't insert lump\n"); pkg_free(s); return -1; } return 1; }
/* * Append header to SIP message * param msg SIP message * param header Header to be appended * return 0 success, -1 failure */ static int ospAppendHeader( struct sip_msg* msg, str* header) { char* s; struct lump* anchor; if((msg == 0) || (header == 0) || (header->s == 0) || (header->len <= 0)) { LM_ERR("bad parameters for appending header\n"); return -1; } if (parse_headers(msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return -1; } anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); if (anchor == 0) { LM_ERR("failed to get anchor\n"); return -1; } s = (char*)pkg_malloc(header->len); if (s == 0) { LM_ERR("no pkg memory\n"); return -1; } memcpy(s, header->s, header->len); if (insert_new_lump_before(anchor, s, header->len, 0) == 0) { LM_ERR("failed to insert lump\n"); pkg_free(s); return -1; } return 0; }
/* * Copy of append_hf_helper from textops. */ static inline int append_rpid_helper(struct sip_msg* _m, str *_s) { struct lump* anchor; if (parse_headers(_m, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return -1; } anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0); if (!anchor) { LM_ERR("can't get anchor\n"); return -2; } if (!insert_new_lump_before(anchor, _s->s, _s->len, 0)) { LM_ERR("can't insert lump\n"); return -3; } return 0; }
static int insert_value_lump(struct sip_msg* msg, struct hdr_field* hf, char* msg_position, int lump_before, str *val) { struct lump* anchor; char *s; int len; anchor = anchor_lump(msg, msg_position - msg->buf, 0, 0); if (anchor == 0) { LOG(L_ERR, "ERROR: textops: insert_value_lump(): Can't get anchor\n"); return -1; } len=val->len+1; s = (char*)pkg_malloc(len); if (!s) { LOG(L_ERR, "ERROR: textops: insert_value_lump(): not enough memory\n"); return -1; } if (!hf) { memcpy(s, val->s, val->len); len--; } else if (msg_position == hf->body.s+hf->body.len) { s[0] = ','; memcpy(s+1, val->s, val->len); } else { memcpy(s, val->s, val->len); s[val->len] = ','; } if ( (lump_before?insert_new_lump_before(anchor, s, len, 0):insert_new_lump_after(anchor, s, len, 0)) == 0) { LOG(L_ERR, "ERROR: textops: insert_value_lump(): Can't insert lump\n"); pkg_free(s); return -1; } return 1; }
static inline struct lump *insert_rr_param_lump(struct lump *before, char *s, int l) { struct lump *rrp_l; char *s1; /* duplicate data in pkg mem */ s1 = (char*)pkg_malloc(l); if (s1==0) { LM_ERR("no more pkg mem (%d)\n",l); return 0; } memcpy( s1, s, l); /* add lump */ rrp_l = insert_new_lump_before( before, s1, l, 0); if (rrp_l==0) { LM_ERR("failed to add before lump\n"); pkg_free(s1); return 0; } return rrp_l; }
static int assign_hf_do_lumping(struct sip_msg* msg,struct hdr_field* hf, struct hname_data* hname, str* value, int upd_del_fl, str* lump_upd, str* lump_del, char delim) { int len, i; char *s; struct lump* anchor; if (upd_del_fl) { len = value?lump_upd->len:lump_del->len; if (len > 0) { if (!del_lump(msg, (value?lump_upd->s:lump_del->s)-msg->buf, len, 0)) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n"); return -1; } } if (value && value->len) { anchor = anchor_lump(msg, lump_upd->s - msg->buf, 0, 0); if (anchor == 0) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't get anchor\n"); return -1; } len = 1+value->len; s = pkg_malloc(len); if (!s) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n"); return -1; } s[0]='='; memcpy(s+1, value->s, value->len); if ( (insert_new_lump_before(anchor, s, len, 0)) == 0) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't insert lump\n"); pkg_free(s); return -1; } } } else { if (!value) return -1; anchor = anchor_lump(msg, lump_del->s - msg->buf, 0, 0); if (anchor == 0) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't get anchor\n"); return -1; } len = 1+hname->param.len+(value->len?value->len+1:0); s = pkg_malloc(len); if (!s) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n"); return -1; } if (delim) { s[0] = delim; i = 1; } else { i = 0; len--; } memcpy(s+i, hname->param.s, hname->param.len); if (value->len) { s[hname->param.len+i]='='; memcpy(s+i+hname->param.len+1, value->s, value->len); } if ( (insert_new_lump_before(anchor, s, len, 0)) == 0) { LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't insert lump\n"); pkg_free(s); return -1; } } return 1; }
int rtjson_prepare_branch(sip_msg_t *msg, srjson_doc_t *jdoc, srjson_t *nj) { srjson_t *rj = NULL; srjson_t *tj = NULL; srjson_t *vj = NULL; str xdsp = {0}; str xuri = {0}; str xhdr = {0}; unsigned int fr = 0; unsigned int fr_inv = 0; struct lump *anchor = NULL; char *s; if(tmb.set_fr!=NULL) { rj = srjson_GetObjectItem(jdoc, nj, "fr_timer"); if(rj!=NULL && rj->type==srjson_Number && SRJSON_GET_UINT(rj)!=0) { fr = SRJSON_GET_UINT(rj); } rj = srjson_GetObjectItem(jdoc, nj, "fr_inv_timer"); if(rj!=NULL && rj->type==srjson_Number && SRJSON_GET_UINT(rj)!=0) { fr_inv = SRJSON_GET_UINT(rj); } if(fr || fr_inv) tmb.set_fr(msg, fr_inv, fr); } rj = srjson_GetObjectItem(jdoc, nj, "headers"); if(rj==NULL || rj->type!=srjson_Object || rj->child==NULL) { LM_DBG("no header operations - done\n"); return 0; } tj = srjson_GetObjectItem(jdoc, rj, "extra"); if(tj!=NULL && tj->type==srjson_String && tj->valuestring!=0) { xhdr.s = tj->valuestring; xhdr.len = strlen(xhdr.s); } if(xhdr.len>4) { LM_DBG("appending extra headers: [%.*s]\n", xhdr.len, xhdr.s); anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); if(anchor == 0) { LM_ERR("can't get anchor\n"); return -1; } s = pkg_malloc(xhdr.len+1); if(s==NULL) { LM_ERR("no more pkg\n"); return -1; } strncpy(s, xhdr.s, xhdr.len); s[xhdr.len] = '\0'; if (insert_new_lump_before(anchor, s, xhdr.len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(s); return -1; } } if(uacb.replace_from!=NULL) { tj = srjson_GetObjectItem(jdoc, rj, "from"); if(tj!=NULL && tj->type==srjson_Object && rj->child!=NULL) { vj = srjson_GetObjectItem(jdoc, tj, "display"); if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) { xdsp.s = vj->valuestring; xdsp.len = strlen(xdsp.s); } vj = srjson_GetObjectItem(jdoc, tj, "uri"); if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) { xuri.s = vj->valuestring; xuri.len = strlen(xuri.s); } if(xdsp.len>0 || xuri.len>0) { uacb.replace_from(msg, &xdsp, &xuri); } } } if(uacb.replace_to!=NULL) { tj = srjson_GetObjectItem(jdoc, rj, "to"); if(tj!=NULL && tj->type==srjson_Object && rj->child!=NULL) { vj = srjson_GetObjectItem(jdoc, tj, "display"); if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) { xdsp.s = vj->valuestring; xdsp.len = strlen(xdsp.s); } vj = srjson_GetObjectItem(jdoc, tj, "uri"); if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) { xuri.s = vj->valuestring; xuri.len = strlen(xuri.s); } if(xdsp.len>0 || xuri.len>0) { uacb.replace_to(msg, &xdsp, &xuri); } } } return 0; }
/*! \brief * build a Record-Route header field */ static inline int build_rr(struct lump* _l, struct lump* _l2, str* user, str *tag, str *params, struct lump *lp, int _inbound) { char* prefix, *suffix, *term, *r2; int suffix_len, prefix_len; char *p; prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0); suffix_len = RR_LR_LEN + (params?params->len:0) + ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0); prefix = pkg_malloc(prefix_len); suffix = pkg_malloc(suffix_len); term = pkg_malloc(RR_TERM_LEN); r2 = pkg_malloc(RR_R2_LEN); if (!prefix || !suffix || !term || !r2) { LM_ERR("No more pkg memory\n"); if (suffix) pkg_free(suffix); if (prefix) pkg_free(prefix); if (term) pkg_free(term); if (r2) pkg_free(r2); return -3; } memcpy(prefix, RR_PREFIX, RR_PREFIX_LEN); if (user->len) { memcpy(prefix + RR_PREFIX_LEN, user->s, user->len); #ifdef ENABLE_USER_CHECK /* don't add the ignored user into a RR */ if(i_user.len && i_user.len == user->len && !strncmp(i_user.s, user->s, i_user.len)) { if(prefix[RR_PREFIX_LEN]=='x') prefix[RR_PREFIX_LEN]='y'; else prefix[RR_PREFIX_LEN]='x'; } #endif prefix[RR_PREFIX_LEN + user->len] = '@'; } p = suffix; memcpy( p, RR_LR, RR_LR_LEN); p += RR_LR_LEN; if (tag && tag->len) { memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN); p += RR_FROMTAG_LEN; memcpy(p, tag->s, tag->len); p += tag->len; } if (params && params->len) { memcpy(p, params->s, params->len); p += params->len; } memcpy(term, RR_TERM, RR_TERM_LEN); memcpy(r2, RR_R2, RR_R2_LEN); if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0))) goto lump_err; prefix = 0; _l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_ALL:SUBST_SND_ALL, 0); if (_l ==0 ) goto lump_err; if (enable_double_rr) { if (!(_l = insert_cond_lump_after(_l, COND_IF_DIFF_REALMS, 0))) goto lump_err; if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0))) goto lump_err; r2 = 0; } else { pkg_free(r2); r2 = 0; } _l2 = insert_new_lump_before(_l2, suffix, suffix_len, 0); if (_l2 == 0) goto lump_err; suffix = 0; if ( lp ) { /* link the pending buffered params and go at the end of the list */ for ( _l2->before = lp ; _l2 && _l2->before ; _l2=_l2->before); } if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0))) goto lump_err; term = 0; return 0; lump_err: LM_ERR("failed to insert lumps\n"); if (prefix) pkg_free(prefix); if (suffix) pkg_free(suffix); if (r2) pkg_free(r2); if (term) pkg_free(term); return -4; }
static int request_hf_helper(struct sip_msg* msg, str* hf, avp_ident_t* ident, struct lump* anchor, struct search_state* st, int front, int reverse, int reply) { struct lump* new_anchor; static struct search_state state; avp_t* avp; char* s; str fin_val; int len, ret; int_str val; struct hdr_field* pos, *found = NULL; if (!anchor && !reply) { if (parse_headers(msg, HDR_EOH_F, 0) == -1) { LOG(L_ERR, "ERROR: request_hf_helper: Error while parsing message\n"); return -1; } pos = msg->headers; while (pos && (pos->type != HDR_EOH_T)) { if ((hf->len == pos->name.len) && (!strncasecmp(hf->s, pos->name.s, pos->name.len))) { found = pos; if (front) { break; } } pos = pos->next; } if (found) { if (front) { len = found->name.s - msg->buf; } else { len = found->name.s + found->len - msg->buf; } } else { len = msg->unparsed - msg->buf; } new_anchor = anchor_lump(msg, len, 0, 0); if (new_anchor == 0) { LOG(L_ERR, "ERROR: request_hf_helper: Can't get anchor\n"); return -1; } } else { new_anchor = anchor; } if (!st) { st = &state; avp = search_avp(*ident, NULL, st); ret = -1; } else { avp = search_next_avp(st, NULL); ret = 1; } if (avp) { if (reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) { return -1; } get_avp_val(avp, &val); if (avp->flags & AVP_VAL_STR) { fin_val = val.s; } else { fin_val.s = int2str(val.n, &fin_val.len); } len = hf->len + 2 + fin_val.len + 2; s = (char*)pkg_malloc(len); if (!s) { LOG(L_ERR, "ERROR: request_hf_helper: No memory left for data lump\n"); return -1; } memcpy(s, hf->s, hf->len); memcpy(s + hf->len, ": ", 2 ); memcpy(s + hf->len+2, fin_val.s, fin_val.len ); memcpy(s + hf->len + 2 + fin_val.len, CRLF, CRLF_LEN); if (reply) { if (add_lump_rpl( msg, s, len, LUMP_RPL_HDR | LUMP_RPL_NODUP) == 0) { LOG(L_ERR, "ERROR: request_hf_helper: Can't insert RPL lump\n"); pkg_free(s); return -1; } } else { if ((front && (insert_new_lump_before(new_anchor, s, len, 0) == 0)) || (!front && (insert_new_lump_after(new_anchor, s, len, 0) == 0))) { LOG(L_ERR, "ERROR: request_hf_helper: Can't insert lump\n"); pkg_free(s); return -1; } } if (!reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) { return -1; } return 1; }; /* in case of topmost call (st==NULL) return error */ /* otherwise it's OK, no more AVPs found */ return ret; }
/** * Send the request back simulating an AS. * - Inserts a Header with the contents of str2 * - Tries to find the Route: appserver_uri, s-cscf_uri header and removes appserver_uri from it * - It forwards the message to s-scsf_uri, or if none found to str1 * @param msg - The sip message * @param str1 - The uri of the SCSCF to default to if Route header is not found * @param str2 - The Header to add to the message - if empty none will be added * @returns - 0 to cancel further script processing */ int isc_appserver_forward(struct sip_msg *msg,char *str1,char *str2 ) { struct hdr_field *last,*hdr; struct lump* anchor; str header_mark; rr_t *rr; LOG(L_DBG,"DEBUG:"M_NAME":isc_appserver_forward: Forward-back request reached\n"); parse_headers(msg,HDR_EOH_F,0); last = msg->headers; while(last->next) last = last->next; LOG(L_INFO,"INFO:"M_NAME":isc_appserver_forward: New header: [%s]\n%.*s",str2,msg->len,msg->buf); /* Put header marking */ if (strlen(str2)){ header_mark.s = pkg_malloc(256);//36 should be enough sprintf(header_mark.s,"%.*s\n",strlen(str2),str2); header_mark.len =strlen(header_mark.s); anchor = anchor_lump(msg, last->name.s + last->len - msg->buf, 0 , 0); if (anchor == NULL) { LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: anchor_lump failed\n"); } if (!insert_new_lump_before(anchor, header_mark.s,header_mark.len,0)){ LOG( L_ERR, "ERROR:"M_NAME":isc_appserver_forward: error creting lump for header_mark\n" ); } //pkg_free(header_mark.s); } LOG(L_ERR, "INFO:"M_NAME":isc_appserver_forward: Searching Route header to rewrite\n"); /* Search for the Route */ hdr = msg->headers; while(hdr){ if (hdr->type == HDR_ROUTE_T){ if (!hdr->parsed){ if (parse_rr(hdr) < 0) { LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: Error while parsing Route HF\n"); continue; } } rr = (rr_t*)hdr->parsed; while(rr){ if (rr->nameaddr.uri.len >= ISC_MARK_USERNAME_LEN && strncasecmp(rr->nameaddr.uri.s,ISC_MARK_USERNAME,ISC_MARK_USERNAME_LEN)==0) { LOG(L_INFO,"DEBUG:"M_NAME":isc_appserver_forward: Found S-CSCF marking <%.*s> \n",rr->nameaddr.uri.len,rr->nameaddr.uri.s); /* delete the header */ if (!del_lump(msg, hdr->name.s - msg->buf, hdr->len, 0)) { LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: Can't remove Route HF\n"); } /* add the new header */ anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0); header_mark.s = pkg_malloc(256);//36 should be enough sprintf(header_mark.s,"Route: <%.*s>\n",rr->nameaddr.uri.len,rr->nameaddr.uri.s); header_mark.len =strlen(header_mark.s); if (!insert_new_lump_before(anchor, header_mark.s,header_mark.len,0)){ LOG( L_ERR, "ERROR:"M_NAME":isc_appserver_forward: error creting lump for route header\n" ); } /* send the message */ msg->dst_uri.s = pkg_malloc(rr->nameaddr.uri.len); memcpy(msg->dst_uri.s,rr->nameaddr.uri.s,rr->nameaddr.uri.len); msg->dst_uri.len=rr->nameaddr.uri.len; isc_tmb.t_relay(msg,0,0); return 0; } rr = rr->next; } } hdr = hdr->next; } /* In case no suitable route header found, just fwd to the given parameter */ msg->dst_uri.len = strlen(str1); msg->dst_uri.s = str1; isc_tmb.t_relay(msg,0,0); LOG(L_DBG,"DEBUG:"M_NAME":isc_appserver_forward: Mirror request finished\n"); return 0; }
/*! \brief * Insert manually created Record-Route header, no checks, no restrictions, * always adds lr parameter, only fromtag is added automatically when requested */ int record_route_preset(struct sip_msg* _m, str* _data) { str user; struct to_body* from; struct lump* l, *lp, *ap; struct lump* l2; char *hdr, *suffix, *p, *term; int hdr_len, suffix_len; from = 0; user.len = 0; user.s = 0; if (add_username) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } if (append_fromtag) { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); return -2; } from = (struct to_body*)_m->from->parsed; } hdr_len = RR_PREFIX_LEN; if (user.len) hdr_len += user.len + 1; /* @ */ hdr_len += _data->len; suffix_len = 0; if (append_fromtag && from->tag_value.len) { suffix_len += RR_FROMTAG_LEN + from->tag_value.len; } suffix_len += RR_LR_LEN; hdr = pkg_malloc(hdr_len); term = pkg_malloc(RR_TERM_LEN); suffix = pkg_malloc(suffix_len); if (!hdr || !term || !suffix) { LM_ERR("no pkg memory left\n"); return -4; } /* header */ p = hdr; memcpy(p, RR_PREFIX, RR_PREFIX_LEN); p += RR_PREFIX_LEN; if (user.len) { memcpy(p, user.s, user.len); p += user.len; *p = '@'; p++; } memcpy(p, _data->s, _data->len); p += _data->len; /*suffix*/ p = suffix; if (append_fromtag && from->tag_value.len) { memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN); p += RR_FROMTAG_LEN; memcpy(p, from->tag_value.s, from->tag_value.len); p += from->tag_value.len; } memcpy(p, RR_LR, RR_LR_LEN); p += RR_LR_LEN; memcpy(term, RR_TERM, RR_TERM_LEN); l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T); if (!l || !l2) { LM_ERR("failed to create lump anchor\n"); goto error; } if (!(l=insert_new_lump_after(l, hdr, hdr_len, 0))) { LM_ERR("failed to insert new lump\n"); goto error; } hdr = NULL; l2 = insert_new_lump_before(l2, suffix, suffix_len, HDR_RECORDROUTE_T); if (l2==NULL) { LM_ERR("failed to insert suffix lump\n"); goto error; } suffix = NULL; /* look for pending RR params */ for( lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) { if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP && ap->before && ap->before->op==LUMP_ADD_OPT && ap->before->u.cond==COND_FALSE) { /* found our phony anchor lump */ /* jump over the anchor and conditional lumps */ lp = ap->before->before; /* unlink it */ ap->before->before = NULL; ap->type = 0; /* link the pending buffered params and go at the end of the list*/ for ( l2->before = lp ; l2 && l2->before ; l2=l2->before); break; } } if (!(l2=insert_new_lump_before(l2, term, RR_TERM_LEN, 0))) { LM_ERR("failed to insert term lump"); goto error; } term = NULL; return 1; error: if (hdr) pkg_free(hdr); if (term) pkg_free(term); if (suffix) pkg_free(suffix); return -1; }
/** * sngtc_caller_answer - attaches an SDP body to ACK requests */ static int sngtc_caller_answer(struct sip_msg *msg) { char *p; str body; struct dlg_cell *dlg; struct lump *lump; struct sngtc_info *info; int len; LM_DBG("processing ACK\n"); if (get_body(msg, &body) != 0 || body.len > 0) { LM_ERR("ACK should not contain a SDP body\n"); return SNGTC_ERR; } dlg = dlg_binds.get_dlg(); if (!dlg) { LM_ERR("failed to fetch current dialog\n"); return SNGTC_ERR; } /* get the SDP body from the INVITE which was mangled at 200 OK */ if (dlg_binds.fetch_dlg_value(dlg, &dlg_key_sngtc_info, &body, 0) != 0) { LM_ERR("failed to fetch caller sdp\n"); return SNGTC_ERR; } info = *(struct sngtc_info **)(body.s); /* duplicate the SDP in pkg mem for the lumps mechanism */ if (pkg_str_dup(&body, &info->modified_caller_sdp) != 0) { LM_ERR("failed to dup in pkg mem\n"); return SNGTC_ERR; } LM_DBG("Duplicated SDP: '%.*s'\n", body.len, body.s); lump = anchor_lump(msg, msg->content_length->name.s - msg->buf, 0); if (!lump) { LM_ERR("failed to insert anchor lump\n"); return SNGTC_ERR; } p = pkg_malloc(SDP_CONTENT_TYPE_LEN); if (!p) { LM_ERR("no more pkg memory\n"); return SNGTC_ERR; } /* add the Content-Type header */ memcpy(p, "Content-Type: application/sdp\r\n", SDP_CONTENT_TYPE_LEN); if (!insert_new_lump_before(lump, p, SDP_CONTENT_TYPE_LEN, 0)) { LM_ERR("failed to insert Content-Type lump\n"); return SNGTC_ERR; } LM_DBG("blen: %d\n", msg->content_length->body.len); lump = del_lump(msg, msg->content_length->body.s - msg->buf, msg->content_length->body.len, HDR_OTHER_T); if (!lump) { LM_ERR("failed to insert del lump for the content length\n"); return SNGTC_ERR; } p = pkg_malloc(CONTENT_LEN_DIGITS); if (!p) { LM_ERR("no more pkg memory\n"); return SNGTC_ERR; } LM_DBG("len: %d\n", body.len); len = sprintf(p, "%d", body.len); if (!insert_new_lump_after(lump, p, len, HDR_OTHER_T)) { LM_ERR("failed to insert Content-Length lump\n"); return SNGTC_ERR; } lump = anchor_lump(msg, msg->len - CRLF_LEN, 0); if (!lump) { LM_ERR("failed to insert anchor lump\n"); return SNGTC_ERR; } if (!insert_new_lump_before(lump, body.s, body.len, 0)) { LM_ERR("failed to insert SDP body lump\n"); return SNGTC_ERR; } return 1; }