1 | #include "SipDissector.h" |
---|
2 | #include "Logger/Logger.h" |
---|
3 | #include <boost/regex.hpp> |
---|
4 | |
---|
5 | SipDissector::SipDissector() : |
---|
6 | m_nMessageLength(HEADER_NOT_PARSED) |
---|
7 | { |
---|
8 | } |
---|
9 | |
---|
10 | SipDissector::~SipDissector() |
---|
11 | { |
---|
12 | } |
---|
13 | |
---|
14 | SipDissector * SipDissector::Clone() const |
---|
15 | { |
---|
16 | return new SipDissector(); |
---|
17 | } |
---|
18 | |
---|
19 | bool SipDissector::IsPacketValid() const |
---|
20 | { |
---|
21 | return m_nMessageLength != PARSING_ERROR; |
---|
22 | } |
---|
23 | |
---|
24 | bool SipDissector::FinishDissection() |
---|
25 | { |
---|
26 | if (m_nMessageLength == PARSING_ERROR) { |
---|
27 | return true; |
---|
28 | } |
---|
29 | // detect SIP header |
---|
30 | int i = 0; |
---|
31 | ssize_t nDataLen = GetPayloadSize(); |
---|
32 | const unsigned char * pData = GetPayload(); |
---|
33 | std::string s(reinterpret_cast<const char *>(pData), nDataLen); |
---|
34 | if (m_nMessageLength == HEADER_NOT_PARSED) |
---|
35 | { |
---|
36 | int nIndex = s.find("\r\n"); |
---|
37 | if (nIndex > -1) |
---|
38 | { |
---|
39 | std::string sTmp = s.substr(0, nIndex); |
---|
40 | boost::regex rgx1("(\\A.* SIP/[0-9]+[\\.][0-9]+)|(\\ASIP/[0-9]+[\\.][0-9]+ .*)", boost::regex::perl|boost::regex::icase); |
---|
41 | if (!boost::regex_match(sTmp, rgx1)) |
---|
42 | { |
---|
43 | Logger::Instance().LogError("Invalid SIP message"); |
---|
44 | m_nMessageLength = PARSING_ERROR; |
---|
45 | return true; |
---|
46 | } |
---|
47 | else |
---|
48 | m_nMessageLength = LENGTH_NOT_PARSED; |
---|
49 | } |
---|
50 | } |
---|
51 | if (m_nMessageLength == LENGTH_NOT_PARSED) |
---|
52 | { |
---|
53 | int nIndex = s.find("\r\n\r\n"); |
---|
54 | if (nIndex > -1) |
---|
55 | { |
---|
56 | std::string sTmp = s.substr(0, nIndex); |
---|
57 | boost::regex rgxContentLength("^(?:(?:Content-Length)|l)[ \\t]*[:]\\s*([0-9]+)$", |
---|
58 | boost::regex::perl|boost::regex::icase); |
---|
59 | boost::smatch matches; |
---|
60 | if (boost::regex_search(sTmp, matches, rgxContentLength)) |
---|
61 | { |
---|
62 | std::string sLen(matches[1].first, matches[1].second); |
---|
63 | m_nMessageLength = sTmp.length() + 4 + boost::lexical_cast<int>(sLen); |
---|
64 | } |
---|
65 | } |
---|
66 | } |
---|
67 | if (m_nMessageLength >= 0 && m_nMessageLength < nDataLen) |
---|
68 | // unlikely case: two or more messages came in one packet |
---|
69 | SeparateUnprocessedData(m_nMessageLength); |
---|
70 | |
---|
71 | return m_nMessageLength >= 0 && m_nMessageLength <= nDataLen; |
---|
72 | } |
---|
73 | |
---|
74 | |
---|
75 | bool SipDissector::Dissect(const unsigned char * pData, const ssize_t nDataLength) |
---|
76 | { |
---|
77 | SavePayload(pData, nDataLength); |
---|
78 | return true; |
---|
79 | } |
---|
80 | |
---|
81 | bool SipDissector::NeedReassembly() const |
---|
82 | { |
---|
83 | return m_nMessageLength < 0 || m_nMessageLength > GetPayloadSize(); |
---|
84 | } |
---|
85 | |
---|
86 | bool SipDissector::Reassemble(Dissector * pDissector, ProtocolInfo * pProtocolInfo) |
---|
87 | { |
---|
88 | if (!MatchProtocolInfo(pProtocolInfo)) { |
---|
89 | return false; // Different addresses or ports than expected |
---|
90 | } |
---|
91 | AppendPayload(pDissector); |
---|
92 | FinishDissection(); |
---|
93 | return true; |
---|
94 | } |
---|
95 | |
---|
96 | const EProtocolType SipDissector::GetUpperLayerType() const |
---|
97 | { |
---|
98 | return EProtocolType_None; |
---|
99 | } |
---|
100 | |
---|
101 | ProtocolInfoElement * SipDissector::CreateLayerInfo() |
---|
102 | { |
---|
103 | return 0; |
---|
104 | } |
---|
105 | |
---|
106 | bool SipDissector::CreatesUnprocessedData() const |
---|
107 | { |
---|
108 | return true; |
---|
109 | } |
---|