Documentation |
Documentation -> Development Manual -> Changing SIP MessagesThis page has been visited 253 times.
Table of Content (hide) 1. Changing SIP MessagesThe standard mechanism for performing changes on SIP messages within OpenSIPS is by using the so called lumps system.
2. SIP Request LumpsThis type of lumps operate on the current SIP message context.
2.1 Delete Lumpsdata_lump.h exposes /* Parameters : msg - the SIP message the lump will affect offset - the offset in the SIP message at which to start deleting len - the number of characters to delete from the SIP message type - indication on which header the current lump affects ( can be 0 ) Returns : the created lump structure for deleting part of the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error. */ struct lump* del_lump(struct sip_msg* msg, unsigned int offset, unsigned int len, enum _hdr_types_t type);
/* first parse the header to figure out where it actually starts in the SIP message */ if( parse_headers(msg,HDR_RPID_F,0)<0 || msg->rpid == NULL ){ LM_DBG(“No rpid header – nothing to delete \n”); return 0; } /* delete the entire RPID header */ if ( del_lump(msg, msg->rpid->name.s-msg->buf, msg->rpid->len,HDR_RPID_T )== NULL) { LM_ERR(“Failed to delete RPID header \n”); return -1; } 2.2 Add Lumpsdata_lump.h exposes /* Parameters : after/before - the lump where we will connect our new lump new_hdr - string to be added len - length of the string to be added type - header type that is affected by the current change ( can be 0 ) Returns : the created lump structure for adding to the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error. */ struct lump* insert_new_lump_after(struct lump* after, char* new_hdr, unsigned int len, enum _hdr_types_t type); struct lump* insert_new_lump_before(struct lump* before, char* new_hdr, unsigned int len,enum _hdr_types_t type);
/* Parameters : msg - the SIP message that will be affected by the lump anchor offset - the offset in the SIP message where the anchor will be placed len - not currently used ( should be 0 ) type - header type that is affected by the current change ( can be 0 ) Returns: the created lump structure for adding to the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error. */ struct lump* anchor_lump(struct sip_msg* msg, unsigned int offset, int unsigned len, enum _hdr_types_t type)
/* make sure we detect all headers */ if (parse_headers(msg, HDR_EOH_F, 0) == -1) { LM_ERR("error while parsing message\n"); return -1; } /* add the anchor at the very end of the SIP headers */ anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); if (anchor == NULL) { LM_ERR(“Failed to create lump anchor\n”); return -1; } len = sizeof(“MY_HDR: MY_VAL\r\n”) -1; new_hdr=pkg_malloc(len); if (!new_hdr) { LM_ERR(“No more pkg mem\n”); return -1; } memcpy(new_hdr,”MY_HDR: MY_VAL\r\n”,len); if (insert_new_lump_after(anchor, new_hdr, len, 0) == 0) { LM_ERR("can't insert lump\n"); pkg_free(new_hdr); return -1; } /* job done, the PKG new_hdr mem will be free internally when the lump will be applied */ return 0; If we want to replace a particular part of a SIP message, the operation can be split in two steps, first deleting the part we don't need anymore by calling del_lump, and then using the returned lump to add a new lump after it.
/* first parse the header to figure out where it actually starts in the SIP message */ if( parse_headers(msg,HDR_RPID_F,0)<0 || msg->rpid == NULL ){ LM_DBG(“No rpid header – nothing to delete \n”); return 0; } /* delete just the contents of the RPID header */ del = del_lump(msg, msg->rpid->body.s-msg->buf, msg->rpid->body.len,HDR_RPID_T); if ( del == NULL) { LM_ERR(“Failed to delete RPID header \n”); return -1; } len = sizeof(“sip:new_rpid@my_domain.com\r\n”) -1; new_rpid=pkg_malloc(len); if (!new_rpid) { LM_ERR(“No more pkg mem\n”); return -1; } memcpy(new_rpid,“sip:new_rpid@my_domain.com\r\n”,len); if(insert_new_lump_after(del,new_rpid,len,HDR_RPID_T)==NULL) { LM_ERR("Failed to insert new callid\n"); pkg_free(new_rpid); return -1; } 3. SIP Reply LumpsWhen used in the case of a SIP request, these lumps will operate on the SIP reply that will be internally generated when rejecting a request from within OpenSIPS ( if the Request if forwarded instead of rejected at OpenSIPS level, these lumps will have no effect ). Since the reply will be internally generated by OpenSIPS, the Reply Lumps can only add new content.
/* Parameters : msg - the SIP Request that the reply will be generated for s - the string to be added to the reply len - the length of the string to be added flags - Since the reply will be generated by OpenSIPS, it is important to mark your lump if it should be added to the Reply headers or to the Reply body. Relevant flags for these cases are LUMP_RPL_HDR and LUMP_RPL_BODY. Returns : the created lump structure for adding to the SIP reply. Can be further used to chain together lumps in the message attached list of lumps. NULL is returned in case of internal error. */ struct lump_rpl* add_lump_rpl(struct sip_msg *msg, char *s, int len, int flags);
static char ct[CT_LEN] = “Contact: opensips@my_domain.com\r\n”; /* we are adding a lump to the headers, so we pass the LUMP_RPL_HDR flag also , our buffer is located in a static buffer, thus no need for the core to allocate memory for this lump, we also pass the LUMP_RPL_NODUP flag */ if (add_lump_rpl(msg, ct, CT_LEN, LUMP_RPL_HDR | LUMP_RPL_NODUP)==0) { LM_ERR("unable to add lump\n"); return -1; } |