Login | Register

Documentation

Documentation -> Development Manual -> Changing SIP Messages

This page has been visited 253 times.



Changing SIP Messages

1.  Changing SIP Messages

The standard mechanism for performing changes on SIP messages within OpenSIPS is by using the so called lumps system.
The lump system works very similarly to the diff/patch tools in the Linux environment – the developer adds add and/or remove operations to a SIP message. The lumps are stored in a list, and are only applied after the OpenSIPS script is fully executed and before the SIP message is relayed. Because of this, changes done on a SIP message are not immediately reflected on the SIP message upon further inspection ( eg. Adding a new header from the script and then checking for the header's existence ).
When talking about the SIP message they have an effect on, the lumps can be split into the following categories :

2.  SIP Request Lumps

This type of lumps operate on the current SIP message context.
From operational point of view, they are also split into two categories :

2.1  Delete Lumps

data_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);


Example of deleting the RPID header :

      /* 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 Lumps

data_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);


If the developer's desire is just to add a particular string to the SIP message, a new anchor lump must be created, that will then have to be provided as the first parameter to insert_new_lump_after/insert_new_lump_before.
For creating a new anchor lump, data_lump.h also exports

/*
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)


Example of adding a new SIP header at the end of the SIP message headers :

      /* 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.
Example of replacing the content of the RPID header :

      /* 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 Lumps

When 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.
data_lump_rpl.h exposes

/*
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);


Example of Adding contact header to the internally generated reply :

      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;
      }

Page last modified on May 31, 2024, at 09:53 AM