如何解码SIP数据包?

时间:2014-10-26 10:22:59

标签: c++ linux sip decode decoding

SIP(​​会话发起协议)数据包的格式类似于:

INVITE sip:999999@192.168.202.90:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.100.86:5060;rport;branch=z9hG4bKPj3f79189a-581d-4f58-a4dd-bc64e050421c
Max-Forwards: 70
From: <sip:192.168.100.86>;tag=60f4c35a-6cdb-4b19-b580-f3d3ad5c1abf
To: <sip:999999@192.168.202.90>
Contact: <sip:192.168.101.86:5060;ob>
Call-ID: 247ee45e-957a-481a-b97b-82f2429a999d
CSeq: 17491 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Session-Expires: 1800
Min-SE: 90
User-Agent: PJSUA v2.3 Linux-3.2.0.4/x86_64/glibc-2.13
Content-Type: application/sdp
Content-Length:   479

我需要解码此数据包并提取其中的一些字段,例如FromToCall-ID等。数据包采用ASCII格式,每个字段都编码为分开的。此外,不确定字段的顺序,它们可以是任何顺序。从这样的数据包中提取所需字段值的最佳方法是什么?我需要能够分别设置和获取每个字段。我想到的最简单的想法是逐行读取数据包,并检查每行是否以任何我想要的值开头。我非常感谢有关向我展示有效方法的建议。

2 个答案:

答案 0 :(得分:3)

就个人而言,我是手工做的。这完全是确定性的。字段名称中永远不会有冒号,因此您只需在每一行上查找它,剪切并填充地图。我尝试不为“Via”这样的特定字段编写代码。只需编写一些通用的东西,它也可以在没有代码更改的情您可以尝试找一个图书馆,但它会带上您不需要的行李。它足够小,可以手工编写。注意安全问题,如无休止的线路。

答案 1 :(得分:1)

更好的方法之一是使用Lex / Yaml。无论每个SIP标头中有多少相似之处,每个标头都有一个特定的模式。捕获解析逻辑的方法之一应该分解为ABNF中为SIP定义的最常见的基本类型。然后为每个标题构建它们并逐渐构建它,覆盖更多更好的标题,每隔几天就会从IETF中出现。

我发现这种方法实际上是可扩展的,并且SIP堆栈确实使用类似的方法进行解析。顺便说一下,如果你只对几个常见的标题感兴趣,我会采用第二个阿德里安的方法。