Commit 39c51017 authored by Victor Seva's avatar Victor Seva

Imported Upstream version 1.0.0

parent 34a4162a
2015-10-06 Ivan Alonso <kaian@irontec.com>
* sngrep 1.0.0 released
* Implemented basic TCP reassembly
* Implemented basic IP reassembly
* Implememted EEP/HEP client/server support
* Implemented command line option --dump-config
* Disabled RTP packet payload storage by default
* Removed --enable-openssl configure flag (use --with-openssl instead)
* Removed configurable ignore directives in rc file
* Removed configurable option cl.filter
* Improved payload memory storage
* Added a confirmation dialog to overwrite saved files
* Added save button to Columns select UI
* Added a keybinding to remove selected dialogs in Call List
* Added a keybinding to move to the first and last item in Call List
* Added attribute color support (can be disabled with cl.colorattr)
* Added a compressed view in Call Flow (one message per row)
* Fixed IPv6 support
* Fixed multiple memory leaks
2015-09-01 Ivan Alonso <kaian@irontec.com>
* sngrep 0.4.2 released
* Fixed a crash with RTP format detection
* Fixed capture.rtp setting
* Fixed a crash while parsing captured packets headers
* Fixed a crash while creating new columns in call flow window
* Restored TLS and WS transport payload display
* Added Timestamp to the first RTP packet displayed in call flow window
* Improved packet payload storage
2015-07-08 Ivan Alonso <kaian@irontec.com>
* sngrep 0.4.1 released
......
......@@ -2,10 +2,11 @@ ToDo List
=========
capture:
* Handle Packet fragmentation
Right now capture process only handle packets with SIP payload,
so if a packet is marked as fragmented, part of its payload
will not be displayed.
* Improve Packet fragmentation
Right now capture process only handle packet IP fragmentation and
TCP segmentation when all parts come ordered. Also, packets being
reassembled are stored in memory until fully assembled (which may
never occur).
ui:
* Change panels initialization
......
......@@ -19,7 +19,7 @@ case `uname -sr` in
;;
FreeBSD*)
AUTOCONF_VERSION=2.69
AUTOMAKE_VERSION=1.12
AUTOMAKE_VERSION=1.15
export AUTOCONF_VERSION
export AUTOMAKE_VERSION
;;
......
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
......@@ -100,16 +100,3 @@
##-----------------------------------------------------------------------------
## Uncomment to display dialogs that does not start with a request method
# set sip.ignoreincomplete off
##-----------------------------------------------------------------------------
## You can ignore some calls with any of the previous attributes with a given
## value with ignore directive.
##
## ignore {field} {value}
##
## Examples:
# ignore method OPTIONS
# ignore method REGISTER
# ignore method BYE
# ignore srchost 192.168.1.1
# ignore transport TCP
AC_PREREQ([2.59])
AC_INIT([sngrep], [0.4.2], [kaian@irontec.com], [sngrep], [http://www.irontec.com/])
AC_INIT([sngrep], [1.0.0], [kaian@irontec.com], [sngrep], [http://www.irontec.com/])
AM_INIT_AUTOMAKE([1.9])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_CONFIG_HEADERS([src/config.h])
......@@ -15,7 +15,7 @@ AC_ARG_ENABLE(debug,
enable_debug=$enableval, enable_debug=no)
if test "$enable_debug" = "yes" ; then
CFLAGS="$CFLAGS -g -O0 -Wall -Werror -Wno-unused-but-set-variable -pg"
CFLAGS="$CFLAGS -g -O0 -Wall -Werror -Wno-unused-but-set-variable"
CXXFLAGS="$CXXFLAGS $CFLAGS"
fi
......@@ -105,15 +105,6 @@ AC_ARG_WITH([openssl],
[AC_SUBST(WITH_OPENSSL, no)]
)
# Check for SSL dependencies
AS_IF([test "x$WITH_OPENSSL" == "xno"], [
AC_ARG_ENABLE([openssl],
AC_HELP_STRING([--enable-openssl], [Enable SSL Support (TLS SIP Transport)]),
[AC_SUBST(WITH_OPENSSL, $enableval)],
[AC_SUBST(WITH_OPENSSL, no)]
)
], [])
AS_IF([test "x$WITH_OPENSSL" == "xyes"], [
AC_CHECK_LIB([ssl], [SSL_new], [], [
AC_MSG_ERROR([ You need to have libssl installed to compile sngrep])
......@@ -149,15 +140,15 @@ AS_IF([test "x$WITH_PCRE" == "xyes"], [
####
AC_ARG_ENABLE([ipv6],
AS_HELP_STRING([--enable-ipv6], [Enable IPv6 Support]),
[AC_SUBST(WITH_IPV6, $enableval)],
[AC_SUBST(WITH_IPV6, no)]
[AC_SUBST(USE_IPV6, $enableval)],
[AC_SUBST(USE_IPV6, no)]
)
AS_IF([test "x$WITH_IPV6" == "xyes"], [
AS_IF([test "x$USE_IPV6" == "xyes"], [
AC_CHECK_HEADER([netinet/ip6.h], [], [
AC_MSG_ERROR([ You dont seem to have ipv6 support (no ip6.h found).])
])
AC_DEFINE([WITH_IPV6],[],[Compile With IPv6 support])
AC_DEFINE([USE_IPV6],[],[Compile With IPv6 support])
], [])
......@@ -189,7 +180,7 @@ AC_MSG_NOTICE( ====================================================== )
AC_MSG_NOTICE( OpenSSL Support : ${WITH_OPENSSL} )
AC_MSG_NOTICE( Unicode Support : ${UNICODE} )
AC_MSG_NOTICE( Perl Expressions Support : ${WITH_PCRE} )
AC_MSG_NOTICE( IPv6 Support : ${WITH_IPV6} )
AC_MSG_NOTICE( IPv6 Support : ${USE_IPV6} )
AC_MSG_NOTICE( ====================================================== )
AC_MSG_NOTICE
......
......@@ -3,7 +3,7 @@
.\" Copyright (c) 2013-2015 Ivan Alonso <kaian@irontec.com>
.\" Copyright (c) 2013-2015 Irontec S.L.
.TH SNGREP 8 "June 2015" "sngrep 0.4.2"
.TH SNGREP 8 "June 2015" "sngrep 1.0.0"
.SH NAME
......
bin_PROGRAMS=sngrep
sngrep_SOURCES=capture.c capture_ws.c sip.c sip_call.c sip_msg.c sip_attr.c main.c option.c
sngrep_SOURCES=capture.c capture_eep.c capture_reasm.c capture_ws.c
if WITH_OPENSSL
sngrep_SOURCES+=capture_tls.c
endif
sngrep_SOURCES+=sip.c sip_call.c sip_msg.c sip_attr.c main.c option.c
sngrep_SOURCES+=group.c filter.c keybinding.c media.c setting.c rtp.c util.c vector.c
sngrep_SOURCES+=ui_manager.c ui_call_list.c ui_call_flow.c ui_call_raw.c
sngrep_SOURCES+=ui_filter.c ui_save.c ui_msg_diff.c ui_column_select.c ui_settings.c
if WITH_OPENSSL
sngrep_SOURCES+=capture_tls.c
endif
This diff is collapsed.
......@@ -72,6 +72,9 @@
#define ADDRESSLEN 47
#endif
//! Max allowed packet assembled size
#define MAX_CAPTURE_LEN 20480
//! Capture modes
enum capture_status {
CAPTURE_ONLINE = 0,
......@@ -80,12 +83,22 @@ enum capture_status {
CAPTURE_OFFLINE_LOADING,
};
//! Shorter declaration of capture_info structure
enum capture_storage {
CAPTURE_STORAGE_NONE = 0,
CAPTURE_STORAGE_MEMORY,
CAPTURE_STORAGE_DISK
};
//! Shorter declaration of capture_config structure
typedef struct capture_config capture_config_t;
//; Shorter declaration of capture_info structure
typedef struct capture_info capture_info_t;
//! Shorter declaration of dns_cache structure
typedef struct dns_cache dns_cache_t;
//! Shorter declaration of capture_packet structure
typedef struct capture_packet capture_packet_t;
//! Shorter declaration of capture_frame structure
typedef struct capture_frame capture_frame_t;
//! Stored packet types
enum capture_packet_type {
......@@ -110,59 +123,118 @@ struct dns_cache {
};
/**
* @brief store all information related with packet capture
* @brief Capture common configuration
*
* All required information to capture and process packets
* will be stored in this
* Store capture configuration and global data
*/
struct capture_info {
struct capture_config {
//! Capture status
int status;
//! Calls capture limit. 0 for disabling
int limit;
//! Also capture RTP packets
int rtp_capture;
//! Input file in Offline capture
const char *infile;
//! Where should we store captured packets
int storage;
//! Key file for TLS decrypt
const char *keyfile;
//! The compiled filter expression
struct bpf_program fp;
//! Netmask of our sniffing device
bpf_u_int32 mask;
//! The IP of our sniffing device
bpf_u_int32 net;
//! libpcap capture handler
pcap_t *handle;
//! libpcap dump file handler
pcap_dumper_t *pd;
//! libpcap link type
int link;
//! libpcap link header size
int8_t link_hl;
//! Cache for DNS lookups
dns_cache_t dnscache;
//! Local devices pointer
pcap_if_t *devices;
//! Capture sources
vector_t *sources;
//! Packets pending IP reassembly
vector_t *ip_reasm;
//! Packets pending TCP reassembly
vector_t *tcp_reasm;
//! Capture Lock. Avoid parsing and handling data at the same time
pthread_mutex_t lock;
};
/**
* @brief store all information related with packet capture
*
* Store capture required data from one packet source
*/
struct capture_info
{
//! libpcap link type
int link;
//! libpcap link header size
int8_t link_hl;
//! libpcap capture handler
pcap_t *handle;
//! Netmask of our sniffing device
bpf_u_int32 mask;
//! The IP of our sniffing device
bpf_u_int32 net;
//! Input file in Offline capture
const char *infile;
//! Capture thread for online capturing
pthread_t capture_t;
};
/**
* Packet capture data.
*
* One packet can contain more than one frame after
* assembly. We assume than one SIP message has one packet
* (maybe in multiple frames) and that one packet can only contain
* one SIP message.
*
*/
struct capture_packet {
// IP protocol
uint8_t ip_version;
// Transport protocol
uint8_t proto;
// Packet type as defined in capture_packet_type
int type;
//! PCAP Packet Header data
struct pcap_pkthdr *header;
//! PCAP Packet content
u_char *data;
// Packet source and destination address
char ip_src[ADDRESSLEN], ip_dst[ADDRESSLEN];
// Packet source and destination port
u_short sport, dport;
//! Packet IP id
uint16_t ip_id;
//! PCAP Packet payload when it can not be get from data
u_char *payload;
//! PPCAP Packet content len
uint32_t size;
//! Payload length
uint32_t payload_len;
//! Packet frame list (capture_frame_t)
vector_t *frames;
};
/**
* Capture frame.
* One packet can contain multiple frames.
*/
struct capture_frame {
//! PCAP Frame Header data
struct pcap_pkthdr *header;
//! PCAP Frame content
u_char *data;
};
/**
* @brief Initialize capture data
*
* @param limit Numbers of calls >0
* @param rtp_catpure Enable rtp capture
*/
void
capture_init(int limit, int rtp_capture);
/**
* @brief Deinitialize capture data
*/
void
capture_deinit();
/**
* @brief Online capture function
*
......@@ -194,10 +266,20 @@ capture_offline(const char *infile, const char *outfile);
* methods using pcap. This will get the payload from a package and
* add it to the SIP storage layer.
*
* @param handle LIBPCAP capture handler
*/
void
parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packet);
parse_packet(u_char *capinfo, const struct pcap_pkthdr *header, const u_char *packet);
/**
* @brief Check if the given packet structure is SIP/RTP/..
*
* This function will call parse functions to determine if packet has relevant data
*
* @return 0 in case this packets has SIP/RTP data
* @return 1 otherwise
*/
int
capture_packet_parse(capture_packet_t *pkt);
/**
* @brief Create a capture thread for online mode
......@@ -233,15 +315,6 @@ capture_is_online();
int
capture_set_bpf_filter(const char *filter);
/**
* @brief Set capture options
*
* @param limit Numbers of calls >0
* @param rtp_catpure Enable rtp capture
*/
void
capture_set_opts(int limit, int rtp_capture);
/**
* @brief Pause/Resume capture
*
......@@ -301,11 +374,34 @@ capture_set_keyfile(const char *keyfile);
char *
capture_last_error();
/**
* @brief Avoid parsing more packets
*/
void
capture_lock();
/**
* @brief Allow parsing more packets
*/
void
capture_unlock();
/**
* @brief Allocate memory to store new packet data
*/
capture_packet_t *
capture_packet_create(const struct pcap_pkthdr *header, const u_char *packet, int size);
capture_packet_create(uint8_t ip_ver, uint8_t proto, const char *ip_src, const char *ip_dst, uint32_t id);
/**
* @brief Set Transport layer information
*/
capture_packet_t *
capture_packet_set_transport_data(capture_packet_t *pkt, u_short sport, u_short dport, int type);
/**
* @brief Add a new frame to the given packet
*/
capture_frame_t *
capture_packet_add_frame(capture_packet_t *pkt, const struct pcap_pkthdr *header, const u_char *packet);
/**
* @brief Deallocate a packet structure memory
......@@ -319,6 +415,14 @@ capture_packet_destroy(capture_packet_t *packet);
void
capture_packet_destroyer(void *packet);