Пример #1
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;
}
Пример #2
0
/*BUGGY*/
char* parse_cseq(char* const buf, const char* const end, struct cseq_body* const cb)
{
	char *t, *m, *m_end;
	
	cb->error=PARSE_ERROR;
	t=buf;
	
	cb->number.s=t;
	t=eat_token_end(t, end);
	if (t>=end) goto error;
	cb->number.len=t-cb->number.s;

	m=eat_space_end(t, end);
	m_end=eat_token_end(m, end);

	if (m_end>=end) {
			LOG(L_ERR, "ERROR: parse_cseq: "
						"method terminated unexpectedly\n");
			goto error;
	}
	if (m_end==m){
		/* null method*/
		LOG(L_ERR,  "ERROR:parse_cseq: no method found\n");
		goto error;
	}
	cb->method.s=m;
	t=m_end;
	cb->method.len=t-cb->method.s;

	/* Cache method id */
	if (parse_method_name(&cb->method, &cb->method_id)!=0){
		LOG(L_ERR, "Cannot parse method string\n");
		goto error;
	}

	/* there may be trailing LWS 
	 * (it was not my idea to put it in SIP; -jiri )
	 */
	t=eat_lws_end(t, end);
	/*check if the header ends here*/
	if (t>=end) {
		LOG(L_ERR, "ERROR: parse_cseq: strange EoHF\n");
		goto error;
	}
	if (*t=='\r' && t+1<end && *(t+1)=='\n') {
			cb->error=PARSE_OK;
			return t+2;
	}
	if (*t=='\n') {
			cb->error=PARSE_OK;
			return t+1;
	}
	LOG(L_ERR, "ERROR: CSeq EoL expected\n");

error:
	LOG(L_ERR, "ERROR: parse_cseq: bad cseq\n");
	return t;
}
Пример #3
0
char* parse_cseq(char *buf, char* end, struct cseq_body* cb)
{
	char *t, *m, *m_end;
	
	cb->error=PARSE_ERROR;
	t=buf;
	
	cb->number.s=t;
	t=eat_token_end(t, end);
	if (t>=end) goto error;
	cb->number.len=t-cb->number.s;

	m=eat_space_end(t, end);
	m_end=eat_token_end(m, end);

	if (m_end>=end) {
			LM_ERR("method terminated unexpectedly\n");
			goto error;
	}
	if (m_end==m){
		/* null method*/
		LM_ERR("no method found\n");
		goto error;
	}
	cb->method.s=m;
	t=m_end;
	cb->method.len=t-cb->method.s;
	
	/* cache the method id */
	if(parse_method(cb->method.s, t, (unsigned int*)&cb->method_id)==0)
	{
		LM_ERR("cannot parse the method\n");
		goto error;
	}
	
	/* there may be trailing LWS 
	 * (it was not my idea to put it in SIP; -jiri )
	 */
	t=eat_lws_end(t, end);
	/*check if the header ends here*/
	if (t>=end) {
		LM_ERR("strange EoHF\n");
		goto error;
	}
	if (*t=='\r' && t+1<end && *(t+1)=='\n') {
			cb->error=PARSE_OK;
			return t+2;
	}
	if (*t=='\n') {
			cb->error=PARSE_OK;
			return t+1;
	}
	LM_ERR("expecting CSeq EoL\n");

error:
	LM_ERR("bad cseq\n");
	return t;
}
Пример #4
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
/* parses the first line, returns pointer to  next line  & fills fl;
   also  modifies buffer (to avoid extra copy ops) */
