Exemple #1
0
/* returns pointer to next header line, and fill hdr_f ;
 * if at end of header returns pointer to the last crlf  (always buf)*/
char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
{

	char* tmp;
	char *match;
	struct via_body *vb;
	struct cseq_body* cseq_b;
	struct to_body* to_b;
	int integer;

	if ((*buf)=='\n' || (*buf)=='\r'){
		/* double crlf or lflf or crcr */
		LM_DBG("found end of header\n");
		hdr->type=HDR_EOH_T;
		return buf;
	}

	tmp=parse_hname(buf, end, hdr);
	if (hdr->type==HDR_ERROR_T){
		LM_ERR("bad header\n");
		goto error_bad_hdr;
	}

	/* eliminate leading whitespace */
	tmp=eat_lws_end(tmp, end);
	if (tmp>=end) {
		LM_ERR("hf empty\n");
		goto error_bad_hdr;
	}

	/* if header-field well-known, parse it, find its end otherwise ;
	 * after leaving the hdr->type switch, tmp should be set to the
	 * next header field
	 */
	switch(hdr->type){
		case HDR_VIA_T:
			/* keep number of vias parsed -- we want to report it in
			   replies for diagnostic purposes */
			via_cnt++;
			vb=pkg_malloc(sizeof(struct via_body));
			if (vb==0){
				LM_ERR("out of pkg memory\n");
				goto error;
			}
			memset(vb,0,sizeof(struct via_body));
			hdr->body.s=tmp;
			tmp=parse_via(tmp, end, vb);
			if (vb->error==PARSE_ERROR){
				LM_ERR("bad via\n");
				free_via_list(vb);
				set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
					"error parsing Via");
				set_err_reply(400, "bad Via header");
				goto error;
			}
			hdr->parsed=vb;
			vb->hdr.s=hdr->name.s;
			vb->hdr.len=hdr->name.len;
			hdr->body.len=tmp-hdr->body.s;
			break;
		case HDR_CSEQ_T:
			cseq_b=pkg_malloc(sizeof(struct cseq_body));
			if (cseq_b==0){
				LM_ERR("out of pkg memory\n");
				goto error;
			}
			memset(cseq_b, 0, sizeof(struct cseq_body));
			hdr->body.s=tmp;
			tmp=parse_cseq(tmp, end, cseq_b);
			if (cseq_b->error==PARSE_ERROR){
				LM_ERR("bad cseq\n");
				pkg_free(cseq_b);
				set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
					"error parsing CSeq`");
				set_err_reply(400, "bad CSeq header");
				goto error;
			}
			hdr->parsed=cseq_b;
			hdr->body.len=tmp-hdr->body.s;
			LM_DBG("cseq <%.*s>: <%.*s> <%.*s>\n",
					hdr->name.len, ZSW(hdr->name.s),
					cseq_b->number.len, ZSW(cseq_b->number.s),
					cseq_b->method.len, cseq_b->method.s);
			break;
		case HDR_TO_T:
			to_b=pkg_malloc(sizeof(struct to_body));
			if (to_b==0){
				LM_ERR("out of pkg memory\n");
				goto error;
			}
			memset(to_b, 0, sizeof(struct to_body));
			hdr->body.s=tmp;
			tmp=parse_to(tmp, end,to_b);
			if (to_b->error==PARSE_ERROR){
				LM_ERR("bad to header\n");
				pkg_free(to_b);
				set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
					"error parsing To header");
				set_err_reply(400, "bad header");
				goto error;
			}
			hdr->parsed=to_b;
			hdr->body.len=tmp-hdr->body.s;
			LM_DBG("<%.*s> [%d]; uri=[%.*s] \n",
				hdr->name.len, ZSW(hdr->name.s),
				hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
			LM_DBG("to body [%.*s]\n",to_b->body.len, ZSW(to_b->body.s));
			break;
		case HDR_CONTENTLENGTH_T:
			hdr->body.s=tmp;
			tmp=parse_content_length(tmp,end, &integer);
			if (tmp==0){
				LM_ERR("bad content_length header\n");
				set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
					"error parsing Content-Length");
				set_err_reply(400, "bad Content-Length header");
				goto error;
			}
			hdr->parsed=(void*)(long)integer;
			hdr->body.len=tmp-hdr->body.s;
			LM_DBG("content_length=%d\n", (int)(long)hdr->parsed);
			break;
		case HDR_SUPPORTED_T:
		case HDR_CONTENTTYPE_T:
		case HDR_FROM_T:
		case HDR_CALLID_T:
		case HDR_CONTACT_T:
		case HDR_ROUTE_T:
		case HDR_RECORDROUTE_T:
		case HDR_PATH_T:
		case HDR_MAXFORWARDS_T:
		case HDR_AUTHORIZATION_T:
		case HDR_EXPIRES_T:
		case HDR_PROXYAUTH_T:
		case HDR_PROXYREQUIRE_T:
		case HDR_UNSUPPORTED_T:
		case HDR_ALLOW_T:
		case HDR_EVENT_T:
		case HDR_ACCEPT_T:
		case HDR_ACCEPTLANGUAGE_T:
		case HDR_ORGANIZATION_T:
		case HDR_PRIORITY_T:
		case HDR_SUBJECT_T:
		case HDR_USERAGENT_T:
		case HDR_CONTENTDISPOSITION_T:
		case HDR_ACCEPTDISPOSITION_T:
		case HDR_DIVERSION_T:
		case HDR_RPID_T:
		case HDR_REFER_TO_T:
		case HDR_SESSION_EXPIRES_T:
		case HDR_MIN_SE_T:
		case HDR_MIN_EXPIRES_T:
		case HDR_PPI_T:
		case HDR_PAI_T:
		case HDR_PRIVACY_T:
		case HDR_RETRY_AFTER_T:
		case HDR_CALL_INFO_T:
		case HDR_WWW_AUTHENTICATE_T:
		case HDR_PROXY_AUTHENTICATE_T:
		case HDR_OTHER_T:
			/* just skip over it */
			hdr->body.s=tmp;
			/* find end of header */
			/* find lf */
			do{
				match=q_memchr(tmp, '\n', end-tmp);
				if (match){
					match++;
				}else {
					LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type);
					tmp=end;
					goto error_bad_hdr;
				}
				tmp=match;
			}while( match<end &&( (*match==' ')||(*match=='\t') ) );
			tmp=match;
			hdr->body.len=match-hdr->body.s;
			break;
		default:
			LM_CRIT("unknown header type %d\n", hdr->type);
			goto error;
	}
	/* jku: if \r covered by current length, shrink it */
	trim_r( hdr->body );
	hdr->len=tmp-hdr->name.s;
	return tmp;

