sip消息拆包原理及組包流程

操作系統 :CentOS 7.6_x64     
freeswitch版本 :1.10.9
sofia-sip版本: sofia-sip-1.13.14
 
freeswitch使用sip協議進行通信,當sip消息超過mtu時,會出現拆包的情況,這裏整理下sip消息拆包原理及組包流程。

一、拆包的原理

 簡單來說:拆包的原因是,sip消息過長,超過mtu值。
 具體原理可以參考《TCP/IP詳解 卷2:實現》第10章 : IP的分片與重裝

這裏貼下拆包的示意圖:

二、生成sip拆包的pcap文件

1、讓sip消息超過mtu值

這裏列舉兩種方法讓sip消息超過mtu值,具體如下:
1) 添加sip消息內容,超出默認mtu值
該方法和真實場景比較貼合,建議使用,可以通過在orginate時添加自定義sip頭實現,具體操作步驟獲取途徑:
關注微信公衆號(聊聊博文,文末可掃碼)後回覆 20230402 獲取。
2)設置網卡的mtu爲比較小的值
一般網卡默認的mut值是 1500 ,可以通過以下命令修改:
ifconfig enp0s3 mtu 500up

其中,500是新的mtu值,具體效果如下:

2、抓包獲取pcap文件

爲了方便起見,這裏以修改mtu值的方式演示下。
這裏使用tcpdump進行抓包,具體如下:
tcpdump -i enp0s3 udp -w sipTest1-mtu.pcap
具體效果如下:

上圖的INVITE消息已經拆包了。

組包時,需要看ip頭裏面的 More fragments 標識,拆包的數據Identification字段一致,在本示例裏面是 22448 這個值。

三、sip消息組包

由於拆包是IP層的行爲,sip消息大多基於udp實現,拆包的數據包裏面可能沒有端口信息(端口數據在udp裏面定義的),解析之前需要先進行組包,這裏以python爲例進行演示。
python版本:python 3.9
libpcap版本:1.11.0b7
python3如何使用libpcap的具體講解,可從如下途徑獲取:
關注微信公衆號(聊聊博文,文末可掃碼)後回覆 2022102901  獲取。

1、基於udp實現的sip協議數據報文結構

完整的sip消息的IP數據報有IP首部、UDP首部、UDP數據組成,具體如下:

 

 其中IP首部爲20字節,結構如下:

UDP首部爲8字節,結構如下:

2、解析IP首部及UDP首部

ip首部解析如下:
ipHdr = struct.unpack('!BBHHHBBH4s4s',bytes(p[14:34]))
ver = (ipHdr[0] & 0xF0) >> 4
udp首部解析如下:
udpHdr = struct.unpack('!HHHH',bytes(p[34:42]))
srcPort,dstPort = udpHdr[0],udpHdr[1]

3、拼接SIP消息

解析過程大概分爲以下幾個步驟:
1)解析ip頭及udp頭;
2)判斷ip頭是否有moreFrag標識,如果有,則進行特殊標記處理;
3)根據數據包標識拼接sip消息,然後解析;
運行效果如下:

拼接效果如下:

示例代碼如下:

 

 四、資源獲取

本文涉及文件和完整python示例代碼從如下途徑獲取:

關注微信公衆號(聊聊博文,文末可掃碼)後回覆 20230408 獲取。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章