Exemplo 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;
}
Exemplo n.º 2
0
int encode_content_disposition(char *hdrstart,int hdrlen,struct disposition *body,unsigned char *where)
{
   unsigned char i=3;

   /*where[0] reserved flags for future use*/
   where[1]=(unsigned char)(body->type.s-hdrstart);
   where[2]=(unsigned char)body->type.len;
   i+=encode_parameters(&where[3],(void *)body->params,hdrstart,body,'d');
   return i;
}
Exemplo n.º 3
0
/* Encoder for vias.
 * Returns the length of the encoded structure in bytes
 * FORMAT (byte meanings):
 * 1: flags
 *
 */
int encode_via(char *hdrstart,int hdrlen,struct via_body *body,unsigned char *where)
{
   int i;/* 1*flags + 1*hostport_len*/
   unsigned char flags=0;

   where[1]=REL_PTR(hdrstart,body->name.s);
   where[2]=REL_PTR(hdrstart,body->version.s);
   where[3]=REL_PTR(hdrstart,body->transport.s);
   where[4]=REL_PTR(hdrstart,body->transport.s+body->transport.len+1);
   where[5]=REL_PTR(hdrstart,body->host.s);
   if(body->port_str.s && body->port_str.len){
      flags|=HAS_PORT_F;
      where[6]=REL_PTR(hdrstart,body->port_str.s);
      where[7]=REL_PTR(hdrstart,body->port_str.s+body->port_str.len+1);
      i=8;
   }else{
      where[6]=REL_PTR(hdrstart,body->host.s+body->host.len+1);
      i=7;
   }
   if(body->params.s && body->params.len){
      flags|=HAS_PARAMS_F;
      where[i++]=REL_PTR(hdrstart,body->params.s);
      where[i++]=(unsigned char)body->params.len;
   }
   if(body->branch && body->branch->value.s && body->branch->value.len){
      flags|=HAS_BRANCH_F;
      where[i++]=REL_PTR(hdrstart,body->branch->value.s);
      where[i++]=(unsigned char)body->branch->value.len;
   }
   if(body->received && body->received->value.s && body->received->value.len){
      flags|=HAS_RECEIVED_F;
      where[i++]=REL_PTR(hdrstart,body->received->value.s);
      where[i++]=(unsigned char)body->received->value.len;
   }
   if(body->rport && body->rport->value.s && body->rport->value.len){
      flags|=HAS_RPORT_F;
      where[i++]=REL_PTR(hdrstart,body->rport->value.s);
      where[i++]=(unsigned char)body->rport->value.len;
   }
   if(body->i && body->i->value.s && body->i->value.len){
      flags|=HAS_I_F;
      where[i++]=REL_PTR(hdrstart,body->i->value.s);
      where[i++]=(unsigned char)body->i->value.len;
   }
   if(body->alias && body->alias->value.s && body->alias->value.len){
      flags|=HAS_ALIAS_F;
      where[i++]=REL_PTR(hdrstart,body->alias->value.s);
      where[i++]=(unsigned char)body->alias->value.len;
   }

   where[0]=flags;
   i+=encode_parameters(&where[i],body->param_lst,hdrstart,(void *)body,'v');
   return i;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
/*The XURI is one of the most important parts in SEAS, as
 * most of the SIP MESSAGE structured headers (that is,
 * headers which have a well-specified body construction)
 * use the URI as the body (ie. via, route, record-route,
 * contact, from, to, RURI)
 *
 * the XURI is a codified structure of flags and pointers
 * that ease the parsing of the URI string.
 *
 * 1: The first byte of the structure, is a
 * HEADER_START-based pointer to the beginning of the URI
 * (including the "sip:").  
 * 1: The next byte is the length of the uri, so URIMAX 
 * is 256 (enough...) 
 * 2: Flags specifying the parts that are present in the URI
 *
 * as follows:
 * 	1: first byte
 * 		SIP_OR_TEL_F	0x01 it is SIP or TEL uri.
 *		SECURE_F	0x02 it is secure or not (SIPS,TELS)
 *		USER_F		0x04 it as a user part (user@host)
 *		PASSWORD_F	0x08 it has a password part
 *		HOST_F		0x10 it has a host part
 *		PORT_F		0x20 it has a port part
 *		PARAMETERS_F	0x40 it has a port part
 *		HEADERS_F	0x80 it has a port part
 *	1: second byte
 *		TRANSPORT_F	0x01 it has other parameters
 *		TTL_F		0x02 it has headers
 *		USER_F		0x04 it has the transport parameter
 *		METHOD_F	0x08 it has the ttl parameter
 *		MADDR_F		0x10 it has the user parameter
 *		LR_F		0x20 it has the method parameter
 *
 * All the following bytes are URI_START-based pointers to
 * the fields that are present in the uri, as specified by
 * the flags. They must appear in the same order shown in
 * the flags, and only appear if the flag was set to 1.
 *
 * the end of the field, will be the place where the
 * following pointer points to, minus one (note that all the
 * fields present in a URI are preceded by 1 character, ie
 * sip[:user][:passwod][@host][:port][;param1=x][;param2=y][?hdr1=a][&hdr2=b]$p
 * it will be necessary to have a pointer at the end,
 * pointing two past the end of the uri, so that the length
 * of the last header can be computed.
 *
 * The reason to have the OTHER and HEADERS flags at the
 * beginning(just after the strictly-uri stuff), is that it
 * will be necessary to know the length of the parameters
 * section and the headers section.  
 *
 * The parameters can
 * appear in an arbitrary order, so they won't be following
 * the convention of transport-ttl-user-method-maddr-lr, so
 * we can't rely on the next pointer to compute the length
 * of the previous pointer field, as the ttl param can 
 * appear before the transport param. so the parameter 
 * pointers must have 2 bytes: pointer+length.
 *
 */
int encode_uri2(char *hdr,int hdrlen,str uri_str, struct sip_uri *uri_parsed,unsigned char *payload)
{
   int i=4,j;/* 1*pointer+1*len+2*flags*/
   unsigned int scheme;
   unsigned char flags1=0,flags2=0,uriptr;

   uriptr=REL_PTR(hdr,uri_str.s);
   if(uri_str.len>255 || uriptr>hdrlen){
      LM_ERR("uri too long, or out of the sip_msg bounds\n");
      return -1;
   }
   payload[0]=uriptr;
   payload[1]=(unsigned char)uri_str.len;
   if(uri_parsed->user.s && uri_parsed->user.len){
      flags1 |= USER_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->user.s);
   }
   if(uri_parsed->passwd.s && uri_parsed->passwd.len){
      flags1 |= PASSWORD_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->passwd.s);
   }
   if(uri_parsed->host.s && uri_parsed->host.len){
      flags1 |= HOST_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->host.s);
   }
   if(uri_parsed->port.s && uri_parsed->port.len){
      flags1 |= PORT_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->port.s);
   }
   if(uri_parsed->params.s && uri_parsed->params.len){
      flags1 |= PARAMETERS_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->params.s);
   }
   if(uri_parsed->headers.s && uri_parsed->headers.len){
      flags1 |= HEADERS_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->headers.s);
   }
   payload[i]=(unsigned char)(uri_str.len+1);
   i++;

   if(uri_parsed->transport.s && uri_parsed->transport.len){
      flags2 |= TRANSPORT_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->transport.s);
      payload[i+1]=(unsigned char)(uri_parsed->transport.len);
      i+=2;
   }
   if(uri_parsed->ttl.s && uri_parsed->ttl.len){
      flags2 |= TTL_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->ttl.s);
      payload[i+1]=(unsigned char)uri_parsed->ttl.len;
      i+=2;
   }
   if(uri_parsed->user_param.s && uri_parsed->user_param.len){
      flags2 |= USER_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->user_param.s);
      payload[i+1]=(unsigned char)uri_parsed->user_param.len;
      i+=2;
   }
   if(uri_parsed->method.s && uri_parsed->method.len){
      flags2 |= METHOD_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->method.s);
      payload[i+1]=(unsigned char)uri_parsed->method.len;
      i+=2;
   }
   if(uri_parsed->maddr.s && uri_parsed->maddr.len){
      flags2 |= MADDR_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->maddr.s);
      payload[i+1]=(unsigned char)uri_parsed->maddr.len;
      i+=2;
   }
   if(uri_parsed->lr.s && uri_parsed->lr.len){
      flags2 |= LR_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->lr.s);
      payload[i+1]=(unsigned char)uri_parsed->lr.len;
      i+=2;
   }
   /*in parse_uri, when there's a user=phone, the type
    * is set to TEL_URI_T, even if there's a sip: in the beginning
    * so lets check it by ourselves:
   switch(uri_parsed->type){
      case SIP_URI_T:
	 flags1 |= SIP_OR_TEL_F;
	 break;
      case SIPS_URI_T:
	 flags1 |= (SIP_OR_TEL_F|SECURE_F);
	 break;
      case TEL_URI_T:
	 break;
      case TELS_URI_T:
	 flags1 |= SECURE_F;
	 break;
      default:
	 return -1;
   }*/
#define SIP_SCH		0x3a706973
#define SIPS_SCH	0x73706973
#define TEL_SCH		0x3a6c6574
#define TELS_SCH	0x736c6574
   scheme=uri_str.s[0]+(uri_str.s[1]<<8)+(uri_str.s[2]<<16)+(uri_str.s[3]<<24);
   scheme|=0x20202020;
   if (scheme==SIP_SCH){
      flags1 |= SIP_OR_TEL_F;
   }else if(scheme==SIPS_SCH){
      if(uri_str.s[4]==':'){
	 flags1 |= (SIP_OR_TEL_F|SECURE_F);
      }else goto error;
   }else if (scheme==TEL_SCH){
      /*nothing*/
   }else if (scheme==TELS_SCH){
      if(uri_str.s[4]==':'){
	 flags1 |= SECURE_F;
      }
   }else goto error;
	
   payload[2]=flags1;
   payload[3]=flags2;
   j=i;
   i+=encode_parameters(&payload[i],uri_parsed->params.s,uri_str.s,&uri_parsed->params.len,'u');
   if(i<j)
      goto error;
   return i;
error:
   return -1;
}