error_bad_hdr:
	set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
		"error parsing headers");
	set_err_reply(400, "bad headers");
error:
	LM_DBG("error exit\n");
	update_stat( bad_msg_hdr, 1);
	hdr->type=HDR_ERROR_T;
	hdr->len=tmp-hdr->name.s;
	return tmp;
}
Exemple #2
0
/* returns pointer to next header line, and fill hdr_f ;
 * if at end of header returns pointer to the last crlf  (always buf)*/
char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hdr)
{

    char *tmp = 0;
    char *match;
    struct via_body *vb;
    struct cseq_body* cseq_b;
    struct to_body* to_b;
    int integer, err;
    unsigned uval;

    if(!buf) {
        DBG("null buffer pointer\n");
        goto error;
    }

    if ((*buf)=='\n' || (*buf)=='\r') {
        /* double crlf or lflf or crcr */
        DBG("found end of header\n");
        hdr->type=HDR_EOH_T;
        return buf;
    }

    tmp=parse_hname(buf, end, hdr);
    if (hdr->type==HDR_ERROR_T) {
        LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
        goto error;
    }

    /* eliminate leading whitespace */
    tmp=eat_lws_end(tmp, end);
    if (tmp>=end) {
        LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n");
        goto error;
    }

    /* if header-field well-known, parse it, find its end otherwise ;
     * after leaving the hdr->type switch, tmp should be set to the
     * next header field
     */
    switch(hdr->type) {
    case HDR_VIA_T:
        /* keep number of vias parsed -- we want to report it in
           replies for diagnostic purposes */
        via_cnt++;
        vb=pkg_malloc(sizeof(struct via_body));
        if (vb==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(vb,0,sizeof(struct via_body));
        hdr->body.s=tmp;
        tmp=parse_via(tmp, end, vb);
        if (vb->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
            free_via_list(vb);
            goto error;
        }
        hdr->parsed=vb;
        vb->hdr.s=hdr->name.s;
        vb->hdr.len=hdr->name.len;
        hdr->body.len=tmp-hdr->body.s;
        break;
    case HDR_CSEQ_T:
        cseq_b=pkg_malloc(sizeof(struct cseq_body));
        if (cseq_b==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(cseq_b, 0, sizeof(struct cseq_body));
        hdr->body.s=tmp;
        tmp=parse_cseq(tmp, end, cseq_b);
        if (cseq_b->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
            free_cseq(cseq_b);
            goto error;
        }
        hdr->parsed=cseq_b;
        hdr->body.len=tmp-hdr->body.s;
        DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n",
            hdr->name.len, ZSW(hdr->name.s),
            cseq_b->number.len, ZSW(cseq_b->number.s),
            cseq_b->method.len, cseq_b->method.s);
        break;
    case HDR_TO_T:
        to_b=pkg_malloc(sizeof(struct to_body));
        if (to_b==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(to_b, 0, sizeof(struct to_body));
        hdr->body.s=tmp;
        tmp=parse_to(tmp, end,to_b);
        if (to_b->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n");
            free_to(to_b);
            goto error;
        }
        hdr->parsed=to_b;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n",
            hdr->name.len, ZSW(hdr->name.s),
            hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
        DBG("DEBUG: to body [%.*s]\n",to_b->body.len,
            ZSW(to_b->body.s));
        break;
    case HDR_CONTENTLENGTH_T:
        hdr->body.s=tmp;
        tmp=parse_content_length(tmp,end, &integer);
        if (tmp==0) {
            LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n");
            goto error;
        }
        hdr->parsed=(void*)(long)integer;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_body : content_length=%d\n",
            (int)(long)hdr->parsed);
        break;
    case HDR_RETRY_AFTER_T:
        hdr->body.s=tmp;
        tmp=parse_retry_after(tmp,end, &uval, &err);
        if (err) {
            LOG(L_ERR, "ERROR:get_hdr_field: bad retry_after header\n");
            goto error;
        }
        hdr->parsed=(void*)(unsigned long)uval;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_body : retry_after=%d\n",
            (unsigned)(long)hdr->parsed);
        break;
    case HDR_IDENTITY_T:
    case HDR_DATE_T:
    case HDR_IDENTITY_INFO_T:
    case HDR_SUPPORTED_T:
    case HDR_REQUIRE_T:
    case HDR_CONTENTTYPE_T:
    case HDR_FROM_T:
    case HDR_CALLID_T:
    case HDR_CONTACT_T:
    case HDR_ROUTE_T:
    case HDR_RECORDROUTE_T:
    case HDR_MAXFORWARDS_T:
    case HDR_AUTHORIZATION_T:
    case HDR_EXPIRES_T:
    case HDR_PROXYAUTH_T:
    case HDR_PROXYREQUIRE_T:
    case HDR_UNSUPPORTED_T:
    case HDR_ALLOW_T:
    case HDR_EVENT_T:
    case HDR_ACCEPT_T:
    case HDR_ACCEPTLANGUAGE_T:
    case HDR_ORGANIZATION_T:
    case HDR_PRIORITY_T:
    case HDR_SUBJECT_T:
    case HDR_USERAGENT_T:
    case HDR_SERVER_T:
    case HDR_CONTENTDISPOSITION_T:
    case HDR_DIVERSION_T:
    case HDR_RPID_T:
    case HDR_SIPIFMATCH_T:
    case HDR_REFER_TO_T:
    case HDR_SESSIONEXPIRES_T:
    case HDR_MIN_SE_T:
    case HDR_SUBSCRIPTION_STATE_T:
    case HDR_ACCEPTCONTACT_T:
    case HDR_ALLOWEVENTS_T:
    case HDR_CONTENTENCODING_T:
    case HDR_REFERREDBY_T:
    case HDR_REJECTCONTACT_T:
    case HDR_REQUESTDISPOSITION_T:
    case HDR_WWW_AUTHENTICATE_T:
    case HDR_PROXY_AUTHENTICATE_T:
    case HDR_PATH_T:
    case HDR_PRIVACY_T:
    case HDR_PAI_T:
    case HDR_PPI_T:
    case HDR_REASON_T:
    case HDR_OTHER_T:
        /* just skip over it */
        hdr->body.s=tmp;
        /* find end of header */
        /* find lf */
        do {
            match=q_memchr(tmp, '\n', end-tmp);
            if (match) {
                match++;
            } else {
                LOG(L_ERR,
                    "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
                    hdr->name.s, hdr->type);
                /* abort(); */
                tmp=end;
                goto error;
            }
            tmp=match;
        } while( match<end &&( (*match==' ')||(*match=='\t') ) );
        tmp=match;
        hdr->body.len=match-hdr->body.s;
        break;
    default:
        LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
            hdr->type);
        goto error;
    }
    /* jku: if \r covered by current length, shrink it */
    trim_r( hdr->body );
    hdr->len=tmp-hdr->name.s;
    return tmp;
