13 echo "Usage: $0 <pcap_file> [results_dir]"
15 echo " pcap_file: pcap formatted file to be processed."
16 echo " results_dir: directory where results are stored."
17 echo " By default, pcap file dirname is used."
19 echo " The utility, dumps the extracted hexadecimal content"
20 echo " and useful information as timestamps, source and"
22 echo " <results_dir>/<frame sequence>.hex"
23 echo " <results_dir>/<frame sequence>.metadata"
47 echo "============================================"
48 echo "Diameter buffer extractor from PCAP raw file"
49 echo "============================================"
53 [ "$1" = "" ] && usage
57 [ ! -f $PCAP_FILE ] && _exit "Cannot found provided pcap file '$1' !!"
59 # Optional result dir:
60 RESULTS_DIR=`dirname $PCAP_FILE`
61 [ "$2" != "" ] && RESULTS_DIR=$2
62 [ ! -d $RESULTS_DIR ] && _exit "The results directory '$RESULTS_DIR' must exists !!"
64 # Get the frames with diameter content (take care about '-2' two-pass option and don't add it, because we need to get reassembled parts in their corresponding frames):
65 # Fields needed (we won't need diameter.hopbyhopid & diameter.endtoendid to verify diameter message as hint patterns; length management will be enough):
66 FIELDS="-e frame.number -e frame.time_epoch -e ip.src_host -e ip.dst_host -e tcp.len -e diameter.length -e frame.protocols -e tcp.segment"
67 tshark -E separator="|" -r $PCAP_FILE -N mntC -Tfields $FIELDS 2>/dev/null | grep -i diameter > $tmpdir/diameter_frames
70 # frame timestamp src dst TCP DIAM protocol segments
71 # 1|1427215933.697904000|gt_traf|vcbavipt|432|432|eth:ip:tcp:diameter:diameter:diameter3gpp|
72 # 3|1427215934.449523000|vcbavipt|gt_traf|292|292|eth:ip:tcp:diameter:diameter:diameter3gpp|
73 # 5|1427215934.456160000|gt_traf|vcbavipt|1400||eth:ip:tcp:diameter|
74 # 6|1427215934.456204000|gt_traf|vcbavipt|572|1972|eth:ip:tcp:diameter:diameter:diameter3gpp|5,6
75 # 8|1427215935.123559000|vcbavipt|gt_traf|248|248|eth:ip:tcp:diameter:diameter:diameter3gpp|
76 all_frames=( $(cat $tmpdir/diameter_frames | cut -d\| -f1) )
77 needs_join=( $(cat $tmpdir/diameter_frames | cut -d\| -f8) )
78 main_frames=( $(cat $tmpdir/diameter_frames | awk -F\| '{ if ($6 != "") print $1 }') )
80 # Reassemble procedure (using frame 1 as example):
81 # (for non segmented frames, it is enough with tcp or diameter length within the frame content itself)
82 # 1) Get the TCP length: 432 bytes. 432*2 = 864 characters per byte in hexadecimal string format
83 # 2) Get the frame length: `wc -c $tmpdir/block.$frame` => 997
84 # 3) Get 864 from the tail: `cat $tmpdir/block.$frame | cut -c133
86 # Dump the hex blocks for all the diameter frames:
87 cat $PCAP_FILE | rawshark -s -r - -d proto:diameter -F data 2>/dev/null > $tmpdir/all_hex_data
88 for frame in ${all_frames[@]}; do
89 grep "^$frame " $tmpdir/all_hex_data | cut -d\" -f2 | sed 's/://g' > $tmpdir/block.$frame
90 frame_info=$(grep "^${frame}|" $tmpdir/diameter_frames)
92 # Get the diameter part:
93 tcp_len=$(echo $frame_info | cut -d\| -f5)
94 frm_len=$(wc -c $tmpdir/block.$frame | awk '{ print $1 }')
95 cut_len=$((frm_len-2*tcp_len))
96 cat $tmpdir/block.$frame | cut -c${cut_len}- > $RESULTS_DIR/$frame.hex
97 echo -n "Created $RESULTS_DIR/$frame.hex"
100 ts=$(echo $frame_info | cut -d\| -f2)
102 src=$(echo $frame_info | cut -d\| -f3)
103 dst=$(echo $frame_info | cut -d\| -f4)
104 echo -e "timestamp=$ts\ndate=$date\nsrc=$src\ndst=$dst" > $RESULTS_DIR/$frame.metadata
105 echo " and $RESULTS_DIR/$frame.metadata"
108 # Join frames which need to be reassembled:
109 for group in ${needs_join[@]}; do
110 echo "Grouping frames $group ..."
111 group_array=( $(echo $group | sed 's/,/ /g') )
112 for frame in ${group_array[@]}; do
113 cat $RESULTS_DIR/$frame.hex >> $tmpdir/diam.$group
115 cat $tmpdir/diam.$group | tr -d '\n' > $RESULTS_DIR/$frame.hex
118 # Delete superfluous metadata:
119 echo "Deleting superfluous metadata ..."
120 segments=( $(cat $tmpdir/diameter_frames | awk -F\| '{ if ($6 == "") print $1 }') )
121 for s in ${segments[@]}; do rm $RESULTS_DIR/$s.metadata; done