Esempio n. 1
0
/* Encoder for route/record-route units (may be inside an aggegated
 * Route/RRoute header, see [rfc3261, 7.3.1, page 30] ).
 * Returns the length of the encoded structure in bytes
 * FORMAT (byte meanings):
 * 1: flags
 * 	0x01 :	there is a Display Name
 * 1: length of the XURI-encoded uri in bytes.
 * [2]: optionally, 1 HDR-based ptr to the displayname + the length of the name
 * N: the XURI-encoded URI.
 * [N:] optionally, HDR-based pointers to the different header-parameters
 *
 */
int encode_route(char *hdrstart,int hdrlen,rr_t *body,unsigned char *where)
{
   int i=2,j=0;/* 1*flags + 1*URI_len*/
   unsigned char flags=0;
   struct sip_uri puri;

   if(body->nameaddr.name.s && body->nameaddr.name.len){
      flags|=HAS_NAME_F;
      where[i++]=(unsigned char)(body->nameaddr.name.s-hdrstart);
      where[i++]=(unsigned char)body->nameaddr.name.len;
   }

   if (parse_uri(body->nameaddr.uri.s, body->nameaddr.uri.len,&puri) < 0 ) {
      LM_ERR("Bad URI in address\n");
	  return -1;
   }else{
      if((j=encode_uri2(hdrstart,hdrlen,body->nameaddr.uri,&puri,&where[i]))<0){
	 LM_ERR("error codifying the URI\n");
	 return -1;
      }else{
	 i+=j;
      }
   }
   where[0]=flags;
   where[1]=(unsigned char)j;
   i+=encode_parameters(&where[i],(void *)body->params,hdrstart,body,'n');
   return i;
}
Esempio n. 2
0
/* Encoder for contacts.
 * Returns the length of the encoded structure in bytes
 * FORMAT (byte meanings):
 * 1: flags
 * 	0x01 :	there is a Display Name
 * 	0x02 :	there is a Q parameter
 * 	0x04 :	there is an EXPIRES parameter
 * 	0x08 :	there is a RECEIVED parameter
 * 	0x10 :	there is a METHOD parameter
 * 1: length of the XURI-encoded uri in bytes.
 * [2]: optionally, 1 HDR-based ptr to the displayname + the length of the name
 * [2]: optionally, 1 HDR-based ptr to the q + the length of the q
 * [2]: optionally, 1 HDR-based ptr to the expires + the length of the expires
 * [2]: optionally, 1 HDR-based ptr to the received param + the length of the param
 * [2]: optionally, 1 HDR-based ptr to the method + the length of the method parameter
 * N: the XURI-encoded URI.
 * [N:] optionally, HDR-based pointers to the different header-parameters
 *
 */
int encode_contact(char *hdrstart,int hdrlen,contact_t *body,unsigned char *where)
{
   int i=2,j=0;/* 1*flags + 1*URI_len*/
   unsigned char flags=0;
   struct sip_uri puri;

   if(body->name.s && body->name.len){
      flags|=HAS_NAME_F;
      where[i++]=(unsigned char)(body->name.s-hdrstart);
      where[i++]=(unsigned char)body->name.len;
   }
   if(body->q){
      flags|=HAS_Q_F;
      where[i++]=(unsigned char)(body->q->name.s-hdrstart);
      where[i++]=(unsigned char)body->q->len;
   }
   if(body->expires){
      flags|=HAS_EXPIRES_F;
      where[i++]=(unsigned char)(body->expires->name.s-hdrstart);
      where[i++]=(unsigned char)body->expires->len;
   }
   if(body->received){
      flags|=HAS_RECEIVED_F;
      where[i++]=(unsigned char)(body->received->name.s-hdrstart);
      where[i++]=(unsigned char)body->received->len;
   }
   if(body->methods){
      flags|=HAS_METHOD_F;
      where[i++]=(unsigned char)(body->methods->name.s-hdrstart);
      where[i++]=(unsigned char)body->methods->len;
   }

   if (parse_uri(body->uri.s, body->uri.len,&puri) < 0 ) {
      LM_ERR("Bad URI in address\n");
      return -1;
   }else{
      if((j=encode_uri2(hdrstart,hdrlen,body->uri,&puri,&where[i]))<0){
	 LM_ERR("failed to codify the URI\n");
	 return -1;
      }else{
	 i+=j;
      }
   }
   where[0]=flags;
   where[1]=(unsigned char)j;
   /*CAUTION the  parameters are in reversed order !!! */
   /*TODO parameter encoding logic should be moved to a specific function...*/

   i+=encode_parameters(&where[i],body->params,hdrstart,body,'n');
   return i;
}
Esempio n. 3
0
/* Encoder for From and To headers.
 * Returns the length of the encoded structure in bytes
 * FORMAT (byte meanings):
 * 1: flags
 * 	0x10 :	there is a Display Name
 * 	0x20 :	there is a tag parameter
 * 	0x40 :	there are other parameters
 * 1: length of the XURI-encoded uri in bytes.
 * [2]: optionally, 1 HDR-based ptr to the displayname + the length of the name
 * [2]: optionally, 1 HDR-based ptr to the tag + the length of the tag parameter
 * N: the XURI-encoded URI.
 * [N:] optionally, HDR-based pointers to the different header-parameters
 *
 */