error:
    DBG("get_hdr_field: error exit\n");
    STATS_BAD_MSG_HDR();
    hdr->type=HDR_ERROR_T;
    hdr->len=tmp-hdr->name.s;
    return tmp;
}
Exemple #3
0
/* returns pointer to next header line, and fill hdr_f ;
 * if at end of header returns pointer to the last crlf  (always buf)*/
char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
{

	char* tmp;
	char *match;
	struct via_body *vb;
	struct cseq_body* cseq_b;
	struct to_body* to_b;
	int integer;

	if ((*buf)=='\n' || (*buf)=='\r'){
		/* double crlf or lflf or crcr */
		DBG("found end of header\n");
		hdr->type=HDR_EOH;
		return buf;
	}

	tmp=parse_hname(buf, end, hdr);
	if (hdr->type==HDR_ERROR){
		LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
		goto error;
	}

	/* eliminate leading whitespace */
	tmp=eat_lws_end(tmp, end); 
	if (tmp>=end) {
		LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n");
		goto error;
	}

	/* if header-field well-known, parse it, find its end otherwise ;
	 * after leaving the hdr->type switch, tmp should be set to the
	 * next header field
	 */
	switch(hdr->type){
		case HDR_VIA:
			/* keep number of vias parsed -- we want to report it in
			   replies for diagnostic purposes */
			via_cnt++;
			vb=pkg_malloc(sizeof(struct via_body));
			if (vb==0){
				LOG(L_ERR, "get_hdr_field: out of memory\n");
				goto error;
			}
			memset(vb,0,sizeof(struct via_body));
			hdr->body.s=tmp;
			tmp=parse_via(tmp, end, vb);
			if (vb->error==PARSE_ERROR){
				LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
				free_via_list(vb);
				goto error;
			}
			hdr->parsed=vb;
			vb->hdr.s=hdr->name.s;
			vb->hdr.len=hdr->name.len;
			hdr->body.len=tmp-hdr->body.s;
			break;
		case HDR_CSEQ:
			cseq_b=pkg_malloc(sizeof(struct cseq_body));
			if (cseq_b==0){
				LOG(L_ERR, "get_hdr_field: out of memory\n");
				goto error;
			}
			memset(cseq_b, 0, sizeof(struct cseq_body));
			hdr->body.s=tmp;
			tmp=parse_cseq(tmp, end, cseq_b);
			if (cseq_b->error==PARSE_ERROR){
				LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
				pkg_free(cseq_b);
				goto error;
			}
			hdr->parsed=cseq_b;
			hdr->body.len=tmp-hdr->body.s;
			DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n",
					hdr->name.len, ZSW(hdr->name.s), 
					cseq_b->number.len, ZSW(cseq_b->number.s), 
					cseq_b->method.len, cseq_b->method.s);
			break;
		case HDR_TO:
			to_b=pkg_malloc(sizeof(struct to_body));
			if (to_b==0){
				LOG(L_ERR, "get_hdr_field: out of memory\n");
				goto error;
			}
			memset(to_b, 0, sizeof(struct to_body));
			hdr->body.s=tmp;
			tmp=parse_to(tmp, end,to_b);
			if (to_b->error==PARSE_ERROR){
				LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n");
				pkg_free(to_b);
				goto error;
			}
			hdr->parsed=to_b;
			hdr->body.len=tmp-hdr->body.s;
			DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n",
				hdr->name.len, ZSW(hdr->name.s), 
				hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
			DBG("DEBUG: to body [%.*s]\n",to_b->body.len,
				ZSW(to_b->body.s));
			break;
		case HDR_CONTENTLENGTH:
			hdr->body.s=tmp;
			tmp=parse_content_length(tmp,end, &integer);
			if (tmp==0){
				LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n");
				goto error;
			}
			hdr->parsed=(void*)(long)integer;
			hdr->body.len=tmp-hdr->body.s;
			DBG("DEBUG: get_hdr_body : content_length=%d\n",
					(int)(long)hdr->parsed);
			break;
		case HDR_SUPPORTED:
		case HDR_CONTENTTYPE:
		case HDR_FROM:
		case HDR_CALLID:
		case HDR_CONTACT:
		case HDR_ROUTE:
		case HDR_RECORDROUTE:
		case HDR_MAXFORWARDS:
		case HDR_AUTHORIZATION:
		case HDR_EXPIRES:
		case HDR_PROXYAUTH:
		case HDR_PROXYREQUIRE:
		case HDR_UNSUPPORTED:
		case HDR_ALLOW:
		case HDR_EVENT:
	        case HDR_ACCEPT:
	        case HDR_ACCEPTLANGUAGE:
	        case HDR_ORGANIZATION:
	        case HDR_PRIORITY:
	        case HDR_SUBJECT:
	        case HDR_USERAGENT:
	        case HDR_CONTENTDISPOSITION:
	        case HDR_ACCEPTDISPOSITION:
	        case HDR_DIVERSION:
	        case HDR_RPID:
		case HDR_OTHER:
			/* just skip over it */
			hdr->body.s=tmp;
			/* find end of header */
			/* find lf */
			do{
				match=q_memchr(tmp, '\n', end-tmp);
				if (match){
					match++;
				}else {
					LOG(L_ERR,
							"ERROR: get_hdr_field: bad body for <%s>(%d)\n",
							hdr->name.s, hdr->type);
					/* abort(); */
					tmp=end;
					goto error;
				}
				tmp=match;
			}while( match<end &&( (*match==' ')||(*match=='\t') ) );
			tmp=match;
			hdr->body.len=match-hdr->body.s;
			break;
		default:
			LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
					hdr->type);
			goto error;
	}
	/* jku: if \r covered by current length, shrink it */
	trim_r( hdr->body );
	hdr->len=tmp-hdr->name.s;
	return tmp;
error:
	DBG("get_hdr_field: error exit\n");
	hdr->type=HDR_ERROR;
	hdr->len=tmp-hdr->name.s;
	return tmp;
}