char* parse_first_line(char* buffer, unsigned int len, struct msg_start * fl)
{
	
	char *tmp;
	char* second;
	char* third;
	char* nl;
	int offset;
	/* int l; */
	char* end;
	char s1,s2,s3;
	char *prn;
	unsigned int t;

	/* grammar:
		request  =  method SP uri SP version CRLF
		response =  version SP status  SP reason  CRLF
		(version = "SIP/2.0")
	*/
	

	end=buffer+len;
	/* see if it's a reply (status) */

	/* jku  -- parse well-known methods */

	/* drop messages which are so short they are for sure useless;
           utilize knowledge of minimum size in parsing the first
	   token 
        */
	if (len <=16 ) {
		LOG(L_INFO, "ERROR: parse_first_line: message too short: %d\n", len);
		goto error1;
	}

	tmp=buffer;
  	/* is it perhaps a reply, ie does it start with "SIP...." ? */
	if ( 	(*tmp=='S' || *tmp=='s') && 
		strncasecmp( tmp+1, SIP_VERSION+1, SIP_VERSION_LEN-1)==0 &&
		(*(tmp+SIP_VERSION_LEN)==' ')) {
			fl->type=SIP_REPLY;
			fl->u.reply.version.len=SIP_VERSION_LEN;
			tmp=buffer+SIP_VERSION_LEN;
	} else IFISMETHOD( INVITE, 'I' )
	else IFISMETHOD( CANCEL, 'C')
	else IFISMETHOD( ACK, 'A' )
	else IFISMETHOD( BYE, 'B' ) 
	/* if you want to add another method XXX, include METHOD_XXX in
           H-file (this is the value which you will take later in
           processing and define XXX_LEN as length of method name;
	   then just call IFISMETHOD( XXX, 'X' ) ... 'X' is the first
	   latter; everything must be capitals
	*/
	else {
		/* neither reply, nor any of known method requests, 
		   let's believe it is an unknown method request
        	*/
		tmp=eat_token_end(buffer,buffer+len);
		if ((tmp==buffer)||(tmp>=end)){
			LOG(L_INFO, "ERROR:parse_first_line: empty  or bad first line\n");
			goto error1;
		}
		if (*tmp!=' ') {
			LOG(L_INFO, "ERROR:parse_first_line: method not followed by SP\n");
			goto error1;
		}
		fl->type=SIP_REQUEST;
		fl->u.request.method_value=METHOD_OTHER;
		fl->u.request.method.len=tmp-buffer;
	}


	/* identifying type of message over now; 
	   tmp points at space after; go ahead */

	fl->u.request.method.s=buffer;  /* store ptr to first token */
	second=tmp+1;			/* jump to second token */
	offset=second-buffer;

/* EoJku */
	
	/* next element */
	tmp=eat_token_end(second, second+len-offset);
	if (tmp>=end){
		goto error;
	}
	offset+=tmp-second;
	third=eat_space_end(tmp, tmp+len-offset);
	offset+=third-tmp;
	if ((third==tmp)||(tmp>=end)){
		goto error;
	}
	fl->u.request.uri.s=second;
	fl->u.request.uri.len=tmp-second;

	/* jku: parse status code */
	if (fl->type==SIP_REPLY) {
		if (fl->u.request.uri.len!=3) {
			LOG(L_INFO, "ERROR:parse_first_line: len(status code)!=3: %.*s\n",
				fl->u.request.uri.len, ZSW(second) );
			goto error;
		}
		s1=*second; s2=*(second+1);s3=*(second+2);
		if (s1>='0' && s1<='9' && 
		    s2>='0' && s2<='9' &&
		    s3>='0' && s3<='9' ) {
			fl->u.reply.statuscode=(s1-'0')*100+10*(s2-'0')+(s3-'0');
		} else {
			LOG(L_INFO, "ERROR:parse_first_line: status_code non-numerical: %.*s\n",
				fl->u.request.uri.len, ZSW(second) );
			goto error;
		}
	}
	/* EoJku */

	/*  last part: for a request it must be the version, for a reply
	 *  it can contain almost anything, including spaces, so we don't care
	 *  about it*/
	if (fl->type==SIP_REQUEST){
		tmp=eat_token_end(third,third+len-offset);
		offset+=tmp-third;
		if ((tmp==third)||(tmp>=end)){
			goto error;
		}
		if (! is_empty_end(tmp, tmp+len-offset)){
			goto error;
		}
	}else{
		tmp=eat_token2_end(third,third+len-offset,'\r'); /* find end of line 
												  ('\n' or '\r') */
		if (tmp>=end){ /* no crlf in packet => invalid */
			goto error;
		}
		offset+=tmp-third;
	}
	nl=eat_line(tmp,len-offset);
	if (nl>=end){ /* no crlf in packet or only 1 line > invalid */
		goto error;
	}
	fl->u.request.version.s=third;
	fl->u.request.version.len=tmp-third;
	fl->len=nl-buffer;

	return nl;

error:
	LOG(L_INFO, "ERROR:parse_first_line: bad %s first line\n",
		(fl->type==SIP_REPLY)?"reply(status)":"request");

	LOG(L_INFO, "ERROR: at line 0 char %d: \n", offset );
	prn=pkg_malloc( offset );
	if (prn) {
		for (t=0; t<offset; t++)
			if (*(buffer+t)) *(prn+t)=*(buffer+t);
			else *(prn+t)='°';
		LOG(L_INFO, "ERROR: parsed so far: %.*s\n", offset, ZSW(prn) );
		pkg_free( prn );
	};
error1:
	fl->type=SIP_INVALID;
	LOG(L_INFO, "ERROR:parse_first_line: bad message\n");
	/* skip  line */
	nl=eat_line(buffer,len);
	return nl;
}
Пример #8
0
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;
}
Пример #9
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;
}
Пример #10
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;
}
Пример #11
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;
}