/* looks for the MAX FORWARDS header * returns its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { if ( parse_headers( msg , HDR_MAXFORWARDS_F, 0 )==-1 ){ LM_ERR("parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { LM_DBG("max_forwards header not found!\n"); return -1; } } else if (IS_MAXWD_STORED(msg)) { trim_len( foo->len , foo->s , msg->maxforwards->body ); return FETCH_MAXWD_VAL(msg); } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LM_ERR("unable to parse the max forwards number\n"); return -2; } /* store the parsed values */ STORE_MAXWD_VAL(msg, x); LM_DBG("value = %d \n",x); return x; }
unsigned int new_hash( str call_id, str cseq_nr ) { unsigned int hash_code = 0; int i,j, k, third; int ci_len, cs_len; char *ci, *cs; /* trim EoLs */ /* ci_len = call_id.len; while (ci_len && ((c=call_id.s[ci_len-1])==0 || c=='\r' || c=='\n')) ci_len--; cs_len = cseq_nr.len; while (cs_len && ((c=cseq_nr.s[cs_len-1])==0 || c=='\r' || c=='\n')) cs_len--; */ trim_len( ci_len, ci, call_id ); trim_len( cs_len, cs, cseq_nr ); /* run the cycle from the end ... we are interested in the most-right digits ... and just take the %10 value of it */ third=(ci_len-1)/3; for ( i=ci_len-1, j=2*third, k=third; k>0 ; i--, j--, k-- ) { hash_code+=crc_16_tab[(unsigned char)(*(ci+i)) /*+7*/ ]+ ccitt_tab[(unsigned char)*(ci+k)+63]+ ccitt_tab[(unsigned char)*(ci+j)+13]; } for( i=0 ; i<cs_len ; i++ ) //hash_code+=crc_32_tab[(cseq_nr.s[i]+hash_code)%243]; hash_code+=ccitt_tab[(unsigned char)*(cs+i)+123]; /* hash_code conditioning */ #ifdef _BUG /* not flat ... % 111b has shorter period than & 111b by one and results in different distribution; ( 7 % 7 == 0, 7 %7 == 1 ) % is used as a part of the hash function too, not only for rounding; & is not flat; whoever comes up with a nicer flat hash function which does not take costly division is welcome; feel free to verify distribution using hashtest() */ hash_code &= (TABLE_ENTRIES-1); /* TABLE_ENTRIES = 2^k */ #endif hash_code=hash_code%(TABLE_ENTRIES-1)+1; return hash_code; }
/* looks for the MAX FORWARDS header returns the its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { if ( parse_headers( msg , HDR_MAXFORWARDS_F, 0 )==-1 ){ LOG( L_ERR , "ERROR:maxfwd:is_maxfwd_present :" " parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { DBG("DEBUG: is_maxfwd_present: max_forwards header not found!\n"); return -1; } } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LOG(L_ERR, "ERROR:maxfwd:is_maxfwd_present:" " unable to parse the max forwards number !\n"); return -2; } DBG("DEBUG:maxfwd:is_maxfwd_present: value = %d \n",x); return x; }
int extract_bwidth(str *body, str *bwtype, str *bwwitdth) { char *cp, *cp1; int len; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = (char*)ser_memmem(cp, "b=", len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) return -1; bwtype->s = cp1 + 2; bwtype->len = eat_line(bwtype->s, body->s + body->len - bwtype->s) - bwtype->s; trim_len(bwtype->len, bwtype->s, *bwtype); cp = bwtype->s; len = bwtype->len; cp1 = (char*)ser_memmem(cp, ":", len, 1); len -= cp1 - cp; if (len <= 0) { LM_ERR("invalid encoding in `b=%.*s'\n", bwtype->len, bwtype->s); return -1; } bwtype->len = cp1 - cp; /* skip ':' */ bwwitdth->s = cp1 + 1; bwwitdth->len = len - 1; return 0; }
static int extract_mediaport(str *body, str *mediaport) { char *cp, *cp1; int len; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = ser_memmem(cp, "m=", len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) { LOG(L_ERR, "ERROR: extract_mediaport: no `m=' in SDP\n"); return -1; } mediaport->s = cp1 + 2; mediaport->len = eat_line(mediaport->s, body->s + body->len - mediaport->s) - mediaport->s; trim_len(mediaport->len, mediaport->s, *mediaport); if (mediaport->len < 7 || memcmp(mediaport->s, "audio", 5) != 0 || !isspace((int)mediaport->s[5])) { LOG(L_ERR, "ERROR: extract_mediaport: can't parse `m=' in SDP\n"); return -1; } cp = eat_space_end(mediaport->s + 5, mediaport->s + mediaport->len); mediaport->len = eat_token_end(cp, mediaport->s + mediaport->len) - cp; mediaport->s = cp; return 1; }
/* TODO - altough in most of the cases the targetted key is the 2nd query string, that's not always the case ! - make this 100% */ int redis_raw_query_extract_key(str *attr,str *query_key) { int len; char *p,*q,*r; if (!attr || attr->s == NULL || query_key == NULL) return -1; trim_len(len,p,*attr); q = memchr(p,' ',len); if (q == NULL) { LM_ERR("Malformed Redis RAW query \n"); return -1; } query_key->s = q+1; r = memchr(query_key->s,' ',len - (query_key->s - p)); if (r == NULL) { query_key->len = (p+len) - query_key->s; } else { query_key->len = r-query_key->s; } return 0; }
int extract_mediaip(str *body, str *mediaip, int *pf, char *line) { char *cp, *cp1; int len, nextisip; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = (char*)ser_memmem(cp, line, len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) return -1; mediaip->s = cp1 + 2; mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s; trim_len(mediaip->len, mediaip->s, *mediaip); nextisip = 0; for (cp = mediaip->s; cp < mediaip->s + mediaip->len;) { len = eat_token_end(cp, mediaip->s + mediaip->len) - cp; if (nextisip == 1) { mediaip->s = cp; mediaip->len = len; nextisip++; break; } if (len == 3 && memcmp(cp, "IP", 2) == 0) { switch (cp[2]) { case '4': nextisip = 1; *pf = AF_INET; break; case '6': nextisip = 1; *pf = AF_INET6; break; default: break; } } /* consume all spaces starting from the second char after the token First char after the token is the char that stoped the token parsing, so it is space or \r / \n, so we simply skip it */ cp = eat_space_end(cp + len + 1, mediaip->s + mediaip->len); } if (nextisip != 2 || mediaip->len == 0) { LM_ERR("no `IP[4|6]' in `%s' field\n",line); return -1; } return 1; }
static int extract_mediaip(str *body, str *mediaip, int *pf) { char *cp, *cp1; int len, nextisip; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = ser_memmem(cp, "c=", len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) { LOG(L_ERR, "ERROR: extract_mediaip: no `c=' in SDP\n"); return -1; } mediaip->s = cp1 + 2; mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s; trim_len(mediaip->len, mediaip->s, *mediaip); nextisip = 0; for (cp = mediaip->s; cp < mediaip->s + mediaip->len;) { len = eat_token_end(cp, mediaip->s + mediaip->len) - cp; if (nextisip == 1) { mediaip->s = cp; mediaip->len = len; nextisip++; break; } if (len == 3 && memcmp(cp, "IP", 2) == 0) { switch (cp[2]) { case '4': nextisip = 1; *pf = AF_INET; break; case '6': nextisip = 1; *pf = AF_INET6; break; default: break; } } cp = eat_space_end(cp + len, mediaip->s + mediaip->len); } if (nextisip != 2 || mediaip->len == 0) { LOG(L_ERR, "ERROR: extract_mediaip: " "no `IP[4|6]' in `c=' field\n"); return -1; } return 1; }
int extract_fmtp( str *body, str *fmtp_payload, str *fmtp_string ) { char *cp, *cp1; int len; if (strncasecmp(body->s, "a=fmtp:", 7) !=0) { /*LM_DBG("We are not pointing to an a=fmtp: attribute =>`%.*s'\n", body->len, body->s); */ return -1; } cp1 = body->s; fmtp_payload->s = cp1 + 7; /* skip `a=fmtp:' */ fmtp_payload->len = eat_line(fmtp_payload->s, body->s + body->len - fmtp_payload->s) - fmtp_payload->s; trim_len(fmtp_payload->len, fmtp_payload->s, *fmtp_payload); len = fmtp_payload->len; /* */ cp = eat_token_end(fmtp_payload->s, fmtp_payload->s + fmtp_payload->len); fmtp_payload->len = cp - fmtp_payload->s; if (fmtp_payload->len <= 0 || cp == fmtp_payload->s) { LM_ERR("no encoding in `a=fmtp:'\n"); return -1; } len -= fmtp_payload->len; fmtp_string->s = cp; cp = eat_space_end(fmtp_string->s, fmtp_string->s + len); len -= cp - fmtp_string->s; if (len <= 0 || cp == fmtp_string->s) { LM_ERR("no encoding in `a=fmtp:'\n"); return -1; } fmtp_string->s = cp; fmtp_string->len = eat_line(fmtp_string->s, body->s + body->len - fmtp_string->s) - fmtp_string->s; trim_len(fmtp_string->len, fmtp_string->s, *fmtp_string); return 0; }
static struct socket_info *get_sock_hdr(struct sip_msg *msg) { struct socket_info *sock; struct hdr_field *hf; unsigned int port_no; str sock_str; str port; char *p; if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LOG(L_ERR,"ERROR:registrar:get_sock_hdr: failed to parse message\n"); return 0; } for (hf=msg->headers; hf; hf=hf->next) { if (hf->name.len==sock_hdr_name.len && strncasecmp(hf->name.s, sock_hdr_name.s, sock_hdr_name.len)==0 ) break; } /* hdr found? */ if (hf==0) return 0; trim_len( sock_str.len, sock_str.s, hf->body ); if (sock_str.len==0) return 0; for(p=sock_str.s+(sock_str.len-1) ; p>sock_str.s && *p!='_' ; p-- ); if (p!=sock_str.s) { /* has port */ port.s = p+1; port.len = (sock_str.s + sock_str.len) - port.s; if (str2int( &port, &port_no)!=0) { LOG(L_ERR,"ERROR:registrar:get_sock_hdr: bad port <%.*s> in " "socket\n",port.len,port.s); port_no = SIP_PORT; } sock_str.len = (port.s - sock_str.s) - 1; } else { /* no port */ port_no = SIP_PORT; } sock = grep_sock_info( &sock_str, (unsigned short)port_no, PROTO_NONE /*FIXME - correct proto?*/); DBG("DEBUG:registrar:get_sock_hdr: <%.*s>:%d -> p=%p\n", sock_str.len,sock_str.s,port_no,sock ); return sock; }
/* generic method for attribute extraction * field must has format "a=attrname:" */ int extract_field(str *body, str *value, str field) { if (strncmp(body->s, field.s, field.len < body->len ? field.len : body->len) !=0) { /*LM_DBG("We are not pointing to an %.* attribute =>`%.*s'\n", field.len, field.s, body->len, body->s); */ return -1; } value->s = body->s + field.len; /* skip `a=attrname:' */ value->len = eat_line(value->s, body->s + body->len - value->s) - value->s; trim_len(value->len, value->s, *value); return 0; }
/*! \brief */ static struct socket_info *get_sock_hdr(struct sip_msg *msg) { struct socket_info *sock; struct hdr_field *hf; str socks; str hosts; int port; int proto; char c; if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return 0; } for (hf=msg->headers; hf; hf=hf->next) { if (cmp_hdrname_str(&hf->name, &sock_hdr_name)==0) break; } /* hdr found? */ if (hf==0) return 0; trim_len( socks.len, socks.s, hf->body ); if (socks.len==0) return 0; /*FIXME: This is a hack */ c = socks.s[socks.len]; socks.s[socks.len] = '\0'; if (parse_phostport( socks.s, &hosts.s, &hosts.len, &port, &proto)!=0) { socks.s[socks.len] = c; LM_ERR("bad socket <%.*s> in \n", socks.len, socks.s); return 0; } socks.s[socks.len] = c; sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto); if (sock==0) { LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s); return 0; } LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port_no,sock ); return sock; }
/*! \brief * Calculate a MD5 digests over a string array and stores * the result in the destination char array. * This function assumes 32 bytes in the destination buffer. * \param dest destination * \param src string input array * \param size elements in the input array */ void MD5StringArray(char *dest, str src[], unsigned int size) { MD5_CTX context; unsigned char digest[16]; int i, len; char *tmp; MD5Init (&context); for (i=0; i < size; i++) { trim_len(len, tmp, src[i]); MD5Update(&context, tmp, len); } MD5Final(digest, &context); string2hex(digest, 16, dest); LM_DBG("MD5 calculated: %.*s\n", MD5_LEN, dest); }
/*! \brief */ static int set_sock_hdr(struct sip_msg *msg, ucontact_info_t *ci, unsigned int reg_flags) { struct socket_info *sock; struct hdr_field *hf; str socks; str hosts; int port; int proto; if (!msg || !(reg_flags & REG_SAVE_SOCKET_FLAG)) return 1; if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return 1; } hf = get_header_by_name( msg, sock_hdr_name.s, sock_hdr_name.len); if (hf==0) return 1; trim_len( socks.len, socks.s, hf->body ); if (socks.len==0) return 1; if (parse_phostport( socks.s, socks.len, &hosts.s, &hosts.len, &port, &proto)!=0) { LM_ERR("bad socket <%.*s> in \n", socks.len, socks.s); return 1; } set_sip_defaults( port, proto); sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto); if (sock==0) { LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s); return 1; } LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port,sock ); ci->sock = sock; return 0; }
/* Digests a string array and store the result in dst; assumes 32 bytes in dst */ void MD5StringArray (char *dst, str src[], int size) { MD_CTX context; unsigned char digest[16]; int i; int len; char *s; /* # ifdef EXTRA_DEBUG int j; int sum; #endif */ MDInit (&context); for (i=0; i<size; i++) { trim_len( len, s, src[i] ); /* # ifdef EXTRA_DEBUG fprintf(stderr, "EXTRA_DEBUG: %d. (%d) {", i+1, len); sum=0; for (j=0; j<len; j++) { fprintf( stderr, "%c ", *(s+j)); sum+=*(s+j); } for (j=0; j<len; j++) { fprintf( stderr, "%d ", *(s+j)); sum+=*(s+j); } fprintf(stderr, " [%d]\n", sum ); # endif */ if (len > 0) MDUpdate (&context, s, len); } MDFinal (digest, &context); string2hex(digest, 16, dst ); DBG("DEBUG: MD5 calculated: %.*s\n", MD5_LEN, dst ); }
/*! * \brief Calculate a MD5 digests over a string array * * Calculate a MD5 digests over a string array and stores the result in the * destination char array. This function assumes 32 bytes in the destination * buffer. * \param dst destination * \param src string input array * \param size elements in the input array */ void MD5StringArray (char *dst, str src[], int size) { MD5_CTX context; unsigned char digest[16]; int i; int len; char *s; MD5Init (&context); for (i=0; i<size; i++) { trim_len( len, s, src[i] ); if (len > 0) MD5Update (&context, s, len); } U_MD5Final (digest, &context); string2hex(digest, 16, dst ); DBG("DEBUG: MD5 calculated: %.*s\n", MD5_LEN, dst ); }
/* looks for the MAX FORWARDS header returns the its value, -1 if is not present or -2 for error */ int is_maxfwd_present( struct sip_msg* msg , str *foo) { int x, err; /* hey man, run -Wall before committing ... -jiri char c; */ /* lookup into the message for MAX FORWARDS header*/ if ( !msg->maxforwards ) { DBG("DEBUG : is_maxfwd_present: searching for max_forwards header\n"); if ( parse_headers( msg , HDR_MAXFORWARDS, 0 )==-1 ){ LOG( L_ERR , "ERROR: is_maxfwd_present :" " parsing MAX_FORWARD header failed!\n"); return -2; } if (!msg->maxforwards) { DBG("DEBUG: is_maxfwd_present: max_forwards header not found!\n"); return -1; } }else{ DBG("DEBUG : is_maxfwd_present: max_forward header already found!\n"); } /* if header is present, trim to get only the string containing numbers */ trim_len( foo->len , foo->s , msg->maxforwards->body ); /* convert from string to number */ x = str2s( foo->s,foo->len,&err); if (err){ LOG(L_ERR, "ERROR: is_maxfwd_zero :" " unable to parse the max forwards number !\n"); return -2; } if (x > 255){ LOG(L_NOTICE, "is_maxfwd_present: value %d decreased to 255\n", x); x = 255; } DBG("DEBUG: is_maxfwd_present: value = %d \n",x); return x; }
/*! \brief */ static struct socket_info *get_sock_hdr(struct sip_msg *msg) { struct socket_info *sock; struct hdr_field *hf; str socks; str hosts; int port; int proto; if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return 0; } hf = get_header_by_name( msg, sock_hdr_name.s, sock_hdr_name.len); if (hf==0) return 0; trim_len( socks.len, socks.s, hf->body ); if (socks.len==0) return 0; if (parse_phostport( socks.s, socks.len, &hosts.s, &hosts.len, &port, &proto)!=0) { LM_ERR("bad socket <%.*s> in \n", socks.len, socks.s); return 0; } set_sip_defaults( port, proto); sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto); if (sock==0) { LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s); return 0; } LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port_no,sock ); return sock; }
int check_content_type(struct sip_msg *msg) { static unsigned int appl[16] = { 0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/, 0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/, 0x6c505061/*aPPl*/,0x6c505041/*APPl*/,0x4c707061/*appL*/, 0x4c707041/*AppL*/,0x4c705061/*aPpL*/,0x4c705041/*APpL*/, 0x4c507061/*apPL*/,0x4c507041/*ApPL*/,0x4c505061/*aPPL*/, 0x4c505041/*APPL*/}; static unsigned int icat[16] = { 0x74616369/*icat*/,0x74616349/*Icat*/,0x74614369/*iCat*/, 0x74614349/*ICat*/,0x74416369/*icAt*/,0x74416349/*IcAt*/, 0x74414369/*iCAt*/,0x74414349/*ICAt*/,0x54616369/*icaT*/, 0x54616349/*IcaT*/,0x54614369/*iCaT*/,0x54614349/*ICaT*/, 0x54416369/*icAT*/,0x54416349/*IcAT*/,0x54414369/*iCAT*/, 0x54414349/*ICAT*/}; static unsigned int ion_[8] = { 0x006e6f69/*ion_*/,0x006e6f49/*Ion_*/,0x006e4f69/*iOn_*/, 0x006e4f49/*IOn_*/,0x004e6f69/*ioN_*/,0x004e6f49/*IoN_*/, 0x004e4f69/*iON_*/,0x004e4f49/*ION_*/}; static unsigned int sdp_[8] = { 0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/, 0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/, 0x00504473/*sDP_*/,0x00504453/*SDP_*/}; str str_type; unsigned int x; char *p; if (!msg->content_type) { LM_WARN("the header Content-TYPE is absent!" "let's assume the content is text/plain ;-)\n"); return 1; } trim_len(str_type.len,str_type.s,msg->content_type->body); p = str_type.s; advance(p,4,str_type,error_1); x = READ(p-4); if (!one_of_16(x,appl)) goto other; advance(p,4,str_type,error_1); x = READ(p-4); if (!one_of_16(x,icat)) goto other; advance(p,3,str_type,error_1); x = READ(p-3) & 0x00ffffff; if (!one_of_8(x,ion_)) goto other; /* skip spaces and tabs if any */ while (*p==' ' || *p=='\t') advance(p,1,str_type,error_1); if (*p!='/') { LM_ERR("no / found after primary type\n"); goto error; } advance(p,1,str_type,error_1); while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len) advance(p,1,str_type,error_1); advance(p,3,str_type,error_1); x = READ(p-3) & 0x00ffffff; if (!one_of_8(x,sdp_)) goto other; if (*p==';'||*p==' '||*p=='\t'||*p=='\n'||*p=='\r'||*p==0) { LM_DBG("type <%.*s> found valid\n", (int)(p-str_type.s), str_type.s); return 1; } else { LM_ERR("bad end for type!\n"); return -1; } error_1: LM_ERR("body ended :-(!\n"); error: return -1; other: LM_ERR("invalid type for a message\n"); return -1; }
int extract_media_attr(str *body, str *mediamedia, str *mediaport, str *mediatransport, str *mediapayload, int *is_rtp) { char *cp, *cp1; int len, i; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = (char*)ser_memmem(cp, "m=", len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) { LM_ERR("no `m=' in SDP\n"); return -1; } mediaport->s = cp1 + 2; /* skip `m=' */ mediaport->len = eat_line(mediaport->s, body->s + body->len - mediaport->s) - mediaport->s; trim_len(mediaport->len, mediaport->s, *mediaport); mediapayload->len = mediaport->len; mediamedia->s = mediaport->s; /* Skip media supertype and spaces after it */ cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; mediamedia->len = mediapayload->len - mediaport->len; if (mediaport->len <= 0 || cp == mediaport->s) { LM_ERR("no port in `m='\n"); return -1; } mediaport->s = cp; cp = eat_space_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; if (mediaport->len <= 0 || cp == mediaport->s) { LM_ERR("no port in `m='\n"); return -1; } /* Extract port */ mediaport->s = cp; cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); mediatransport->len = mediaport->len - (cp - mediaport->s); if (mediatransport->len <= 0 || cp == mediaport->s) { LM_ERR("no port in `m='\n"); return -1; } mediatransport->s = cp; mediaport->len = cp - mediaport->s; /* Skip spaces after port */ cp = eat_space_end(mediatransport->s, mediatransport->s + mediatransport->len); mediatransport->len -= cp - mediatransport->s; if (mediatransport->len <= 0 || cp == mediatransport->s) { LM_ERR("no protocol type in `m='\n"); return -1; } /* Extract protocol type */ mediatransport->s = cp; cp = eat_token_end(mediatransport->s, mediatransport->s + mediatransport->len); if (cp == mediatransport->s) { LM_ERR("no protocol type in `m='\n"); return -1; } mediatransport->len = cp - mediatransport->s; mediapayload->s = mediatransport->s + mediatransport->len; mediapayload->len -= mediapayload->s - mediamedia->s; cp = eat_space_end(mediapayload->s, mediapayload->s + mediapayload->len); mediapayload->len -= cp - mediapayload->s; mediapayload->s = cp; for (i = 0; sup_ptypes[i].s != NULL; i++) if (mediatransport->len == sup_ptypes[i].len && strncasecmp(mediatransport->s, sup_ptypes[i].s, mediatransport->len) == 0) { *is_rtp = sup_ptypes[i].is_rtp; return 0; } /* Unproxyable protocol type. Generally it isn't error. */ return 0; }
int extract_mediaip(str *body, str *mediaip, int *pf, char *line) { char *cp, *cp1; int len; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = (char*)ser_memmem(cp, line, len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) return -1; mediaip->s = cp1 + 2; mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s; trim_len(mediaip->len, mediaip->s, *mediaip); if (mediaip->len == 0) { LM_ERR("no [%s] line in SDP\n",line); return -1; } /* search reverse for IP[4|6] in c=/o= line */ cp = (char*)ser_memrmem(mediaip->s, " IP", mediaip->len, 3); if (cp == NULL) { LM_ERR("no `IP[4|6]' in `%s' field\n",line); return -1; } /* safety checks: * - for length, at least 6: ' IP[4|6] x...' * - white space after */ if(cp + 6 > mediaip->s + mediaip->len && cp[4]!=' ') { LM_ERR("invalid content for `%s' line\n",line); return -1; } switch(cp[3]) { case '4': *pf = AF_INET; break; case '6': *pf = AF_INET6; break; default: LM_ERR("invalid addrtype IPx for `%s' line\n",line); return -1; } cp += 5; /* next token is the IP address */ cp = eat_space_end(cp, mediaip->s + mediaip->len); len = eat_token_end(cp, mediaip->s + mediaip->len) - cp; mediaip->s = cp; mediaip->len = len; if (mediaip->len == 0) { LM_ERR("no `IP[4|6]' address in `%s' field\n",line); return -1; } LM_DBG("located IP address [%.*s] in `%s' field\n", mediaip->len, mediaip->s, line); return 1; }
static inline char* append2buf( char *buf, int len, struct sip_msg *req, struct hdr_avp *ha) { struct hdr_field *hdr; struct usr_avp *avp; int_str avp_val; int_str avp_name; char *end; str foo; int msg_parsed; end = buf+len; msg_parsed = 0; while(ha) { if (ha->type==ELEM_IS_AVP) { /* search for the AVP */ if (ha->sval.s) { avp_name.s=ha->sval; avp = search_first_avp( AVP_NAME_STR, avp_name, &avp_val, 0); DBG("AVP <%.*s>: %p\n",avp_name.s.len, avp_name.s.s, avp); } else { avp_name.n=ha->ival; avp = search_first_avp( 0, avp_name, &avp_val, 0); DBG("AVP <%i>: %p\n",avp_name.n,avp); } if (avp) { if (avp->flags&AVP_VAL_STR) { buf=add2buf( buf, end, ha->title.s, ha->title.len, avp_val.s.s , avp_val.s.len); if (!buf) goto overflow_err; } else { foo.s=int2str( (unsigned long)avp_val.n, &foo.len); buf=add2buf( buf, end, ha->title.s, ha->title.len, foo.s , foo.len); if (!buf) goto overflow_err; } } } else if (ha->type==ELEM_IS_HDR) { /* parse the HDRs */ if (!msg_parsed) { if (parse_headers( req, HDR_EOH_F, 0)!=0) { LOG(L_ERR,"ERROR:tm:append2buf: parsing hdrs failed\n"); goto error; } msg_parsed = 1; } /* search the HDR */ if (ha->ival==HDR_OTHER_T) { for(hdr=req->headers;hdr;hdr=hdr->next) if (ha->sval.len==hdr->name.len && strncasecmp( ha->sval.s, hdr->name.s, hdr->name.len)==0) break; } else { for(hdr=req->headers;hdr;hdr=hdr->next) if (ha->ival==hdr->type) break; } if (hdr) { trim_len( foo.len, foo.s, hdr->body); buf=add2buf( buf, end, ha->title.s, ha->title.len, foo.s , foo.len); if (!buf) goto overflow_err; } } else { LOG(L_ERR,"BUG:tm:append2buf: unknown element type %d\n", ha->type); goto error; } ha = ha->next; } return buf; overflow_err: LOG(L_ERR,"ERROR:tm:append2buf: overflow -> append exceeded %d len\n",len); error: return 0; }
/** * rfc4566: * a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>] */ int extract_rtpmap(str *body, str *rtpmap_payload, str *rtpmap_encoding, str *rtpmap_clockrate, str *rtpmap_parmas) { char *cp, *cp1; int len; if (strncasecmp(body->s, "a=rtpmap:", 9) !=0) { /*LM_DBG("We are not pointing to an a=rtpmap: attribute =>`%.*s'\n", body->len, body->s); */ return -1; } cp1 = body->s; rtpmap_payload->s = cp1 + 9; /* skip `a=rtpmap:' */ rtpmap_payload->len = eat_line(rtpmap_payload->s, body->s + body->len - rtpmap_payload->s) - rtpmap_payload->s; trim_len(rtpmap_payload->len, rtpmap_payload->s, *rtpmap_payload); len = rtpmap_payload->len; /* */ cp = eat_token_end(rtpmap_payload->s, rtpmap_payload->s + rtpmap_payload->len); rtpmap_payload->len = cp - rtpmap_payload->s; if (rtpmap_payload->len <= 0 || cp == rtpmap_payload->s) { LM_ERR("no encoding in `a=rtpmap'\n"); return -1; } len -= rtpmap_payload->len; rtpmap_encoding->s = cp; cp = eat_space_end(rtpmap_encoding->s, rtpmap_encoding->s + len); len -= cp - rtpmap_encoding->s; if (len <= 0 || cp == rtpmap_encoding->s) { LM_ERR("no encoding in `a=rtpmap:'\n"); return -1; } rtpmap_encoding->s = cp; cp1 = (char*)ser_memmem(cp, "/", len, 1); if(cp1==NULL) { LM_ERR("invalid encoding in `a=rtpmap' at [%.*s]\n", len, cp); return -1; } len -= cp1 - cp; rtpmap_encoding->len = cp1 - cp; cp = cp1+1; /* skip '/' */ len--; rtpmap_clockrate->s = cp; cp1 = (char*)ser_memmem(cp, "/", len, 1); if(cp1==NULL) { /* no encoding parameters */ rtpmap_clockrate->len = len; rtpmap_parmas->s = NULL; rtpmap_parmas->len = 0; return 0; } rtpmap_clockrate->len = cp1 - cp; len -= cp1 - cp; rtpmap_parmas->s = cp1 + 1; /* skip '/' */ rtpmap_parmas->len = len - 1; return 0; }
static int extract_mediaport(str *body, str *mediaport) { char *cp, *cp1; int len, i; str ptype; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = ser_memmem(cp, "m=", len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) { LOG(L_ERR, "ERROR: extract_mediaport: no `m=' in SDP\n"); return -1; } mediaport->s = cp1 + 2; /* skip `m=' */ mediaport->len = eat_line(mediaport->s, body->s + body->len - mediaport->s) - mediaport->s; trim_len(mediaport->len, mediaport->s, *mediaport); /* Skip media supertype and spaces after it */ cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; if (mediaport->len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } mediaport->s = cp; cp = eat_space_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; if (mediaport->len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } /* Extract port */ mediaport->s = cp; cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); ptype.len = mediaport->len - (cp - mediaport->s); if (ptype.len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } ptype.s = cp; mediaport->len = cp - mediaport->s; /* Skip spaces after port */ cp = eat_space_end(ptype.s, ptype.s + ptype.len); ptype.len -= cp - ptype.s; if (ptype.len <= 0 || cp == ptype.s) { LOG(L_ERR, "ERROR: extract_mediaport: no protocol type in `m='\n"); return -1; } /* Extract protocol type */ ptype.s = cp; cp = eat_token_end(ptype.s, ptype.s + ptype.len); if (cp == ptype.s) { LOG(L_ERR, "ERROR: extract_mediaport: no protocol type in `m='\n"); return -1; } ptype.len = cp - ptype.s; for (i = 0; sup_ptypes[i].s != NULL; i++) if (ptype.len == sup_ptypes[i].len && strncasecmp(ptype.s, sup_ptypes[i].s, ptype.len) == 0) return 0; /* Unproxyable protocol type. Generally it isn't error. */ return -1; }
/*! \brief */ static struct socket_info *get_sock_val(struct sip_msg *msg) { struct socket_info *sock; struct hdr_field *hf; str xsockname = str_init("socket"); sr_xavp_t *vavp = NULL; str socks; str hosts; int port; int proto; char c = 0; if(sock_hdr_name.len>0) { if (parse_headers( msg, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse message\n"); return 0; } for (hf=msg->headers; hf; hf=hf->next) { if (cmp_hdrname_str(&hf->name, &sock_hdr_name)==0) break; } /* hdr found? */ if (hf==0) return 0; trim_len( socks.len, socks.s, hf->body ); if (socks.len==0) return 0; /*FIXME: This is a hack */ c = socks.s[socks.len]; socks.s[socks.len] = '\0'; } else { /* xavp */ if(reg_xavp_cfg.s!=NULL) vavp = xavp_get_child_with_sval(®_xavp_cfg, &xsockname); if(vavp==NULL || vavp->val.v.s.len<=0) return 0; socks = vavp->val.v.s; } if (parse_phostport( socks.s, &hosts.s, &hosts.len, &port, &proto)!=0) { socks.s[socks.len] = c; LM_ERR("bad socket <%.*s> in \n", socks.len, socks.s); return 0; } if(sock_hdr_name.len>0 && c!=0) { socks.s[socks.len] = c; } sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto); if (sock==0) { LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s); return 0; } LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port_no,sock ); return sock; }