int encode_to_body(char *hdrstart,int hdrlen,struct to_body *body,unsigned char *where)
{
   int i=2,j=0;/* 1*flags + 1*URI_len*/
   unsigned char flags=0;
   struct sip_uri puri;

   if(body->display.s && body->display.len){
      flags|=HAS_DISPLAY_F;
      if(body->display.s[0]=='\"'){
	 body->display.s++;
	 body->display.len-=2;
      }
      where[i++]=(unsigned char)(body->display.s-hdrstart);
      where[i++]=(unsigned char)(body->display.len);
   }
   if(body->tag_value.s && body->tag_value.len){
      flags|=HAS_TAG_F;
      where[i++]=(unsigned char)(body->tag_value.s-hdrstart);
      where[i++]=(unsigned char)body->tag_value.len;
   }
   if (parse_uri(body->uri.s, body->uri.len,&puri) < 0 ) {
      LM_ERR("Bad URI in address\n");
      return -1;
   }else{
      if((j=encode_uri2(hdrstart,hdrlen,body->uri,&puri,&where[i]))<0){
	 LM_ERR("failed to codify the URI\n");
	 return -1;
      }else{
	 i+=j;
      }
   }
   where[0]=flags;
   where[1]=(unsigned char)j;
   i+=encode_parameters(&where[i],(void *)body->param_lst,hdrstart,body,'t');

   return i;
}
Esempio n. 4
0
int encode_digest(char *hdrstart,int hdrlen,dig_cred_t *digest,unsigned char *where)
{
   int i=2,j=0;/* 2*flags */
   unsigned char flags1=0,flags2=0;
   struct sip_uri sipuri;

   if(digest->username.whole.s && digest->username.whole.len){
      flags1|=HAS_NAME_F;
      where[i++]=(unsigned char)(digest->username.whole.s-hdrstart);
      where[i++]=(unsigned char)digest->username.whole.len;
   }
   if(digest->realm.s && digest->realm.len){
      flags1|=HAS_REALM_F;
      where[i++]=(unsigned char)(digest->realm.s-hdrstart);
      where[i++]=(unsigned char)digest->realm.len;
   }
   if(digest->nonce.s && digest->nonce.len){
      flags1|=HAS_NONCE_F;
      where[i++]=(unsigned char)(digest->nonce.s-hdrstart);
      where[i++]=(unsigned char)digest->nonce.len;
   }
   if(digest->uri.s && digest->uri.len){
      memset(&sipuri,0,sizeof(struct sip_uri));
      flags1|=HAS_URI_F;
      if (parse_uri(digest->uri.s, digest->uri.len,&sipuri) < 0 ) {
	 LM_ERR("Bad URI in address\n");
	 return -1;
      }else{
	 if((j=encode_uri2(hdrstart,hdrlen,digest->uri,&sipuri,&where[i+1]))<0){
	    LM_ERR("Error encoding the URI\n");
	    return -1;
	 }else{
	    where[i]=(unsigned char)j;
	    i+=(j+1);
	 }
      }
   }
   if(digest->response.s && digest->response.len){
      flags1|=HAS_RESPONSE_F;
      where[i++]=(unsigned char)(digest->response.s-hdrstart);
      where[i++]=(unsigned char)digest->response.len;
   }
   if(digest->alg.alg_str.s && digest->alg.alg_str.len){
      flags1|=HAS_ALG_F;
      where[i++]=(unsigned char)(digest->alg.alg_str.s-hdrstart);
      where[i++]=(unsigned char)digest->alg.alg_str.len;
   }
   if(digest->cnonce.s && digest->cnonce.len){
      flags1|=HAS_CNONCE_F;
      where[i++]=(unsigned char)(digest->cnonce.s-hdrstart);
      where[i++]=(unsigned char)digest->cnonce.len;
   }
   if(digest->opaque.s && digest->opaque.len){
      flags1|=HAS_OPAQUE_F;
      where[i++]=(unsigned char)(digest->opaque.s-hdrstart);
      where[i++]=(unsigned char)digest->opaque.len;
   }
   if(digest->qop.qop_str.s && digest->qop.qop_str.len){
      flags2|=HAS_QoP_F;
      where[i++]=(unsigned char)(digest->qop.qop_str.s-hdrstart);
      where[i++]=(unsigned char)digest->qop.qop_str.len;
   }
   if(digest->nc.s && digest->nc.len){
      flags2|=HAS_NC_F;
      where[i++]=(unsigned char)(digest->nc.s-hdrstart);
      where[i++]=(unsigned char)digest->nc.len;
   }
   where[0]=flags1;
   where[1]=flags2;
   return i;
}
Esempio n. 5
0
/* This function extracts meta-info from the sip_msg structure and
 * formats it so that it can be used to rapidly access the message structured
 * parts.
 *
 * RETURNS: LENGTH of structure on success, <0 if failure
 * if there was failure, you dont need to pkg_free the payload (it is done inside).
 * if there was success, you __NEED_TO_PKG_FREE_THE_PAYLOAD__ from the calling function.
 *
 * The encoded meta-info is composed by 3 sections:
 *
 * MSG_META_INFO:
 * 2: short int in network-byte-order, if <100, the msg is a REQUEST and the int
 * is the code of the METHOD. if >100, it is a RESPONSE and the int is the code
 * of the response.
 * 2: short int in NBO: payload-start based pointer (index) to where the SIP MSG starts.
 * 2: short int in NBO: the sip-message length
 * 2: METHOD or CODE string SIP-START-based pointer and length
 * 2: R-URI or REASON PHRASE string SIP-START-based pointer and length
 * 2: VERSION string SIP-START-based pointer and length
 * 2: short int in NBO: start of the content of the SIP message
 * [1+N]: in case this is a request, the length of the encoded-uri and the encoded-uri
 * 1: how many present headers have been found.
 *
 * MSG_HEADERS_INDEX:
 * N*3: groups of 3 bytes, each one describing a header struct: the first byte
 * is a letter that corresponds to a header type, the second and third bytes are a NBO
 * inidex to where this struct begins within the HEADERS_META_INFO section.
 *
 * HEADERS_META_INFO:
 * M: all the codified headers meta info structs one after another
 *
 * SIP_MSG:
 * the SIP message as it has been received.
 *
 * The length of the structure, will be ((short*)payload)[1] + ((short*)payload)[2]
 *
 * TODO: msg->parsed_uri msg->parsed_orig_uri_ok, msg->first_line->u.request.uri
 * buggy and little bit fuzzy
 */
