fc217cdc751166ac79d2cb88cf5b17f4caa828c3
[anna.git] / example / diameter / launcher / resources / pcap2diameterHex.sh
1 #!/bin/bash
2
3 #############
4 # VARIABLES #
5 #############
6 tmpdir=$(mktemp -d)
7
8 #############
9 # FUNCTIONS #
10 #############
11
12 usage () {
13   echo "Usage: $0 <pcap_file> [results_dir]"
14   echo
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."
18   echo
19   echo "       The utility, dumps the extracted hexadecimal content"
20   echo "       and useful information as timestamps, source and"
21   echo "       destination:"
22   echo "          <results_dir>/<frame sequence>.hex"
23   echo "          <results_dir>/<frame sequence>.metadata"
24   echo
25   _exit
26 }
27
28 _exit () {
29   echo
30   echo -e $1
31   echo
32
33   # Cleanup
34   rm -rf $tmpdir
35
36   rc=1
37   [ -n "$2" ] && rc=$2
38   exit $rc
39 }
40
41
42 #############
43 # EXECUTION #
44 #############
45
46 echo
47 echo "============================================"
48 echo "Diameter buffer extractor from PCAP raw file"
49 echo "============================================"
50 echo
51
52 # Usage:
53 [ "$1" = "" ] && usage
54
55 # Pcap file:
56 PCAP_FILE=$1
57 [ ! -f $PCAP_FILE ] && _exit "Cannot found provided pcap file '$1' !!"
58
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 !!"
63
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
68 # Example output:
69 #                                           /length\
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 }') )
79
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
85
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)
91
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"
98
99   # Metadata:
100   ts=$(echo $frame_info | cut -d\| -f2)
101   date=$(date -d @$ts)
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"
106 done
107
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
114   done
115   cat $tmpdir/diam.$group | tr -d '\n' > $RESULTS_DIR/$frame.hex
116 done
117
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
122
123
124 _exit "Done!" 0
125