#include #include "log.h" #include "AmSipHeaders.h" #include "sip_parser.h" #include "parse_common.h" #include "parse_100rel.h" #define EAT_WS(_c_, _end_) \ do { \ while ((_c_) < (_end_) && (*(_c_) == ' ' || *(_c_) == '\t')) \ (_c_) ++; \ } while (0) #define READ_NUMBER(_no, _c_, _end_) \ do { \ register bool fin; \ (_no) = 0; \ for (fin = false; !fin && (_c_) < (_end_); ) { \ switch (*(_c_)) { \ case '0' ... '9': \ if (UINT_MAX - (_no) < (unsigned)*(_c_)) { \ INFO("not an uint32_t.\n"); \ goto error; \ } \ (_no) = (_no) * 10 + *(_c_) - '0'; \ break; \ default: \ fin = true; \ continue; \ } \ (_c_) ++; \ } \ } while (0) #define EAT_TOKEN(_c_, _end_) \ do { \ while ((_c_) < (_end_) && IS_TOKEN(*(_c_))) \ (_c_) ++; \ } while (0) bool parse_rseq(unsigned *_rseq, const char *start, int len) { unsigned rseq; const char *pos = start; const char *end = start + len; const char *sav; EAT_WS(pos, end); sav = pos; READ_NUMBER(rseq, pos, end); if (sav == pos) goto error; *_rseq = rseq; DBG("parsed sequence content: %u.\n", rseq); return true; error: INFO("invalid content in sequence header content <%.*s>.\n", len, start); return false; } bool parse_rack(sip_rack *rack, const char *start, int len) { const char *pos; const char *sav; const char *end = start + len; unsigned rseq, cseq; cstring method_str; cstring cseq_str; int method; pos = start; EAT_WS(pos, end); sav = pos; READ_NUMBER(rseq, pos, end); if (pos == sav) goto error; EAT_WS(pos, end); sav = pos; READ_NUMBER(cseq, pos, end); if (pos == sav) goto error; cseq_str.s = sav; cseq_str.len = pos - sav; EAT_WS(pos, end); sav = pos; EAT_TOKEN(pos, end); method_str.s = sav; method_str.len = pos - sav; if (parse_method(&method, method_str.s, method_str.len)) goto error; DBG("parsed '" SIP_HDR_RSEQ "' header: %u %u <%.*s> <%.*s>.\n", rseq, cseq, cseq_str.len, cseq_str.s, method_str.len, method_str.s); rack->rseq = rseq; rack->cseq = cseq; rack->cseq_str.s = cseq_str.s; rack->cseq_str.len = cseq_str.len; rack->method = method; rack->method_str.s = method_str.s; rack->method_str.len = method_str.len; return true; error: INFO("failed to parse <%.*s> as '" SIP_HDR_RSEQ "' header.\n", len, start); return false; }