패킷 데이터를 저장하는 방법은 다양합니다. PCAP 파일 그 자체가 될 수도 있고, 각 필드를 분리하여 해당 내용만 저장하거나 텍스트 또는 CSV, C 어레이 형태등 다양합니다. 패킷 데이터를 활용하는 방법에 따라 저장 방법의 차이가 있지만 구조화된 XML 로 데이터를 얻을 수는 없을까요?
이런 고민을 했다면 와이어샤크가 한 순간에 해결해 줍니다. 와이어샤크에서 기본적으로 지원하고 있기 때문인데요, 메뉴에서
File->Export->File->as XML - "PSML", "PDML"
위와 같은 경로를 보시면 쉽게 해당 패킷데이터를 XML 로 변경 저장해 줍니다. PSML 은 패킷 요약 정보이고 PDML 은 패킷 상세 정보입니다.
와이어샤크에서 지원하기 때문에 명령어 모드인 tshark 에서도 -T 옵션을 통해 사용가능합니다.
-T pdml|ps|psml|text|fields
format of text output (def: text)
어디한번 패킷요약 정보를 XML 로 살펴볼까요?
# tshark -T psml -r 1.pcap | more
<?xml version="1.0"?>
<psml version="0" creator="wireshark/1.7.0">
<structure>
<section>No.</section>
<section>Time</section>
<section>Source</section>
<section>Destination</section>
<section>Protocol</section>
<section>Length</section>
<section>Info</section>
</structure>
<packet>
<section>1</section>
<section>0.000000</section>
<section>192.168.70.103</section>
<section>192.168.70.101</section>
<section>TCP</section>
<section>66</section>
<section>49239 > ms-wbt-server [SYN] Seq=989508872 Win=8192 Len=0 MSS=1460 WS
=256 SACK_PERM=1</section>
</packet>
우리가 와이어샤크 메인 화면에서 보았던 형태의 구조로 데이터가 저장되어 있습니다. 처음에 각 섹션의 필드가 설명되어있고 <packet> 안에 각 섹션 정보가 들어가 있습니다. 두번째로 상세 정보를 보겠습니다.
# tshark -T pdml -r 1.pcap | more
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="pdml2html.xsl"?>
<!-- You can find pdml2html.xsl in /usr/local/share/wireshark or at http://anons
vn.wireshark.org/trunk/wireshark/pdml2html.xsl. -->
<pdml version="0" creator="wireshark/1.7.0" time="Mon May 13 08:34:45 2013" capt
ure_file="1.pcap">
<packet>
<proto name="geninfo" pos="0" showname="General information" size="66">
<field name="num" pos="0" show="1" showname="Number" value="1" size="66"/>
<field name="len" pos="0" show="66" showname="Frame Length" value="42" size=
"66"/>
<field name="caplen" pos="0" show="66" showname="Captured Length" value="42"
size="66"/>
<field name="timestamp" pos="0" show="Sep 2, 2012 07:36:41.107704000 KST" s
howname="Captured Time" value="1346539001.107704000" size="66"/>
</proto>
<proto name="frame" showname="Frame 1: 66 bytes on wire (528 bits), 66 bytes c
aptured (528 bits)" size="66" pos="0">
<field name="frame.time" showname="Arrival Time: Sep 2, 2012 07:36:41.10770
4000 KST" size="0" pos="0" show="Sep 2, 2012 07:36:41.107704000"/>
<field name="frame.offset_shift" showname="Time shift for this packet: 0.000
000000 seconds" size="0" pos="0" show="0.000000000"/>
<field name="frame.time_epoch" showname="Epoch Time: 1346539001.107704000 se
conds" size="0" pos="0" show="1346539001.107704000"/>
<field name="frame.time_delta" showname="Time delta from previous captured f
rame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
<field name="frame.time_delta_displayed" showname="Time delta from previous
displayed frame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
<field name="frame.time_relative" showname="Time since reference or first fr
ame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
<field name="frame.number" showname="Frame Number: 1" size="0" pos="0" show=
"1"/>
<field name="frame.len" showname="Frame Length: 66 bytes (528 bits)" size="0
" pos="0" show="66"/>
<field name="frame.cap_len" showname="Capture Length: 66 bytes (528 bits)" s
ize="0" pos="0" show="66"/>
<field name="frame.marked" showname="Frame is marked: False" size="0" pos="0
" show="0"/>
<field name="frame.ignored" showname="Frame is ignored: False" size="0" pos=
"0" show="0"/>
<field name="frame.protocols" showname="Protocols in frame: eth:ip:tcp" size
="0" pos="0" show="eth:ip:tcp"/>
</proto>
<proto name="eth" showname="Ethernet II, Src: Vmware_33:75:1f (00:0c:29:33:75:
1f), Dst: Vmware_8a:43:28 (00:0c:29:8a:43:28)" size="14" pos="0">
<field name="eth.dst" showname="Destination: Vmware_8a:43:28 (00:0c:29:8a:43
보시는 것과 같이 꽤 많은 정보가 포함되어 있습니다. 이 XML 구조는 필드 이름으로 각 정보가 구분되어 들어가 있는데, 이 필드이름은 출력필터 문법으로 사용되고 있습니다. caplen 은 캡쳐된 길이를 뜻하고 timestampe 는 시간, frame.len 은 프레임 길이 eth.dst 는 이더넷 목적지 맥 주소 ip.id 는 IP 헤더의 Identification, tcp.port 는 TCP 포트 정보와 같습니다. 필드 이름을 보면 쉽게 이해가 되시죠? 출력필터를 그대로 사용하고 있기 때문에 이해가 쉽습니다. 즉, 프로토콜 구조 밑에 각 필드가 들어가는 구조입니다.
<proto name="geninfo">
<field name="num">
<field name="len">
<field name="caplen">
<field name="timestampe">
</proto>
<proto name="frame">
<proto name="eth">
<proto name="ip">
<proto name="tcp">
이제 이런 데이터의 활용은 여러분의 몫 이겠죠?
:-)