Python
Wireshark
pcap
ZigBee

SmartRF Protocol Packet Snifferで取得したZigbeeのパケットキャプチャデータをPCAPファイルに変換するツール

More than 1 year has passed since last update.


Zigbeeのパケットキャプチャツールについて

無線通信のパケットキャプチャツールである以下を使ってZigbeeのデータを取得できます。

SmartRF Protocol Packet Sniffer

http://www.tij.co.jp/tool/jp/packet-sniffer


SmartRF Protocol Packet Snifferの問題点

Zigbeeのプロトコルには、セキュリティ機能のメッセージがあるのですが、そのメッセージを識別することができません。またツールからpcapファイルに出力することができません。

そのため非常に解析しづらかったので、SmartRF Protocol Packet Snifferで取得したデータ(.psd)ファイルをWiresharkなどで読める.pcapファイルに変換するツールを自作することにしました。


事前準備


  • Wiresharkをインストールしてあること

  • 環境変数PATHにWiresharkのexeフォルダのパスを入れてあること(text2pcap.exeを変換に使用します)


PSD to PCAPファイル変換ツール

以下のアプローチでツールを作成

- pcapへの変換はWiresharkの標準ツールであるtext2pcapを使う

- text2pcapで読み込めるtext形式にpsdファイルのパケットデータから出力する


psd2pcap_for_zigbee.py

import sys

import os

def main():
#読み込みファイル名取得
if(len(sys.argv)>1):
filename = sys.argv[1]
else:
filename = raw_input('file name:')

#PSD file読み込み
fp_r = open(filename,"rb")

#変数定義
ct_payload = 0
head_flg = 0
head_cnt = 0
payload_flg = 0
null_flg = 1
data = []
data_all = []
d_str_old = ""
while True:
d = fp_r.read(1)
if len(d) == 0:
break
else:
pass
d_str = '%02x'%ord(d)
d_int = int('0x'+d_str,16)

if (null_flg==1) & (d_str_old.find("03")==0) & (d_int==head_cnt+1):
null_flg = 0
head_flg = 14
head_cnt = head_cnt + 1
elif (head_flg==1):
ct_payload = d_int
head_flg = 0
elif (head_flg > 1):
head_flg = head_flg -1
elif (ct_payload > 0):
data.append(d_str)
ct_payload = ct_payload - 1
elif (null_flg == 1):
pass
else:
null_flg = 1
#dataをまとめる
data_str =""
for i in range(0,len(data)):
data_str = data_str+data[i]
data_all.append(data)
data = []

d_str_old = d_str
fp_r.close

#pcap変換用txt作成
export_txt(filename.split(".")[0]+".txt",data_all)
#pcap生成
os.system("text2pcap -l 195 "+filename.split(".")[0]+".txt "+filename.split(".")[0]+".pcap")
os.system("del " + filename.split(".")[0]+".txt")

#Zigbeeデータをpcap変換用txtに出力
def export_txt(filename,data_all):
fp = open(filename,"w")
for i in range(0,len(data_all)):
cnt=0
for j in range(0,len(data_all[i])):
if ((j%16)==0):
fp.write("%03x"%(cnt)+"0"+" "+data_all[i][j])
cnt=cnt+1
elif ((j%16)==15):
fp.write(" "+data_all[i][j]+"\n")
else:
fp.write(" "+data_all[i][j])
fp.write("\n")
fp.close

if __name__ == '__main__':
main()



Wiresharkの設定

最後に、Wiresharkの設定で、いくつか変更が必要になります。

- 「編集」→「設定」→「Protocols」→「IEEE802.15.4」の"TI CC24XX FCS format"にチェックを入れる

- 「編集」→「設定」→「Protocols」→「IEEE802.15.4」のSecurity Suiteを適切な値に合わせる