rem: DBG(" first  via: <%s/%s/%s> <%s:%d>", vb1.name, vb1.version, vb1.transport, vb1.host, vb1.port); if (vb1.params)  DBG(";<%s>", vb1.params); if (vb1.comment) DBG(" <%s>", vb1.comment); DBG ("\n");
add: if (first_via){ DBG(" first  via: <%s/%s/%s> <%s:%d>", vb1.name, vb1.version, vb1.transport, vb1.host, vb1.port); if (vb1.params)  DBG(";<%s>", vb1.params); if (vb1.comment) DBG(" <%s>", vb1.comment); DBG ("\n"); }
context: int parse_msg(char* buf, unsigned int len, struct sip_msg* msg){	char *tmp, *bar;	char* rest;	char* first_via;	char* second_via;	struct msg_start fl;	struct hdr_field hf;	struct via_body vb1, vb2;	int offset;		/* eat crlf from the beginning */	for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&&			tmp-buf < len ; tmp++);	offset=tmp-buf;	rest=parse_first_line(tmp, len-offset, &fl);	offset+=rest-tmp;	tmp=rest;	switch(fl.type){		case SIP_INVALID:			DBG("parse_msg: invalid message\n");			goto error;			break;		case SIP_REQUEST:			DBG("SIP Request:\n");			DBG(" method:  <%s>\n",fl.u.request.method);			DBG(" uri:     <%s>\n",fl.u.request.uri);			DBG(" version: <%s>\n",fl.u.request.version);			break;		case SIP_REPLY:			DBG("SIP Reply  (status):\n");			DBG(" version: <%s>\n",fl.u.reply.version);			DBG(" status:  <%s>\n",fl.u.reply.status);			DBG(" reason:  <%s>\n",fl.u.reply.reason);			break;		default:			DBG("unknown type %d\n",fl.type);	}		/*find first Via: */	hf.type=HDR_ERROR;	first_via=0;	second_via=0;	do{		rest=get_hdr_field(tmp, len-offset, &hf);		offset+=rest-tmp;		switch (hf.type){			case HDR_ERROR:				LOG(L_INFO,"ERROR: bad header  field\n");				goto  error;			case HDR_EOH: 				goto skip;			case HDR_VIA:				if (first_via==0){						first_via=hf.body;						vb1.hdr=hf.name;						/* replace cr/lf with space in first via */						for (bar=first_via;(first_via) && (*bar);bar++)							if ((*bar=='\r')||(*bar=='\n'))	*bar=' ';				#ifdef DEBUG						DBG("first via: <%s>\n", first_via);				#endif						bar=parse_via_body(first_via, strlen(first_via), &vb1);						if (vb1.error!=VIA_PARSE_OK){							LOG(L_INFO, "ERROR: parsing via body: %s\n",									first_via);							goto error;						}												vb1.size=bar-first_via+first_via-vb1.hdr; 												/* compact via */						if (vb1.next) {							second_via=vb1.next;							/* not interested in the rest of the header */							goto skip;						}else{						/*  add 1 (we don't see the trailing lf which						 *  was zeroed by get_hfr_field */							vb1.size+=1;						}				}else if (second_via==0){							second_via=hf.body;							vb2.hdr=hf.name;							goto skip;				}				break;		}	#ifdef DEBUG		DBG("header field type %d, name=<%s>, body=<%s>\n",			hf.type, hf.name, hf.body);	#endif		tmp=rest;	}while(hf.type!=HDR_EOH && rest-buf < len);skip:	/* replace cr/lf with space in the second via */	for (tmp=second_via;(second_via) && (*tmp);tmp++)		if ((*tmp=='\r')||(*tmp=='\n'))	*tmp=' ';	if (second_via) {		tmp=parse_via_body(second_via, strlen(second_via), &vb2);		if (vb2.error!=VIA_PARSE_OK){			LOG(L_INFO, "ERROR: parsing via2 body: %s\n", second_via);			goto error;		}		vb2.size=tmp-second_via; 		if (vb2.next==0) vb2.size+=1; /* +1 from trailing lf */		if (vb2.hdr) vb2.size+=second_via-vb2.hdr;	}	#ifdef DEBUG	/* dump parsed data */	DBG(" first  via: <%s/%s/%s> <%s:%d>",			vb1.name, vb1.version, vb1.transport, vb1.host, vb1.port);	if (vb1.params)  DBG(";<%s>", vb1.params);	if (vb1.comment) DBG(" <%s>", vb1.comment);	DBG ("\n");	if (second_via){		DBG(" second via: <%s/%s/%s> <%s:%d>",				vb2.name, vb2.version, vb2.transport, vb2.host, vb2.port);		if (vb2.params)  DBG(";<%s>", vb2.params);		if (vb2.comment) DBG(" <%s>", vb2.comment);		DBG("\n");	}#endif		/* copy data into msg */	memcpy(&(msg->first_line), &fl, sizeof(struct msg_start));	memcpy(&(msg->via1), &vb1, sizeof(struct via_body));	memcpy(&(msg->via2), &vb2, sizeof(struct via_body));#ifdef DEBUG	DBG("exiting parse_msg\n");#endif	return 0;	error:	return -1;}