public void ExtractHeadersUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); string sipMsg = "From: <sip:[email protected]>;tag=0477183750" + m_CRLF + "To: <sip:[email protected]>;tag=414dedfe" + m_CRLF + "CSeq: 1 REGISTER" + m_CRLF + "Call-ID: 438676792abe47328fc557da2d84d0ee" + m_CRLF + "Via: SIP/2.0/UDP 192.168.1.102:7246;branch=z9hG4bK92460620adf84edab2341899a3453f79;received=124.168.235.200;rport=10552" + m_CRLF + "Server: Huawei SoftX3000 R006B03D" + m_CRLF + "Refer-To: Test Refer-To" + m_CRLF + "Authentication-Info: Test Authentication-Info" + m_CRLF + "WWW-Authenticate: Digest realm=\"huawei\"," + m_CRLF + " nonce=\"248e4b4457f252ae53c859bfe03c4f93\",domain=\"sip:huawei.com\"," + m_CRLF + " stale=false,algorithm=MD5" + m_CRLF + "Content-Length: 0" + m_CRLF + m_CRLF; logger.LogDebug("Original SIP Headers:\n" + sipMsg); string[] headersCollection = SIPHeader.SplitHeaders(sipMsg); SIPHeader sipHeader = SIPHeader.ParseSIPHeaders(headersCollection); Assert.Equal("Test Refer-To", sipHeader.ReferTo); Assert.Equal("Test Authentication-Info", sipHeader.AuthenticationInfo); logger.LogDebug("-----------------------------------------"); }
public void MultipleContactHeadersUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); string sipMsg = "From: <sip:[email protected]>;tag=0477183750" + m_CRLF + "To: <sip:[email protected]>;tag=414dedfe" + m_CRLF + "CSeq: 1 REGISTER" + m_CRLF + "Contact: \"Joe Bloggs\" <sip:[email protected]>;expires=0" + m_CRLF + "Call-ID: 438676792abe47328fc557da2d84d0ee" + m_CRLF + "Via: SIP/2.0/UDP 192.168.1.102:7246;branch=z9hG4bK92460620adf84edab2341899a3453f79;received=124.168.235.200;rport=10552" + m_CRLF + "Server: Huawei SoftX3000 R006B03D" + m_CRLF + "WWW-Authenticate: Digest realm=\"huawei\"," + m_CRLF + " nonce=\"248e4b4457f252ae53c859bfe03c4f93\",domain=\"sip:huawei.com\"," + m_CRLF + " stale=false,algorithm=MD5" + m_CRLF + "Contact: \"Jane Doe\" <sip:[email protected]>" + m_CRLF + "Content-Length: 0" + m_CRLF + m_CRLF; logger.LogDebug("Original SIP Headers:\n" + sipMsg); string[] headersCollection = SIPHeader.SplitHeaders(sipMsg); SIPHeader sipHeader = SIPHeader.ParseSIPHeaders(headersCollection); Assert.True(sipHeader.Contact.Count == 2, "The SIP header had the wrong number of Contacts."); Assert.True(sipHeader.Contact[0].ToString() == "\"Joe Bloggs\" <sip:[email protected]>;expires=0", "The first Contact header was not parsed correctly."); Assert.True(sipHeader.Contact[1].ToString() == "\"Jane Doe\" <sip:[email protected]>", "The second Contact header was not parsed correctly."); logger.LogDebug("-----------------------------------------"); }
public void HuaweiRegisterUnitTest() { Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); string sipMsg = "From: <sip:[email protected]>;tag=0477183750" + m_CRLF + "To: <sip:[email protected]>;tag=414dedfe" + m_CRLF + "CSeq: 1 REGISTER" + m_CRLF + "Call-ID: 438676792abe47328fc557da2d84d0ee" + m_CRLF + "Via: SIP/2.0/UDP 192.168.1.102:7246;branch=z9hG4bK92460620adf84edab2341899a3453f79;received=124.168.235.200;rport=10552" + m_CRLF + "Server: Huawei SoftX3000 R006B03D" + m_CRLF + "WWW-Authenticate: Digest realm=\"huawei\"," + m_CRLF + " nonce=\"248e4b4457f252ae53c859bfe03c4f93\",domain=\"sip:huawei.com\"," + m_CRLF + " stale=false,algorithm=MD5" + m_CRLF + "Content-Length: 0" + m_CRLF + m_CRLF; Console.WriteLine("Original SIP Headers:\n" + sipMsg); string[] headersCollection = SIPHeader.SplitHeaders(sipMsg); SIPHeader sipHeader = SIPHeader.ParseSIPHeaders(headersCollection); Console.WriteLine(sipHeader.ToString()); Console.WriteLine(sipHeader.AuthenticationHeader.ToString()); Assert.IsTrue(Regex.Match(sipHeader.AuthenticationHeader.ToString(), "nonce").Success, "The WWW-Authenticate header was not correctly parsed across multpiple lines."); Console.WriteLine("-----------------------------------------"); }
public static SIPMessage ParseSIPMessage(string message, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { try { SIPMessage sipMessage = new SIPMessage(); sipMessage.LocalSIPEndPoint = localSIPEndPoint; sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint; sipMessage.RawMessage = message; int endFistLinePosn = message.IndexOf(m_CRLF); if (endFistLinePosn != -1) { sipMessage.FirstLine = message.Substring(0, endFistLinePosn); if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX) { sipMessage.SIPMessageType = SIPMessageTypesEnum.Response; } else { sipMessage.SIPMessageType = SIPMessageTypesEnum.Request; } int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF); if (endHeaderPosn == -1) { // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body. string headerString = message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); //Regex.Split(headerString, m_CRLF); } else { string headerString = message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); //Regex.Split(headerString, m_CRLF); if (message.Length > endHeaderPosn + 4) { sipMessage.Body = message.Substring(endHeaderPosn + 4); } } return(sipMessage); } else { logger.Warn("Error ParseSIPMessage, there were no end of line characters in the string being parsed."); return(null); } } catch (Exception excp) { logger.Error("Exception ParseSIPMessage. " + excp.Message + "\nSIP Message=" + message + "."); return(null); } }
public void ParseAMulitLineHeaderTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); string mulitLineHeader = "Via: SIP/2.0/UDP 213.168.225.135:5060;branch=z9hG4bK8Z4EIWBeY45fRGwC0qIeu/xpw3A=" + m_CRLF + "Via: SIP/2.0/UDP 192.168.1.2:5065;received=220.240.255.198:64091;branch=z9hG4bK4E0728C26A0640E7830D7C9179D08D67" + m_CRLF + "Record-Route: <sip:213.168.225.133:5060;lr>," + m_CRLF + " <sip:220.240.255.198:64091;lr>" + m_CRLF + "From: bluesipd <sip:bluesipd@bluesipd:5065>;tag=457825353" + m_CRLF + "To: <sip:303@bluesipd>;tag=as02a64a42" + m_CRLF + "Call-ID: [email protected]" + m_CRLF + "CSeq: 38002 INVITE" + m_CRLF + "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY" + m_CRLF + "Contact: <sip:[email protected]>" + m_CRLF + "Content-Type: application/sdp" + m_CRLF + "Content-Length: 350" + m_CRLF; logger.LogDebug("Original SIP Headers:\n" + mulitLineHeader); string[] headersCollection = SIPHeader.SplitHeaders(mulitLineHeader); foreach (string headerStr in headersCollection) { logger.LogDebug("Header => " + headerStr + "."); } Assert.True(headersCollection.Length == 12, "The headers were not split properly."); logger.LogDebug(""); SIPHeader sipHeader = SIPHeader.ParseSIPHeaders(headersCollection); logger.LogDebug("Parsed SIP Headers:\n" + sipHeader.ToString()); Assert.True(sipHeader.RecordRoutes.Length == 2, "An incorrect number of record route entries was extracted, number was " + sipHeader.RecordRoutes.Length + "."); SIPRoute topRoute = sipHeader.RecordRoutes.PopRoute(); Assert.True(topRoute.Host == "213.168.225.133:5060", "The top record route was not parsed correctly."); logger.LogDebug("---------------------------------------------------"); }
/// <summary> /// Attempts to parse a SIP message from a string containing a single SIP request or response. /// </summary> /// <param name="message">The string to parse.</param> /// <param name="localSIPEndPoint">The end point the message was received on.</param> /// <param name="remoteSIPEndPoint">The end point the message was received from.</param> /// <returns>If successful a SIP message or null if not.</returns> public static SIPMessageBuffer ParseSIPMessage(string message, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { try { SIPMessageBuffer sipMessage = new SIPMessageBuffer(); sipMessage.LocalSIPEndPoint = localSIPEndPoint; sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint; // For connection oriented transports the same connection should be used for responses and subsequent requests. if (sipMessage.LocalSIPEndPoint != null && remoteSIPEndPoint.ConnectionID != null) { sipMessage.LocalSIPEndPoint.ConnectionID = remoteSIPEndPoint.ConnectionID; } sipMessage.RawMessage = message; int endFistLinePosn = message.IndexOf(m_CRLF); if (endFistLinePosn != -1) { sipMessage.FirstLine = message.Substring(0, endFistLinePosn); if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX) { sipMessage.SIPMessageType = SIPMessageTypesEnum.Response; } else { sipMessage.SIPMessageType = SIPMessageTypesEnum.Request; } int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF); if (endHeaderPosn == -1) { // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body. string headerString = message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); } else { string headerString = message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); if (message.Length > endHeaderPosn + 4) { sipMessage.Body = message.Substring(endHeaderPosn + 4); } } return(sipMessage); } else { Logger.Logger.Warn( "Error ParseSIPMessage, there were no end of line characters in the string being parsed."); return(null); } } catch (Exception excp) { Logger.Logger.Error("Exception ParseSIPMessage. ->" + excp.Message + "->SIP Message=" + message + "."); return(null); } }
/// <summary> /// Attempts to parse a SIP message from a single buffer that can only contain a single message. /// </summary> /// <param name="buffer">The buffer that will be parsed for a SIP message.</param> /// <param name="sipBodyEncoding">SIP payload encoding</param> /// <param name="localSIPEndPoint">The end point the message was received on.</param> /// <param name="remoteSIPEndPoint">The end point the message was received from.</param> /// <param name="sipEncoding">SIP protocol encoding, according to RFC should be UTF-8 </param> /// <returns>If successful a SIP message or null if not.</returns> public static SIPMessageBuffer ParseSIPMessage( byte[] buffer, Encoding sipEncoding, Encoding sipBodyEncoding, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteSIPEndPoint) { if (buffer == null || buffer.Length < m_minFirstLineLength) { // Ignore. return(null); } else if (buffer.Length > SIPConstants.SIP_MAXIMUM_RECEIVE_LENGTH) { throw new ApplicationException("SIP message received that exceeded the maximum allowed message length, ignoring."); } else if (!BufferUtils.HasString(buffer, 0, buffer.Length, SIP_MESSAGE_IDENTIFIER, m_CRLF)) { // Message does not contain "SIP" anywhere on the first line, ignore. return(null); } else { var sipMessage = new SIPMessageBuffer(sipEncoding, sipBodyEncoding); sipMessage.RawBuffer = buffer; sipMessage.LocalSIPEndPoint = localSIPEndPoint; sipMessage.RemoteSIPEndPoint = remoteSIPEndPoint; // For connection oriented transports the same connection should be used for responses and subsequent requests. if (sipMessage.LocalSIPEndPoint != null && remoteSIPEndPoint.ConnectionID != null) { sipMessage.LocalSIPEndPoint.ConnectionID = remoteSIPEndPoint.ConnectionID; } string message = sipEncoding.GetString(buffer); int endFistLinePosn = message.IndexOf(m_CRLF); if (endFistLinePosn != -1) { sipMessage.FirstLine = message.Substring(0, endFistLinePosn); if (sipMessage.FirstLine.Substring(0, 3) == SIP_RESPONSE_PREFIX) { sipMessage.SIPMessageType = SIPMessageTypesEnum.Response; } else { sipMessage.SIPMessageType = SIPMessageTypesEnum.Request; } int endHeaderPosn = message.IndexOf(m_CRLF + m_CRLF); if (endHeaderPosn == -1) { // Assume flakey implementation if message does not contain the required CRLFCRLF sequence and treat the message as having no body. string headerString = message.Substring(endFistLinePosn + 2, message.Length - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); } else { string headerString = message.Substring(endFistLinePosn + 2, endHeaderPosn - endFistLinePosn - 2); sipMessage.SIPHeaders = SIPHeader.SplitHeaders(headerString); if (message.Length > endHeaderPosn + 4) { sipMessage.Body = new byte[buffer.Length - (endHeaderPosn + 4)]; Buffer.BlockCopy(buffer, endHeaderPosn + 4, sipMessage.Body, 0, buffer.Length - (endHeaderPosn + 4)); } } return(sipMessage); } else { logger.LogWarning("Error ParseSIPMessage, there were no end of line characters in the string being parsed."); return(null); } } }