int encode_msg(struct sip_msg *msg,char *payload,int len)
{
    int i,j,k,u,request;
    unsigned short int h;
    struct hdr_field* hf;
    struct msg_start* ms;
    struct sip_uri miuri;
    char *myerror=NULL;
    ptrdiff_t diff;

    if(len < MAX_ENCODED_MSG + MAX_MESSAGE_LEN)
        return -1;
    if(parse_headers(msg,HDR_EOH_F,0)<0) {
        myerror="in parse_headers";
        goto error;
    }
    memset(payload,0,len);
    ms=&msg->first_line;
    if(ms->type == SIP_REQUEST)
        request=1;
    else if(ms->type == SIP_REPLY)
        request=0;
    else {
        myerror="message is neither request nor response";
        goto error;
    }
    if(request) {
        for(h=0; h<32; j=(0x01<<h),h++)
            if(j & ms->u.request.method_value)
                break;
    } else {
        h=(unsigned short)(ms->u.reply.statuscode);
    }
    if(h==32) { /*statuscode wont be 32...*/
        myerror="unknown message type\n";
        goto error;
    }
    h=htons(h);
    /*first goes the message code type*/
    memcpy(payload,&h,2);
    h=htons((unsigned short int)msg->len);
    /*then goes the message start idx, but we'll put it later*/
    /*then goes the message length (we hope it to be less than 65535 bytes...)*/
    memcpy(&payload[MSG_LEN_IDX],&h,2);
    /*then goes the content start index (starting from SIP MSG START)*/
    if(0>(diff=(get_body(msg)-(msg->buf)))) {
        myerror="body starts before the message (uh ?)";
        goto error;
    } else
        h=htons((unsigned short int)diff);
    memcpy(payload+CONTENT_IDX,&h,2);
    payload[METHOD_CODE_IDX]=(unsigned char)(request?
                             (ms->u.request.method.s-msg->buf):
                             (ms->u.reply.status.s-msg->buf));
    payload[METHOD_CODE_IDX+1]=(unsigned char)(request?
                               (ms->u.request.method.len):
                               (ms->u.reply.status.len));
    payload[URI_REASON_IDX]=(unsigned char)(request?
                                            (ms->u.request.uri.s-msg->buf):
                                            (ms->u.reply.reason.s-msg->buf));
    payload[URI_REASON_IDX+1]=(unsigned char)(request?
                              (ms->u.request.uri.len):
                              (ms->u.reply.reason.len));
    payload[VERSION_IDX]=(unsigned char)(request?
                                         (ms->u.request.version.s-msg->buf):
                                         (ms->u.reply.version.s-msg->buf));
    if(request) {
        if (parse_uri(ms->u.request.uri.s,ms->u.request.uri.len, &miuri)<0) {
            LM_ERR("<%.*s>\n",ms->u.request.uri.len,ms->u.request.uri.s);
            myerror="while parsing the R-URI";
            goto error;
        }
        if(0>(j=encode_uri2(msg->buf,
                            ms->u.request.method.s-msg->buf+ms->len,
                            ms->u.request.uri,&miuri,
                            (unsigned char*)&payload[REQUEST_URI_IDX+1])))
        {
            myerror="ENCODE_MSG: ERROR while encoding the R-URI";
            goto error;
        }
        payload[REQUEST_URI_IDX]=(unsigned char)j;
        k=REQUEST_URI_IDX+1+j;
    } else
        k=REQUEST_URI_IDX;
    u=k;
    k++;
    for(i=0,hf=msg->headers; hf; hf=hf->next,i++);
    i++;/*we do as if there was an extra header, that marks the end of
	 the previous header in the headers hashtable(read below)*/
    j=k+3*i;
    for(i=0,hf=msg->headers; hf; hf=hf->next,k+=3) {
        payload[k]=(unsigned char)(hf->type & 0xFF);
        h=htons(j);
        /*now goes a payload-based-ptr to where the header-code starts*/
        memcpy(&payload[k+1],&h,2);
        /*TODO fix this... fixed with k-=3?*/
        if(0>(i=encode_header(msg,hf,(unsigned char*)(payload+j),MAX_ENCODED_MSG+MAX_MESSAGE_LEN-j))) {
            LM_ERR("encoding header %.*s\n",hf->name.len,hf->name.s);
            goto error;
            k-=3;
            continue;
        }
        j+=(unsigned short int)i;
    }
    /*now goes the number of headers that have been found, right after the meta-msg-section*/
    payload[u]=(unsigned char)((k-u-1)/3);
    j=htons(j);
    /*now copy the number of bytes that the headers-meta-section has occupied,right afther
     * headers-meta-section(the array with ['v',[2:where],'r',[2:where],'R',[2:where],...]
     * this is to know where the LAST header ends, since the length of each header-struct
     * is calculated substracting the nextHeaderStart - presentHeaderStart
     * the k+1 is because payload[k] is usually the letter*/
    memcpy(&payload[k+1],&j,2);
    k+=3;
    j=ntohs(j);
    /*now we copy the headers-meta-section after the msg-headers-meta-section*/
    /*memcpy(&payload[k],payload2,j);*/
    /*j+=k;*/
    /*pkg_free(payload2);*/
    /*now we copy the actual message after the headers-meta-section*/
    memcpy(&payload[j],msg->buf,msg->len);
    LM_DBG("msglen = %d,msg starts at %d\n",msg->len,j);
    j=htons(j);
    /*now we copy at the beginning, the index to where the actual message starts*/
    memcpy(&payload[MSG_START_IDX],&j,2);
    return GET_PAY_SIZE( payload );
error:
    LM_ERR("%s\n",myerror);
    return -1;
}