#! /bin/bash . /usr/src/m2/framework/bash_functions.sh shopt -s extglob if [[ "`/sbin/pidof -x $(basename $0) -o %PPID`" ]]; then echo "$(date_time) [WARNING] $(basename $0) script is already running with PID `/sbin/pidof -x $(basename $0) -o %PPID`" exit 0 fi VERSION="1.1.3" PCAP_ROOT="/var/log/m2/pcap_tshark" LOG_FILE="/var/log/m2/m2_pcap_tshark.log" TMP_FOR_MSC="$PCAP_ROOT/pcap_tmp/cp_info.txt" PCAPS_JSON_FILE="$PCAP_ROOT/pcap_tmp/pcaps.json" initial_pcap="$PCAP_ROOT/pcap_tmp/invite_packets/initial.pcap" config="/etc/m2/system.conf" mkdir -p /var/log/m2 FIVE_MB_IN_B=5242880 pcap_files=0 pcaps_to_check="" leg_b_include_complete_call=0 # Asguments from GUI: call_date="$1" dst="$2" src="$3" originator_ip="$4" terminator_ip="$5" call_id="$6" # LOG everything to file LOG_FILE # Close STDOUT file descriptor exec 1<&- # Close STDERR FD exec 2<&- # Open STDOUT as $LOG_FILE file for read and write. exec 1>>$LOG_FILE # Redirect STDERR to STDOUT exec 2>&1 pcap_tshark_show_all_b_legs=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_show_all_b_legs/{print $2}') pcap_tshark_search_threshold=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_search_threshold/{print $2}') pcap_tshark_capture_directory=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_capture_directory/{print $2}') pcap_tshark_compress=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_compress/{print $2}') pcap_tshark_search_all_files=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_search_all_files/{print $2}') pcap_tshark_search_limit_all_files=$(sed 's/ //g' $config | awk -F"=" '/pcap_tshark_search_limit_all_files/{print $2}') if ! [[ -n $pcap_tshark_search_threshold && $pcap_tshark_search_threshold =~ ^[0-9]+$ ]]; then pcap_tshark_search_threshold=10 fi if [[ -z $pcap_tshark_capture_directory ]]; then pcap_tshark_capture_directory="/var/spool/pcaps" fi if [[ -z $pcap_tshark_show_all_b_legs ]]; then pcap_tshark_show_all_b_legs=0 fi if [[ -z $pcap_tshark_compress ]]; then pcap_tshark_compress=0 fi if [[ -z $pcap_tshark_search_all_files ]]; then pcap_tshark_search_all_files=0 fi if [[ -z $pcap_tshark_search_limit_all_files ]]; then pcap_tshark_search_limit_all_files=0 fi #read -r dst src originator_ip terminator_ip < <( MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select dst, src, originator_ip, terminator_ip from calls where id=$call_id") #echo "$dst, $src, $originator_ip, $terminator_ip" set_database_variables call_date=$(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select calldate from calls where id=$call_id") localized_dst=$(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select localized_dst from calls where id=$call_id") uniqueid=$(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select uniqueid from calls where id=$call_id") real_duration=$(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select sum(real_duration) from calls where calldate='$call_date' and uniqueid='$uniqueid'") start_timestamp=$(date -d "$call_date" +%s) rounded_real_duration=$( LL_ALL=C /usr/bin/printf '%.*f\n' 0 "$real_duration") end_timestamp=$((start_timestamp + rounded_real_duration + 2)) start_timestamp=$((start_timestamp - 2)) dst_shortened=${dst:${#dst}<5?0:-5} src_shortened=${src:${#src}<5?0:-5} localized_dst_shortened=${localized_dst:${#localized_dst}<5?0:-5} RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' NC='\033[0m' GR="$GREEN" BL="$BLUE" print_settings() { echo -e "$(date_time) [NOTICE] pcap_tshark ${GREEN}$VERSION${NC} settings:" echo -e "${BLUE}pcap_tshark srcript version:${NC} ${GREEN}$VERSION${NC}" echo -e "${BLUE}pcap_tshark_search_threshold:${NC} ${GREEN}$pcap_tshark_search_threshold${NC}" echo -e "${BLUE}pcap_tshark_capture_directory:${NC} ${GREEN}$pcap_tshark_capture_directory${NC}" echo -e "${BLUE}pcap_tshark_show_all_b_legs:${NC} ${GREEN}$pcap_tshark_show_all_b_legs${NC}" echo -e "${BLUE}pcap_tshark_compress:${NC} ${GREEN}$pcap_tshark_compress${NC}" echo -e "${BLUE}pcap_tshark_search_all_files:${NC} ${GREEN}$pcap_tshark_search_all_files${NC}" echo -e "${BLUE}pcap_tshark_search_limit_all_files:${NC} ${GREEN}$pcap_tshark_search_limit_all_files${NC}" } print_call_info() { echo -e "$(date_time) [NOTICE] Search PCAP for a call...:" echo -e "${BLUE}call_id:${NC} ${GREEN}$call_id${NC}" echo -e "${BLUE}call_date:${NC} ${GREEN}$call_date${NC}" echo -e "${BLUE}dst:${NC} ${GREEN}$dst${NC}" echo -e "${BLUE}src:${NC} ${GREEN}$src${NC}" echo -e "${BLUE}originator_ip:${NC} ${GREEN}$originator_ip${NC}" echo -e "${BLUE}terminator_ip:${NC} ${GREEN}$terminator_ip${NC}" } get_pcaps() { # $1 - dir to check pcaps # Returns: # 0 and populates pcaps_to_check string with files if found any # > 0 if error encountered or no pcaps files found echo "/usr/local/m2/m2_pcap_tshark_find_suitable_pcaps.rb \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"" if pcaps_json=$(/usr/local/m2/m2_pcap_tshark_find_suitable_pcaps.rb "$1" "$2" "$3" "$4" "$5"); then echo "$pcaps_json" | /usr/local/sbin/jq . | tee $PCAPS_JSON_FILE pcap_files=$(echo "$pcaps_json" | jq '.merged_files_count') if ((pcap_files > 0)); then if ((pcap_files > pcap_tshark_search_limit_all_files)); then # IF pcaps count exceed limit, get limit/2 from the start and limit/2 from the end echo "pcap_files $pcap_files exceed pcap_tshark_search_limit_all_files limit $pcap_tshark_search_limit_all_files" echo "Only $pcap_tshark_search_limit_all_files files will be used" (( start_file_last = (pcap_tshark_search_limit_all_files/2) )) (( end_file_first = pcap_files - start_file_last )) pcaps_to_check_1=$(echo "$pcaps_json" | /usr/local/sbin/jq -r ".merged_files[:$start_file_last] | join (\" \")") echo "pcaps_to_check_1: $pcaps_to_check_1" pcaps_to_check_2=$(echo "$pcaps_json" | /usr/local/sbin/jq -r ".merged_files[$end_file_first:] | join (\" \")") echo "pcaps_to_check_2: $pcaps_to_check_2" pcaps_to_check="${pcaps_to_check_1} ${pcaps_to_check_2}" else pcaps_to_check=$(echo "$pcaps_json" | /usr/local/sbin/jq -r '.merged_files | join (" ")') fi echo -e "$(date_time) [NOTICE] Will check these pcaps files ${GREEN}$pcaps_to_check${NC}" else echo -e "$(date_time) [WARNING] ${BLUE}No suitable PCAP files found${NC}" return 1 fi else echo -e "$(date_time) [ERROR] ${RED}Error generating PCAP files list. Check errors from ruby script above${NC}" return 1 fi return 0 } extract_frames_by_time() { mkdir -p $PCAP_ROOT/pcap_tmp/invite_packets/ cd $PCAP_ROOT/pcap_tmp/invite_packets/ || exit rm -f initial* local pcaps_globed local i=1 for pcap_file in $pcaps_to_check; do if (( pcap_tshark_search_all_files == 0 || (pcap_tshark_search_all_files == 1 && (i == 1 || i == pcap_files)) )); then echo -e "$(date_time) [NOTICE] Extracting packets by time from ${BLUE}$pcap_file${NC} into ${BLUE}$initial_pcap.$i${BLUE}" if ((pcap_tshark_compress == 0)); then echo -e "/usr/sbin/tshark -r ${GR}$pcap_file${NC} -Y \"frame.time_epoch > ${GR}$start_timestamp${NC} and frame.time_epoch < ${GR}$end_timestamp${NC}\" -w ${GR}$initial_pcap${NC}" /usr/sbin/tshark -r "$pcap_tshark_capture_directory/$pcap_file" -Y "frame.time_epoch > $start_timestamp and frame.time_epoch < $end_timestamp" -w "$initial_pcap.$i" 2>/dev/null else echo -e "/usr/sbin/tshark -r <(${GR}zstdcat $pcap_file${NC}) -Y \"frame.time_epoch > ${GR}$start_timestamp${NC} and frame.time_epoch < ${GR}$end_timestamp${NC}\" -w ${GR}$initial_pcap${NC}" /usr/sbin/tshark -r <( zstdcat "$pcap_tshark_capture_directory/$pcap_file") -Y "frame.time_epoch > $start_timestamp and frame.time_epoch < $end_timestamp" -w "$initial_pcap.$i" 2>/dev/null fi else echo -e "zstdcat \"$pcap_tshark_capture_directory/$pcap_file\" > \"$initial_pcap.$i\"" zstdcat "$pcap_tshark_capture_directory/$pcap_file" > "$initial_pcap.$i" fi ((i++)) done if ((pcap_files > 1)); then echo -e "$(date_time) [NOTICE] Merging files into file ${GR}$initial_pcap${GR}" pcaps_globed=$(echo $initial_pcap.*) echo -e "/usr/sbin/mergecap -w ${GR}$initial_pcap${NC} ${BL}$pcaps_globed${NC}" /usr/sbin/mergecap -w $initial_pcap $initial_pcap.* else mv $initial_pcap.1 $initial_pcap fi } find_legA_pcap() { local packets_found=0 local op_pcap="$PCAP_ROOT/pcap_tmp/invite_packets/final/originator.pcap" mkdir -p $PCAP_ROOT/pcap_tmp/invite_packets/final/ rm -f $op_pcap echo -e "$(date_time) [NOTICE] Searching for ${GR}Leg A${NC} packets" echo -e "/usr/sbin/tshark -r $initial_pcap -Y \"${BL}((sip.From contains $src_shortened and sip.To contains $dst_shortened) or (sip.To contains $src_shortened and sip.From contains $dst_shortened)) and (ip.addr == $originator_ip or sip contains $originator_ip)${NC}\" -w $op_pcap" /usr/sbin/tshark -r $initial_pcap -Y "((sip.From contains \"$src_shortened\" and sip.To contains \"$dst_shortened\") or (sip.To contains \"$src_shortened\" and sip.From contains \"$dst_shortened\")) and (ip.addr == $originator_ip or sip contains \"$originator_ip\")" -w $op_pcap 2>/dev/null packets_found=$(/usr/sbin/capinfos $op_pcap 2>&1 | grep -F 'Number of packets:' | awk -F: '{print $2}' | sed 's/\s*//') #if [[ -z $packets_found || $packets_found -eq 0 ]]; then # /usr/bin/tshark -r $pcap_file -Y "ip.src == $originator_ip -w $PCAP_ROOT/pcap_tmp/invite_packets/final/originator.pcap" #fi if [[ -z $packets_found || $packets_found -eq 0 ]]; then echo -e "$(date_time) [WARNING] ${RED}No Leg A packets found${NC}" else echo -e "$(date_time) [NOTICE] ${GR}$packets_found${NC} Leg A packets have been found" fi } find_legB_pcap() { local packets_found=0 local tp_pcap="$PCAP_ROOT/pcap_tmp/invite_packets/final/terminator.pcap" mkdir -p $PCAP_ROOT/pcap_tmp/invite_packets/final/ rm -f $tp_pcap # src ip and callerid # TODO: we can also check src and other fields in SIP header echo -e "$(date_time) [NOTICE] Searching for ${GR}Leg B${NC} packets" # in M4, if there are several attempts, Call-ID will be like this: # 37d7e11863616c6c2e7be5be@lb1 # 37d7e11863616c6c2e7be5be@lb2 # 37d7e11863616c6c2e7be5be@lb3 # So searching for pcaps, remove eveything after (and including) @ uniqueid_cleaned="${uniqueid%@*}" if ((pcap_tshark_show_all_b_legs == 1)); then echo -e "/usr/sbin/tshark -r \"$initial_pcap\" -Y \"${BL}sip.Call-ID contains $uniqueid_cleaned${NC}\" -w $tp_pcap" /usr/sbin/tshark -r "$initial_pcap" -Y "sip.Call-ID contains \"$uniqueid_cleaned\"" -w $tp_pcap 2>/dev/null leg_b_include_complete_call=1 else echo -e "/usr/sbin/tshark -r \"$initial_pcap\" -Y \"${BL}((sip.To contains \"$localized_dst_shortened\" and sip.From contains \"$src_shortened\" ) or (sip.To contains \"$src_shortened\" and sip.From contains \"$localized_dst_shortened\")) and (ip.addr == $terminator_ip or sip contains $terminator_ip)${NC}\" -w $tp_pcap" /usr/sbin/tshark -r "$initial_pcap" -Y "((sip.To contains $localized_dst_shortened and sip.From contains $src_shortened ) or (sip.To contains $src_shortened and sip.From contains $localized_dst_shortened)) and (ip.addr == $terminator_ip or sip contains \"$terminator_ip\")" -w $tp_pcap 2>/dev/null fi packets_found=$(/usr/sbin/capinfos $tp_pcap 2>&1 | grep -F 'Number of packets:' | awk -F: '{print $2}' | sed 's/\s*//') #if [[ -z $packets_found || $packets_found -eq 0 ]]; then # /usr/sbin/tshark -r $pcap_file -Y "ip.dst == $terminator_ip" -w "$PCAP_ROOT/pcap_tmp/invite_packets/final/terminator.pcap" # fi # packets_found=$(/usr/sbin/capinfos $PCAP_ROOT/pcap_tmp/invite_packets/final/terminator.pcap 2>&1 | grep -E 'Number of packets:\s+0' | awk -F: '{print $2}' | sed 's/\s*//') if [[ -z $packets_found || $packets_found -eq 0 ]]; then echo -e "$(date_time) [WARNING] ${RED}No Leg B packets found${NC}" return 1 else echo -e "$(date_time) [NOTICE] ${GR}$packets_found${NC} Leg B packets have been found" fi } merge_packets() { rm -f $PCAP_ROOT/pcap_tmp/invite_packets/final/out.png.hex $PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt.hex $PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap.hex rm -f $PCAP_ROOT/pcap_tmp/invite_packets/final/out.png $PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt $PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap if ((leg_b_include_complete_call==0)); then /usr/sbin/mergecap -w "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap" $PCAP_ROOT/pcap_tmp/invite_packets/final/*.pcap else cp -f "$PCAP_ROOT/pcap_tmp/invite_packets/final/terminator.pcap" "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap" fi /usr/sbin/tshark -n -r "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap" > "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt" 2> /dev/null if ! /usr/local/bin/pcap2msc "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap" sip | /usr/src/m2/scripts/mscgen -T png -o "$PCAP_ROOT/pcap_tmp/invite_packets/final/out.png"; then echo -e "$(date_time) [WARNING] ${RED}Failed to generate msc diagram${NC}" return 1 fi } create_call_info_record() { local call_id="$1" local count=0 if ! count=$(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "SELECT count(*) from call_details where call_id=$call_id"); then return 1 fi if ((count == 0)); then if ! MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "INSERT INTO call_details(call_id) VALUES($call_id)"; then return 1 fi fi return 0 } _print_cp_info() { local description="$1" local ipaddr="$2" local host="$3" local type="$4" [[ -z $description ]] && return 1 [[ -n $ipaddr ]] && echo "$ipaddr,$description,$type" >> "$TMP_FOR_MSC" [[ -n $host ]] && echo "$host,$description,$type" >> "$TMP_FOR_MSC" } collect_cp_info() { local description="" local ipaddr="" local host="" rm -f "$TMP_FOR_MSC" && touch "$TMP_FOR_MSC" read -r ipaddr < <(/sbin/ifconfig | awk -F "[: ]+" '/inet addr:/ { if ($4 != "127.0.0.1") print $4 }') _print_cp_info "M2" "$ipaddr" "" "system" #echo $ipaddr #TODO: deal with hostnames #ipaddr=$(grep -F 'Web_URL' /home/m2/config/environment.rb | awk -F'=' '{print $2}' | grep -Po '[\d\.]+') #_print_cp_info "M2" "$ipaddr" "" "system" #echo $ipaddr while IFS='@' read -r description ipaddr host; do #echo "$description $ipaddr $host tp" _print_cp_info "$description" "$ipaddr" "$host" "tp" done < <(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select CONCAT (description, '@', ipaddr, '@', host) from devices, calls where calldate='$call_date' and uniqueid='$uniqueid' and devices.id = calls.dst_device_id") IFS='@' read -r description ipaddr host < <(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select CONCAT (description, '@', ipaddr, '@', host) from devices, calls where calls.id='$call_id' and devices.id = calls.src_device_id") _print_cp_info "$description" "$ipaddr" "$host" "op" #echo "$description $ipaddr $host tp" while IFS='@' read -r description ipaddr; do _print_cp_info "$description" "$ipaddr" "" "system" #echo "$description $ipaddr $host system" done < <(MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select CONCAT(comment, '@', server_ip) from servers") _print_cp_info "SEMS" "127.0.0.1" "" "system" #echo "m2 $ipaddr system" } #collect_cp_info() { # # TP info # >> $TMP_FOR_MSC_MYSQL MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select description, ipaddr, host from devices, calls where calldate='$call_date' and uniqueid='$uniqueid' and devices.id = calls.dst_device_id") # # OP info # >> $TMP_FOR_MSC_MYSQL MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select description, ipaddr, host from devices, calls where id='$call_id' and devices.id = calls.src_device_id") # # Servers info # >> $TMP_FOR_MSC_MYSQL MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "select description, ipaddr, host ") # _print_cp_info "$description" "$ipaddr" "$host" "op" #} insert_packets() { xxd -c $FIVE_MB_IN_B -l $((FIVE_MB_IN_B/2)) -p $PCAP_ROOT/pcap_tmp/invite_packets/final/out.png > $PCAP_ROOT/pcap_tmp/invite_packets/final/out.png.hex xxd -c $FIVE_MB_IN_B -l $((FIVE_MB_IN_B/2)) -p $PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt > $PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt.hex xxd -c $FIVE_MB_IN_B -l $((FIVE_MB_IN_B/2)) -p $PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap > $PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap.hex if [[ "$DB_HOST" != "localhost" && "$DB_HOST" != "127.0.0.1" ]]; then if ! echo "UPDATE call_details set pcap_graph='$(cat $PCAP_ROOT/pcap_tmp/invite_packets/final/out.png.hex)' where call_id=$call_id" | MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME"; then echo -e "$(date_time) [ERROR] ${RED}Error updating pcap in MySQL. Check MySQL errors above${NC}" return 1 fi echo "UPDATE call_details set pcap_text='$(cat $PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt.hex)' where call_id=$call_id" | MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" echo "UPDATE call_details set pcap='$(cat $PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap.hex)' where call_id=$call_id" | MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" else if ! MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "UPDATE call_details set pcap_graph=LOAD_FILE('$PCAP_ROOT/pcap_tmp/invite_packets/final/out.png.hex') where call_id=$call_id"; then echo -e "$(date_time) [ERROR] ${RED}Error updating pcap in MySQL. Check MySQL errors above${NC}" return 1 fi MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "UPDATE call_details set pcap_text=LOAD_FILE('$PCAP_ROOT/pcap_tmp/invite_packets/final/out.txt.hex') where call_id=$call_id" MYSQL_PWD="$DB_PASSWORD" /usr/bin/mysql -h "$DB_HOST" -u "$DB_USERNAME" "$DB_NAME" -sNe "UPDATE call_details set pcap=LOAD_FILE('$PCAP_ROOT/pcap_tmp/invite_packets/final/out.pcap.hex') where call_id=$call_id" fi } ########## MAIN ################## echo "" echo "##################################################################################" print_settings print_call_info if ! get_pcaps "$pcap_tshark_capture_directory" "$start_timestamp" "$end_timestamp" "$pcap_tshark_search_threshold" "$pcap_tshark_search_all_files"; then exit 1 fi extract_frames_by_time find_legA_pcap legA_status=$? if ! find_legB_pcap && [[ legA_status -ne 0 ]]; then echo -e "$(date_time) [WARNING] ${RED}Neither LegA, nor LegB packets have been found. Goodbye.{NC}" exit 1 fi collect_cp_info if merge_packets; then if create_call_info_record "$call_id"; then insert_packets fi fi