int parse_param_name(str* _s, dig_par_t* _type) { register char* p; register int val; char* end; end = _s->s + _s->len; p = _s->s; val = READ(p); if (_s->len < 4) { goto other; } switch(LOWER_DWORD(val)) { FIRST_QUATERNIONS; default: PARSE_SHORT; goto other; } end: _s->len -= p - _s->s; _s->s = p; trim_leading(_s); if (_s->s[0] == '=') { return 0; } other: p = q_memchr(p, '=', end - p); if (!p) { return -1; /* Parse error */ } else { *_type = PAR_OTHER; _s->len -= p - _s->s; _s->s = p; return 0; } }
/* returns the pointer to the first VIA header */ char *lw_find_via(char *buf, char *buf_end) { char *p; unsigned int val; /* skip the first line */ p = eat_line(buf, buf_end - buf); while (buf_end - p > 4) { val = LOWER_DWORD(READ(p)); if ((val == _via1_) || (val == _via2_) || ((LOWER_BYTE(*p) == 'v') /* compact header */ && ((*(p+1) == ' ') || (*(p+1) == ':')) ) ) return p; p = lw_next_line(p, buf_end); } /* not found */ return 0; }
char* parse_hname2(char* begin, char* end, struct hdr_field* hdr) { register char* p; register unsigned int val; if ((end - begin) < 4) { hdr->type = HDR_ERROR_T; return begin; } p = begin; val = LOWER_DWORD(READ(p)); hdr->name.s = begin; switch(val) { FIRST_QUATERNIONS; default: switch(LOWER_BYTE(*p)) { case 't': switch(LOWER_BYTE(*(p + 1))) { case 'o': case ' ': hdr->type = HDR_TO_T; p += 2; goto dc_end; case ':': hdr->type = HDR_TO_T; hdr->name.len = 1; return (p + 2); } break; case 'v': PARSE_COMPACT(HDR_VIA_T); break; case 'f': PARSE_COMPACT(HDR_FROM_T); break; case 'i': PARSE_COMPACT(HDR_CALLID_T); break; case 'm': PARSE_COMPACT(HDR_CONTACT_T); break; case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH_T); break; case 'k': PARSE_COMPACT(HDR_SUPPORTED_T); break; case 'c': PARSE_COMPACT(HDR_CONTENTTYPE_T); break; case 'o': PARSE_COMPACT(HDR_EVENT_T); break; case 'x': PARSE_COMPACT(HDR_SESSIONEXPIRES_T);break; case 'a': PARSE_COMPACT(HDR_ACCEPTCONTACT_T); break; case 'u': PARSE_COMPACT(HDR_ALLOWEVENTS_T); break; case 'e': PARSE_COMPACT(HDR_CONTENTENCODING_T); break; case 'b': PARSE_COMPACT(HDR_REFERREDBY_T); break; case 'j': PARSE_COMPACT(HDR_REJECTCONTACT_T); break; case 'd': PARSE_COMPACT(HDR_REQUESTDISPOSITION_T); break; case 's': PARSE_COMPACT(HDR_SUBJECT_T); break; case 'r': PARSE_COMPACT(HDR_REFER_TO_T); break; } goto other; } /* Double colon hasn't been found yet */ dc_end: p = skip_ws(p, end - p); if (*p != ':') { goto other; } else { hdr->name.len = p - hdr->name.s; return (p + 1); } /* Unknown header type */ other: p = q_memchr(p, ':', end - p); if (!p) { /* No double colon found, error.. */ hdr->type = HDR_ERROR_T; hdr->name.s = 0; hdr->name.len = 0; return 0; } else { hdr->type = HDR_OTHER_T; hdr->name.len = p - hdr->name.s; return (p + 1); } }
/* * Parse Supported HF body. */ int parse_supported_body(str *body, unsigned int *sup) { register char* p; register unsigned int val; int len, pos = 0; *sup = 0; p = body->s; len = body->len; while (pos < len) { /* skip spaces and commas */ for (; pos < len && IS_DELIM(p); ++pos, ++p); val = LOWER_DWORD(READ(p)); switch (val) { /* "path" */ case _path_: if(pos + 4 <= len && IS_DELIM(p+4)) { *sup |= F_SUPPORTED_PATH; pos += 5; p += 5; } else goto default_label; break; /* "gruu" */ case _gruu_: if(pos + 4 <= len && IS_DELIM(p+4)) { *sup |= F_SUPPORTED_GRUU; pos += 5; p += 5; } else goto default_label; break; /* "100rel" */ case _100r_: if ( pos+6 <= len && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l' && IS_DELIM(p+6)) { *sup |= F_SUPPORTED_100REL; pos += SUPPORTED_100REL_LEN + 1; p += SUPPORTED_100REL_LEN + 1; } else goto default_label; break; /* "timer" */ case _time_: if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r' && IS_DELIM(p+5) ) { *sup |= F_SUPPORTED_TIMER; pos += SUPPORTED_TIMER_LEN + 1; p += SUPPORTED_TIMER_LEN + 1; } else goto default_label; break; /* "eventlist" */ case _even_: if ( pos+9 <= len && LOWER_DWORD(READ(p+4))==_tlis_ && LOWER_BYTE(*(p+8))=='t' && IS_DELIM(p+9) ) { *sup |= F_SUPPORTED_EVENTLIST; pos += SUPPORTED_EVENTLIST_LEN + 1; p += SUPPORTED_EVENTLIST_LEN + 1; } else goto default_label; break; /* unknown */ default: default_label: /* skip element */ for (; pos < len && !IS_DELIM(p); ++pos, ++p); break; } } return 0; }
/*! * Parse Supported HF body. */ static inline int parse_supported_body(str *body, unsigned int *sup) { register char* p; register unsigned int val; int len, pos = 0; *sup = 0; p = body->s; len = body->len; while (pos < len) { /* skip spaces and commas */ for (; pos < len && IS_DELIM(p); ++pos, ++p); val = LOWER_DWORD(READ(p)); switch (val) { /* "path" */ case _path_: if(pos + 4 <= len && IS_DELIM(p+4)) { *sup |= F_SUPPORTED_PATH; pos += 5; p += 5; } break; /* "100rel" */ case _100r_: if ( pos+6 <= len && LOWER_BYTE(*(p+4))=='e' && LOWER_BYTE(*(p+5))=='l' && IS_DELIM(p+6)) { *sup |= F_SUPPORTED_100REL; pos += SUPPORTED_100REL_LEN + 1; p += SUPPORTED_100REL_LEN + 1; } break; /* "timer" */ case _time_: if ( pos+5 <= len && LOWER_BYTE(*(p+4))=='r' && IS_DELIM(p+5) ) { *sup |= F_SUPPORTED_TIMER; pos += SUPPORTED_TIMER_LEN + 1; p += SUPPORTED_TIMER_LEN + 1; } break; /* extra supported or unknown */ default: if(pos+SUPPORTED_EVENTLIST_LEN<=len && strncasecmp(p, SUPPORTED_EVENTLIST_STR, SUPPORTED_EVENTLIST_LEN)==0 && IS_DELIM(p+9) ) { *sup |= F_SUPPORTED_EVENTLIST; pos += SUPPORTED_EVENTLIST_LEN + 1; p += SUPPORTED_EVENTLIST_LEN + 1; } else { /* skip element */ for (; pos < len && !IS_DELIM(p); ++pos, ++p); } break; } } return 0; }
char* parse_hname2(char* begin, char* end, struct hdr_field* hdr) { register char* p; register unsigned int val; if ((end - begin) < 4) { hdr->type = HDR_ERROR_T; return begin; } p = begin; val = LOWER_DWORD(READ(p)); hdr->name.s = begin; switch(val) { FIRST_QUATERNIONS; default: switch(LOWER_BYTE(*p)) { case 't': switch(LOWER_BYTE(*(p + 1))) { case 'o': p += 2; hdr->type = HDR_TO_T; hdr->name.len = 2; goto dc_cont; case ' ': case '\t': p += 2; hdr->type = HDR_TO_T; hdr->name.len = 1; goto dc_end; case ':': hdr->type = HDR_TO_T; hdr->name.len = 1; return (p + 2); } break; case 'v': PARSE_COMPACT(HDR_VIA_T); break; case 'f': PARSE_COMPACT(HDR_FROM_T); break; case 'i': PARSE_COMPACT(HDR_CALLID_T); break; case 'm': PARSE_COMPACT(HDR_CONTACT_T); break; case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH_T); break; case 'k': PARSE_COMPACT(HDR_SUPPORTED_T); break; case 'c': PARSE_COMPACT(HDR_CONTENTTYPE_T); break; case 'o': PARSE_COMPACT(HDR_EVENT_T); break; case 'x': PARSE_COMPACT(HDR_SESSION_EXPIRES_T); break; } goto other; } /* the above swtich will never continue here */ dc_end: /* HDR name entirely found, consume WS till colon */ /* overflow during the "switch-case" parsing ? */ if (p>=end) goto error; p = skip_ws(p, end); if (*p != ':') goto error; /* hdr type, name should be already set at this point */ return (p+1); /*done*/ dc_cont: /* HDR name partially found, see what's next */ /* overflow during the "switch-case" parsing ? */ if (p>=end) goto error; /* hdr type, name should be already set at this point (for partial finding) */ switch (*p) { case ':' : return (p+1); case ' ': case '\t': /* consume spaces to the end of name */ p = skip_ws( p+1, end); if (*p != ':') goto error; return (p+1); /* default: it seems the hdr name continues, fall to "other" */ } other: /* Unknown header type */ hdr->type = HDR_OTHER_T; /* if overflow during the "switch-case" parsing, the "while" will * exit and we will fall in the "error" section */ while ( p < end ) { switch (*p) { case ':' : hdr->name.len = p - hdr->name.s; return (p + 1); case ' ' : case '\t': hdr->name.len = p - hdr->name.s; p = skip_ws(p+1, end); if (*p != ':') goto error; return (p+1); } p++; } error: /* No double colon found, error.. */ hdr->type = HDR_ERROR_T; hdr->name.s = 0; hdr->name.len = 0; return 0; }
/* * lightweight header field name parser * used by build_local_reparse() function in order to construct ACK or CANCEL request * from the INVITE buffer * this parser supports only the header fields which are needed by build_local_reparse() */ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) { char *p; unsigned int val; if (end - begin < 4) { *type = HDR_ERROR_T; return begin; } p = begin; val = LOWER_DWORD(READ(p)); switch(val) { case _cseq_: /* Cseq */ *type = HDR_CSEQ_T; p += 4; break; case _via1_: /* Via */ case _via2_: *type = HDR_VIA_T; p += 3; break; case _from_: /* From */ *type = HDR_FROM_T; p += 4; break; case _to12_: /* To */ *type = HDR_TO_T; p += 2; break; case _requ_: /* Require */ p += 4; val = LOWER_DWORD(READ(p)); switch(val) { case _ire1_: case _ire2_: p += 3; *type = HDR_REQUIRE_T; break; default: p -= 4; *type = HDR_OTHER_T; break; } break; case _prox_: /* Proxy-Require */ if ((LOWER_DWORD(READ(p+4)) == _y_re_) && (LOWER_DWORD(READ(p+8)) == _quir_) && (LOWER_BYTE(*(p+12)) == 'e')) { p += 13; *type = HDR_PROXYREQUIRE_T; break; } else { *type = HDR_OTHER_T; break; } case _cont_: /* Content-Length */ if ((LOWER_DWORD(READ(p+4)) == _ent__) && (LOWER_DWORD(READ(p+8)) == _leng_) && (LOWER_BYTE(*(p+12)) == 't') && (LOWER_BYTE(*(p+13)) == 'h')) { p += 14; *type = HDR_CONTENTLENGTH_T; break; } else { *type = HDR_OTHER_T; break; } case _call_: /* Call-Id */ p += 4; val = LOWER_DWORD(READ(p)); switch(val) { case __id1_: case __id2_: p += 7; *type = HDR_CALLID_T; break; default: p -= 4; *type = HDR_OTHER_T; break; } break; case _rout_: /* Route */ if (LOWER_BYTE(*(p+4)) == 'e') { p += 5; *type = HDR_ROUTE_T; break; } else { *type = HDR_OTHER_T; break; } case _max__: /* Max-Forwards */ if ((LOWER_DWORD(READ(p+4)) == _forw_) && (LOWER_DWORD(READ(p+8)) == _ards_)) { p += 12; *type = HDR_MAXFORWARDS_T; break; } else { *type = HDR_OTHER_T; break; } default: /* compact headers */ switch(LOWER_BYTE(*p)) { case 'v': /* Via */ if ((*(p+1) == ' ') || (*(p+1) == ':')) { p++; *type = HDR_VIA_T; break; } *type = HDR_OTHER_T; break; case 'f': /* From */ if ((*(p+1) == ' ') || (*(p+1) == ':')) { p++; *type = HDR_FROM_T; break; } *type = HDR_OTHER_T; break; case 't': /* To */ if (LOWER_BYTE(*(p+1)) == 'o') { p += 2; *type = HDR_TO_T; break; } if ((*(p+1) == ' ') || (*(p+1) == ':')) { p++; *type = HDR_TO_T; break; } *type = HDR_OTHER_T; break; case 'l': /* Content-Length */ if ((*(p+1) == ' ') || (*(p+1) == ':')) { p++; *type = HDR_CONTENTLENGTH_T; break; } *type = HDR_OTHER_T; break; case 'i': /* Call-Id */ if ((*(p+1) == ' ') || (*(p+1) == ':')) { p++; *type = HDR_CALLID_T; break; } *type = HDR_OTHER_T; break; default: *type = HDR_OTHER_T; break; } } return p; }