├── NEWS ├── README.md ├── pkg ├── debian │ ├── compat │ ├── source │ │ └── format │ ├── watch │ ├── rules │ ├── control │ ├── copyright │ └── changelog ├── apk │ └── APKBUILD └── rpm │ └── SPECS │ └── sngrep.spec ├── doc ├── Makefile.am ├── ironlogo.png ├── footer.html └── sngrep.8 ├── AUTHORS ├── config ├── Makefile.am └── sngreprc ├── tests ├── aaa.pcap ├── ipip.pcap ├── ipv6frag.pcap ├── README ├── Makefile.am ├── test_001.c ├── test_011.c ├── test_006.c ├── test_008.c ├── test_009.c ├── test_005.c ├── test_002.c ├── test_004.c ├── test_003.c ├── test_input.c ├── test_007.c └── test_010.c ├── Makefile.am ├── .travis.yml ├── .gitignore ├── bootstrap.sh ├── src ├── Makefile.am ├── curses │ ├── ui_stats.h │ ├── theme.h │ ├── scrollbar.h │ ├── scrollbar.c │ ├── ui_msg_diff.h │ ├── ui_filter.h │ ├── ui_call_raw.h │ ├── ui_column_select.h │ ├── ui_save.h │ ├── ui_panel.c │ └── ui_manager.h ├── hash.h ├── config.h.cmake ├── media.h ├── address.h ├── util.h ├── media.c ├── address.c ├── hash.c ├── filter.h ├── option.h ├── packet.h ├── packet.c ├── sip_msg.c ├── sip_msg.h ├── util.c ├── sip_attr.c ├── sip_attr.h ├── keybinding.h ├── setting.h └── option.c ├── m4 └── sngrep.m4 ├── LICENSE.OpenSSL ├── TODO └── README /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /pkg/debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | man_MANS = sngrep.8 2 | -------------------------------------------------------------------------------- /pkg/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Ivan Alonso (aka Kaian) First version of all files 2 | -------------------------------------------------------------------------------- /config/Makefile.am: -------------------------------------------------------------------------------- 1 | sysconfdir=@sysconfdir@ 2 | sysconf_DATA=sngreprc 3 | -------------------------------------------------------------------------------- /tests/aaa.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irontec/sngrep/HEAD/tests/aaa.pcap -------------------------------------------------------------------------------- /doc/ironlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irontec/sngrep/HEAD/doc/ironlogo.png -------------------------------------------------------------------------------- /tests/ipip.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irontec/sngrep/HEAD/tests/ipip.pcap -------------------------------------------------------------------------------- /tests/ipv6frag.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irontec/sngrep/HEAD/tests/ipv6frag.pcap -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | SUBDIRS=src config doc tests 3 | EXTRA_DIST=bootstrap.sh 4 | -------------------------------------------------------------------------------- /doc/footer.html: -------------------------------------------------------------------------------- 1 |
2 | Generated on $datetime for $projectname  irontec
3 | 4 | -------------------------------------------------------------------------------- /pkg/debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | opts="filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/sngrep_$1\.tar\.gz/,pgpsigurlmangle=s/archive\/v(\d\S*)\.tar\.gz/releases\/download\/v$1\/v$1.tar.gz.asc/,uversionmangle=s/\-rc([\d]+)//" \ 3 | https://github.com/irontec/sngrep/tags .*/v?(\d\S*)\.tar\.gz 4 | -------------------------------------------------------------------------------- /pkg/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | override_dh_auto_configure: 4 | dh_auto_configure -- --with-gnutls --with-pcre --enable-unicode --enable-ipv6 --enable-eep 5 | 6 | override_dh_strip: 7 | dh_strip --dbg-package=sngrep-dbg 8 | 9 | override_dh_auto_install: 10 | dh_auto_install --destdir=debian/sngrep 11 | 12 | override_dh_installdocs: 13 | dh_installdocs --link-doc=sngrep 14 | 15 | %: 16 | dh $@ --with autoreconf 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | arch: 3 | - amd64 4 | - ppc64le 5 | compiler: 6 | - clang 7 | - gcc 8 | notifications: 9 | recipients: 10 | - kaian@irontec.com 11 | install: 12 | - sudo apt-get -qq update || true 13 | - sudo apt-get install -y libncurses5-dev libpcap-dev libssl-dev 14 | script: 15 | - ./bootstrap.sh 16 | - ./configure 17 | - make 18 | branches: 19 | only: 20 | - master 21 | - travis 22 | - ppc64le 23 | -------------------------------------------------------------------------------- /tests/README: -------------------------------------------------------------------------------- 1 | Basic testing programs for sngrep. 2 | 3 | This set of test will do some basic inputs to check sngrep screen navigation 4 | doesn't crash. This checks are ultra-super-basic. 5 | 6 | - test_001 : UI testing 7 | - test_002 : Call List testing 8 | - test_003 : Call Flow testing 9 | - test_004 : Call Raw testing 10 | - test_005 : Column selection testing 11 | - test_006 : Message diff testing 12 | - test_007: Test vector container structures 13 | - test_011: Test mix of normal packets with IPIP tunneled packets 14 | 15 | Sample capture files has been taken from wireshark Wiki: 16 | - https://wiki.wireshark.org/SampleCaptures 17 | 18 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=subdir-objects 2 | 3 | check_PROGRAMS=test-001 test-002 test-003 test-004 test-005 4 | check_PROGRAMS+=test-006 test-007 test-008 test-009 test-010 5 | check_PROGRAMS+=test-011 6 | 7 | test_001_SOURCES=test_001.c 8 | test_002_SOURCES=test_002.c 9 | test_003_SOURCES=test_003.c 10 | test_004_SOURCES=test_004.c 11 | test_005_SOURCES=test_005.c 12 | test_006_SOURCES=test_006.c 13 | test_007_SOURCES=test_007.c ../src/vector.c ../src/util.c 14 | test_008_SOURCES=test_008.c 15 | test_009_SOURCES=test_009.c 16 | test_010_SOURCES=test_010.c ../src/hash.c 17 | test_011_SOURCES=test_011.c 18 | 19 | TESTS = $(check_PROGRAMS) 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore eclipse files 2 | .*project 3 | .settings 4 | .vscode 5 | .idea 6 | build 7 | 8 | # Build files 9 | src/sngrep 10 | tests/test-*.log 11 | tests/test-*.trs 12 | tests/test-??? 13 | *.o 14 | .deps 15 | .dirstamp 16 | *gmon.out 17 | src/config.h.in 18 | src/config.h 19 | src/stamp-h1 20 | 21 | .autotools 22 | Makefile 23 | Makefile.in 24 | aclocal.m4 25 | autom4te.cache 26 | config.log 27 | config.status 28 | config.sub 29 | config.guess 30 | configure 31 | missing 32 | install-sh 33 | depcomp 34 | test-driver 35 | 36 | # Ignore Doxygen generated files 37 | doc/html 38 | 39 | # Tags file 40 | tags 41 | TAGS 42 | 43 | # Vim swap files 44 | .*.swp 45 | .*.swo 46 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | check_for_app() { 4 | $1 --version 2>&1 >/dev/null 5 | if [ $? != 0 ] 6 | then 7 | echo "Please install $1 and run bootstrap.sh again!" 8 | exit 1 9 | fi 10 | } 11 | 12 | # On FreeBSD and OpenBSD, multiple autoconf/automake versions have different names. 13 | # On Linux, environment variables tell which one to use. 14 | 15 | case `uname -sr` in 16 | OpenBSD*) 17 | export AUTOCONF_VERSION=2.69 18 | export AUTOMAKE_VERSION=1.15 19 | ;; 20 | FreeBSD*) 21 | AUTOCONF_VERSION=2.69 22 | AUTOMAKE_VERSION=1.15 23 | export AUTOCONF_VERSION 24 | export AUTOMAKE_VERSION 25 | ;; 26 | *) 27 | ;; 28 | esac 29 | 30 | check_for_app autoconf 31 | check_for_app autoheader 32 | check_for_app automake 33 | check_for_app aclocal 34 | 35 | echo "Generating the configure script ..." 36 | 37 | aclocal 38 | autoconf 39 | autoheader 40 | automake --add-missing --copy 2>/dev/null 41 | 42 | exit 0 43 | 44 | -------------------------------------------------------------------------------- /pkg/apk/APKBUILD: -------------------------------------------------------------------------------- 1 | # Contributor: Francesco Colista 2 | # Maintainer: Francesco Colista 3 | pkgname=sngrep 4 | pkgver=1.8.3 5 | pkgrel=0 6 | pkgdesc="display SIP call message flows from a terminal" 7 | url="https://github.com/irontec/sngrep" 8 | arch="all !ppc64le" 9 | license="GPL-3.0-or-later" 10 | depends="sed" 11 | makedepends="autoconf automake ncurses-dev libpcap-dev 12 | pcre-dev libgcrypt-dev openssl-dev" 13 | subpackages="$pkgname-doc" 14 | source="$pkgname-$pkgver.tar.gz::https://github.com/irontec/sngrep/releases/download/v$pkgver/sngrep-$pkgver.tar.gz" 15 | 16 | prepare() { 17 | default_prepare 18 | ./bootstrap.sh 19 | } 20 | 21 | build() { 22 | ./configure \ 23 | --prefix=/usr \ 24 | --sysconfdir=/etc \ 25 | --with-openssl \ 26 | --with-pcre \ 27 | --disable-logo \ 28 | --enable-unicode \ 29 | --enable-ipv6 30 | make 31 | } 32 | 33 | check() { 34 | make check 35 | } 36 | 37 | package() { 38 | make DESTDIR="$pkgdir/" install 39 | } 40 | 41 | sha512sums="d3aabe22a31ec5860ec80f94b6556d345d72574e552c4e92dfebdddeaaa5f69caf811fc2fa201ca7af24cabfcbdd530a4f50248ebf0381cef26390a78824d1af sngrep-1.4.10.tar.gz" 42 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=subdir-objects 2 | bin_PROGRAMS=sngrep 3 | sngrep_SOURCES=capture.c 4 | sngrep_CFLAGS= 5 | sngrep_LDADD= 6 | if USE_EEP 7 | sngrep_SOURCES+=capture_eep.c 8 | endif 9 | if WITH_GNUTLS 10 | sngrep_SOURCES+=capture_gnutls.c 11 | sngrep_CFLAGS+=$(LIBGNUTLS_CFLAGS) $(LIBGCRYPT_CFLAGS) 12 | sngrep_LDADD+=$(LIBGNUTLS_LIBS) $(LIBGCRYPT_LIBS) 13 | endif 14 | if WITH_OPENSSL 15 | sngrep_SOURCES+=capture_openssl.c 16 | sngrep_CFLAGS+=$(SSL_CFLAGS) 17 | sngrep_LDADD+=$(SSL_LIBS) 18 | endif 19 | if WITH_PCRE2 20 | sngrep_CFLAGS+=$(PCRE2_CFLAGS) 21 | sngrep_LDADD+=$(PCRE2_LIBS) 22 | endif 23 | if WITH_ZLIB 24 | sngrep_CFLAGS+=$(ZLIB_CFLAGS) 25 | sngrep_LDADD+=$(ZLIB_LIBS) 26 | endif 27 | 28 | sngrep_SOURCES+=address.c packet.c sip.c sip_call.c sip_msg.c sip_attr.c main.c 29 | sngrep_SOURCES+=option.c group.c filter.c keybinding.c media.c setting.c rtp.c 30 | sngrep_SOURCES+=util.c hash.c vector.c curses/ui_panel.c curses/scrollbar.c 31 | sngrep_SOURCES+=curses/ui_manager.c curses/ui_call_list.c curses/ui_call_flow.c curses/ui_call_raw.c 32 | sngrep_SOURCES+=curses/ui_stats.c curses/ui_filter.c curses/ui_save.c curses/ui_msg_diff.c 33 | sngrep_SOURCES+=curses/ui_column_select.c curses/ui_settings.c 34 | 35 | -------------------------------------------------------------------------------- /tests/test_001.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_001.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic read from file test 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | 27, 32 | 10, 33 | 0 34 | }; 35 | 36 | #include "test_input.c" 37 | -------------------------------------------------------------------------------- /pkg/debian/control: -------------------------------------------------------------------------------- 1 | Source: sngrep 2 | Section: comm 3 | Build-Depends: dh-autoreconf, debhelper, libpcap-dev, libncursesw5-dev, gnutls-dev, libgcrypt-dev, libpcre3-dev | libpcre2-dev, libncurses5-dev, pkg-config 4 | Priority: optional 5 | Standards-Version: 3.9.6 6 | Homepage: https://github.com/irontec/sngrep 7 | Maintainer: Ivan Alonso 8 | 9 | Package: sngrep 10 | Architecture: any 11 | Pre-Depends: ${misc:Pre-Depends} 12 | Depends: ${misc:Depends}, ${shlibs:Depends}, libpcap0.8, libncursesw5 | libncursesw6, libpcre3 | libpcre2 | libpcre2-8-0 13 | Description: Ncurses SIP Messages flow viewer 14 | sngrep displays SIP Messages grouped by Call-Id into flow 15 | diagrams. It can be used as an offline PCAP viewer or online 16 | capture using libpcap functions. 17 | . 18 | It supports SIP UDP, TCP and TLS transports (when each message is 19 | delivered in one packet). 20 | . 21 | You can also create new PCAP files from captures or displayed dialogs. 22 | . 23 | 24 | Package: sngrep-dbg 25 | Architecture: any 26 | Section: debug 27 | Priority: extra 28 | Depends: sngrep (= ${binary:Version}), ${misc:Depends} 29 | Description: Debugging symbols for sngrep SIP Messages flow viewer 30 | sngrep displays SIP Messages grouped by Call-Id into flow 31 | diagrams. It can be used as an offline PCAP viewer or online 32 | capture using libpcap functions. 33 | . 34 | This package contains the debugging sysmbols. 35 | . 36 | -------------------------------------------------------------------------------- /tests/test_011.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_011.c 24 | * @author Evgeny Khramtsov 25 | * 26 | * IP-IP tunnel test from ipip.pcap 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* Enter Call Flow */ 32 | 10, 33 | /* Leave Call Flow */ 34 | 27, 35 | /* Exit */ 36 | 27, 37 | 10, 38 | 0 39 | }; 40 | 41 | #define TEST_PCAP_INPUT "ipip.pcap" 42 | 43 | #include "test_input.c" 44 | -------------------------------------------------------------------------------- /tests/test_006.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_006.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic Message diff testing 27 | */ 28 | const char keys[] = 29 | { 30 | /* Select some dialog */ 31 | 107, 107, 107, 32, 10, 32 | /* Move Select some messages */ 33 | 107, 107, 32, 32, 107, 32, 34 | 107, 107, 107, 106, 32, 35 | /* Leave Diff screen */ 36 | 27, 27, 37 | /* Exit */ 38 | 27, 39 | 10, 40 | 0 41 | }; 42 | 43 | #include "test_input.c" 44 | -------------------------------------------------------------------------------- /src/curses/ui_stats.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_stats.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage ui window for capture stats display 27 | */ 28 | #ifndef __SNGREP_UI_STATS_H 29 | #define __SNGREP_UI_STATS_H 30 | 31 | /** 32 | * @brief Creates a new stats panel 33 | * 34 | * This function allocates all required memory for 35 | * displaying the stats panel. It also draws all the 36 | * static information of the panel that will never be 37 | * redrawn. 38 | * 39 | * @param ui UI structure pointer 40 | */ 41 | void 42 | stats_create(ui_t *ui); 43 | 44 | #endif /* __SNGREP_UI_STATS_H */ 45 | -------------------------------------------------------------------------------- /tests/test_008.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_008.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Test for sorting columns based on standard attributes 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* show sort menu */ 32 | 60, 33 | /* move arround menu */ 34 | 107, 107, 106, 106, 106, 107, 35 | /* select sort field */ 36 | 10, 37 | /* move arround call list */ 38 | 107, 107, 106, 106, 106, 107, 39 | /* change sort order */ 40 | 106, 106, 60, 10, 41 | /* change sort order */ 42 | 122, 122, 43 | /* Leave */ 44 | 27, 10, 45 | 0 46 | }; 47 | 48 | #include "test_input.c" 49 | -------------------------------------------------------------------------------- /tests/test_009.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_009.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Test for adding a new attribute column and sorting using it. 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* show sort menu */ 32 | 60, 33 | /* select sort field */ 34 | 106, 106, 10, 35 | /* Enter Column screen */ 36 | 116, 27, 37 | /* add a new column */ 38 | 106, 106, 106, 32, 39 | /* select new sort attribute */ 40 | 60, 106, 106, 106, 106, 106, 106, 10, 41 | /* swap order */ 42 | 122, 122, 43 | /* Leave */ 44 | 27, 10, 45 | 0 46 | }; 47 | 48 | #include "test_input.c" 49 | -------------------------------------------------------------------------------- /pkg/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: sngrep 3 | Source: http://github.com/irontec/sngrep 4 | 5 | Files: * 6 | Copyright: 2013-2015 Ivan Alonso 7 | 2013-2015 Irontec SL. 8 | License: GPL-3+ with OpenSSL exception 9 | 10 | License: GPL-3+ with OpenSSL exception 11 | This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | . 16 | In addition, as a special exception, the author of this 17 | program gives permission to link the code of its 18 | release with the OpenSSL project's "OpenSSL" library (or 19 | with modified versions of it that use the same license as 20 | the "OpenSSL" library), and distribute the linked 21 | executables. You must obey the GNU General Public 22 | License in all respects for all of the code used other 23 | than "OpenSSL". If you modify this file, you may extend 24 | this exception to your version of the file, but you are 25 | not obligated to do so. If you do not wish to do so, 26 | delete this exception statement from your version. 27 | . 28 | This program is distributed in the hope that it will be useful, 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 | GNU General Public License for more details. 32 | . 33 | You should have received a copy of the GNU General Public License 34 | along with this program. If not, see . 35 | . 36 | On Debian systems, the full text of the GNU General Public 37 | License version 3 can be found in the file 38 | '/usr/share/common-licenses/GPL-3'. 39 | . 40 | -------------------------------------------------------------------------------- /src/curses/theme.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file theme.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Theme and Color definitions 27 | * 28 | */ 29 | #ifndef __SNGREP_THEME_H 30 | #define __SNGREP_THEME_H 31 | 32 | /** 33 | * @brief Enum for available color pairs 34 | */ 35 | enum sngrep_colors_pairs { 36 | CP_DEFAULT = 0, 37 | CP_CYAN_ON_DEF, 38 | CP_YELLOW_ON_DEF, 39 | CP_MAGENTA_ON_DEF, 40 | CP_GREEN_ON_DEF, 41 | CP_RED_ON_DEF, 42 | CP_BLUE_ON_DEF, 43 | CP_WHITE_ON_DEF, 44 | CP_DEF_ON_CYAN, 45 | CP_DEF_ON_BLUE, 46 | CP_WHITE_ON_BLUE, 47 | CP_BLACK_ON_CYAN, 48 | CP_WHITE_ON_CYAN, 49 | CP_YELLOW_ON_CYAN, 50 | CP_BLUE_ON_CYAN, 51 | CP_BLUE_ON_WHITE, 52 | CP_CYAN_ON_BLACK, 53 | CP_CYAN_ON_WHITE, 54 | }; 55 | 56 | // Used to configure color pairs only with fg color 57 | #define COLOR_DEFAULT -1 58 | 59 | 60 | #endif /* __SNGREP_THEME_H */ 61 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file hash.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage hash tables 27 | */ 28 | 29 | #ifndef __SNGREP_HASH_H_ 30 | #define __SNGREP_HASH_H_ 31 | 32 | #include "config.h" 33 | #include 34 | 35 | //! Shorter declaration of hash structures 36 | typedef struct htable htable_t; 37 | typedef struct hentry hentry_t; 38 | 39 | /** 40 | * Structure to hold a Hash table entry 41 | */ 42 | struct hentry { 43 | //! Key of the hash entry 44 | const char *key; 45 | //! Pointer to has entry data 46 | void *data; 47 | //! Next entry sharing the same hash value 48 | hentry_t *next; 49 | }; 50 | 51 | struct htable { 52 | //! Fixed hash table limit 53 | size_t size; 54 | // Hash table entries 55 | hentry_t **buckets; 56 | }; 57 | 58 | htable_t * 59 | htable_create(size_t size); 60 | 61 | void 62 | htable_destroy(htable_t *table); 63 | 64 | int 65 | htable_insert(htable_t *table, const char *key, void *data); 66 | 67 | void 68 | htable_remove(htable_t *table, const char *key); 69 | 70 | void * 71 | htable_find(htable_t *table, const char *key); 72 | 73 | size_t 74 | htable_hash(htable_t *table, const char *key); 75 | 76 | #endif /* __SNGREP_HASH_H_ */ 77 | -------------------------------------------------------------------------------- /tests/test_005.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_005.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic Column selection testing 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* Show Raw panel */ 32 | 't', 33 | /* Cycle through fields */ 34 | 9, 9, 9, 9, 9, 9, 35 | 9, 107, 107, 9, 106, 36 | /* Move through Column list */ 37 | 107, 107, 107, 107, 107, 106, 38 | 107, 107, 107, 107, 107, 107, 39 | 107, 107, 107, 107, 107, 107, 40 | 107, 107, 107, 107, 107, 107, 41 | 107, 107, 107, 107, 107, 107, 42 | 107, 107, 107, 106, 106, 106, 43 | 106, 106, 106, 106, 106, 106, 44 | 106, 106, 106, 106, 106, 106, 45 | 106, 106, 106, 106, 106, 106, 46 | 106, 106, 106, 106, 106, 106, 47 | 106, 106, 106, 106, 106, 106, 48 | 106, 106, 106, 106, 106, 106, 49 | /* Move items up and down */ 50 | '-', '-', '-', '-', 51 | 107, 107, 52 | '+', '+', '+', '+', 53 | 107, 107, 54 | '-', '-', '-', '-', 55 | /* Apply new settings */ 56 | 10, 57 | /* Exit */ 58 | 27, 59 | 10, 60 | 0 61 | }; 62 | 63 | #include "test_input.c" 64 | -------------------------------------------------------------------------------- /tests/test_002.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_002.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic Call list testing 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* Swap some options */ 32 | 'c', 'l', 'p', 'p', 33 | /* Select some dialogs */ 34 | 107, 32, 107, 107, 32, 107, 107, 107, 32, 107, 107, 35 | /* Enter Call Flow */ 36 | 10, 27, 37 | /* Enter Call Raw */ 38 | 'R', 27, 39 | /* Enter Filter screen */ 40 | 'F', 27, 41 | /* Enter Column screen */ 42 | 't', 27, 43 | /* Unselect some dialogs */ 44 | 32, 107, 32, 45 | /* Move beyond list limits */ 46 | 107, 107, 107, 107, 107, 106, 47 | 107, 107, 107, 106, 106, 106, 48 | 106, 106, 106, 106, 106, 106, 49 | 106, 106, 106, 106, 106, 106, 50 | 4, 4, 2, 2, 4, 2, 4, 2, 51 | /* Enter help screen */ 52 | 'h', 100, 53 | /* Enter save screen */ 54 | 's', 20, 30, 40, 50, 27, 55 | /* Enter display filter */ 56 | '/', 20, 30, 40, 40, 10, 57 | '/', 27, 58 | /* Enter Call Flow once again */ 59 | 10, 27, 60 | /* Exit */ 61 | 27, 62 | 10, 63 | 0 64 | }; 65 | 66 | #include "test_input.c" 67 | -------------------------------------------------------------------------------- /src/curses/scrollbar.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file scrollbar.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Scrollbar function and structures 27 | * 28 | */ 29 | 30 | #ifndef __SNGREP_SCROLLBAR_H 31 | #define __SNGREP_SCROLLBAR_H 32 | 33 | #ifdef WITH_UNICODE 34 | #define _X_OPEN_SOURCE_EXTENDED 35 | #include 36 | #endif 37 | #include 38 | 39 | //! Shorter declaration of scrollbar 40 | typedef struct scrollbar scrollbar_t; 41 | 42 | //! Available scrollbar alignments 43 | enum sb_alignment 44 | { 45 | SB_HORIZONTAL, 46 | SB_VERTICAL 47 | }; 48 | 49 | //! Available scrollbar positions 50 | enum sb_dock 51 | { 52 | SB_TOP, 53 | SB_BOTTOM, 54 | SB_LEFT, 55 | SB_RIGHT 56 | }; 57 | 58 | /** 59 | * @brief Window scrollbar 60 | * 61 | * This struct contains the required information to draw 62 | * a scrollbar into a ncurses window 63 | */ 64 | struct scrollbar 65 | { 66 | //! Ncurses window associated to this scrollbar 67 | WINDOW *win; 68 | //! Alignment 69 | enum sb_alignment alignment; 70 | //! Position 71 | enum sb_dock dock; 72 | //! Current scrollbar position 73 | int pos; 74 | //! Max scrollbar positions 75 | int max; 76 | }; 77 | 78 | scrollbar_t 79 | ui_set_scrollbar(WINDOW *win, int alignment, int dock); 80 | 81 | 82 | void 83 | ui_scrollbar_draw(scrollbar_t sb); 84 | 85 | #endif /* __SNGREP_SCROLLBAR_H */ 86 | -------------------------------------------------------------------------------- /src/curses/scrollbar.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file scrollbar.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in scrollbar.h 27 | */ 28 | 29 | #include "config.h" 30 | #include "scrollbar.h" 31 | 32 | scrollbar_t 33 | ui_set_scrollbar(WINDOW *win, int alignment, int dock) 34 | { 35 | scrollbar_t sb; 36 | sb.win = win; 37 | sb.alignment = alignment; 38 | sb.dock = dock; 39 | return sb; 40 | } 41 | 42 | 43 | void 44 | ui_scrollbar_draw(scrollbar_t sb) 45 | { 46 | int height, width, cline, scrollen, scrollypos, scrollxpos; 47 | 48 | // Get window available space 49 | getmaxyx(sb.win, height, width); 50 | 51 | // If no even a screen has been filled, don't draw it 52 | if (sb.max < height) 53 | return; 54 | 55 | // Display the scrollbar left or right 56 | scrollxpos = (sb.dock == SB_LEFT) ? 0 : width - 1; 57 | 58 | // Initialize scrollbar line 59 | mvwvline(sb.win, 0, scrollxpos, ACS_VLINE, height); 60 | 61 | // How long the scroll will be 62 | if (!(scrollen = (height * 1.0f / sb.max * height) + 0.5)) 63 | scrollen = 1; 64 | 65 | // Where will the scroll start 66 | scrollypos = height * (sb.pos * 1.0f / sb.max); 67 | 68 | // Draw the N blocks of the scrollbar 69 | for (cline = 0; cline < scrollen; cline++) { 70 | mvwaddch(sb.win, cline + scrollypos, scrollxpos, ACS_CKBOARD); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /tests/test_004.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_004.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic Call Raw testing 27 | */ 28 | const char keys[] = 29 | { 30 | /* Select some dialogs */ 31 | 32, 107, 107, 107, 32, 107, 32 | /* Show Raw panel */ 33 | 'r', 34 | /* Cicle options */ 35 | 'c', 'c', 'c', 'c', 'c', 'c', 36 | 'a', 'a', 'a', 'a', 'a', 'a', 37 | 'l', 'l', 'l', 'C', 'C', 'C', 38 | /* Move through Raw panel */ 39 | 107, 107, 107, 107, 107, 106, 40 | 107, 107, 107, 106, 106, 106, 41 | 106, 106, 106, 106, 106, 106, 42 | 106, 106, 106, 106, 106, 106, 43 | 4, 4, 2, 2, 4, 2, 4, 2, 44 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 45 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 46 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 48 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 49 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 50 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 54 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55 | /* Enter save screen */ 56 | 's', 20, 30, 40, 50, 60, 27, 57 | /* Leave call Raw */ 58 | 27, 59 | /* Exit */ 60 | 27, 61 | 10, 62 | 0 63 | }; 64 | 65 | #include "test_input.c" 66 | -------------------------------------------------------------------------------- /src/config.h.cmake: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2023 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2023 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file config.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Generated from config.h.cmake by CMake 27 | * 28 | */ 29 | 30 | #ifndef __SNGREP_CONFIG_H 31 | #define __SNGREP_CONFIG_H 32 | 33 | /* Parameters of AC_INIT() */ 34 | #define PACKAGE "@AC_PACKAGE_NAME@" 35 | #define PACKAGE_BUGREPORT "@AC_PACKAGE_BUGREPORT@" 36 | #define PACKAGE_NAME "@AC_PACKAGE_NAME@" 37 | #define PACKAGE_STRING "@AC_PACKAGE_STRING@" 38 | #define PACKAGE_URL "@AC_PACKAGE_URL@" 39 | #define PACKAGE_VERSION "@AC_PACKAGE_VERSION@" 40 | #define VERSION "@AC_PACKAGE_VERSION@" 41 | 42 | /* Define if you have the `fopencookie' function */ 43 | #cmakedefine HAVE_FOPENCOOKIE 44 | 45 | /* Compile With Unicode compatibility */ 46 | #cmakedefine WITH_UNICODE 47 | 48 | /* Compile With GnuTLS compatibility */ 49 | #cmakedefine WITH_GNUTLS 50 | 51 | /* Compile With Openssl compatibility */ 52 | #cmakedefine WITH_OPENSSL 53 | 54 | /* Compile With Perl Compatible regular expressions support */ 55 | #cmakedefine WITH_PCRE 56 | 57 | /* Compile With Perl Compatible regular expressions support */ 58 | #cmakedefine WITH_PCRE2 59 | 60 | /* Compile With zlib support */ 61 | #cmakedefine WITH_ZLIB 62 | 63 | /* Compile With IPv6 support */ 64 | #cmakedefine USE_IPV6 65 | 66 | /* Compile With EEP support */ 67 | #cmakedefine USE_EEP 68 | 69 | /* CMAKE_CURRENT_BINARY_DIR is needed in tests/test_input.c */ 70 | #define CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@" 71 | 72 | #endif /* __SNGREP_CONFIG_H */ 73 | 74 | -------------------------------------------------------------------------------- /m4/sngrep.m4: -------------------------------------------------------------------------------- 1 | # serial 100 2 | # sngrep.m4: Custom autotools macros for sngrep 3 | # 4 | # @author Adam Duskett 5 | # @version 2017-05-25 6 | # @license GNU General Public License 3.0 7 | # 8 | # This program is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2, or (at your option) 11 | # any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 | # 02110-1301, USA. 22 | # 23 | # As a special exception, the you may copy, distribute and modify the 24 | # configure scripts that are the output of Autoconf when processing 25 | # the Macro. You need not follow the terms of the GNU General Public 26 | # License when using or distributing such scripts. 27 | # 28 | 29 | # SNGREP_CHECK_SCRIPT(LIBNAME, FUNCTION, DEFINE, CONFIG_SCRIPT, ELSE_PART) 30 | AC_DEFUN([SNGREP_CHECK_SCRIPT], 31 | [ 32 | if test ! -z "m4_toupper($SNGREP_[$1]_CONFIG_SCRIPT)"; then 33 | # to be used to set the path to *-config when cross-compiling 34 | sngrep_config_script_libs=$(m4_toupper($SNGREP_[$1]_CONFIG_SCRIPT) --libs 2> /dev/null) 35 | sngrep_config_script_cflags=$(m4_toupper($SNGREP_[$1]_CONFIG_SCRIPT) --cflags 2> /dev/null) 36 | else 37 | sngrep_config_script_libs=$([$4] --libs 2> /dev/null) 38 | sngrep_config_script_cflags=$([$4] --cflags 2> /dev/null) 39 | fi 40 | sngrep_script_success=no 41 | sngrep_save_LDFLAGS="$LDFLAGS" 42 | if test ! "x$sngrep_config_script_libs" = x; then 43 | LDFLAGS="$sngrep_config_script_libs $LDFLAGS" 44 | AC_CHECK_LIB([$1], [$2], [ 45 | AC_DEFINE([$3], 1, [The library is present.]) 46 | LIBS="$sngrep_config_script_libs $LIBS " 47 | CFLAGS="$sngrep_config_script_cflags $CFLAGS " 48 | sngrep_script_success=yes 49 | ], []) 50 | LDFLAGS="$sngrep_save_LDFLAGS" 51 | fi 52 | if test "x$sngrep_script_success" = xno; then 53 | [$5] 54 | fi 55 | ]) 56 | 57 | # SNGREP_CHECK_LIB(LIBNAME, FUNCTION, DEFINE, ELSE_PART) 58 | AC_DEFUN([SNGREP_CHECK_LIB], 59 | [ 60 | AC_CHECK_LIB([$1], [$2], [ 61 | AC_DEFINE([$3], 1, [The library is present.]) 62 | LIBS="-l[$1] $LIBS " 63 | ], [$4]) 64 | ]) 65 | -------------------------------------------------------------------------------- /tests/test_003.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_003.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic Call Flow testing 27 | */ 28 | 29 | const char keys[] = 30 | { 31 | /* Select some dialogs */ 32 | 32, 107, 32, 107, 33 | /* Enter Call Flow */ 34 | 10, 27, 35 | /* Move arrow messages */ 36 | 107, 107, 107, 107, 107, 106, 37 | 107, 107, 107, 106, 106, 106, 38 | 106, 106, 106, 106, 106, 106, 39 | 106, 106, 106, 106, 106, 106, 40 | 4, 4, 2, 2, 4, 2, 4, 2, 41 | /* Reenter Call Flow */ 42 | 10, 43 | /* Swap colors */ 44 | 'c', 'c', 'c', 'c', 'c', 'c', 45 | /* Enter Extended Call Flow */ 46 | 'x', 'x', 'x', 'x', 47 | /* Compress column display */ 48 | 's', 49 | /* Toggle media display */ 50 | 'd', 'd', 'd', 'd', 'd', 51 | /* Toggle Only SDP */ 52 | 'D', 53 | /* Enter Call Raw (all dialogs) */ 54 | 'R', 27, 55 | /* Enter Call Raw (single message) */ 56 | 10, 27, 57 | /* Enter help screen */ 58 | 'h', 100, 59 | /* Toggle raw screen */ 60 | 't', 't', 't', 't', 61 | /* Change Raw size */ 62 | '0', '0', '0', '0', '0', '0', '0', '0', 63 | '9', '9', '9', '9', '9', '9', '9', '9', 64 | /* Reset Raw size */ 65 | 'T', 'T', 66 | /* Leave Call Flow */ 67 | 27, 68 | /* Exit */ 69 | 27, 70 | 10, 71 | 0 72 | }; 73 | 74 | #include "test_input.c" 75 | -------------------------------------------------------------------------------- /LICENSE.OpenSSL: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * 3. All advertising materials mentioning features or use of this 17 | * software must display the following acknowledgment: 18 | * "This product includes software developed by the OpenSSL Project 19 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 | * 21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 | * endorse or promote products derived from this software without 23 | * prior written permission. For written permission, please contact 24 | * openssl-core@openssl.org. 25 | * 26 | * 5. Products derived from this software may not be called "OpenSSL" 27 | * nor may "OpenSSL" appear in their names without prior written 28 | * permission of the OpenSSL Project. 29 | * 30 | * 6. Redistributions of any form whatsoever must retain the following 31 | * acknowledgment: 32 | * "This product includes software developed by the OpenSSL Project 33 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 | * 35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 | * OF THE POSSIBILITY OF SUCH DAMAGE. 47 | * ==================================================================== 48 | * 49 | * This product includes cryptographic software written by Eric Young 50 | * (eay@cryptsoft.com). This product includes software written by Tim 51 | * Hudson (tjh@cryptsoft.com). 52 | * 53 | */ 54 | 55 | -------------------------------------------------------------------------------- /tests/test_input.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_input.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic input injector for sngrep testing 27 | */ 28 | #include "config.h" 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #ifndef TEST_MAX_DURATION 36 | #define TEST_MAX_DURATION 60 37 | #endif 38 | 39 | #ifndef TEST_INITIAL_WAIT 40 | #define TEST_INITIAL_WAIT 1000 * 1200 41 | #endif 42 | 43 | #ifndef TEST_KEY_DELAY 44 | #define TEST_KEY_DELAY 3000 45 | #endif 46 | 47 | #ifndef TEST_PCAP_INPUT 48 | #define TEST_PCAP_INPUT "aaa.pcap" 49 | #endif 50 | 51 | /* keys array needs to be of type "char" */ 52 | const char keys[]; 53 | 54 | int 55 | main() 56 | { 57 | int ppipe[2]; 58 | int unused, ret = 0; 59 | int child; 60 | unused = pipe(ppipe); 61 | 62 | // Max test duration 63 | alarm(TEST_MAX_DURATION); 64 | 65 | if ((child = fork()) < 0) { 66 | fprintf(stderr, "Fatal: unable to fork test.\n"); 67 | return 127; 68 | } else if (child == 0) { 69 | // Child process, run sngrep with test pcap 70 | dup2(ppipe[0], STDIN_FILENO); 71 | #ifdef CMAKE_CURRENT_BINARY_DIR 72 | char *argv[] = { CMAKE_CURRENT_BINARY_DIR "/sngrep", "-I", TEST_PCAP_INPUT, 0 }; 73 | #else 74 | char *argv[] = { "../src/sngrep", "-I", TEST_PCAP_INPUT, 0 }; 75 | #endif 76 | execv(argv[0], argv); 77 | } else { 78 | // Parent process, send keys to child stdin 79 | usleep(TEST_INITIAL_WAIT); 80 | int i; 81 | for (i = 0; keys[i]; i++) { 82 | unused = write(ppipe[1], &keys[i], sizeof(char)); 83 | usleep(TEST_KEY_DELAY); 84 | } 85 | unused = wait(&ret); 86 | } 87 | 88 | return ret; 89 | } 90 | -------------------------------------------------------------------------------- /tests/test_007.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_vector.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic testing of vector structures 27 | */ 28 | 29 | #include "config.h" 30 | #include 31 | #include 32 | #include "../src/vector.h" 33 | #include "../src/util.h" 34 | 35 | int main () 36 | { 37 | vector_t *vector; 38 | 39 | // Basic Vector append/remove test 40 | vector = vector_create(10, 10); 41 | assert(vector); 42 | assert(vector_count(vector) == 0); 43 | vector_append(vector, 0); 44 | assert(vector_count(vector) == 0); 45 | vector_append(vector, sng_malloc(1024)); 46 | assert(vector_count(vector) == 1); 47 | assert(vector_first(vector) == vector_item(vector, 0)); 48 | vector_remove(vector, vector_first(vector)); 49 | assert(vector_count(vector) == 0); 50 | assert(vector_first(vector) == vector_item(vector, 0)); 51 | 52 | // Vector overflow test 53 | vector_append(vector, sng_malloc(32)); 54 | vector_append(vector, sng_malloc(32)); 55 | vector_append(vector, sng_malloc(32)); 56 | vector_append(vector, sng_malloc(32)); 57 | vector_append(vector, sng_malloc(32)); 58 | vector_append(vector, sng_malloc(32)); 59 | vector_append(vector, sng_malloc(32)); 60 | vector_append(vector, sng_malloc(32)); 61 | vector_append(vector, sng_malloc(32)); 62 | vector_append(vector, sng_malloc(32)); 63 | // Next append requires memory reallocation 64 | vector_append(vector, sng_malloc(32)); 65 | vector_append(vector, sng_malloc(32)); 66 | vector_append(vector, sng_malloc(32)); 67 | vector_append(vector, sng_malloc(32)); 68 | vector_append(vector, sng_malloc(32)); 69 | vector_append(vector, sng_malloc(32)); 70 | // Expected vector size 71 | assert(vector_count(vector) == 16); 72 | // Expected empty position 73 | assert(vector_item(vector, vector_count(vector)) == 0); 74 | // Remove position (use generic destroyer) 75 | vector_set_destroyer(vector, vector_generic_destroyer); 76 | vector_remove(vector, vector_item(vector, 12)); 77 | assert(vector_count(vector) == 15); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /src/media.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file media.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage call media 27 | * 28 | */ 29 | 30 | #ifndef __SNGREP_MEDIA_H_ 31 | #define __SNGREP_MEDIA_H_ 32 | 33 | #include "config.h" 34 | #include 35 | #include "capture.h" 36 | 37 | #define MEDIATYPELEN 15 38 | 39 | //! Shorter declaration of sdp_media structure 40 | typedef struct sdp_media sdp_media_t; 41 | //! Shorter declaration of sdp_media_fmt structure 42 | typedef struct sdp_media_fmt sdp_media_fmt_t; 43 | 44 | struct sip_msg; 45 | struct sip_call; 46 | 47 | struct sdp_media_fmt { 48 | uint32_t id; 49 | char format[50]; 50 | }; 51 | 52 | 53 | struct sdp_media { 54 | //! SDP Addresses information 55 | address_t address; 56 | char type[MEDIATYPELEN]; 57 | uint32_t fmtcode; 58 | //! List of described formats in this media 59 | vector_t *formats; 60 | //! Message with this SDP content 61 | struct sip_msg *msg; 62 | }; 63 | 64 | /** 65 | * @brief Allocate memory for a new media structure 66 | * 67 | * Create a structure for a new message sdp connection data. 68 | * 69 | * @param msg SIP Message pointer owner of this media 70 | * @return new allocated structure 71 | */ 72 | sdp_media_t * 73 | media_create(struct sip_msg *msg); 74 | 75 | /** 76 | * @brief Vector destroyer for media items 77 | */ 78 | void 79 | media_destroyer(void *item); 80 | 81 | void 82 | media_set_type(sdp_media_t *media, const char *type); 83 | 84 | void 85 | media_set_address(sdp_media_t *media, address_t addr); 86 | 87 | void 88 | media_set_prefered_format(sdp_media_t *media, uint32_t code); 89 | 90 | void 91 | media_add_format(sdp_media_t *media, uint32_t code, const char *format); 92 | 93 | const char * 94 | media_get_type(sdp_media_t *media); 95 | 96 | const char * 97 | media_get_format(sdp_media_t *media, uint32_t code); 98 | 99 | const char * 100 | media_get_prefered_format(sdp_media_t *media); 101 | 102 | int 103 | media_get_format_code(sdp_media_t *media); 104 | 105 | #endif /* __SNGREP_MEDIA_H_ */ 106 | -------------------------------------------------------------------------------- /src/address.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file address.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage network addresses 27 | * 28 | * Multiple structures contain source and destination address. 29 | * This file contains the unification of all sngrep address containers. 30 | * 31 | */ 32 | 33 | #ifndef __SNGREP_ADDRESS_H 34 | #define __SNGREP_ADDRESS_H 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | //! Address string Length 41 | #ifdef USE_IPV6 42 | #ifdef INET6_ADDRSTRLEN 43 | #define ADDRESSLEN INET6_ADDRSTRLEN 44 | #else 45 | #define ADDRESSLEN 46 46 | #endif 47 | #else 48 | #define ADDRESSLEN INET_ADDRSTRLEN 49 | #endif 50 | 51 | //! Shorter declaration of address structure 52 | typedef struct address address_t; 53 | 54 | /** 55 | * @brief Network address 56 | */ 57 | struct address { 58 | //! IP address 59 | char ip[ADDRESSLEN]; 60 | //! Port 61 | uint16_t port; 62 | }; 63 | 64 | /** 65 | * @brief Check if two address are equal (including port) 66 | * 67 | * @param addr1 Address structure 68 | * @param addr2 Address structure 69 | * @return true if addresses contain the IP address, false otherwise 70 | */ 71 | bool 72 | addressport_equals(address_t addr1, address_t addr2); 73 | 74 | /** 75 | * @brief Check if two address are equal (ignoring port) 76 | * 77 | * @param addr1 Address structure 78 | * @param addr2 Address structure 79 | * @return true if addresses contain the same data, false otherwise 80 | */ 81 | bool 82 | address_equals(address_t addr1, address_t addr2); 83 | 84 | /** 85 | * @brief Check if a given IP address belongs to a local device 86 | * 87 | * @param address Address structure 88 | * @return true if address is local, false otherwise 89 | */ 90 | bool 91 | address_is_local(address_t addr); 92 | 93 | /** 94 | * @brief Convert string IP:PORT to address structure 95 | * 96 | * @param string in format IP:PORT 97 | * @return address structure 98 | */ 99 | address_t 100 | address_from_str(const char *ipport); 101 | 102 | 103 | #endif /* __SNGREP_ADDRESS_H */ 104 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file util.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions for general use in the program 27 | * 28 | */ 29 | #ifndef __SNGREP_UTIL_H 30 | #define __SNGREP_UTIL_H 31 | 32 | // Capture headers has some fixes for pcap timevals in BSD systems 33 | #include "capture.h" 34 | 35 | // Max Memmory allocation 36 | #define MALLOC_MAX_SIZE 102400 37 | 38 | // Stringify numbers for concatenation 39 | #define STRINGIFY_ARG(x) #x 40 | #define STRINGIFY(x) STRINGIFY_ARG(x) 41 | 42 | /** 43 | * @brief Wrapper for memory allocation 44 | */ 45 | void * 46 | sng_malloc(size_t size); 47 | 48 | /** 49 | * @brief Wrapper for memmory deallocation 50 | */ 51 | void 52 | sng_free(void *ptr); 53 | 54 | /* 55 | * @brief Generic implementation of basename 56 | */ 57 | char * 58 | sng_basename(const char *name); 59 | 60 | /* 61 | * @brief Wrapper for strncpy 62 | */ 63 | char * 64 | sng_strncpy(char *dst, const char *src, size_t len); 65 | 66 | /** 67 | * @brief Compare two timeval structures 68 | * 69 | * @param t1 First timeval structure 70 | * @param t2 Second timval structure 71 | * @return 1 if t1 > t2, 0 if t1 <= t2 72 | */ 73 | int 74 | timeval_is_older(struct timeval t1, struct timeval t2); 75 | 76 | /** 77 | * @brief Convert timeval to yyyy/mm/dd format 78 | */ 79 | const char * 80 | timeval_to_date(struct timeval time, char *out); 81 | 82 | /** 83 | * @brief Convert timeval to HH:MM:SS.mmmmmm format 84 | */ 85 | const char * 86 | timeval_to_time(struct timeval time, char *out); 87 | 88 | /** 89 | * @brief Calculate the time difference between two timeval 90 | * 91 | * @return Human readable time difference in mm:ss format 92 | */ 93 | const char * 94 | timeval_to_duration(struct timeval start, struct timeval end, char *out); 95 | 96 | /** 97 | * @brief Convert timeval diference to +mm:ss.mmmmmm 98 | */ 99 | const char * 100 | timeval_to_delta(struct timeval start, struct timeval end, char *out); 101 | 102 | /** 103 | * @brief Return a given string without trailing spaces 104 | */ 105 | char * 106 | strtrim(char *str); 107 | 108 | /** 109 | * @brief Set up handler for SIGTERM, SIGINT and SIGQUIT 110 | */ 111 | void setup_sigterm_handler(void); 112 | 113 | /** 114 | * @brief Check if SIGTERM, SIGINT or SIGQUIT were received 115 | * 116 | * @return true if any of the exit signals were received 117 | */ 118 | bool was_sigterm_received(void); 119 | 120 | #endif /* __SNGREP_UTIL_H */ 121 | -------------------------------------------------------------------------------- /src/media.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file media.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in media.h 27 | */ 28 | 29 | #include "config.h" 30 | #include 31 | #include 32 | #include "media.h" 33 | #include "rtp.h" 34 | #include "util.h" 35 | 36 | sdp_media_t * 37 | media_create(struct sip_msg *msg) 38 | { 39 | sdp_media_t *media;; 40 | 41 | // Allocate memory for this media structure 42 | if (!(media = sng_malloc(sizeof(sdp_media_t)))) 43 | return NULL; 44 | 45 | // Initialize all fields 46 | media->msg = msg; 47 | media->formats = vector_create(0, 1); 48 | vector_set_destroyer(media->formats, vector_generic_destroyer); 49 | return media; 50 | } 51 | 52 | void 53 | media_destroyer(void *item) 54 | { 55 | sdp_media_t *media = (sdp_media_t *) item; 56 | if (!item) 57 | return; 58 | vector_destroy(media->formats); 59 | sng_free(media); 60 | } 61 | 62 | void 63 | media_set_type(sdp_media_t *media, const char *type) 64 | { 65 | sng_strncpy(media->type, type, MEDIATYPELEN); 66 | } 67 | 68 | void 69 | media_set_address(sdp_media_t *media, address_t addr) 70 | { 71 | media->address = addr; 72 | } 73 | 74 | void 75 | media_set_prefered_format(sdp_media_t *media, uint32_t code) 76 | { 77 | media->fmtcode = code; 78 | } 79 | 80 | void 81 | media_add_format(sdp_media_t *media, uint32_t code, const char *format) 82 | { 83 | sdp_media_fmt_t *fmt; 84 | 85 | if (!(fmt = sng_malloc(sizeof(sdp_media_fmt_t)))) 86 | return; 87 | 88 | fmt->id = code; 89 | sng_strncpy(fmt->format, format, sizeof(fmt->format)); 90 | vector_append(media->formats, fmt); 91 | } 92 | 93 | const char * 94 | media_get_format(sdp_media_t *media, uint32_t code) 95 | { 96 | sdp_media_fmt_t *format; 97 | vector_iter_t iter; 98 | iter = vector_iterator(media->formats); 99 | while ((format = vector_iterator_next(&iter))) { 100 | if (format->id == code) 101 | return format->format; 102 | } 103 | 104 | return "Unassigned"; 105 | } 106 | 107 | const char * 108 | media_get_prefered_format(sdp_media_t *media) 109 | { 110 | const char *format; 111 | 112 | // Check if format is standard 113 | if ((format = rtp_get_standard_format(media->fmtcode))) { 114 | return format; 115 | } 116 | // Try to get format form SDP payload 117 | return media_get_format(media, media->fmtcode); 118 | } 119 | 120 | int 121 | media_get_format_code(sdp_media_t *media) 122 | { 123 | return media->fmtcode; 124 | } 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /tests/test_010.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file test_vector.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * Basic testing of vector structures 27 | */ 28 | 29 | #include "config.h" 30 | #include 31 | #include 32 | #include "../src/hash.h" 33 | 34 | int main () 35 | { 36 | htable_t *table; 37 | table = htable_create(10); 38 | assert(table); 39 | 40 | // Check a key is not found 41 | assert(htable_find(table, "notfoud") == NULL); 42 | 43 | // Check a key can be added 44 | htable_insert(table, "key", "data"); 45 | const char *data = htable_find(table, "key"); 46 | // And found 47 | assert(strcmp(data, "data") == 0); 48 | 49 | // Try filling all the buckets 50 | htable_insert(table, "key1", "data1"); 51 | htable_insert(table, "key2", "data2"); 52 | htable_insert(table, "key3", "data3"); 53 | htable_insert(table, "key4", "data4"); 54 | htable_insert(table, "key5", "data5"); 55 | htable_insert(table, "key6", "data6"); 56 | htable_insert(table, "key7", "data7"); 57 | htable_insert(table, "key8", "data8"); 58 | htable_insert(table, "key9", "data9"); 59 | htable_insert(table, "key10", "data10"); 60 | htable_insert(table, "key11", "data11"); 61 | htable_insert(table, "key12", "data12"); 62 | htable_insert(table, "key13", "data13"); 63 | htable_insert(table, "key14", "data14"); 64 | htable_insert(table, "key15", "data15"); 65 | 66 | // Find one entry 67 | const char *data7 = htable_find(table, "key7"); 68 | assert(strcmp(data7, "data7") == 0); 69 | 70 | // Remove one entry 71 | htable_remove(table, "key7"); 72 | assert(htable_find(table, "key7") == NULL); 73 | 74 | // Find another entries 75 | const char *data5 = htable_find(table, "key5"); 76 | assert(strcmp(data5, "data5") == 0); 77 | const char *data10 = htable_find(table, "key10"); 78 | assert(strcmp(data10, "data10") == 0); 79 | 80 | // Remove all entries 81 | htable_remove(table, "key1"); 82 | htable_remove(table, "key2"); 83 | htable_remove(table, "key3"); 84 | htable_remove(table, "key4"); 85 | htable_remove(table, "key5"); 86 | htable_remove(table, "key6"); 87 | htable_remove(table, "key7"); 88 | htable_remove(table, "key8"); 89 | htable_remove(table, "key9"); 90 | htable_remove(table, "key10"); 91 | htable_remove(table, "key11"); 92 | htable_remove(table, "key12"); 93 | htable_remove(table, "key13"); 94 | htable_remove(table, "key14"); 95 | htable_remove(table, "key15"); 96 | 97 | // Search a not found entry 98 | assert(htable_find(table, "key7") == NULL); 99 | 100 | // Destroy the table 101 | htable_destroy(table); 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /config/sngreprc: -------------------------------------------------------------------------------- 1 | ##----------------------------------------------------------------------------- 2 | ## sngreprc - sngrep configuration file 3 | ##----------------------------------------------------------------------------- 4 | ## This file stores sngrep configuration and it's totally optional 5 | ## 6 | 7 | ##----------------------------------------------------------------------------- 8 | ## Enable color on or off 9 | # set color off 10 | ## Use default foreground and background colors of your terminal 11 | # set background default 12 | ## Disable syntax highlighting 13 | # set syntax off 14 | ## Or enable branch/tag highlighting 15 | # set syntax.tag on 16 | # set syntax.branch on 17 | 18 | ##----------------------------------------------------------------------------- 19 | ## Uncomment to configure packet count capture limit (can't be disabled) 20 | # set capture.limit 50000 21 | 22 | ## Default capture keyfile for TLS transport 23 | # set capture.keyfile /etc/ssl/key.pem 24 | 25 | ## Uncommnet to lookup hostnames from packets ips 26 | # set capture.lookup on 27 | 28 | ## Set default capture device 29 | # use special keyword 'any', a device name 'eth0' or a comma-separated list like 'eth1,eth3' 30 | # set capture.device any 31 | 32 | ## Set default dump file 33 | # set capture.outfile /tmp/last_capture.pcap 34 | 35 | ## Set size of pcap capture buffer in MB (default: 2) 36 | # set capture.buffer 2 37 | 38 | ## Uncomment to enable parsing of captured HEP3 packets 39 | # set capture.eep on 40 | 41 | ##----------------------------------------------------------------------------- 42 | ## Default path in save dialog 43 | # set savepath /tmp/sngrep-captures 44 | 45 | ##----------------------------------------------------------------------------- 46 | ## Change default scrolling in call list and call flow 47 | # set cl.scrollstep 20 48 | # set cf.scrollstep 4 49 | ## Disable exit prompt 50 | # set cl.noexitprompt off 51 | ## Or set its default button 52 | # set cl.defexitbutton 0/1 53 | 54 | # Set default filter on startup 55 | # set filter.methods INVITE 56 | 57 | ##----------------------------------------------------------------------------- 58 | ## You can change the default number of columns in call list 59 | ## 60 | ## Set displayed columns in call list screen 61 | ## set cl.column{num} {field} 62 | ## 63 | ## You can optionally configure the column width using 64 | ## set cl.column{num}.width {num} 65 | ## 66 | ## Available columns fields are: 67 | ## - sipfrom 68 | ## - sipfromuser 69 | ## - sipto 70 | ## - siptouser 71 | ## - src 72 | ## - srchost 73 | ## - dst 74 | ## - dsthost 75 | ## - callid 76 | ## - xcallid 77 | ## - date 78 | ## - time 79 | ## - msgcnt 80 | ## - transport 81 | ## - state 82 | ## - convdur 83 | ## - totaldur 84 | ## 85 | ## Examples: 86 | # set cl.column0 sipfrom 87 | # set cl.column0.width 30 88 | # set cl.column1 sipto 89 | # set cl.column2 msgcnt 90 | # set cl.column3 src 91 | # set cl.column4 dst 92 | # set cl.column4.width 22 93 | # set cl.column5 starting 94 | # set cl.column5.width 15 95 | # set cl.column6 state 96 | 97 | ##----------------------------------------------------------------------------- 98 | ## Default minimun size from Message payload in Call Flow panel 99 | # set cf.rawminwidth 40 100 | 101 | ## Fixed raw preview size 102 | # set cf.rawfixedwidth 40 103 | 104 | ## Set selected highlight mode in call flow (bold, reverse or reversebold) 105 | # set cf.highlight reverse 106 | 107 | ##----------------------------------------------------------------------------- 108 | ## Uncomment to display dialogs that does not start with a request method 109 | # set sip.noincomplete off 110 | 111 | ##----------------------------------------------------------------------------- 112 | ## Uncomment to define custom b_leg correlation header 113 | # set sip.xcid X-Call-ID|X-CID 114 | -------------------------------------------------------------------------------- /src/address.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file address.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in address.h 27 | * 28 | */ 29 | 30 | #include "config.h" 31 | #include "address.h" 32 | #include "util.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | bool 40 | addressport_equals(address_t addr1, address_t addr2) 41 | { 42 | return addr1.port == addr2.port && !strcmp(addr1.ip, addr2.ip); 43 | } 44 | 45 | bool 46 | address_equals(address_t addr1, address_t addr2) 47 | { 48 | return !strcmp(addr1.ip, addr2.ip); 49 | } 50 | 51 | bool 52 | address_is_local(address_t addr) 53 | { 54 | //! Local devices pointer 55 | static pcap_if_t *devices = 0; 56 | pcap_if_t *dev; 57 | pcap_addr_t *da; 58 | char errbuf[PCAP_ERRBUF_SIZE]; 59 | struct sockaddr_in *ipaddr; 60 | #ifdef USE_IPV6 61 | struct sockaddr_in6 *ip6addr; 62 | #endif 63 | char ip[ADDRESSLEN]; 64 | 65 | // Get all network devices 66 | if (!devices) { 67 | // Get Local devices addresses 68 | pcap_findalldevs(&devices, errbuf); 69 | } 70 | 71 | for (dev = devices; dev; dev = dev->next) { 72 | for (da = dev->addresses; da ; da = da->next) { 73 | // Ingore empty addresses 74 | if (!da->addr) 75 | continue; 76 | 77 | // Initialize variables 78 | memset(ip, 0, sizeof(ip)); 79 | 80 | // Get address representation 81 | switch (da->addr->sa_family) { 82 | case AF_INET: 83 | ipaddr = (struct sockaddr_in *) da->addr; 84 | inet_ntop(AF_INET, &ipaddr->sin_addr, ip, sizeof(ip)); 85 | break; 86 | #ifdef USE_IPV6 87 | case AF_INET6: 88 | ip6addr = (struct sockaddr_in6 *) da->addr; 89 | inet_ntop(AF_INET, &ip6addr->sin6_addr, ip, sizeof(ip)); 90 | break; 91 | #endif 92 | } 93 | 94 | // Check if this address matches 95 | if (!strcmp(addr.ip, ip)) { 96 | return true; 97 | } 98 | 99 | } 100 | } 101 | return false; 102 | } 103 | 104 | address_t 105 | address_from_str(const char *ipport) 106 | { 107 | address_t ret = {}; 108 | char scanipport[256]; 109 | char address[ADDRESSLEN + 1]; 110 | int port; 111 | 112 | if (!ipport || strlen(ipport) > ADDRESSLEN + 6) 113 | return ret; 114 | 115 | sng_strncpy(scanipport, ipport, sizeof(scanipport)); 116 | 117 | if (sscanf(scanipport, "%" STRINGIFY(ADDRESSLEN) "[^:]:%d", address, &port) == 2) { 118 | sng_strncpy(ret.ip, address, sizeof(ret.ip)); 119 | ret.port = port; 120 | } 121 | 122 | return ret; 123 | } 124 | -------------------------------------------------------------------------------- /pkg/rpm/SPECS/sngrep.spec: -------------------------------------------------------------------------------- 1 | %bcond_with openssl 2 | 3 | Summary: SIP Messages flow viewer 4 | Name: sngrep 5 | Version: 1.8.3 6 | Release: 0%{?dist} 7 | License: GPLv3 8 | Group: Applications/Engineering 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 10 | Source: https://github.com/irontec/sngrep/releases/download/v%{version}/sngrep-%{version}.tar.gz 11 | URL: http://github.com/irontec/sngrep 12 | BuildRequires: ncurses-devel 13 | BuildRequires: make 14 | BuildRequires: libpcap-devel 15 | BuildRequires: pcre-devel 16 | BuildRequires: autoconf 17 | BuildRequires: automake 18 | BuildRequires: gcc 19 | %if %{with openssl} 20 | BuildRequires: openssl-devel 21 | %endif 22 | Requires: ncurses 23 | Requires: libpcap 24 | Requires: pcre 25 | 26 | %description 27 | sngrep displays SIP Messages grouped by Call-Id into flow 28 | diagrams. It can be used as an offline PCAP viewer or online 29 | capture using libpcap functions. 30 | 31 | It supports SIP UDP, TCP and TLS transports (when each message is 32 | delivered in one packet). 33 | 34 | You can also create new PCAP files from captures or displayed dialogs. 35 | 36 | %prep 37 | %setup -q 38 | 39 | %build 40 | ./bootstrap.sh 41 | %configure --with-pcre \ 42 | --enable-unicode \ 43 | --enable-ipv6 \ 44 | --enable-eep \ 45 | %{?_with_openssl} 46 | 47 | make %{?_smp_mflags} 48 | 49 | %install 50 | %{__make} install DESTDIR=%{buildroot} 51 | 52 | %files 53 | %doc README TODO COPYING ChangeLog 54 | %{_bindir}/* 55 | %{_mandir}/man8/* 56 | %config(noreplace) %{_sysconfdir}/* 57 | 58 | %clean 59 | %{__rm} -rf %{buildroot} 60 | 61 | %changelog 62 | * Thu Oct 16 2025 Ivan Alonso - 1.8.3 63 | - Version 1.8.3 64 | * Mon Jul 08 2024 Ivan Alonso - 1.8.2 65 | - Version 1.8.2 66 | * Mon Apr 08 2024 Ivan Alonso - 1.8.1 67 | - Version 1.8.1 68 | * Wed Dec 20 2023 Ivan Alonso - 1.8.0 69 | - Version 1.8.0 70 | * Fri Mar 31 2023 Ivan Alonso - 1.7.0 71 | - Version 1.7.0 72 | * Wed Aug 31 2022 Ivan Alonso - 1.6.0 73 | - Version 1.6.0 74 | * Tue Apr 26 2022 Ivan Alonso - 1.5.0 75 | - Version 1.5.0 76 | * Fri Nov 19 2021 Ivan Alonso - 1.4.10 77 | - Version 1.4.10 78 | * Thu May 20 2021 Ivan Alonso - 1.4.9 79 | - Version 1.4.9 80 | * Tue Oct 10 2020 Ivan Alonso - 1.4.8 81 | - Version 1.4.8 82 | * Thu May 21 2020 Ivan Alonso - 1.4.7 83 | - Version 1.4.7 84 | * Wed Oct 31 2018 Ivan Alonso - 1.4.6 85 | - Version 1.4.6 86 | * Fri Dec 22 2017 Ivan Alonso - 1.4.5 87 | - Version 1.4.5 88 | * Sun Sep 17 2017 Ivan Alonso - 1.4.4 89 | - Version 1.4.4 90 | * Wed May 10 2017 Ivan Alonso - 1.4.3 91 | - Version 1.4.3 92 | * Fri Dec 19 2016 Ivan Alonso - 1.4.2 93 | - Version 1.4.2 94 | * Fri Oct 28 2016 Ivan Alonso - 1.4.1 95 | - Version 1.4.1 96 | * Tue Aug 23 2016 Ivan Alonso - 1.4.0 97 | - Version 1.4.0 98 | * Mon Mar 28 2016 Ivan Alonso - 1.3.1 99 | - Version 1.3.1 100 | * Tue Mar 15 2016 Ivan Alonso - 1.3.0 101 | - Version 1.3.0 102 | * Thu Dec 10 2015 Ivan Alonso - 1.2.0 103 | - Version 1.2.0 104 | * Wed Oct 28 2015 Ivan Alonso - 1.1.0 105 | - Version 1.1.0 106 | * Tue Oct 06 2015 Ivan Alonso - 1.0.0 107 | - Version 1.0.0 108 | * Mon Aug 31 2015 Ivan Alonso - 0.4.2 109 | - Version 0.4.2 110 | * Tue Jul 07 2015 Ivan Alonso - 0.4.1 111 | - Version 0.4.1 112 | * Mon Jun 29 2015 Ivan Alonso - 0.4.0 113 | - Version 0.4.0 114 | * Tue Apr 14 2015 Ivan Alonso - 0.3.1 115 | - Version 0.3.1 116 | * Wed Mar 04 2015 Ivan Alonso - 0.3.0 117 | - First RPM version of sngrep 118 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file hash.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source code of functions defined in hash.h 27 | * 28 | */ 29 | #include "hash.h" 30 | #include 31 | #include 32 | 33 | htable_t * 34 | htable_create(size_t size) 35 | { 36 | htable_t *h; 37 | 38 | // Allocate memory for this table data 39 | if (!(h = malloc(sizeof(htable_t)))) 40 | return NULL; 41 | 42 | h->size = size; 43 | 44 | // Allocate memory for this table buckets 45 | if (!(h->buckets = malloc(sizeof(hentry_t) * size))) { 46 | free(h); 47 | return NULL; 48 | } 49 | 50 | // Initialize allocated memory 51 | memset(h->buckets, 0, sizeof(hentry_t) * size); 52 | 53 | // Return allocated table 54 | return h; 55 | } 56 | 57 | void 58 | htable_destroy(htable_t *table) 59 | { 60 | free(table->buckets); 61 | free(table); 62 | } 63 | 64 | int 65 | htable_insert(htable_t *table, const char *key, void *data) 66 | { 67 | // Get hash position for given entry 68 | size_t pos = htable_hash(table, key); 69 | 70 | // Create a new entry for given key 71 | hentry_t *entry; 72 | if (!(entry = malloc(sizeof(hentry_t)))) 73 | return -1; 74 | 75 | entry->key = key; 76 | entry->data = data; 77 | entry->next = 0; 78 | 79 | // Check if the hash position is in use 80 | hentry_t *exists = table->buckets[pos]; 81 | 82 | if (!exists) { 83 | table->buckets[pos] = entry; 84 | } else { 85 | while (exists->next) { 86 | exists = exists->next; 87 | } 88 | exists->next = entry; 89 | } 90 | return 0; 91 | } 92 | 93 | void 94 | htable_remove(htable_t *table, const char *key) 95 | { 96 | // Get hash position for given entry 97 | size_t pos = htable_hash(table, key); 98 | 99 | // Check if the hash position is in use 100 | hentry_t *entry, *prev = NULL; 101 | for (entry = table->buckets[pos]; entry; prev = entry, entry = entry->next) { 102 | if (!strcmp(entry->key, key)) { 103 | if (prev) { 104 | prev->next = entry->next; 105 | } else { 106 | table->buckets[pos] = entry->next; 107 | } 108 | // Remove item memory 109 | free(entry); 110 | return; 111 | } 112 | } 113 | } 114 | 115 | void * 116 | htable_find(htable_t *table, const char *key) 117 | { 118 | // Get hash position for given entry 119 | size_t pos = htable_hash(table, key); 120 | 121 | // Check if the hash position is in use 122 | hentry_t *entry; 123 | for (entry = table->buckets[pos]; entry; entry = entry->next) { 124 | if (!strcmp(entry->key, key)) { 125 | //! Found 126 | return entry->data; 127 | } 128 | } 129 | 130 | // Not found 131 | return NULL; 132 | } 133 | 134 | size_t 135 | htable_hash(htable_t *table, const char *key) 136 | { 137 | // dbj2 - http://www.cse.yorku.ca/~oz/hash.html 138 | size_t hash = 5381; 139 | while (*key++) { 140 | hash = ((hash << 5) + hash) ^ *key; 141 | } 142 | return hash & (table->size - 1); 143 | } 144 | -------------------------------------------------------------------------------- /src/filter.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file option.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage filtering options 27 | * 28 | * There are two types of filters: capture and display. 29 | * 30 | * Capture filters are handled in capture functions and they limit the 31 | * number of calls are created in sip storage. 32 | * 33 | * Display filters are handled in this file and they limit the number of 34 | * calls that are displayed to the user. Multiple display filters can be 35 | * set at the same time. In order to be valid, a call MUST match all the 36 | * enabled filters to be shown. 37 | * 38 | */ 39 | 40 | #ifndef __SNGREP_FILTER_H_ 41 | #define __SNGREP_FILTER_H_ 42 | 43 | #include "config.h" 44 | #ifdef WITH_PCRE 45 | #include 46 | #elif defined(WITH_PCRE2) 47 | #include 48 | #else 49 | #include 50 | #endif 51 | #include "sip.h" 52 | 53 | //! Shorter declaration of sip_call_group structure 54 | typedef struct filter filter_t; 55 | 56 | /** 57 | * @brief Available filter types 58 | */ 59 | enum filter_type { 60 | //! SIP From header in packet payload 61 | FILTER_SIPFROM = 0, 62 | //! SIP To header in packet payload 63 | FILTER_SIPTO, 64 | //! Packet source address 65 | FILTER_SOURCE, 66 | //! Packet destination address 67 | FILTER_DESTINATION, 68 | //! SIP Method in packet payload 69 | FILTER_METHOD, 70 | //! SIP Payload in any call packet 71 | FILTER_PAYLOAD, 72 | //! Displayed line in call list 73 | FILTER_CALL_LIST, 74 | //! Number of available filter types 75 | FILTER_COUNT, 76 | }; 77 | 78 | /** 79 | * @brief Filter information 80 | */ 81 | struct filter { 82 | //! The filter text 83 | char *expr; 84 | #ifdef WITH_PCRE 85 | //! The filter compiled expression 86 | pcre *regex; 87 | #elif defined(WITH_PCRE2) 88 | //! The filter compiled expression 89 | pcre2_code *regex; 90 | #else 91 | //! The filter compiled expression 92 | regex_t regex; 93 | #endif 94 | }; 95 | 96 | /** 97 | * @brief Set a given filter expression 98 | * 99 | * This function is used to set the filter expression 100 | * on a given filter. If given expression is NULL 101 | * the filter will be removed. 102 | * 103 | * @param type Type of the filter 104 | * @param expr Regexpression to match 105 | * @return 0 if the filter is valid, 1 otherwise 106 | */ 107 | int 108 | filter_set(int type, const char *expr); 109 | 110 | /** 111 | * @brief Get filter text expression 112 | * 113 | * @param type filter type 114 | * @return filter text expressions 115 | */ 116 | const char * 117 | filter_get(int type); 118 | 119 | /** 120 | * @brief Check if a call if filtered 121 | * 122 | * @param call Call to be checked 123 | * @return 1 if call is filtered 124 | */ 125 | int 126 | filter_check_call(void *item); 127 | 128 | /** 129 | * @brief Check if data matches the filter regexp 130 | * 131 | * @return 0 if the given data matches the filter 132 | */ 133 | int 134 | filter_check_expr(filter_t filter, const char *data); 135 | 136 | /** 137 | * @brief Reset filtered flag in all calls 138 | * 139 | * This function can be used to force reevaluation 140 | * of filters in all calls. 141 | */ 142 | void 143 | filter_reset_calls(); 144 | 145 | #endif /* __SNGREP_FILTER_H_ */ 146 | -------------------------------------------------------------------------------- /src/curses/ui_msg_diff.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_msg_diff.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage diff display 27 | * 28 | */ 29 | #ifndef __UI_MSG_DIFF_H 30 | #define __UI_MSG_DIFF_H 31 | #include "config.h" 32 | #include "ui_manager.h" 33 | 34 | //! Sorter declaration of struct msg_diff_info 35 | typedef struct msg_diff_info msg_diff_info_t; 36 | 37 | /** 38 | * @brief Call raw status information 39 | * 40 | * This data stores the actual status of the panel. It's stored in the 41 | * PANEL user pointer. 42 | */ 43 | struct msg_diff_info { 44 | //! First message to compare 45 | sip_msg_t *one; 46 | //! Second message to compare 47 | sip_msg_t *two; 48 | //! Left displayed subwindow 49 | WINDOW *one_win; 50 | //! Right displayed subwindow 51 | WINDOW *two_win; 52 | }; 53 | 54 | /** 55 | * @brief Create Message diff panel 56 | * 57 | * This function will allocate the ncurses pointer and draw the static 58 | * stuff of the screen (which usually won't be redrawn) 59 | * It will also create an information structure of the panel status and 60 | * store it in the panel's userpointer 61 | * 62 | * @param ui UI structure pointer 63 | * @return the allocated ncurses panel 64 | */ 65 | void 66 | msg_diff_create(ui_t *ui); 67 | 68 | /** 69 | * @brief Deallocate panel memory 70 | * 71 | * This function will be called from ui manager logic to free 72 | * message diff panel memory 73 | * 74 | * @param ui UI structure pointer 75 | */ 76 | void 77 | msg_diff_destroy(ui_t *ui); 78 | 79 | /** 80 | * @brief Get panel information structure 81 | * 82 | * All required information of the panel is stored in the info pointer 83 | * of the panel. 84 | * This function will return the pointer to the info structure of the 85 | * panel. 86 | * 87 | * @param ui UI structure pointer 88 | * @return a pointer to the info structure or NULL if no structure exists 89 | */ 90 | msg_diff_info_t * 91 | msg_diff_info(ui_t *ui); 92 | 93 | /** 94 | * @brief Redraw panel data 95 | * 96 | * This function will be called from ui manager logic when the panels 97 | * needs to be redrawn. 98 | * 99 | * @param ui UI structure pointer 100 | * @return 0 in all cases 101 | */ 102 | int 103 | msg_diff_draw(ui_t *ui); 104 | 105 | /** 106 | * @brief Draw panel footer 107 | * 108 | * Usually panel footer contains useful keybidings. This function 109 | * will draw that footer 110 | * 111 | * @param ui UI structure pointer 112 | */ 113 | void 114 | msg_diff_draw_footer(ui_t *ui); 115 | 116 | /** 117 | * @brief Draw a message into a raw subwindow 118 | * 119 | * This function will be called for each message that wants to be draw 120 | * in the panel. 121 | * 122 | */ 123 | int 124 | msg_diff_draw_message(WINDOW *win, sip_msg_t *msg, char *highlight); 125 | 126 | /** 127 | * @brief Set the panel working messages 128 | * 129 | * This function will access the panel information and will set the 130 | * msg pointers to the processed messages. 131 | * 132 | * @param ui UI structure pointer 133 | * @param one Message pointer to be set in the internal info struct 134 | * @param two Message pointer to be set in the internal info struct 135 | * @return 0 in all cases 136 | */ 137 | int 138 | msg_diff_set_msgs(ui_t *ui, sip_msg_t *one, sip_msg_t *two); 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | ToDo List 2 | ========= 3 | 4 | capture: 5 | * Improve Packet fragmentation 6 | Right now capture process only handle packet IP fragmentation and 7 | TCP segmentation when all parts come ordered. Also, packets being 8 | reassembled are stored in memory until fully assembled (which may 9 | never occur). 10 | 11 | * Improve TCP assembly 12 | We assume a packet is complete when PSH flag is set. In some cases 13 | this is not true and we have multiples SIP messages into what we 14 | consider an assembled packet. It's require to evaluate if a packet 15 | contains a SIP message every time we assemble a new segment. 16 | 17 | * Improve long run performance 18 | Right now, sngrep stores a lot of information in memory making it quite 19 | dangerous in long runs. We implemented a dialog limit to avoid being 20 | afraid of leaving an unattended sngrep, but it ended being also used 21 | by internal structures as a max size reference. While the limit is still 22 | a good idea, it will be nice to decouple it from the internals, allowing 23 | even unlimited captures if specified by the user at own risk. 24 | 25 | rtp: 26 | * Improve RTP stream creation 27 | We create new streams from SDP information every time we parse a 28 | SIP message with SDP content and the information doesn't match the 29 | last call stream. This should be improved to also consider the stream 30 | direction, so we compare with the last call stream with the same 31 | direction. This way, we would avoid drawing RTP arrows that have 32 | the same information 33 | 34 | * Improve RTCP parsing 35 | Right now only RTCP extended report is parsed and the information 36 | provided in flow panel doesn't seem to be useful. Determine what 37 | information will be interesting to display and parse it properly. 38 | 39 | * Remove RTCP stream arrows 40 | RTCP arrows in Call flow doesn't provide useful information. The 41 | RTCP information displayed in the preview panel could be displayed 42 | in the matching RTP arrow. 43 | 44 | pcap: 45 | * Sorting saved pakets 46 | Before creating a pcap, we sort packets by timestamp. When a lot of packets 47 | are handled (especially when RTP is captured) this can take A LOT of time. 48 | We should improve the sorting, allowing the save process to be canceled or 49 | allowing not to sort at all. 50 | 51 | * Allow saving HEP/EEP captured packets 52 | To create a full packet from HEP received packets its required to create 53 | the required Ethernet/TCP/UDP headers before dumping to pcap. 54 | Most of the information are part of HEP headers, other (like ethernet mac 55 | addresses) must be filled with dummy information. 56 | 57 | interface: 58 | * Change panels initialization 59 | Right now, all panels are initializated at the same, because 60 | each panel can only be invoked once (it is not possible to have 61 | two call details panel right now) 62 | 63 | * Add horizontal scrolling 64 | It should be nice to be able to scroll horizontaly (with unused 65 | right and left keys) in Call List and Call flow. 66 | 67 | * Interface resize 68 | When the terminal size changes, the ui is not properly redraw. 69 | It would be nice to handle KEY_RESIZE event and change all displayed 70 | panels. 71 | 72 | * Improve colors for white background terminals 73 | The best approach for colors should be use terminal defaults. 74 | Right now, white background terminals must set background dark option 75 | in order to see colors properly. This could be fixed implementing 76 | color themes. 77 | 78 | * Improve compatibility with IPv6 79 | IPv6 packets are captured but IPv6 addresses can be 45 chars 80 | long, so current UI is not ready to display that kind of 81 | addresses 82 | 83 | * Improve Unicode support 84 | Even when compiling with libncruses wide-character support, we don't 85 | use the special fuctions that provide to write payload into the panels, 86 | making some characters to be displayed incorrectly. 87 | 88 | * Update keybinding display in help screen 89 | Most of the panels have a help window that display keybindings, but they 90 | are updated with the last keybiding mapping changes. 91 | 92 | * Create a loading dialog or include a Loading percentage in Call List 93 | Add the readed % of bytes from the pcap file next to the (Loading) label in 94 | Call List, or create a new Dialog when opening big pcaps that can be hidden 95 | to continue loading in background. 96 | 97 | -------------------------------------------------------------------------------- /src/curses/ui_filter.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_filter.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage ui window for filtering options 27 | * 28 | * This file contains the functions and structures to manage the filter 29 | * dialog, that can be used to filter the lines in call list window. 30 | */ 31 | 32 | #ifndef __UI_FILTER_H 33 | #define __UI_FILTER_H 34 | 35 | #include "config.h" 36 | #include 37 | #include "ui_manager.h" 38 | 39 | /** 40 | * @brief Enum of available dialog fields 41 | * 42 | * Dialog form has a field array. Following enum represents the 43 | * order this fields are stored in panel info structure. 44 | * 45 | */ 46 | enum filter_field_list { 47 | FLD_FILTER_SIPFROM = 0, 48 | FLD_FILTER_SIPTO, 49 | FLD_FILTER_SRC, 50 | FLD_FILTER_DST, 51 | FLD_FILTER_PAYLOAD, 52 | FLD_FILTER_REGISTER, 53 | FLD_FILTER_INVITE, 54 | FLD_FILTER_SUBSCRIBE, 55 | FLD_FILTER_NOTIFY, 56 | FLD_FILTER_INFO, 57 | FLD_FILTER_KDMQ, 58 | FLD_FILTER_OPTIONS, 59 | FLD_FILTER_PUBLISH, 60 | FLD_FILTER_MESSAGE, 61 | FLD_FILTER_REFER, 62 | FLD_FILTER_UPDATE, 63 | FLD_FILTER_FILTER, 64 | FLD_FILTER_CANCEL, 65 | //! Never remove this field id @see filter_info 66 | FLD_FILTER_COUNT 67 | }; 68 | 69 | //! Sorter declaration of struct filter_info 70 | typedef struct filter_info filter_info_t; 71 | 72 | /** 73 | * @brief Filter panel private information 74 | * 75 | * This structure contains the durable data of filter panel. 76 | */ 77 | struct filter_info { 78 | //! Form that contains the filter fields 79 | FORM *form; 80 | //! An array of fields 81 | FIELD *fields[FLD_FILTER_COUNT + 1]; 82 | }; 83 | 84 | /** 85 | * @brief Creates a new filter panel 86 | * 87 | * This function allocates all required memory for 88 | * displaying the filter panel. It also draws all the 89 | * static information of the panel that will never be 90 | * redrawn. 91 | * 92 | * @param ui UI structure pointer 93 | */ 94 | void 95 | filter_create(ui_t *ui); 96 | 97 | /** 98 | * @brief Destroy filter panel 99 | * 100 | * This function do the final cleanups for this panel 101 | * @param ui UI structure pointer 102 | */ 103 | void 104 | filter_destroy(ui_t *ui); 105 | 106 | /** 107 | * @brief Get custom information of given panel 108 | * 109 | * Return ncurses users pointer of the given panel into panel's 110 | * information structure pointer. 111 | * 112 | * @param ui UI structure pointer 113 | * @return a pointer to info structure of given panel 114 | */ 115 | filter_info_t * 116 | filter_info(ui_t *ui); 117 | 118 | /** 119 | * @brief Manage pressed keys for filter panel 120 | * 121 | * This function is called by UI manager every time a 122 | * key is pressed. This allow the filter panel to manage 123 | * its own keys. 124 | * 125 | * @param ui UI structure pointer 126 | * @param key key code 127 | * @return enum @key_handler_ret 128 | */ 129 | int 130 | filter_handle_key(ui_t *ui, int key); 131 | 132 | /** 133 | * @brief Save form data to options 134 | * 135 | * This function will update the options values 136 | * of filter fields with its new value. 137 | * 138 | * @param ui UI structure pointer 139 | */ 140 | void 141 | filter_save_options(ui_t *ui); 142 | 143 | /** 144 | * @brief Return String value for a filter field 145 | * 146 | * @return method name 147 | */ 148 | const char* 149 | filter_field_method(int field_id); 150 | 151 | /** 152 | * @brief Set Method filtering from filter.methods setting format 153 | */ 154 | void 155 | filter_method_from_setting(const char *value); 156 | 157 | /** 158 | * @brief Set Payload filter from filter.payload setting 159 | */ 160 | void 161 | filter_payload_from_setting(const char *value); 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /src/curses/ui_call_raw.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_call_raw.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage Raw output screen of Sip messages 27 | * 28 | * This file contains the functions and structures to manage the raw message 29 | * output screen. 30 | * 31 | */ 32 | #ifndef __UI_CALL_RAW_H 33 | #define __UI_CALL_RAW_H 34 | 35 | #include "config.h" 36 | #include "ui_manager.h" 37 | 38 | //! Sorter declaration of struct call_raw_info 39 | typedef struct call_raw_info call_raw_info_t; 40 | 41 | /** 42 | * @brief Call raw status information 43 | * 44 | * This data stores the actual status of the panel. It's stored in the 45 | * PANEL user pointer. 46 | */ 47 | struct call_raw_info { 48 | //! Group of calls displayed on the panel (Call raw display) 49 | sip_call_group_t *group; 50 | //! Message to display on the panel (Single message raw display) 51 | sip_msg_t *msg; 52 | //! Last printed message on panel (Call raw display) 53 | sip_msg_t *last; 54 | //! Window pad to copy on displayed screen 55 | WINDOW *pad; 56 | //! Already used lines of the window pad 57 | int padline; 58 | //! Scroll position of the window pad 59 | int scroll; 60 | }; 61 | 62 | /** 63 | * @brief Create Call Raw panel 64 | * 65 | * This function will allocate the ncurses pointer and draw the static 66 | * stuff of the screen (which usually won't be redrawn) 67 | * It will also create an information structure of the panel status and 68 | * store it in the panel's userpointer 69 | */ 70 | void 71 | call_raw_create(ui_t *ui); 72 | 73 | /** 74 | * @brief Destroy panel 75 | * 76 | * This function will hide the panel and free all allocated memory. 77 | * 78 | * @param panel Ncurses panel pointer 79 | */ 80 | void 81 | call_raw_destroy(ui_t *ui); 82 | 83 | /** 84 | * @brief Get custom information of given panel 85 | * 86 | * Return ncurses users pointer of the given panel into panel's 87 | * information structure pointer. 88 | * 89 | * @param panel Ncurses panel pointer 90 | * @return a pointer to info structure of given panel 91 | */ 92 | call_raw_info_t * 93 | call_raw_info(ui_t *ui); 94 | 95 | /** 96 | * @brief Determine if the screen requires redrawn 97 | * 98 | * This will query the interface if it requires to be redraw again. 99 | * 100 | * @param ui UI structure pointer 101 | * @return true if the panel requires redraw, false otherwise 102 | */ 103 | bool 104 | call_raw_redraw(ui_t *ui); 105 | 106 | /** 107 | * @brief Draw the Call Raw panel 108 | * 109 | * This function will drawn the panel into the screen based on its stored 110 | * status 111 | * 112 | * @param panel Ncurses panel pointer 113 | * @return 0 if the panel has been drawn, -1 otherwise 114 | */ 115 | int 116 | call_raw_draw(ui_t *ui); 117 | 118 | /** 119 | * @brief Draw a message in call Raw 120 | * 121 | * Draw a new message in the Raw pad. 122 | * 123 | * @param panel Ncurses panel pointer 124 | * @param msg New message to be printed 125 | * @return 0 in call cases 126 | */ 127 | int 128 | call_raw_print_msg(ui_t *ui, sip_msg_t *msg); 129 | 130 | /** 131 | * @brief Handle Call Raw key strokes 132 | * 133 | * This function will manage the custom keybindings of the panel. 134 | * This function return one of the values defined in @key_handler_ret 135 | * 136 | * @param panel Ncurses panel pointer 137 | * @param key Pressed keycode 138 | * @return enum @key_handler_ret 139 | */ 140 | int 141 | call_raw_handle_key(ui_t *ui, int key); 142 | 143 | /** 144 | * @brief Set the active call group of the panel 145 | * 146 | * This function will access the panel information and will set the 147 | * call group pointer to the processed calls. 148 | * 149 | * @param group Call Group pointer to be set in the internal info struct 150 | */ 151 | int 152 | call_raw_set_group(sip_call_group_t *group); 153 | 154 | /** 155 | * @brief Set the active msg of the panel 156 | * 157 | * This function will access the panel information and will set the 158 | * msg pointer to the processed message. 159 | * 160 | * @param msg Message pointer to be set in the internal info struct 161 | */ 162 | int 163 | call_raw_set_msg(sip_msg_t *msg); 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /src/option.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file option.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage application settings 27 | * 28 | * This file contains the functions to manage application settings and 29 | * optionuration resource files. Configuration will be parsed in this order, 30 | * from less to more priority, so the later will overwrite the previous. 31 | * 32 | * - Initialization 33 | * - \@sysdir\@/sngreprc 34 | * - $HOME/.sngreprc 35 | * - $SNGREPRC 36 | * 37 | * This is a basic approach to configuration, but at least a minimun is required 38 | * for those who can not see all the list columns or want to disable colours in 39 | * every sngrep execution. 40 | * 41 | */ 42 | 43 | #ifndef __SNGREP_OPTION_H 44 | #define __SNGREP_OPTION_H 45 | 46 | #include 47 | 48 | //! Shorter declaration of config_option struct 49 | typedef struct config_option option_opt_t; 50 | 51 | //! Option types 52 | enum option_type { 53 | COLUMN = 0, 54 | ALIAS 55 | }; 56 | 57 | /** 58 | * @brief Configurable option structure 59 | * 60 | * sngrep is optionured by a group of attributes that can be 61 | * modified using resource files. 62 | */ 63 | struct config_option { 64 | //! Setting type 65 | enum option_type type; 66 | //! Name of attribute 67 | char *opt; 68 | //! Value of attribute 69 | char *value; 70 | }; 71 | 72 | /** 73 | * @brief Initialize all program options 74 | * 75 | * This function will give all available settings an initial value. 76 | * This values can be overriden using resources files, either from system dir 77 | * or user home dir. 78 | * 79 | * @param no_config Do not load config file if set to 1 80 | * @return 0 in all cases 81 | */ 82 | int 83 | init_options(int no_config); 84 | 85 | /** 86 | * @brief Deallocate options memory 87 | * 88 | * Deallocate memory used for program configurations 89 | */ 90 | void 91 | deinit_options(); 92 | 93 | /** 94 | * @brief Read optionuration directives from file 95 | * 96 | * This function will parse passed filenames searching for configuration 97 | * directives of sngrep. See documentation for a list of available 98 | * directives and attributes 99 | * 100 | * @param fname Full path configuration file name 101 | * @return 0 in case of parse success, -1 otherwise 102 | */ 103 | int 104 | read_options(const char *fname); 105 | 106 | /** 107 | * @brief Get settings option value (string) 108 | * 109 | * Used in all the program to access the optionurable options of sngrep 110 | * Use this function instead of accessing optionuration array. 111 | * 112 | * @param opt Name of optionurable option 113 | * @return configuration option value or NULL if not found 114 | */ 115 | const char* 116 | get_option_value(const char *opt); 117 | 118 | /** 119 | * @brief Get settings option value (int) 120 | * 121 | * Basically the same as get_option_value converting the result to 122 | * integer. 123 | * Use this function instead of accessing configuration array. 124 | * 125 | * @todo -1 is an error! 126 | * 127 | * @param opt Name of optionurable option 128 | * @return option numeric value or -1 in case of error 129 | */ 130 | int 131 | get_option_int_value(const char *opt); 132 | 133 | /** 134 | * @brief Sets a settings option value 135 | * 136 | * Basic setter for 'set' directive attributes 137 | * 138 | * @param opt Name of configuration option 139 | * @param value Value of configuration option 140 | */ 141 | void 142 | set_option_value(const char *opt, const char *value); 143 | 144 | /** 145 | * @brief Sets an alias for a given address 146 | * 147 | * @param address IP Address 148 | * @param string representing the alias 149 | */ 150 | void 151 | set_alias_value(const char *address, const char *alias); 152 | 153 | /** 154 | * @brief Get alias for a given address (string) 155 | * 156 | * @param address IP Address 157 | * @return configured alias or address if alias not found 158 | */ 159 | const char * 160 | get_alias_value(const char *address); 161 | 162 | /** 163 | * @brief Get alias for a given address and port (string) 164 | * 165 | * @param address IP Address 166 | * @param port port 167 | * @return configured alias or address if alias not found 168 | */ 169 | const char * 170 | get_alias_value_vs_port(const char *address, uint16_t port); 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /src/packet.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file packet.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage captured packet 27 | * 28 | * Capture packet contains the information about a one or more packets captured 29 | * from network interface or readed from a .PCAP file. 30 | * 31 | * The binary content of the packet can be stored in one or more frames (if 32 | * packet has been reassembled). 33 | * 34 | */ 35 | 36 | #ifndef __SNGREP_CAPTURE_PACKET_H 37 | #define __SNGREP_CAPTURE_PACKET_H 38 | 39 | #include 40 | #include 41 | #include 42 | #include "address.h" 43 | #include "vector.h" 44 | 45 | //! Stored packet types 46 | enum packet_type { 47 | PACKET_SIP_UDP = 0, 48 | PACKET_SIP_TCP, 49 | PACKET_SIP_TLS, 50 | PACKET_SIP_WS, 51 | PACKET_SIP_WSS, 52 | PACKET_RTP, 53 | PACKET_RTCP, 54 | }; 55 | 56 | //! Shorter declaration of packet structure 57 | typedef struct packet packet_t; 58 | //! Shorter declaration of frame structure 59 | typedef struct frame frame_t; 60 | 61 | /** 62 | * @brief Packet capture data. 63 | * 64 | * One packet can contain more than one frame after assembly. We assume than 65 | * one SIP message has one packet (maybe in multiple frames) and that one 66 | * packet can only contain one SIP message. 67 | */ 68 | struct packet { 69 | //! IP protocol 70 | uint8_t ip_version; 71 | //! Transport protocol 72 | uint8_t proto; 73 | //! Packet type as defined in capture_packet_type 74 | enum packet_type type; 75 | //! Source 76 | address_t src; 77 | //! Destination 78 | address_t dst; 79 | //! Packet IP id 80 | #ifdef USE_IPV6 81 | uint32_t ip_id; 82 | #else 83 | uint16_t ip_id; 84 | #endif 85 | //! Packet IP fragmentation captured data 86 | uint32_t ip_cap_len; 87 | //! Packet IP fragmentation expected data 88 | uint32_t ip_exp_len; 89 | //! Last TCP sequence frame 90 | uint32_t tcp_seq; 91 | //! PCAP Packet payload when it can not be get from data 92 | u_char *payload; 93 | //! Payload length 94 | uint32_t payload_len; 95 | //! Packet frame list (frame_t) 96 | vector_t *frames; 97 | }; 98 | 99 | /** 100 | * @brief Capture frame. 101 | * 102 | * One packet can contain multiple frames. This structure is designed to store 103 | * the required information to save a packet into a PCAP file. 104 | */ 105 | struct frame { 106 | //! PCAP Frame Header data 107 | struct pcap_pkthdr *header; 108 | //! PCAP Frame content 109 | u_char *data; 110 | }; 111 | 112 | /** 113 | * @brief Allocate memory to store new packet data 114 | */ 115 | packet_t * 116 | packet_create(uint8_t ip_ver, uint8_t proto, address_t src, address_t dst, uint32_t id); 117 | 118 | /** 119 | * @brief Deep clone one packet 120 | */ 121 | packet_t* 122 | packet_clone(packet_t *packet); 123 | 124 | /** 125 | * @brief Set Transport layer information 126 | */ 127 | packet_t * 128 | packet_set_transport_data(packet_t *pkt, uint16_t sport, uint16_t dport); 129 | 130 | /** 131 | * @brief Add a new frame to the given packet 132 | */ 133 | frame_t * 134 | packet_add_frame(packet_t *pkt, const struct pcap_pkthdr *header, const u_char *packet); 135 | 136 | /** 137 | * @brief Deallocate a packet structure memory 138 | */ 139 | void 140 | packet_destroy(packet_t *packet); 141 | 142 | /** 143 | * @brief Destroyer function for packet vectors 144 | */ 145 | void 146 | packet_destroyer(void *packet); 147 | 148 | /** 149 | * @brief Free packet frames data. 150 | * 151 | * This can be used to avoid storing packet payload in memory or disk 152 | */ 153 | void 154 | packet_free_frames(packet_t *pkt); 155 | 156 | /** 157 | * @brief Set packet type 158 | */ 159 | void 160 | packet_set_type(packet_t *packet, enum packet_type type); 161 | 162 | /** 163 | * @brief Set packet payload when it can not be get from packet 164 | */ 165 | void 166 | packet_set_payload(packet_t *packet, u_char *payload, uint32_t payload_len); 167 | 168 | /** 169 | * @brief Getter for capture payload size 170 | */ 171 | uint32_t 172 | packet_payloadlen(packet_t *packet); 173 | 174 | /** 175 | * @brief Getter for capture payload pointer 176 | */ 177 | u_char * 178 | packet_payload(packet_t *packet); 179 | 180 | /** 181 | * @brief Get The timestamp for a packet. 182 | */ 183 | struct timeval 184 | packet_time(packet_t *packet); 185 | 186 | #endif /* __SNGREP_CAPTURE_PACKET_H */ 187 | -------------------------------------------------------------------------------- /src/packet.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file packet.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in packet.h 27 | * 28 | */ 29 | #include "config.h" 30 | #include 31 | #include 32 | #include "packet.h" 33 | 34 | packet_t * 35 | packet_create(uint8_t ip_ver, uint8_t proto, address_t src, address_t dst, uint32_t id) 36 | { 37 | // Create a new packet 38 | packet_t *packet; 39 | packet = malloc(sizeof(packet_t)); 40 | memset(packet, 0, sizeof(packet_t)); 41 | packet->ip_version = ip_ver; 42 | packet->proto = proto; 43 | packet->frames = vector_create(1, 1); 44 | packet->ip_id = id; 45 | packet->src = src; 46 | packet->dst = dst; 47 | return packet; 48 | } 49 | 50 | packet_t* 51 | packet_clone(packet_t *packet) 52 | { 53 | packet_t *clone; 54 | frame_t *frame; 55 | 56 | // Create a new packet with the original information 57 | clone = packet_create(packet->ip_version, packet->proto, packet->src, packet->dst, packet->ip_id); 58 | clone->tcp_seq = packet->tcp_seq; 59 | clone->type = packet->type; 60 | 61 | // Append this frames to the original packet 62 | vector_iter_t frames = vector_iterator(packet->frames); 63 | while ((frame = vector_iterator_next(&frames))) 64 | packet_add_frame(clone, frame->header, frame->data); 65 | 66 | return clone; 67 | } 68 | 69 | void 70 | packet_destroy(packet_t *packet) 71 | { 72 | frame_t *frame; 73 | 74 | // Check we have a valid packet pointer 75 | if (!packet) return; 76 | 77 | // Destroy frames 78 | vector_iter_t it = vector_iterator(packet->frames); 79 | while ((frame = vector_iterator_next(&it))) { 80 | free(frame->header); 81 | free(frame->data); 82 | } 83 | 84 | // TODO Free remaining packet data 85 | vector_set_destroyer(packet->frames, vector_generic_destroyer); 86 | vector_destroy(packet->frames); 87 | free(packet->payload); 88 | free(packet); 89 | } 90 | 91 | void 92 | packet_destroyer(void *packet) 93 | { 94 | packet_destroy((packet_t*) packet); 95 | } 96 | 97 | void 98 | packet_free_frames(packet_t *pkt) 99 | { 100 | frame_t *frame; 101 | vector_iter_t it = vector_iterator(pkt->frames); 102 | 103 | while ((frame = vector_iterator_next(&it))) { 104 | free(frame->data); 105 | frame->data = NULL; 106 | } 107 | } 108 | 109 | packet_t * 110 | packet_set_transport_data(packet_t *pkt, uint16_t sport, uint16_t dport) 111 | { 112 | pkt->src.port = sport; 113 | pkt->dst.port = dport; 114 | return pkt; 115 | } 116 | 117 | frame_t * 118 | packet_add_frame(packet_t *pkt, const struct pcap_pkthdr *header, const u_char *packet) 119 | { 120 | frame_t *frame = malloc(sizeof(frame_t)); 121 | frame->header = malloc(sizeof(struct pcap_pkthdr)); 122 | memcpy(frame->header, header, sizeof(struct pcap_pkthdr)); 123 | frame->data = malloc(header->caplen); 124 | memcpy(frame->data, packet, header->caplen); 125 | vector_append(pkt->frames, frame); 126 | return frame; 127 | } 128 | 129 | void 130 | packet_set_type(packet_t *packet, enum packet_type type) 131 | { 132 | packet->type = type; 133 | } 134 | 135 | void 136 | packet_set_payload(packet_t *packet, u_char *payload, uint32_t payload_len) 137 | { 138 | // Free previous payload 139 | if (packet->payload) 140 | free(packet->payload); 141 | packet->payload_len = 0; 142 | 143 | // Set new payload 144 | if (payload) { 145 | packet->payload = malloc(payload_len + 1); 146 | memset(packet->payload, 0, payload_len + 1); 147 | memcpy(packet->payload, payload, payload_len); 148 | packet->payload[payload_len] = '\0'; 149 | packet->payload_len = payload_len; 150 | } 151 | } 152 | 153 | uint32_t 154 | packet_payloadlen(packet_t *packet) 155 | { 156 | return packet->payload_len; 157 | } 158 | 159 | u_char * 160 | packet_payload(packet_t *packet) 161 | { 162 | return packet->payload; 163 | } 164 | 165 | struct timeval 166 | packet_time(packet_t *packet) 167 | { 168 | frame_t *first; 169 | struct timeval ts = { 0 }; 170 | 171 | // Return first frame timestamp 172 | if (packet && (first = vector_first(packet->frames))) { 173 | ts.tv_sec = first->header->ts.tv_sec; 174 | ts.tv_usec = first->header->ts.tv_usec; 175 | } 176 | 177 | // Return packe timestamp 178 | return ts; 179 | } 180 | 181 | -------------------------------------------------------------------------------- /pkg/debian/changelog: -------------------------------------------------------------------------------- 1 | sngrep (1.8.3) experimental; urgency=low 2 | 3 | * sngrep 1.8.3 released 4 | 5 | -- Ivan Alonso Thu, 16 Oct 2025 10:14:20 +0200 6 | 7 | sngrep (1.8.2) experimental; urgency=low 8 | 9 | * sngrep 1.8.2 released 10 | 11 | -- Ivan Alonso Mon, 08 Jul 2024 09:27:47 +0200 12 | 13 | sngrep (1.8.1) experimental; urgency=low 14 | 15 | * sngrep 1.8.1 released 16 | 17 | -- Ivan Alonso Mon, 08 Apr 2024 10:55:20 +0200 18 | 19 | sngrep (1.8.0) experimental; urgency=low 20 | 21 | * sngrep 1.8.0 released 22 | 23 | -- Ivan Alonso Wed, 20 Dec 2023 10:34:52 +0100 24 | 25 | sngrep (1.7.0) experimental; urgency=low 26 | 27 | * sngrep 1.7.0 released 28 | 29 | -- Ivan Alonso Fri, 31 Mar 2023 09:55:37 +0200 30 | 31 | sngrep (1.6.0) experimental; urgency=low 32 | 33 | * sngrep 1.6.0 released 34 | 35 | -- Ivan Alonso Wed, 31 Aug 2022 11:56:30 +0200 36 | 37 | sngrep (1.5.0) experimental; urgency=low 38 | 39 | * sngrep 1.5.0 released 40 | 41 | -- Ivan Alonso Tue, 26 Apr 2022 15:57:37 +0200 42 | 43 | sngrep (1.4.10) experimental; urgency=low 44 | 45 | * sngrep 1.4.10 released 46 | 47 | -- Ivan Alonso Fri, 19 Nov 2021 11:00:24 +0100 48 | 49 | sngrep (1.4.9) experimental; urgency=low 50 | 51 | * sngrep 1.4.9 released 52 | 53 | -- Ivan Alonso Thu, 20 May 2021 09:02:43 +0200 54 | 55 | sngrep (1.4.8) experimental; urgency=low 56 | 57 | * sngrep 1.4.8 released 58 | 59 | -- Ivan Alonso Tue, 10 Oct 2020 10:46:10 +0200 60 | 61 | sngrep (1.4.7) experimental; urgency=low 62 | 63 | * sngrep 1.4.7 released 64 | 65 | -- Ivan Alonso Thu, 21 May 2020 11:46:22 +0200 66 | 67 | sngrep (1.4.6) experimental; urgency=low 68 | 69 | * sngrep 1.4.6 released 70 | 71 | -- Ivan Alonso Wed, 31 Oct 2018 17:19:27 +0100 72 | 73 | sngrep (1.4.5) experimental; urgency=low 74 | 75 | * sngrep 1.4.5 released 76 | 77 | -- Ivan Alonso Fri, 22 Dec 2017 15:13:54 +0100 78 | 79 | sngrep (1.4.4) experimental; urgency=low 80 | 81 | * sngrep 1.4.4 releaed 82 | 83 | -- Ivan Alonso Sun, 17 Sep 2017 10:51:57 +0200 84 | 85 | sngrep (1.4.3) experimental; urgency=low 86 | 87 | * sngrep 1.4.3 releaed 88 | 89 | -- Ivan Alonso Wed, 10 May 2017 16:44:47 +0200 90 | 91 | sngrep (1.4.2) experimental; urgency=low 92 | 93 | * sngrep 1.4.2 released 94 | 95 | -- Ivan Alonso Mon, 19 Dec 2016 14:00:26 +0100 96 | 97 | sngrep (1.4.1) experimental; urgency=low 98 | 99 | * sngrep 1.4.1 released 100 | 101 | -- Ivan Alonso Fri, 28 Oct 2016 11:24:14 +0200 102 | 103 | sngrep (1.4.0) experimental; urgency=low 104 | 105 | * sngrep 1.4.0 released 106 | 107 | -- Ivan Alonso Mon, 08 Aug 2016 10:57:07 +0200 108 | 109 | sngrep (1.3.1) experimental; urgency=low 110 | 111 | * sngrep 1.3.1 released 112 | 113 | -- Ivan Alonso Thu, 28 Apr 2016 11:45:00 +0100 114 | 115 | sngrep (1.3.0) experimental; urgency=low 116 | 117 | * sngrep 1.3.0 released 118 | 119 | -- Ivan Alonso Tue, 15 Mar 2016 13:14:00 +0100 120 | 121 | sngrep (1.2.0) experimental; urgency=low 122 | 123 | * sngrep 1.2.0 released 124 | 125 | -- Ivan Alonso Thu, 10 Dec 2015 13:41:00 +0100 126 | 127 | sngrep (1.1.0) experimental; urgency=low 128 | 129 | * sngrep 1.1.0 released 130 | 131 | -- Ivan Alonso Tue, 27 Oct 2015 16:01:00 +0100 132 | 133 | sngrep (1.0.0) experimental; urgency=low 134 | 135 | * sngrep 1.3.0 released 136 | 137 | -- Ivan Alonso Tue, 06 Oct 2015 19:13:00 +0100 138 | 139 | sngrep (0.4.2) experimental; urgency=low 140 | 141 | * sngrep 0.4.2 released 142 | 143 | -- Ivan Alonso Mon, 31 Aug 2015 11:21:00 +0100 144 | 145 | sngrep (0.4.1) experimental; urgency=low 146 | 147 | * sngrep 0.4.1 released 148 | 149 | -- Ivan Alonso Fri, 10 Jul 2015 10:31:00 +0100 150 | 151 | sngrep (0.4.0) experimental; urgency=low 152 | 153 | * sngrep 0.4.0 released 154 | 155 | -- Ivan Alonso Fri, 29 Jun 2015 15:18:00 +0100 156 | 157 | sngrep (0.3.2) experimental; urgency=low 158 | 159 | * sngrep 0.3.2 released 160 | 161 | -- Ivan Alonso Fri, 29 May 2015 13:18:00 +0100 162 | 163 | sngrep (0.3.1) experimental; urgency=low 164 | 165 | * sngrep 0.3.1 released 166 | 167 | -- Ivan Alonso Tue, 14 Apr 2015 19:22:00 +0100 168 | 169 | sngrep (0.3.0) experimental; urgency=low 170 | 171 | * sngrep 0.3.0 released 172 | 173 | -- Ivan Alonso Wed, 04 Mar 2015 13:09:00 +0100 174 | 175 | sngrep (0.2.2) experimental; urgency=low 176 | 177 | * sngrep 0.2.2 released 178 | 179 | -- Ivan Alonso Fri, 06 Feb 2015 17:54:24 +0100 180 | 181 | sngrep (0.2.1) experimental; urgency=low 182 | 183 | * sngrep 0.2.1 released 184 | 185 | -- Ivan Alonso Thu, 22 Jan 2015 13:14:24 +0100 186 | 187 | sngrep (0.2.0) experimental; urgency=low 188 | 189 | * sngrep 0.2.0 released 190 | 191 | -- Ivan Alonso Thu, 4 Dec 2014 20:39:04 +0100 192 | 193 | sngrep (0.1.0) experimental; urgency=low 194 | 195 | * sngrep 0.1.0 released 196 | 197 | -- Ivan Alonso Sun, 21 Oct 2014 14:35:00 +0100 198 | 199 | sngrep (0.0.1) experimental; urgency=low 200 | 201 | * sngrep 0.0.1 released 202 | 203 | -- Ivan Alonso Wed, 1 Oct 2014 20:39:04 +0100 204 | 205 | -------------------------------------------------------------------------------- /src/sip_msg.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file sip_msg.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage SIP call data 27 | * 28 | * This file contains the functions and structure to manage SIP message data 29 | * 30 | */ 31 | #include "sip_msg.h" 32 | #include "media.h" 33 | #include "sip.h" 34 | 35 | sip_msg_t * 36 | msg_create() 37 | { 38 | sip_msg_t *msg; 39 | if (!(msg = sng_malloc(sizeof(sip_msg_t)))) 40 | return NULL; 41 | return msg; 42 | } 43 | 44 | void 45 | msg_destroy(sip_msg_t *msg) 46 | { 47 | // Free message SDP media 48 | if (!msg->retrans) 49 | vector_destroy(msg->medias); 50 | 51 | // Free message packets 52 | packet_destroy(msg->packet); 53 | // Free all memory 54 | sng_free(msg->resp_str); 55 | sng_free(msg->sip_from); 56 | sng_free(msg->sip_to); 57 | sng_free(msg); 58 | } 59 | 60 | void 61 | msg_destroyer(void *msg) 62 | { 63 | msg_destroy((sip_msg_t *)msg); 64 | } 65 | 66 | struct sip_call * 67 | msg_get_call(const sip_msg_t *msg) { 68 | return msg->call; 69 | } 70 | 71 | int 72 | msg_media_count(sip_msg_t *msg) 73 | { 74 | return vector_count(msg->medias); 75 | } 76 | 77 | int 78 | msg_has_sdp(void *item) 79 | { 80 | return vector_count(((sip_msg_t *)item)->medias) ? 1 : 0; 81 | } 82 | 83 | int 84 | msg_is_request(sip_msg_t *msg) 85 | { 86 | return msg->reqresp < 100; 87 | } 88 | 89 | void 90 | msg_add_media(sip_msg_t *msg, sdp_media_t *media) 91 | { 92 | if (!msg->medias) { 93 | // Create a vector to store sdp 94 | msg->medias = vector_create(2, 2); 95 | vector_set_destroyer(msg->medias, media_destroyer); 96 | } 97 | vector_append(msg->medias, media); 98 | } 99 | 100 | const char * 101 | msg_get_payload(sip_msg_t *msg) 102 | { 103 | return (const char *) packet_payload(msg->packet); 104 | } 105 | 106 | struct timeval 107 | msg_get_time(sip_msg_t *msg) { 108 | struct timeval t = { }; 109 | frame_t *frame; 110 | 111 | if (msg && (frame = vector_first(msg->packet->frames))) { 112 | t.tv_sec = frame->header->ts.tv_sec; 113 | t.tv_usec = frame->header->ts.tv_usec; 114 | } 115 | return t; 116 | } 117 | 118 | const char * 119 | msg_get_attribute(sip_msg_t *msg, int id, char *value) 120 | { 121 | char *ar; 122 | 123 | switch (id) { 124 | case SIP_ATTR_SRC: 125 | if (msg->packet->ip_version == 6) { 126 | sprintf(value, "[%s]:%u", msg->packet->src.ip, msg->packet->src.port); 127 | } else { 128 | sprintf(value, "%s:%u", msg->packet->src.ip, msg->packet->src.port); 129 | } 130 | break; 131 | case SIP_ATTR_DST: 132 | if (msg->packet->ip_version == 6) { 133 | sprintf(value, "[%s]:%u", msg->packet->dst.ip, msg->packet->dst.port); 134 | } else { 135 | sprintf(value, "%s:%u", msg->packet->dst.ip, msg->packet->dst.port); 136 | } 137 | break; 138 | case SIP_ATTR_METHOD: 139 | sprintf(value, "%.*s", SIP_ATTR_MAXLEN, sip_get_msg_reqresp_str(msg)); 140 | break; 141 | case SIP_ATTR_SIPFROM: 142 | sprintf(value, "%.*s", SIP_ATTR_MAXLEN, msg->sip_from); 143 | break; 144 | case SIP_ATTR_SIPTO: 145 | sprintf(value, "%.*s", SIP_ATTR_MAXLEN, msg->sip_to); 146 | break; 147 | case SIP_ATTR_SIPFROMUSER: 148 | if (msg->sip_from && (ar = strchr(msg->sip_from, '@'))) { 149 | sng_strncpy(value, msg->sip_from, ar - msg->sip_from); 150 | } 151 | break; 152 | case SIP_ATTR_SIPTOUSER: 153 | if (msg->sip_to && (ar = strchr(msg->sip_to, '@'))) { 154 | sng_strncpy(value, msg->sip_to, ar - msg->sip_to); 155 | } 156 | break; 157 | case SIP_ATTR_DATE: 158 | timeval_to_date(msg_get_time(msg), value); 159 | break; 160 | case SIP_ATTR_TIME: 161 | timeval_to_time(msg_get_time(msg), value); 162 | break; 163 | default: 164 | fprintf(stderr, "Unhandled attribute %s (%d)\n", sip_attr_get_name(id), id); abort(); 165 | break; 166 | } 167 | 168 | return strlen(value) ? value : NULL; 169 | 170 | } 171 | 172 | int 173 | msg_is_older(sip_msg_t *one, sip_msg_t *two) 174 | { 175 | // Yes, you are older than nothing 176 | if (!two) 177 | return 1; 178 | 179 | // No, you are not older than yourself 180 | if (one == two) 181 | return 0; 182 | 183 | // Otherwise 184 | return timeval_is_older(msg_get_time(one), msg_get_time(two)); 185 | } 186 | -------------------------------------------------------------------------------- /src/sip_msg.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file sip_msg.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage sip messages 27 | * 28 | */ 29 | #ifndef __SNGREP_SIP_MSG_H 30 | #define __SNGREP_SIP_MSG_H 31 | 32 | #include "config.h" 33 | #include 34 | #include "vector.h" 35 | #include "media.h" 36 | #include "sip_attr.h" 37 | #include "util.h" 38 | 39 | //! Shorter declaration of sip_msg structure 40 | typedef struct sip_msg sip_msg_t; 41 | 42 | /** 43 | * @brief Information of a single message withing a dialog. 44 | * 45 | * Most of the data is just stored to be displayed in the UI so 46 | * the formats may be no the best, but the simplest for this 47 | * purpose. It also works as a linked lists of messages in a 48 | * call. 49 | */ 50 | struct sip_call; 51 | 52 | struct sip_msg { 53 | //! Request Method or Response Code @see sip_methods 54 | int reqresp; 55 | //! Response text if it doesn't matches an standard 56 | char *resp_str; 57 | //! Message Cseq 58 | uint32_t cseq; 59 | //! SIP From Header 60 | char *sip_from; 61 | //! SIP To Header 62 | char *sip_to; 63 | //! SDP payload information (sdp_media_t *) 64 | vector_t *medias; 65 | //! Captured packet for this message 66 | packet_t *packet; 67 | //! Index of this message in call 68 | uint32_t index; 69 | //! Message owner 70 | struct sip_call *call; 71 | //! Message is a retransmission from other message 72 | sip_msg_t *retrans; 73 | }; 74 | 75 | 76 | /** 77 | * @brief Create a new message from the readed header and payload 78 | * 79 | * Allocate required memory for a new SIP message. This function 80 | * will only store the given information, but wont parse it until 81 | * needed. 82 | * 83 | * @param payload Raw payload content 84 | * @return a new allocated message 85 | */ 86 | sip_msg_t * 87 | msg_create(); 88 | 89 | /** 90 | * @brief Destroy a SIP message and free its memory 91 | * 92 | * Deallocate memory of an existing SIP Message. 93 | * This function will remove the message from the call and the 94 | * passed pointer will be NULL. 95 | * 96 | * @param nsg SIP message to be deleted 97 | */ 98 | void 99 | msg_destroy(sip_msg_t *msg); 100 | 101 | /** 102 | * @brief Wrapper around Message destroyer to clear msg vectors 103 | */ 104 | void 105 | msg_destroyer(void *msg); 106 | 107 | /** 108 | * @brief Return the call owner of this message 109 | */ 110 | struct sip_call * 111 | msg_get_call(const sip_msg_t *msg); 112 | 113 | /** 114 | * @brief Getter for media of given messages 115 | * 116 | * Return the number of media structures of given msg 117 | * stored in this call. 118 | * 119 | * @param msg SIP message structure 120 | * @return how many media structures are in the msg 121 | */ 122 | int 123 | msg_media_count(sip_msg_t *msg); 124 | 125 | /** 126 | * @brief Check if given message has spd content 127 | */ 128 | int 129 | msg_has_sdp(void *item); 130 | 131 | /** 132 | * @brief Add a media structure to a msg 133 | * 134 | * @param cmsg SIP Message to be updated 135 | * @param media Media structure to be added 136 | */ 137 | void 138 | msg_add_media(sip_msg_t *msg, sdp_media_t *media); 139 | 140 | /** 141 | * @brief Check if a message is a Request or response 142 | * 143 | * @param msg SIP message that will be checked 144 | * @return 1 if the message is a request, 0 if a response 145 | */ 146 | int 147 | msg_is_request(sip_msg_t *msg); 148 | 149 | /** 150 | * @brief Add a new media for given message 151 | * 152 | * A SIP message can have multiple media description in 153 | * the SIP payload content 154 | * 155 | * @param msg SIP message that will store this packet 156 | * @param media parsed media structure from payload 157 | */ 158 | void 159 | msg_add_media(sip_msg_t *msg, sdp_media_t *media); 160 | 161 | /** 162 | * @brief Get SIP Message payload 163 | */ 164 | const char * 165 | msg_get_payload(sip_msg_t *msg); 166 | 167 | /** 168 | * @brief Get Time of message from packet header 169 | * 170 | * @param msg SIP message 171 | * @return timeval structure with message first packet time 172 | */ 173 | struct timeval 174 | msg_get_time(sip_msg_t *msg); 175 | 176 | /** 177 | * @brief Return a message attribute value 178 | * 179 | * This function will be used to avoid accessing call structure 180 | * fields directly. 181 | * 182 | * @param msg SIP message structure 183 | * @param id Attribute id 184 | * @param out Buffer to store attribute value 185 | * @return Attribute value or NULL if not found 186 | */ 187 | const char * 188 | msg_get_attribute(struct sip_msg *msg, int id, char *value); 189 | 190 | /** 191 | * @brief Check if a message is older than other 192 | * 193 | * @param one SIP message pointer 194 | * @param two SIP message pointer 195 | * @return 1 if one is older than two 196 | * @return 0 if equal or two is older than one 197 | */ 198 | int 199 | msg_is_older(sip_msg_t *one, sip_msg_t *two); 200 | 201 | 202 | #endif /* __SNGREP_SIP_MSG_H */ 203 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file util.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in util.h 27 | * 28 | */ 29 | #include "config.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "util.h" 37 | 38 | #if __STDC_VERSION__ >= 201112L && __STDC_NO_ATOMICS__ != 1 39 | // modern C with atomics 40 | #include 41 | typedef atomic_int signal_flag_type; 42 | #else 43 | // no atomics available 44 | typedef volatile sig_atomic_t signal_flag_type; 45 | #endif 46 | 47 | static signal_flag_type sigterm_received = 0; 48 | 49 | static void sigterm_handler(int signum) 50 | { 51 | sigterm_received = 1; 52 | } 53 | 54 | void setup_sigterm_handler(void) 55 | { 56 | // set up SIGTERM handler (also used for SIGINT and SIGQUIT) 57 | // the handler will be served by any of the running threads 58 | // so we just set a flag and check it in one of the two available 59 | // main loops of the program (main for --no-interface and 60 | // ui_wait_for_input() for curses) 61 | 62 | if (signal(SIGTERM, sigterm_handler) == SIG_ERR) 63 | exit(EXIT_FAILURE); 64 | if (signal(SIGINT, sigterm_handler) == SIG_ERR) 65 | exit(EXIT_FAILURE); 66 | if (signal(SIGQUIT, sigterm_handler) == SIG_ERR) 67 | exit(EXIT_FAILURE); 68 | 69 | // Handle SIGHUP signal, received when our controlling terminal is closed. 70 | // This prevents running on dead ssh connections. 71 | if (signal(SIGHUP, sigterm_handler) == SIG_ERR) 72 | exit(EXIT_FAILURE); 73 | } 74 | 75 | bool was_sigterm_received(void) 76 | { 77 | return (sigterm_received == 1); 78 | } 79 | 80 | void * 81 | sng_malloc(size_t size) 82 | { 83 | void *data; 84 | 85 | // Check memory allocation size 86 | if (size <= 0 || size > MALLOC_MAX_SIZE) 87 | return NULL; 88 | 89 | // Allocate memory 90 | if (!(data = malloc(size))) 91 | return NULL; 92 | 93 | // Initialize allocated memory 94 | memset(data, 0, size); 95 | return data; 96 | } 97 | 98 | void 99 | sng_free(void *ptr) 100 | { 101 | if (ptr) 102 | free(ptr); 103 | } 104 | 105 | char * 106 | sng_basename(const char *name) 107 | { 108 | const char *base = name; 109 | 110 | while (*name) 111 | { 112 | if (*name++ == '/') { 113 | base = name; 114 | } 115 | } 116 | return (char *) base; 117 | } 118 | 119 | char * 120 | sng_strncpy(char *dst, const char *src, size_t len) 121 | { 122 | if (dst == NULL || src == NULL) { 123 | return NULL; 124 | } 125 | strncpy(dst, src, len-1); 126 | dst[len-1] = '\0'; 127 | return dst; 128 | } 129 | 130 | int 131 | timeval_is_older(struct timeval t1, struct timeval t2) 132 | { 133 | long long int t1sec, t2sec; 134 | t1sec = t1.tv_sec; 135 | t1sec = t1sec * 1000000; 136 | t2sec = t2.tv_sec; 137 | t2sec = t2sec * 1000000; 138 | return ((t2sec + t2.tv_usec) - (t1sec + t1.tv_usec) <= 0); 139 | } 140 | 141 | const char * 142 | timeval_to_date(struct timeval time, char *out) 143 | { 144 | time_t t = (time_t) time.tv_sec; 145 | struct tm *timestamp = localtime(&t); 146 | strftime(out, 11, "%Y/%m/%d", timestamp); 147 | return out; 148 | } 149 | 150 | 151 | const char * 152 | timeval_to_time(struct timeval time, char *out) 153 | { 154 | time_t t = (time_t) time.tv_sec; 155 | struct tm *timestamp = localtime(&t); 156 | strftime(out, 19, "%H:%M:%S", timestamp); 157 | sprintf(out + 8, ".%06d", (int) time.tv_usec); 158 | return out; 159 | } 160 | 161 | const char * 162 | timeval_to_duration(struct timeval start, struct timeval end, char *out) 163 | { 164 | int seconds; 165 | char duration[20]; 166 | 167 | if (!out || !start.tv_sec || !end.tv_sec) 168 | return NULL; 169 | 170 | // Differnce in secons 171 | seconds = end.tv_sec - start.tv_sec; 172 | // Set Human readable format 173 | sprintf(duration, "%d:%02d", seconds / 60, seconds % 60); 174 | sprintf(out, "%7s", duration); 175 | return out; 176 | } 177 | 178 | const char * 179 | timeval_to_delta(struct timeval start, struct timeval end, char *out) 180 | { 181 | long diff; 182 | int nsec, nusec; 183 | int sign; 184 | 185 | if (!out || !start.tv_sec || !end.tv_sec) 186 | return NULL; 187 | 188 | diff = end.tv_sec * 1000000 + end.tv_usec; 189 | diff -= start.tv_sec * 1000000 + start.tv_usec; 190 | 191 | nsec = diff / 1000000; 192 | nusec = labs(diff - (nsec * 1000000)); 193 | 194 | sign = (diff >= 0) ? '+' : '-'; 195 | 196 | sprintf(out, "%c%d.%06d", sign, abs(nsec), nusec); 197 | return out; 198 | } 199 | char * 200 | strtrim(char *str) 201 | { 202 | int i; 203 | 204 | if (!str || !strlen(str)) 205 | return str; 206 | 207 | for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); i--) 208 | str[i] = 0; 209 | 210 | return str; 211 | } 212 | -------------------------------------------------------------------------------- /src/curses/ui_column_select.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_column_select.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage columns select panel 27 | */ 28 | 29 | #ifndef __UI_COLUMN_SELECT_H 30 | #define __UI_COLUMN_SELECT_H 31 | 32 | #include "config.h" 33 | #include 34 | #include 35 | #include "ui_manager.h" 36 | #include "scrollbar.h" 37 | #include "sip_attr.h" 38 | 39 | /** 40 | * @brief Enum of available fields 41 | */ 42 | enum column_select_field_list { 43 | FLD_COLUMNS_ACCEPT = 0, 44 | FLD_COLUMNS_SAVE, 45 | FLD_COLUMNS_CANCEL, 46 | //! Never remove this field id 47 | FLD_COLUMNS_COUNT 48 | }; 49 | 50 | 51 | //! Sorter declaration of struct columns_select_info 52 | typedef struct column_select_info column_select_info_t; 53 | 54 | /** 55 | * @brief Column selector panel private information 56 | * 57 | * This structure contains the durable data of column selection panel. 58 | */ 59 | struct column_select_info { 60 | // Section of panel where menu is being displayed 61 | WINDOW *menu_win; 62 | // Columns menu 63 | MENU *menu; 64 | // Columns Items 65 | ITEM *items[SIP_ATTR_COUNT + 1]; 66 | //! Form that contains the save fields 67 | FORM *form; 68 | //! An array of window form fields 69 | FIELD *fields[FLD_COLUMNS_COUNT + 1]; 70 | //! Flag to handle key inputs 71 | int form_active; 72 | //! Scrollbar for the menu window 73 | scrollbar_t scroll; 74 | }; 75 | 76 | /** 77 | * @brief Creates a new column selection panel 78 | * 79 | * This function allocates all required memory for 80 | * displaying the column selection panel. It also draws all the 81 | * static information of the panel that will never be 82 | * redrawn. 83 | * 84 | * @param ui UI structure pointer 85 | */ 86 | void 87 | column_select_create(ui_t *ui); 88 | 89 | /** 90 | * @brief Destroy column selection panel 91 | * 92 | * This function do the final cleanups for this panel 93 | * 94 | * @param ui UI structure pointer 95 | */ 96 | void 97 | column_select_destroy(ui_t *ui); 98 | 99 | /** 100 | * @brief Get custom information of given panel 101 | * 102 | * Return ncurses users pointer of the given panel into panel's 103 | * information structure pointer. 104 | * 105 | * @param ui UI structure pointer 106 | * @return a pointer to info structure of given panel 107 | */ 108 | column_select_info_t * 109 | column_select_info(ui_t *ui); 110 | 111 | /** 112 | * @brief Manage pressed keys for column selection panel 113 | * 114 | * This function is called by UI manager every time a 115 | * key is pressed. This allow the filter panel to manage 116 | * its own keys. 117 | * 118 | * @param ui UI structure pointer 119 | * @param key key code 120 | * @return enum @key_handler_ret 121 | */ 122 | int 123 | column_select_handle_key(ui_t *ui, int key); 124 | 125 | /** 126 | * @brief Manage pressed keys for column selection panel 127 | * 128 | * This function will handle keys when menu is active. 129 | * You can switch between menu and rest of the components 130 | * using TAB 131 | * 132 | * @param ui UI structure pointer 133 | * @param key key code 134 | * @return enum @key_handler_ret 135 | */ 136 | int 137 | column_select_handle_key_menu(ui_t *ui, int key); 138 | 139 | /** 140 | * @brief Manage pressed keys for column selection panel 141 | * 142 | * This function will handle keys when form is active. 143 | * You can switch between menu and rest of the components 144 | * using TAB 145 | * 146 | * @param ui UI structure pointer 147 | * @param key key code 148 | * @return enum @key_handler_ret 149 | */ 150 | int 151 | column_select_handle_key_form(ui_t *ui, int key); 152 | 153 | /** 154 | * @brief Update Call List columns 155 | * 156 | * This function will update the columns of Call List 157 | * 158 | * @param ui UI structure pointer 159 | */ 160 | void 161 | column_select_update_columns(ui_t *ui); 162 | 163 | /** 164 | * @brief Save selected columns to user config file 165 | * 166 | * Remove previously configurated columns from user's 167 | * $SNGREPRC or $HOME/.sngreprc and add new ones 168 | * 169 | * @param ui UI structure pointer 170 | */ 171 | void 172 | column_select_save_columns(ui_t *ui); 173 | 174 | /** 175 | * @brief Move a item to a new position 176 | * 177 | * This function can be used to reorder the column list 178 | * 179 | * @param ui UI structure pointer 180 | * @param item Menu item to be moved 181 | * @param post New position in the menu 182 | */ 183 | void 184 | column_select_move_item(ui_t *ui, ITEM *item, int pos); 185 | 186 | /** 187 | * @brief Select/Deselect a menu item 188 | * 189 | * This function can be used to toggle selection status of 190 | * the menu item 191 | * 192 | * @param ui UI structure pointer 193 | * @param item Menu item to be (de)selected 194 | */ 195 | void 196 | column_select_toggle_item(ui_t *ui, ITEM *item); 197 | 198 | /** 199 | * @brief Update menu after a change 200 | * 201 | * After moving an item or updating its selectioactivn status 202 | * menu must be redrawn. 203 | * 204 | * @param ui UI structure pointer 205 | */ 206 | void 207 | column_select_update_menu(ui_t *ui); 208 | 209 | #endif /* __UI_COLUMN_SELECT_H */ 210 | -------------------------------------------------------------------------------- /src/curses/ui_save.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_save_pcap.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage ui window for saving captured packages 27 | * 28 | * This file contains the functions and structures to manage the save 29 | * dialog, that can be used to copy the temporal sngrep file to another location 30 | * 31 | */ 32 | 33 | #ifndef __UI_SAVE_PCAP_H 34 | #define __UI_SAVE_PCAP_H 35 | #include "config.h" 36 | #include 37 | #include "group.h" 38 | #include "ui_manager.h" 39 | 40 | /** 41 | * @brief Enum of available dialog fields 42 | * 43 | * Dialog form has a field array. Following enum represents the 44 | * order this fields are stored in panel info structure. 45 | */ 46 | enum save_field_list { 47 | FLD_SAVE_PATH = 0, 48 | FLD_SAVE_FILE, 49 | FLD_SAVE_ALL, 50 | FLD_SAVE_SELECTED, 51 | FLD_SAVE_DISPLAYED, 52 | FLD_SAVE_MESSAGE, 53 | FLD_SAVE_PCAP, 54 | FLD_SAVE_PCAP_RTP, 55 | FLD_SAVE_TXT, 56 | FLD_SAVE_SAVE, 57 | FLD_SAVE_CANCEL, 58 | FLD_SAVE_COUNT 59 | }; 60 | 61 | /** 62 | * @brief Dialogs to be saved 63 | */ 64 | enum save_mode { 65 | SAVE_ALL = 0, 66 | SAVE_SELECTED, 67 | SAVE_DISPLAYED, 68 | SAVE_MESSAGE 69 | }; 70 | 71 | /** 72 | * @brief Save file formats 73 | */ 74 | enum save_format { 75 | SAVE_PCAP = 0, 76 | SAVE_PCAP_RTP, 77 | SAVE_TXT 78 | }; 79 | 80 | //! Sorter declaration of struct save_info 81 | typedef struct save_info save_info_t; 82 | 83 | /** 84 | * @brief Save panel private information 85 | * 86 | * This structure contains the durable data of save panel. 87 | */ 88 | struct save_info { 89 | //! Form that contains the save fields 90 | FORM *form; 91 | //! An array of fields 92 | FIELD *fields[FLD_SAVE_COUNT + 1]; 93 | //! Save mode @see save_modes 94 | enum save_mode savemode; 95 | //! Save format @see save_formats 96 | enum save_format saveformat; 97 | //! Call group to be saved 98 | sip_call_group_t *group; 99 | //! Message to be saved 100 | sip_msg_t *msg; 101 | }; 102 | 103 | /** 104 | * @brief Creates a new save panel 105 | * 106 | * This function allocates all required memory for 107 | * displaying the save panel. It also draws all the 108 | * static information of the panel that will never be 109 | * redrawn. 110 | * 111 | * @param ui UI structure pointer 112 | */ 113 | void 114 | save_create(ui_t *ui); 115 | 116 | /** 117 | * @brief Destroy save panel 118 | * 119 | * This function do the final cleanups for this panel 120 | * 121 | * @param ui UI structure pointer 122 | */ 123 | void 124 | save_destroy(ui_t *ui); 125 | 126 | /** 127 | * @brief Get custom information of given panel 128 | * 129 | * Return ncurses users pointer of the given panel into panel's 130 | * information structure pointer. 131 | * 132 | * @param ui UI structure pointer 133 | * @return a pointer to info structure of given panel 134 | */ 135 | save_info_t * 136 | save_info(ui_t *ui); 137 | 138 | /** 139 | * @brief Draw the Save panel 140 | * 141 | * This function will drawn the panel into the screen based on its stored 142 | * status 143 | * 144 | * @param ui UI structure pointer 145 | * @return 0 if the panel has been drawn, -1 otherwise 146 | */ 147 | int 148 | save_draw(ui_t *ui); 149 | 150 | /** 151 | * @brief Manage pressed keys for save panel 152 | * 153 | * This function is called by UI manager every time a 154 | * key is pressed. This allow the save panel to manage 155 | * its own keys. 156 | * 157 | * @param ui UI structure pointer 158 | * @param key key code 159 | * @return enum @key_handler_ret 160 | */ 161 | int 162 | save_handle_key(ui_t *ui, int key); 163 | 164 | /** 165 | * @brief Set the group call of the panel 166 | * 167 | * This function will access the panel information and will set the 168 | * group call pointer to the selected calls 169 | * 170 | * @param ui UI structure pointer 171 | * @param group Call group pointer to be set in the internal info struct 172 | */ 173 | void 174 | save_set_group(ui_t *ui, sip_call_group_t *group); 175 | 176 | /** 177 | * @brief Set the SIP message to be saved 178 | * 179 | * This function will access the panel information and will set the 180 | * pointer to the selected SIP message 181 | * 182 | * @param ui UI structure pointer 183 | * @param msg SIP message pointer to be set in the internal info struct 184 | */ 185 | void 186 | save_set_msg(ui_t *ui, sip_msg_t *msg); 187 | 188 | /** 189 | * @brief Print an error message in Save panel 190 | * 191 | * General function to print any save error message 192 | * 193 | * @param ui UI structure pointer 194 | * @param message Message to be printed in the panel 195 | */ 196 | void 197 | save_error_message(ui_t *ui, const char *message); 198 | 199 | /** 200 | * @brief Save form data to options 201 | * 202 | * Save capture packets to a file based on selected modes on screen 203 | * It will display an error or success dialog before exit 204 | * 205 | * @param ui UI structure pointer 206 | * @returns 1 in case of error, 0 otherwise. 207 | */ 208 | int 209 | save_to_file(ui_t *ui); 210 | 211 | /** 212 | * @brief Save one SIP message into open file 213 | * 214 | * @param f File opened with fopen 215 | * @param msg a SIP Message 216 | */ 217 | void 218 | save_msg_txt(FILE *f, sip_msg_t *msg); 219 | 220 | #endif 221 | -------------------------------------------------------------------------------- /src/sip_attr.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file sip_attr.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in sip_attr.h 27 | * 28 | */ 29 | #include "config.h" 30 | #include 31 | #include 32 | #include 33 | #include "option.h" 34 | #include "sip_attr.h" 35 | #include "util.h" 36 | #include "curses/ui_manager.h" 37 | 38 | static sip_attr_hdr_t attrs[SIP_ATTR_COUNT] = { 39 | { SIP_ATTR_CALLINDEX, "index", "Idx", "Call Index", 4 }, 40 | { SIP_ATTR_SIPFROM, "sipfrom", NULL, "SIP From", 25 }, 41 | { SIP_ATTR_SIPFROMUSER, "sipfromuser", NULL, "SIP From User", 20 }, 42 | { SIP_ATTR_SIPTO, "sipto", NULL, "SIP To", 25 }, 43 | { SIP_ATTR_SIPTOUSER, "siptouser", NULL, "SIP To User", 20 }, 44 | { SIP_ATTR_SRC, "src", NULL, "Source", 22 }, 45 | { SIP_ATTR_DST, "dst", NULL, "Destination", 22 }, 46 | { SIP_ATTR_CALLID, "callid", NULL, "Call-ID", 50 }, 47 | { SIP_ATTR_XCALLID, "xcallid", NULL, "X-Call-ID", 50 }, 48 | { SIP_ATTR_DATE, "date", NULL, "Date", 10 }, 49 | { SIP_ATTR_TIME, "time", NULL, "Time", 8 }, 50 | { SIP_ATTR_METHOD, "method", NULL, "Method", 10, sip_attr_color_method }, 51 | { SIP_ATTR_TRANSPORT, "transport", "Trans", "Transport", 3 }, 52 | { SIP_ATTR_MSGCNT, "msgcnt", "Msgs", "Message Count", 5 }, 53 | { SIP_ATTR_CALLSTATE, "state", NULL, "Call State", 10, sip_attr_color_state }, 54 | { SIP_ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", 7 }, 55 | { SIP_ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", 8 }, 56 | { SIP_ATTR_REASON_TXT, "reason", "Reason Text", "Reason Text", 25 }, 57 | { SIP_ATTR_WARNING, "warning", "Warning", "Warning code", 4 } 58 | }; 59 | 60 | sip_attr_hdr_t * 61 | sip_attr_get_header(enum sip_attr_id id) 62 | { 63 | return &attrs[id]; 64 | } 65 | 66 | const char * 67 | sip_attr_get_description(enum sip_attr_id id) 68 | { 69 | sip_attr_hdr_t *header; 70 | if ((header = sip_attr_get_header(id))) { 71 | return header->desc; 72 | } 73 | return NULL; 74 | } 75 | 76 | const char * 77 | sip_attr_get_title(enum sip_attr_id id) 78 | { 79 | sip_attr_hdr_t *header; 80 | if ((header = sip_attr_get_header(id))) { 81 | if (header->title) 82 | return header->title; 83 | return header->desc; 84 | } 85 | return NULL; 86 | } 87 | 88 | const char * 89 | sip_attr_get_name(enum sip_attr_id id) 90 | { 91 | sip_attr_hdr_t *header; 92 | if ((header = sip_attr_get_header(id))) { 93 | return header->name; 94 | } 95 | return NULL; 96 | } 97 | 98 | int 99 | sip_attr_get_width(enum sip_attr_id id) 100 | { 101 | sip_attr_hdr_t *header; 102 | if ((header = sip_attr_get_header(id))) { 103 | return header->dwidth; 104 | } 105 | return 0; 106 | } 107 | 108 | int 109 | sip_attr_from_name(const char *name) 110 | { 111 | int i; 112 | for (i = 0; i < SIP_ATTR_COUNT; i++) { 113 | if (!strcasecmp(name, attrs[i].name)) { 114 | return attrs[i].id; 115 | } 116 | } 117 | return -1; 118 | } 119 | 120 | int 121 | sip_attr_get_color(int id, const char *value) 122 | { 123 | sip_attr_hdr_t *header; 124 | 125 | if (!setting_enabled(SETTING_CL_COLORATTR)) 126 | return 0; 127 | 128 | if ((header = sip_attr_get_header(id))) { 129 | if (header->color) { 130 | return header->color(value); 131 | } 132 | } 133 | return 0; 134 | } 135 | 136 | int 137 | sip_attr_color_method(const char *value) 138 | { 139 | switch (sip_method_from_str(value)) { 140 | case SIP_METHOD_INVITE: 141 | return COLOR_PAIR(CP_RED_ON_DEF) | A_BOLD; 142 | case SIP_METHOD_NOTIFY: 143 | return COLOR_PAIR(CP_YELLOW_ON_DEF); 144 | case SIP_METHOD_OPTIONS: 145 | return COLOR_PAIR(CP_YELLOW_ON_DEF); 146 | case SIP_METHOD_REGISTER: 147 | return COLOR_PAIR(CP_MAGENTA_ON_DEF); 148 | case SIP_METHOD_SUBSCRIBE: 149 | return COLOR_PAIR(CP_BLUE_ON_DEF); 150 | case SIP_METHOD_KDMQ: 151 | return COLOR_PAIR(CP_CYAN_ON_DEF) | A_BOLD; 152 | default: 153 | return 0; 154 | } 155 | } 156 | 157 | int 158 | sip_attr_color_state(const char *value) 159 | { 160 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_CALLSETUP))) 161 | return COLOR_PAIR(CP_YELLOW_ON_DEF); 162 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_INCALL))) 163 | return COLOR_PAIR(CP_BLUE_ON_DEF); 164 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_COMPLETED))) 165 | return COLOR_PAIR(CP_GREEN_ON_DEF); 166 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_CANCELLED))) 167 | return COLOR_PAIR(CP_RED_ON_DEF); 168 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_REJECTED))) 169 | return COLOR_PAIR(CP_RED_ON_DEF); 170 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_BUSY))) 171 | return COLOR_PAIR(CP_MAGENTA_ON_DEF); 172 | if (!strcmp(value, call_state_to_str(SIP_CALLSTATE_DIVERTED))) 173 | return COLOR_PAIR(CP_CYAN_ON_DEF); 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /src/sip_attr.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file sip_attr.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage SIP calls and messages attributes 27 | */ 28 | 29 | #ifndef __SNGREP_SIP_ATTR_H 30 | #define __SNGREP_SIP_ATTR_H 31 | 32 | #include "config.h" 33 | #include "vector.h" 34 | 35 | //! Max attribute length 36 | #define SIP_ATTR_MAXLEN 255 37 | 38 | //! Shorter declaration of sip_attr_hdr structure 39 | typedef struct sip_attr_hdr sip_attr_hdr_t; 40 | //! Shorter declaration of sip_attr structure 41 | typedef struct sip_attr sip_attr_t; 42 | 43 | /** 44 | * @brief Available SIP Attributes 45 | * 46 | * This enum contains the list of available attributes 47 | * a call or message can have. 48 | */ 49 | enum sip_attr_id { 50 | //! Call index in the Call List 51 | SIP_ATTR_CALLINDEX = 0, 52 | //! SIP Message From: header 53 | SIP_ATTR_SIPFROM, 54 | //! SIP Message User of From: header 55 | SIP_ATTR_SIPFROMUSER, 56 | //! SIP Message To: header 57 | SIP_ATTR_SIPTO, 58 | //! SIP Message User of To: header 59 | SIP_ATTR_SIPTOUSER, 60 | //! Package IP source address and port 61 | SIP_ATTR_SRC, 62 | //! Package IP destination address and port 63 | SIP_ATTR_DST, 64 | //! SIP Message Call-ID header 65 | SIP_ATTR_CALLID, 66 | //! SIP Message X-Call-ID or X-CID header 67 | SIP_ATTR_XCALLID, 68 | //! SIP Message Date 69 | SIP_ATTR_DATE, 70 | //! SIP Message Time 71 | SIP_ATTR_TIME, 72 | //! SIP Message Method or Response code 73 | SIP_ATTR_METHOD, 74 | //! SIP Message transport 75 | SIP_ATTR_TRANSPORT, 76 | //! SIP Call message counter 77 | SIP_ATTR_MSGCNT, 78 | //! SIP Call state 79 | SIP_ATTR_CALLSTATE, 80 | //! Conversation duration 81 | SIP_ATTR_CONVDUR, 82 | //! Total call duration 83 | SIP_ATTR_TOTALDUR, 84 | //! Text from SIP Reason header 85 | SIP_ATTR_REASON_TXT, 86 | //! Warning Header 87 | SIP_ATTR_WARNING, 88 | //! SIP Attribute count 89 | SIP_ATTR_COUNT 90 | }; 91 | 92 | /** 93 | * @brief Attribute header data 94 | * 95 | * This sctructure contains the information about the 96 | * attribute, description, id, type and so. It's the 97 | * static information of the attributed shared by all 98 | * attributes pointer to its type. 99 | * 100 | */ 101 | struct sip_attr_hdr { 102 | //! Attribute id 103 | enum sip_attr_id id; 104 | //! Attribute name 105 | char *name; 106 | //! Attribute column title 107 | char *title; 108 | //! Attribute description 109 | char *desc; 110 | //! Attribute default display width 111 | int dwidth; 112 | //! This function determines the color of this attribute in CallList 113 | int (*color)(const char *value); 114 | }; 115 | 116 | /** 117 | * @brief Attribute storage struct 118 | */ 119 | struct sip_attr { 120 | //! Attribute id 121 | enum sip_attr_id id; 122 | //! Attribute value 123 | char *value; 124 | }; 125 | 126 | /** 127 | * @brief Get the header information of an Attribute 128 | * 129 | * Retrieve header data from attribute list 130 | * 131 | * @param id Attribute id 132 | * @return Attribute header data structure pointer 133 | */ 134 | sip_attr_hdr_t * 135 | sip_attr_get_header(enum sip_attr_id id); 136 | 137 | /** 138 | * @brief Get Attribute description 139 | * 140 | * Retrieve description of given attribute from its 141 | * header structure. 142 | * 143 | * @param id Attribute id 144 | * @return Attribute description from its header 145 | */ 146 | const char * 147 | sip_attr_get_description(enum sip_attr_id id); 148 | 149 | /** 150 | * @brief Get Attribute title 151 | * 152 | * Retrieve title of given attribute from its 153 | * header structure. 154 | * 155 | * @param id Attribute id 156 | * @return Attribute title from its header 157 | */ 158 | const char * 159 | sip_attr_get_title(enum sip_attr_id id); 160 | 161 | /** 162 | * @brief Get Attribute name 163 | * 164 | * Retrieve name of given attribute from its 165 | * header structure. 166 | * 167 | * @param id Attribute id 168 | * @return Attribute name from its header 169 | */ 170 | const char * 171 | sip_attr_get_name(enum sip_attr_id id); 172 | 173 | /** 174 | * @brief Get Attribute prefered display width 175 | * 176 | * @param id Attribute id 177 | * @return prefered attribute width 178 | */ 179 | int 180 | sip_attr_get_width(enum sip_attr_id id); 181 | 182 | /** 183 | * @brief Get Attribute id from its name 184 | * 185 | * Retrieve attribute id of the given attribute name. 186 | * 187 | * @param name Attribut name 188 | * @return Attribute id or -1 if not found 189 | */ 190 | int 191 | sip_attr_from_name(const char *name); 192 | 193 | /** 194 | * @brief Determine the color of the attribute in Call List 195 | * 196 | * Return the color pair to display an attribute in 197 | * call list or -1 if default color must be used. 198 | */ 199 | int 200 | sip_attr_get_color(int id, const char *value); 201 | 202 | /** 203 | * @brief Determine the color of the attribute in Call List 204 | * 205 | * This function can be used to show the Method attribute 206 | * with different colours in Call List. 207 | */ 208 | int 209 | sip_attr_color_method(const char *value); 210 | 211 | /** 212 | * @brief Determine the color of the attribute in Call List 213 | * 214 | * This function can be used to show the state attribute 215 | * with different colours in Call List. 216 | */ 217 | int 218 | sip_attr_color_state(const char *value); 219 | 220 | #endif /* __SNGREP_SIP_ATTR_H */ 221 | -------------------------------------------------------------------------------- /doc/sngrep.8: -------------------------------------------------------------------------------- 1 | .\" Man page for the sngrep 2 | .\" 3 | .\" Copyright (c) 2013-2025 Ivan Alonso 4 | .\" Copyright (c) 2013-2025 Irontec S.L. 5 | 6 | .TH SNGREP 8 "Mar 2025" "sngrep 1.8.3" 7 | 8 | .SH NAME 9 | 10 | sngrep \- SIP Messages flow viewer 11 | 12 | .SH SYNOPSIS 13 | 14 | .B sngrep [-hVcivNqrD] [-IO 15 | .I pcap_dump 16 | .B ] [-d 17 | .I dev 18 | .B ] [-l 19 | .I limit 20 | .B ] [-B 21 | .I buffer 22 | .B ] [-k 23 | .I keyfile 24 | .B ] [-f 25 | .I config_file 26 | .B ] [-F] [-T 27 | .I text_file 28 | .B ] [-t] [-R] [-LHE 29 | .I capture_url 30 | .B ] [ 31 | .I 32 | .B ] [ 33 | .I 34 | .B ] 35 | 36 | .SH DESCRIPTION 37 | sngrep is a terminal tool that groups SIP (Session Initiation Protocol) 38 | Messages by Call-Id, and displays them in arrow flows similar to the used in 39 | SIP RFCs. The aim of this tool is to make easier the process of learning or 40 | debugging SIP. It recognizes UDP, TCP and partially TLS SIP packets and 41 | understands bpf filter logic in the same way 42 | .B ngrep (8) 43 | and 44 | .B tcpdump (1) 45 | does. 46 | 47 | .SH OPTIONS 48 | .TP 49 | .I \-h 50 | Display help and usage information. 51 | 52 | .TP 53 | .I \-V 54 | Display version information. 55 | 56 | .TP 57 | .I \-c 58 | Only display dialogs starting with an INVITE request. 59 | 60 | .TP 61 | .I \-r 62 | Capture RTP packets payload. 63 | 64 | .TP 65 | .I \-i 66 | Make match expression case insensitive. 67 | 68 | .TP 69 | .I \-v 70 | Invert match expression. 71 | 72 | .TP 73 | .I \-I pcap_dump 74 | Read packets from pcap file instead of network devices. This option can be used 75 | with bpf filters. 76 | 77 | .TP 78 | .I \-O pcap_dump 79 | Save all captured packets to a pcap file. This option can be used 80 | with bpf filters. When receiving a SIGUSR1 signal sngrep will reopen 81 | the pcap file in order to facilitate pcap file rotation. 82 | 83 | .TP 84 | .I -B buffer 85 | Set pcap buffer size in MB (default: 2) 86 | 87 | .TP 88 | .I \-d dev 89 | Use this capture device instead of default (\fIany\fP). Special keyword 'any', a device name like 'eth0' or a comma separated list like 'eth1,eth3'. This overrides the settings in the configuration file. 90 | 91 | .TP 92 | .I -k keyfile 93 | RSA private keyfile to decrypt captured packets. 94 | 95 | .TP 96 | .I -l limit 97 | Set capture limit to N dialogs. 98 | Limit must be a numeric value above 1 and can not be disabled. This is both 99 | security measure to avoid unlimited memory usage and also used internally 100 | in sngrep to manage hash table sizes. 101 | 102 | .TP 103 | .I -R 104 | Rotate calls when capture limit has been reached. 105 | Although not recommended, this can be used to keep sngrep running during long 106 | times with some control over consumed memory. 107 | 108 | .TP 109 | .I -N 110 | Don't display sngrep interface, just capture. 111 | 112 | .TP 113 | .I -q 114 | Don't print captured dialogs in no interface mode. 115 | 116 | .TP 117 | .I -H 118 | Homer sipcapture url (udp:X.X.X.X:XXXX). 119 | 120 | .TP 121 | .I -L 122 | Listen for encapsulated packets (udp:X.X.X.X:XXXX). 123 | 124 | .TP 125 | .I -E 126 | Enable parsing of captured HEP3 packets. 127 | 128 | .TP 129 | .I -D 130 | Print active configuration settings and exit. 131 | 132 | .TP 133 | .I -f config_file 134 | Read configuration from file. 135 | 136 | .TP 137 | .I -F 138 | Do not read configuration from default config file. 139 | 140 | .TP 141 | .I -T text_file 142 | Save pcap to text file. 143 | 144 | .TP 145 | .I -t 146 | Capture and parse RTP telephone-event packets. 147 | 148 | .TP 149 | .I match expression 150 | Match given expression in Messages' payload. If one request message matches the 151 | given expression, the following messages within the same dialog will be also 152 | captured. 153 | 154 | .TP 155 | .I bpf filter 156 | Selects a filter that specifies what packets will be parsed. If no 157 | \fIbpf filter\fP is given, all SIP packets seen on the selected 158 | interface or pcap file will be displayed. Otherwise, only packets for which 159 | \fIbpf filter\fP is `true' will be displayed. 160 | 161 | .SH Interface 162 | There are multiple windows to provide different information. Most of the 163 | program windows have a help dialog with a brief description and useful 164 | keybindings. 165 | 166 | .SH " Call List Window" 167 | .PP 168 | The first window that sngrep shows is Call List window and display the 169 | different SIP Call-Ids found in messages. The displayed columns depends on your 170 | terminal width and your custom configuration. You can move between dialogs 171 | with arrow keys and selected them using Spacebar. Selecting multiple dialogs 172 | will display all them in Call flow window and Call Raw window, and will allow 173 | to save only the selected message dialogs to a PCAP file. 174 | 175 | .SH " Call Flow Window" 176 | .PP 177 | This window will a flow diagram of the selected dialogs' messages. The selected 178 | message payload will be displayed in the right side of the window. You can move 179 | between messages using arrow keys and select them using Spacebar. Selecting 180 | multiple messages will display the Message Diff Window. 181 | 182 | .SH " Call Raw Window" 183 | .PP 184 | This window will display the selected dialog messages in plain text. It was 185 | designed to allow copying the messages payload easily. You can also save the 186 | displayed information to a text file from this screen. 187 | 188 | .SH " Column selection Window" 189 | .PP 190 | Columns displayed in Call List can be updated in this window. You can add or 191 | remove columns or change their order in the list. Additionally, you can save 192 | column state to be use in next sngrep execution. 193 | 194 | .SH " Message Diff Window" 195 | .PP 196 | This window will compare two messages. Right now the comparison is done 197 | searching each line in the other message, highlighting those not found exactly. 198 | You can reach this window by selecting two messages using Spacebar in Call Flow 199 | window 200 | 201 | .SH FILES 202 | Full paths below may vary between installations. 203 | 204 | .PP 205 | .I /etc/sngreprc 206 | .IP 207 | System\-wide configuration file. Some sngrep options can be overridden using 208 | this file. 209 | 210 | .PP 211 | .I ~/.sngreprc 212 | .IP 213 | User's configuration file. If this file is present, options will be override 214 | system\-wide configurations. 215 | 216 | .SH BUGS 217 | 218 | Please report bugs to the sngrep github project at 219 | 220 | http://github.com/irontec/sngrep 221 | 222 | Non-bug, non-feature-request general feedback should be sent to the 223 | author directly by email. 224 | 225 | .SH AUTHOR 226 | 227 | Written by Ivan Alonso [a.k.a. Kaian] . 228 | 229 | 230 | -------------------------------------------------------------------------------- /src/curses/ui_panel.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_panel.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source of functions defined in ui_panel.h 27 | */ 28 | 29 | #include "config.h" 30 | #include "ui_panel.h" 31 | #include 32 | #include "theme.h" 33 | 34 | ui_t * 35 | ui_create(ui_t *ui) 36 | { 37 | // If ui has no panel 38 | if (!ui->panel) { 39 | // Create the new panel for this ui 40 | if (ui->create) { 41 | ui->create(ui); 42 | } 43 | } 44 | 45 | // Force screen draw for the first time 46 | ui->changed = true; 47 | 48 | // And return it 49 | return ui; 50 | } 51 | 52 | void 53 | ui_destroy(ui_t *ui) 54 | { 55 | // If there is no ui panel, we're done 56 | if (!ui || !ui->panel) 57 | return; 58 | 59 | // Hide this panel before destroying 60 | hide_panel(ui->panel); 61 | 62 | // If panel has a destructor function use it 63 | if (ui->destroy) { 64 | ui->destroy(ui); 65 | } 66 | 67 | // Initialize panel pointer 68 | ui->panel = NULL; 69 | } 70 | 71 | PANEL * 72 | ui_get_panel(ui_t *ui) 73 | { 74 | // Return panel pointer of ui struct 75 | return (ui) ? ui->panel : NULL; 76 | } 77 | 78 | bool 79 | ui_draw_redraw(ui_t *ui) 80 | { 81 | // Sanity check, this should not happen 82 | if (!ui || !ui->panel) 83 | return false; 84 | 85 | // If ui has changed, force redraw. Don't even ask. 86 | if (ui->changed) { 87 | ui->changed = false; 88 | return true; 89 | } 90 | 91 | // Query the panel if its needs to be redrawn 92 | if (ui->redraw) { 93 | return ui->redraw(ui); 94 | } 95 | return true; 96 | } 97 | 98 | int 99 | ui_draw_panel(ui_t *ui) 100 | { 101 | //! Sanity check, this should not happen 102 | if (!ui || !ui->panel) 103 | return -1; 104 | 105 | // Request the panel to draw on the scren 106 | if (ui->draw) { 107 | return ui->draw(ui); 108 | } else { 109 | touchwin(ui->win); 110 | } 111 | 112 | return 0; 113 | } 114 | 115 | int 116 | ui_resize_panel(ui_t *ui) 117 | { 118 | //! Sanity check, this should not happen 119 | if (!ui) 120 | return -1; 121 | 122 | // Notify the panel screen size has changed 123 | if (ui->resize) { 124 | return ui->resize(ui); 125 | } 126 | 127 | return 0; 128 | } 129 | 130 | void 131 | ui_help(ui_t *ui) 132 | { 133 | // Disable input timeout 134 | nocbreak(); 135 | cbreak(); 136 | 137 | // If current ui has help function 138 | if (ui->help) { 139 | ui->help(ui); 140 | } 141 | } 142 | 143 | int 144 | ui_handle_key(ui_t *ui, int key) 145 | { 146 | int hld = KEY_NOT_HANDLED; 147 | // Request the panel to handle the key 148 | if (ui->handle_key) { 149 | hld = ui->handle_key(ui, key); 150 | } 151 | // Force redraw when the user presses keys 152 | ui->changed = true; 153 | return hld; 154 | } 155 | 156 | 157 | void 158 | ui_panel_create(ui_t *ui, int height, int width) 159 | { 160 | ui->width = width; 161 | ui->height = height; 162 | ui->x = ui->y = 0; 163 | 164 | // If panel doesn't fill the screen center it 165 | if (ui->height != LINES) ui->x = (LINES - height) / 2; 166 | if (ui->width != COLS) ui->y = (COLS - width) / 2; 167 | 168 | ui->win = newwin(height, width, ui->x, ui->y); 169 | ui->panel = new_panel(ui->win); 170 | } 171 | 172 | void 173 | ui_panel_destroy(ui_t *ui) 174 | { 175 | // Deallocate panel pointer 176 | del_panel(ui->panel); 177 | // Deallocate panel window 178 | delwin(ui->win); 179 | } 180 | 181 | void 182 | ui_set_title(ui_t *ui, const char *title) 183 | { 184 | // FIXME Reverse colors on monochrome terminals 185 | if (!has_colors()) { 186 | wattron(ui->win, A_REVERSE); 187 | } 188 | 189 | // Center the title on the window 190 | wattron(ui->win, A_BOLD | COLOR_PAIR(CP_DEF_ON_CYAN)); 191 | ui_clear_line(ui, 0); 192 | mvwprintw(ui->win, 0, (ui->width - strlen(title)) / 2, "%s", title); 193 | wattroff(ui->win, A_BOLD | A_REVERSE | COLOR_PAIR(CP_DEF_ON_CYAN)); 194 | } 195 | 196 | void 197 | ui_clear_line(ui_t *ui, int line) 198 | { 199 | // We could do this with wcleartoel but we want to 200 | // preserve previous window attributes. That way we 201 | // can set the background of the line. 202 | mvwprintw(ui->win, line, 0, "%*s", ui->width, ""); 203 | } 204 | 205 | void 206 | ui_draw_bindings(ui_t *ui, const char *keybindings[], int count) 207 | { 208 | int key, xpos = 0; 209 | 210 | // Reverse colors on monochrome terminals 211 | if (!has_colors()) { 212 | wattron(ui->win, A_REVERSE); 213 | } 214 | 215 | // Write a line all the footer width 216 | wattron(ui->win, COLOR_PAIR(CP_DEF_ON_CYAN)); 217 | ui_clear_line(ui, ui->height - 1); 218 | 219 | // Draw keys and their actions 220 | for (key = 0; key < count; key += 2) { 221 | wattron(ui->win, A_BOLD | COLOR_PAIR(CP_WHITE_ON_CYAN)); 222 | mvwprintw(ui->win, ui->height - 1, xpos, "%-*s", 223 | (int) strlen(keybindings[key]) + 1, keybindings[key]); 224 | xpos += strlen(keybindings[key]) + 1; 225 | wattroff(ui->win, A_BOLD | COLOR_PAIR(CP_WHITE_ON_CYAN)); 226 | wattron(ui->win, COLOR_PAIR(CP_BLACK_ON_CYAN)); 227 | mvwprintw(ui->win, ui->height - 1, xpos, "%-*s", 228 | (int) strlen(keybindings[key + 1]) + 1, keybindings[key + 1]); 229 | wattroff(ui->win, COLOR_PAIR(CP_BLACK_ON_CYAN)); 230 | xpos += strlen(keybindings[key + 1]) + 3; 231 | } 232 | 233 | // Disable reverse mode in all cases 234 | wattroff(ui->win, A_REVERSE | A_BOLD); 235 | } 236 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | # sngrep [![Build Status](https://travis-ci.org/irontec/sngrep.svg)](https://travis-ci.org/irontec/sngrep) 2 | 3 | sngrep is a tool for displaying SIP calls message flows from terminal. 4 | 5 | It supports live capture to display realtime SIP packets and can also be used 6 | as PCAP viewer. 7 | 8 | [Some screenshots of sngrep](https://github.com/irontec/sngrep/wiki/Screenshots) 9 | 10 | ## Installing 11 | 12 | ### Binaries 13 | * [Debian / Ubuntu](https://github.com/irontec/sngrep/wiki/Installing-Binaries#debian--ubuntu) 14 | * [CentOS / RedHat / Fedora](https://github.com/irontec/sngrep/wiki/Installing-Binaries#centos--fedora--rhel) 15 | * [Alpine Linux](https://github.com/irontec/sngrep/wiki/Installing-Binaries#alpine-linux) 16 | * [Gentoo](https://github.com/irontec/sngrep/wiki/Installing-Binaries#gentoo) 17 | * [Arch](https://github.com/irontec/sngrep/wiki/Installing-Binaries#arch) 18 | * [OSX](https://github.com/irontec/sngrep/wiki/Installing-Binaries#osx) 19 | * [OpenWRT/LEDE](https://github.com/irontec/sngrep/wiki/Installing-Binaries#openwrtlede) 20 | 21 | ### Building from sources 22 | Prerequisites 23 | 24 | - libncurses5 - for UI, windows, panels. 25 | - libpcap - for capturing packets. 26 | - libssl - (optional) for TLS transport decrypt using OpenSSL and libcrypt 27 | - gnutls - (optional) for TLS transport decrypt using GnuTLS and libgcrypt 28 | - libncursesw5 - (optional) for UI, windows, panels (wide-character support) 29 | - libpcre or libpcre2 - (optional) for Perl Compatible regular expressions 30 | - zlib - (optional) for gzip compressed pcap files 31 | 32 | On most systems the commands to build will be the standard autotools procedure: 33 | 34 | ./bootstrap.sh 35 | ./configure 36 | make 37 | make install (as root) 38 | 39 | You can pass following flags to ./configure to enable some features 40 | 41 | | configure flag | Feature | 42 | | ------------------ | ----------------------------------------------------------------------- | 43 | | `--with-openssl` | Adds OpenSSL support to parse TLS captured messages (req. libssl) | 44 | | `--with-gnutls` | Adds GnuTLS support to parse TLS captured messages (req. gnutls) | 45 | | `--with-pcre` | Adds Perl Compatible regular expressions support in regexp fields | 46 | | `--with-pcre2` | Adds Perl Compatible regular expressions (v2) support in regexp fields | 47 | | `--with-zlib` | Enable zlib to support gzip compressed pcap files | 48 | | `--enable-unicode` | Adds Ncurses UTF-8/Unicode support (req. libncursesw5) | 49 | | `--enable-ipv6` | Enable IPv6 packet capture support. | 50 | | `--enable-eep` | Enable EEP packet send/receive support. | 51 | 52 | Instead of using autotools, sngrep could be build with CMake, e.g.: 53 | 54 | mkdir build && cd build 55 | cmake [] .. 56 | make 57 | make install (as root) 58 | 59 | You can pass following options to cmake to enable some features 60 | 61 | | CMake option | Feature | 62 | | ------------------------ | ---------------------------------------------------------------------- | 63 | | `-D WITH_OPENSSL=ON` | Adds OpenSSL support to parse TLS captured messages (req. libssl) | 64 | | `-D WITH_GNUTLS=ON` | Adds GnuTLS support to parse TLS captured messages (req. gnutls) | 65 | | `-D WITH_PCRE=ON` | Adds Perl Compatible regular expressions support in regexp fields | 66 | | `-D WITH_PCRE2=ON` | Adds Perl Compatible regular expressions (v2) support in regexp fields | 67 | | `-D WITH_ZLIB=ON` | Enable zlib to support gzip compressed pcap files | 68 | | `-D WITH_UNICODE=ON` | Adds Ncurses UTF-8/Unicode support (req. libncursesw5) | 69 | | `-D USE_IPV6=ON` | Enable IPv6 packet capture support | 70 | | `-D USE_EEP=ON` | Enable EEP packet send/receive support | 71 | | `-D CPACK_GENERATOR=DEB` | `make package` builds a Debian package | 72 | | `-D CPACK_GENERATOR=RPM` | `make package` builds a RPM package | 73 | 74 | You can find [detailed instructions for some distributions](https://github.com/irontec/sngrep/wiki/Building) on wiki. 75 | 76 | ## Usage 77 | 78 | See `--help` for a list of available flags and their syntax 79 | 80 | For example, sngrep can be used to view SIP packets from a pcap file, also applying filters 81 | 82 | sngrep -I file.pcap host 192.168.1.1 and port 5060 83 | 84 | or live capturing, saving packets to a new file 85 | 86 | sngrep -d eth0 -O save.pcap port 5060 and udp 87 | 88 | 89 | ## Configuration 90 | 91 | You can configure some options using [sngreprc](https://github.com/irontec/sngrep/wiki/Configuration) file 92 | 93 | ## Frequent Asked Questions 94 | Any feedback, request or question are welcomed at [#sngrep](https://kiwiirc.com/nextclient/irc.libera.chat/#sngrep) channel at irc.libera.chat 95 | 96 | See FAQ on [Github Wiki](https://github.com/irontec/sngrep/wiki#frequent-asked-questions) 97 | 98 | ## License 99 | sngrep - SIP Messages flow viewer 100 | Copyright (C) 2013-2018 Irontec S.L. 101 | 102 | This program is free software: you can redistribute it and/or modify 103 | it under the terms of the GNU General Public License as published by 104 | the Free Software Foundation, either version 3 of the License, or 105 | (at your option) any later version. 106 | 107 | In addition, as a special exception, the copyright holders give 108 | permission to link the code of portions of this program with the 109 | OpenSSL library under certain conditions as described in each 110 | individual source file, and distribute linked combinations 111 | including the two. 112 | You must obey the GNU General Public License in all respects 113 | for all of the code used other than OpenSSL. If you modify 114 | file(s) with this exception, you may extend this exception to your 115 | version of the file(s), but you are not obligated to do so. If you 116 | do not wish to do so, delete this exception statement from your 117 | version. If you delete this exception statement from all source 118 | files in the program, then also delete it here. 119 | 120 | This program is distributed in the hope that it will be useful, 121 | but WITHOUT ANY WARRANTY; without even the implied warranty of 122 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 123 | GNU General Public License for more details. 124 | 125 | You should have received a copy of the GNU General Public License 126 | along with this program. If not, see . 127 | 128 | -------------------------------------------------------------------------------- /src/keybinding.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file option.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage keybindings 27 | * 28 | * sngrep keybindings are associated with actions. Each action can store multiple 29 | * keybindings. 30 | * Keybindings configured by user using *key* directive of sngreprc file, 31 | * in the format: 32 | * 33 | * key ui_action keycode 34 | * 35 | * keycode must be a letter (lowercase or uppercase) or a ^ sign with an uppercase 36 | * letter when Ctrl modifier is used. 37 | * 38 | */ 39 | 40 | #ifndef __SNGREP_KEYBINDING_H_ 41 | #define __SNGREP_KEYBINDING_H_ 42 | 43 | //! Number of keybindings per action 44 | #define MAX_BINDINGS 5 45 | 46 | //! Some undefined key codes 47 | #define KEY_CTRL(n) ((n)-64) 48 | #define KEY_ESC 27 49 | #define KEY_INTRO 10 50 | #define KEY_TAB 9 51 | #define KEY_BACKSPACE2 8 52 | #define KEY_BACKSPACE3 127 53 | #define KEY_SPACE ' ' 54 | 55 | /** 56 | * @brief Available Key actions 57 | */ 58 | enum key_actions { 59 | ACTION_PRINTABLE = 0, 60 | ACTION_UP, 61 | ACTION_DOWN, 62 | ACTION_LEFT, 63 | ACTION_RIGHT, 64 | ACTION_DELETE, 65 | ACTION_BACKSPACE, 66 | ACTION_NPAGE, 67 | ACTION_PPAGE, 68 | ACTION_HNPAGE, 69 | ACTION_HPPAGE, 70 | ACTION_BEGIN, 71 | ACTION_END, 72 | ACTION_PREV_FIELD, 73 | ACTION_NEXT_FIELD, 74 | ACTION_RESIZE_SCREEN, 75 | ACTION_CLEAR, 76 | ACTION_CLEAR_CALLS, 77 | ACTION_CLEAR_CALLS_SOFT, 78 | ACTION_TOGGLE_SYNTAX, 79 | ACTION_CYCLE_COLOR, 80 | ACTION_COMPRESS, 81 | ACTION_SHOW_HOSTNAMES, 82 | ACTION_SHOW_ALIAS, 83 | ACTION_TOGGLE_PAUSE, 84 | ACTION_PREV_SCREEN, 85 | ACTION_SHOW_HELP, 86 | ACTION_SHOW_RAW, 87 | ACTION_SHOW_FLOW, 88 | ACTION_SHOW_FLOW_EX, 89 | ACTION_SHOW_FILTERS, 90 | ACTION_SHOW_COLUMNS, 91 | ACTION_SHOW_SETTINGS, 92 | ACTION_SHOW_STATS, 93 | ACTION_COLUMN_MOVE_UP, 94 | ACTION_COLUMN_MOVE_DOWN, 95 | ACTION_SDP_INFO, 96 | ACTION_DISP_FILTER, 97 | ACTION_SAVE, 98 | ACTION_SELECT, 99 | ACTION_CONFIRM, 100 | ACTION_TOGGLE_MEDIA, 101 | ACTION_ONLY_MEDIA, 102 | ACTION_TOGGLE_RAW, 103 | ACTION_INCREASE_RAW, 104 | ACTION_DECREASE_RAW, 105 | ACTION_RESET_RAW, 106 | ACTION_ONLY_SDP, 107 | ACTION_TOGGLE_HINT, 108 | ACTION_AUTOSCROLL, 109 | ACTION_SORT_PREV, 110 | ACTION_SORT_NEXT, 111 | ACTION_SORT_SWAP, 112 | ACTION_TOGGLE_TIME, 113 | ACTION_SENTINEL 114 | }; 115 | 116 | //! Shorter declaration of key_binding structure 117 | typedef struct key_binding key_binding_t; 118 | 119 | /** 120 | * @brief Struct to hold a keybinding data 121 | */ 122 | struct key_binding { 123 | //! Keybinding action id 124 | int id; 125 | //! Keybinding action name 126 | const char *name; 127 | //! keybindings for this action 128 | int keys[MAX_BINDINGS]; 129 | //! How many keys are binded to this action 130 | int bindcnt; 131 | }; 132 | 133 | /** 134 | * @brief Print configured keybindigs 135 | */ 136 | void 137 | key_bindings_dump(); 138 | 139 | /** 140 | * @brief Return Keybinding data for a given action 141 | * @return key_binding_t structure pointer or NULL if not found 142 | */ 143 | key_binding_t * 144 | key_binding_data(int action); 145 | 146 | /** 147 | * @brief Bind a key to an action 148 | * 149 | * @param action One action defined in @key_actions 150 | * @param key Keycode returned by getch 151 | */ 152 | void 153 | key_bind_action(int action, int key); 154 | 155 | /** 156 | * @brief Unbind a key to an action 157 | * 158 | * @param action One action defined in @key_actions 159 | * @param key Keycode returned by getch 160 | */ 161 | void 162 | key_unbind_action(int action, int key); 163 | 164 | /** 165 | * @brief Find the next action for a given key 166 | * 167 | * Set start parameter to -1 for start searching the 168 | * first action. 169 | * 170 | * @param action One action defined in @key_actions 171 | * @param key Keycode returned by getch 172 | */ 173 | int 174 | key_find_action(int key, int start); 175 | 176 | /** 177 | * @brief Return the action id associate to an action str 178 | * 179 | * This function is used to translate keybindings configuration 180 | * found in sngreprc file to internal Action IDs 181 | * 182 | * @param action Configuration string for an action 183 | * @return action id from @key_actions or -1 if none found 184 | */ 185 | int 186 | key_action_id(const char *action); 187 | 188 | /** 189 | * @brief Check if key is a printable ascii character 190 | * 191 | * @return 1 if key is alphanumeric or space 192 | */ 193 | int 194 | key_is_printable(int key); 195 | 196 | /** 197 | * @brief Return a Human readable representation of a key 198 | * 199 | * @return Character string representing the key 200 | */ 201 | const char * 202 | key_to_str(int key); 203 | 204 | /** 205 | * @brief Parse Human key declaration to curses key 206 | * 207 | * This function is used to translate keybindings configuration 208 | * keys found in sngreprc file into internal ncurses keycodes 209 | * 210 | * @return ncurses keycode for the given key string 211 | */ 212 | int 213 | key_from_str(const char *key); 214 | 215 | /** 216 | * @brief Return Human readable key for an action 217 | * 218 | * This function is used to display keybindings in the bottom bar 219 | * of panels. Depending on sngrep configuration it will display the 220 | * first associated keybding with the action or the second one 221 | * (aka alternative). 222 | * 223 | * @param action One action defined in @key_actions 224 | * @return Main/Alt keybinding for the given action 225 | */ 226 | const char * 227 | key_action_key_str(int action); 228 | 229 | /** 230 | * @brief Return key value for a given action 231 | * 232 | * @param action One action defined in @key_actions 233 | * @return Main/Alt keybinding for the given action 234 | */ 235 | int 236 | key_action_key(int action); 237 | 238 | #endif /* __SNGREP_KEYBINDING_H_ */ 239 | -------------------------------------------------------------------------------- /src/setting.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file setting.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage application settings 27 | * 28 | * This file contains the functions to manage application settings and 29 | * optionuration resource files. Configuration will be parsed in this order, 30 | * from less to more priority, so the later will overwrite the previous. 31 | * 32 | * - Initialization 33 | * - \@sysdir\@/sngreprc 34 | * - $HOME/.sngreprc 35 | * - $SNGREPRC 36 | * 37 | * This is a basic approach to configuration, but at least a minimun is required 38 | * for those who can not see all the list columns or want to disable colours in 39 | * every sngrep execution. 40 | */ 41 | 42 | #ifndef __SNGREP_SETTING_H 43 | #define __SNGREP_SETTING_H 44 | 45 | //! Max setting value 46 | #define MAX_SETTING_LEN 1024 47 | 48 | //! Max extra length needed for "/.sngreprc.old" 49 | #define RCFILE_EXTRA_LEN 16 50 | 51 | //! Shorter declarartion of setting_option struct 52 | typedef struct setting_option setting_t; 53 | 54 | //! Generic setting formats 55 | #define SETTING_ENUM_ONOFF (const char *[]){ "on", "off", NULL } 56 | #define SETTING_ENUM_YESNO (const char *[]){ "yes", "no", NULL } 57 | #define SETTING_ENUM_BACKGROUND (const char *[]){ "dark" , "default", NULL } 58 | #define SETTING_ENUM_COLORMODE (const char *[]){ "request", "cseq", "callid", NULL } 59 | #define SETTING_ENUM_HIGHLIGHT (const char *[]){ "bold", "reverse", "reversebold", NULL } 60 | #define SETTING_ENUM_SDP_INFO (const char *[]){ "off", "first", "full", "compressed", NULL} 61 | #define SETTING_ENUM_STORAGE (const char *[]){ "none", "memory", NULL } 62 | #define SETTING_ENUM_HEPVERSION (const char *[]){ "2", "3", NULL } 63 | #define SETTING_ENUM_MEDIA (const char *[]){ "off", "on", "active", NULL } 64 | 65 | //! Other useful defines 66 | #define SETTING_ON "on" 67 | #define SETTING_OFF "off" 68 | #define SETTING_YES "yes" 69 | #define SETTING_NO "no" 70 | #define SETTING_ACTIVE "active" 71 | 72 | 73 | //! Available setting Options 74 | enum setting_id { 75 | SETTING_BACKGROUND = 0, 76 | SETTING_COLORMODE, 77 | SETTING_SYNTAX, 78 | SETTING_SYNTAX_TAG, 79 | SETTING_SYNTAX_BRANCH, 80 | SETTING_ALTKEY_HINT, 81 | SETTING_EXITPROMPT, 82 | SETTING_CAPTURE_LIMIT, 83 | SETTING_CAPTURE_DEVICE, 84 | SETTING_CAPTURE_OUTFILE, 85 | SETTING_CAPTURE_BUFFER, 86 | #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) 87 | SETTING_CAPTURE_KEYFILE, 88 | SETTING_CAPTURE_TLSSERVER, 89 | #endif 90 | #ifdef USE_EEP 91 | SETTING_CAPTURE_EEP, 92 | #endif 93 | SETTING_CAPTURE_RTP, 94 | SETTING_CAPTURE_STORAGE, 95 | SETTING_CAPTURE_ROTATE, 96 | SETTING_SIP_NOINCOMPLETE, 97 | SETTING_SIP_HEADER_X_CID, 98 | SETTING_SIP_CALLS, 99 | SETTING_SAVEPATH, 100 | SETTING_DISPLAY_ALIAS, 101 | SETTING_ALIAS_PORT, 102 | SETTING_CL_SCROLLSTEP, 103 | SETTING_CL_COLORATTR, 104 | SETTING_CL_AUTOSCROLL, 105 | SETTING_CL_SORTFIELD, 106 | SETTING_CL_SORTORDER, 107 | SETTING_CF_FORCERAW, 108 | SETTING_CF_RAWMINWIDTH, 109 | SETTING_CF_RAWFIXEDWIDTH, 110 | SETTING_CF_SPLITCALLID, 111 | SETTING_CF_HIGHTLIGHT, 112 | SETTING_CF_SCROLLSTEP, 113 | SETTING_CF_LOCALHIGHLIGHT, 114 | SETTING_CF_SDP_INFO, 115 | SETTING_CF_MEDIA, 116 | SETTING_CF_ONLYMEDIA, 117 | SETTING_CF_DELTA, 118 | SETTING_CR_SCROLLSTEP, 119 | SETTING_CR_NON_ASCII, 120 | SETTING_FILTER_PAYLOAD, 121 | SETTING_FILTER_METHODS, 122 | SETTING_TELEPHONE_EVENT, 123 | #ifdef USE_EEP 124 | SETTING_EEP_SEND, 125 | SETTING_EEP_SEND_VER, 126 | SETTING_EEP_SEND_ADDR, 127 | SETTING_EEP_SEND_PORT, 128 | SETTING_EEP_SEND_PASS, 129 | SETTING_EEP_SEND_ID, 130 | SETTING_EEP_LISTEN, 131 | SETTING_EEP_LISTEN_VER, 132 | SETTING_EEP_LISTEN_ADDR, 133 | SETTING_EEP_LISTEN_PORT, 134 | SETTING_EEP_LISTEN_PASS, 135 | SETTING_EEP_LISTEN_UUID, 136 | #endif 137 | SETTING_COUNT 138 | }; 139 | 140 | //! Available setting formats 141 | enum setting_fmt { 142 | SETTING_FMT_STRING = 0, 143 | SETTING_FMT_NUMBER, 144 | SETTING_FMT_ENUM, 145 | }; 146 | 147 | /** 148 | * @brief Configurable Setting structure 149 | */ 150 | struct setting_option { 151 | //! Setting id 152 | enum setting_id id; 153 | //! Setting name 154 | const char *name; 155 | //! Setting format 156 | enum setting_fmt fmt; 157 | //! Value of the setting 158 | char value[MAX_SETTING_LEN]; 159 | //! Compa separated valid values 160 | const char **valuelist; 161 | }; 162 | 163 | setting_t * 164 | setting_by_id(int id); 165 | 166 | setting_t * 167 | setting_by_name(const char *name); 168 | 169 | /** 170 | * @brief Return the setting id of a given string 171 | * 172 | * @param name String representing configurable setting 173 | * @return setting id or -1 if setting is not found 174 | */ 175 | int 176 | setting_id(const char *name); 177 | 178 | /** 179 | * @brief Return string representing given setting id 180 | * 181 | * @param id Setting id from settings enum 182 | * @return string representation of setting or NULL 183 | */ 184 | const char * 185 | setting_name(int id); 186 | 187 | int 188 | setting_format(int id); 189 | 190 | const char ** 191 | setting_valid_values(int id); 192 | 193 | const char* 194 | setting_get_value(int id); 195 | 196 | int 197 | setting_get_intvalue(int id); 198 | 199 | void 200 | setting_set_value(int id, const char *value); 201 | 202 | void 203 | setting_set_intvalue(int id, int value); 204 | 205 | int 206 | setting_enabled(int id); 207 | 208 | int 209 | setting_disabled(int id); 210 | 211 | int 212 | setting_has_value(int id, const char *value); 213 | 214 | void 215 | setting_toggle(int id); 216 | 217 | const char * 218 | setting_enum_next(int id, const char *value); 219 | 220 | /** 221 | * @brief Dump configuration settings 222 | * 223 | * This function will print to stdout configuration settings 224 | * after reading system/local/user resource files (in that order). 225 | * 226 | */ 227 | void 228 | settings_dump(); 229 | 230 | #endif /* __SNGREP_SETTING_H */ 231 | -------------------------------------------------------------------------------- /src/curses/ui_manager.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file ui_manager.h 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Functions to manage interface panels 27 | * 28 | * All sngrep panel pointers are encapsulated into a ui structure that is 29 | * used to invoke custom functions for creating, destroying, drawing, etc 30 | * the screens. 31 | * 32 | * This sctructure also manages concurrents updates and access to ncurses 33 | * panel pointers. 34 | * 35 | */ 36 | #ifndef __SNGREP_UI_MANAGER_H 37 | #define __SNGREP_UI_MANAGER_H 38 | #include "config.h" 39 | #include "theme.h" 40 | #include "ui_panel.h" 41 | #include "sip.h" 42 | #include "group.h" 43 | #include "keybinding.h" 44 | #include "setting.h" 45 | 46 | //! Refresh UI every 200 ms 47 | #define REFRESHTHSECS 2 48 | //! Default dialog dimensions 49 | #define DIALOG_MAX_WIDTH 100 50 | #define DIALOG_MIN_WIDTH 40 51 | 52 | /** 53 | * Define existing panels 54 | */ 55 | extern ui_t ui_call_list; 56 | extern ui_t ui_call_flow; 57 | extern ui_t ui_call_raw; 58 | extern ui_t ui_filter; 59 | extern ui_t ui_save; 60 | extern ui_t ui_msg_diff; 61 | extern ui_t ui_column_select; 62 | extern ui_t ui_settings; 63 | extern ui_t ui_stats; 64 | 65 | /** 66 | * @brief Initialize ncurses mode 67 | * 68 | * This functions will initialize ncurses mode 69 | * 70 | * @returns 0 on ncurses initialization success, 1 otherwise 71 | */ 72 | int 73 | ncurses_init(); 74 | 75 | /** 76 | * @brief Stops ncurses mode 77 | * 78 | * This functions will deinitialize ncurse mode 79 | * 80 | * @returns 0 on ncurses initialization success, 1 otherwise 81 | */ 82 | void 83 | ncurses_deinit(); 84 | 85 | 86 | /** 87 | * @brief Create a panel of a given type 88 | * 89 | * Create a ncurses panel of the given type. 90 | * This function is a small wrapper for panel create function 91 | * 92 | * @param type Panel Type 93 | * @return the ui structure with the panel pointer created* 94 | */ 95 | ui_t * 96 | ui_create_panel(enum panel_types type); 97 | 98 | /** 99 | * @brief Find a ui from its pannel pointer 100 | */ 101 | ui_t * 102 | ui_find_by_panel(PANEL *panel); 103 | 104 | /** 105 | * @brief Find a ui form its panel id 106 | */ 107 | ui_t * 108 | ui_find_by_type(enum panel_types type); 109 | 110 | /** 111 | * @brief Wait for user input in topmost panel 112 | * 113 | * This function manages all user input in all panel types and 114 | * redraws the panel using its own draw function 115 | * 116 | */ 117 | int 118 | ui_wait_for_input(); 119 | 120 | /** 121 | * @brief Default handler for keys 122 | * 123 | * If ui doesn't handle the given key (ui_handle_key returns the key value) 124 | * then the default handler will be invoked 125 | * 126 | * @param ui Current displayed UI structure 127 | * @param key key pressed by user 128 | */ 129 | int 130 | ui_default_handle_key(ui_t *ui, int key); 131 | 132 | /** 133 | * @brief Call Resize function in all panels in the stack 134 | * 135 | * This function acts as handler of screen resize function invoking all 136 | * resize functions of panels that implement it. 137 | */ 138 | void 139 | ui_resize_panels(); 140 | 141 | /** 142 | * @brief Draw a box around passed windows 143 | * 144 | * Draw a box around passed windows with two bars 145 | * (top and bottom) of one line each. 146 | * 147 | * @param win Window to draw borders on 148 | */ 149 | void 150 | title_foot_box(PANEL *panel); 151 | 152 | /** 153 | * @brief Draw a message payload in a window 154 | * 155 | * Generic drawing function for payload. This function will start 156 | * writting at 0,0 and return the number of lines written. 157 | * 158 | * @param win Ncurses window to draw payload 159 | * @param msg Msg to be drawn 160 | */ 161 | int 162 | draw_message(WINDOW *win, sip_msg_t *msg); 163 | 164 | /** 165 | * @brief Draw a message payload in a window starting at a given line 166 | * 167 | * Generic drawing function for payload. This function will start 168 | * writting at line starting and first column and return the number 169 | * of lines written. 170 | * 171 | * @param win Ncurses window to draw payload 172 | * @param msg Msg to be drawn 173 | * @param starting Number of win line to start writting payload 174 | */ 175 | int 176 | draw_message_pos(WINDOW *win, sip_msg_t *msg, int starting); 177 | 178 | /** 179 | * @brief Draw a centered dialog with a message 180 | * 181 | * Create a centered dialog with a message. 182 | * @param msg Message to be drawn 183 | */ 184 | int 185 | dialog_run(const char *fmt, ...); 186 | 187 | /** 188 | * @brief Create a new progress bar dialog 189 | * 190 | * Create a new progress bar dialog with the given text. The returned 191 | * pointer should be used as parameter for @dialog_progress_set_value 192 | * in order to move the progress bar percentage. 193 | * 194 | * @param fmt, vaarg Text to be displayed above the progress bar 195 | * @return a pointer to the created window. 196 | */ 197 | WINDOW * 198 | dialog_progress_run(const char *fmt, ...); 199 | 200 | /** 201 | * @brief Set current percentage of dialog progress bar 202 | * 203 | * @param win Window pointer created with @dialog_progress_run 204 | * @param perc 0-100 percentage of progress bar 205 | */ 206 | void 207 | dialog_progress_set_value(WINDOW *win, int perc); 208 | 209 | /** 210 | * @brief Destroy a dialog created by @dialog_progress_run 211 | * 212 | * This function will deallocate all memory and close the 213 | * given window pointer. 214 | * 215 | * @param win Window pointer created with @dialog_progress_run 216 | */ 217 | void 218 | dialog_progress_destroy(WINDOW *win); 219 | 220 | /** 221 | * @brief Create a new confirmation dialog with multiple buttons 222 | * 223 | * This function can be used to create dialogs with multiple buttons to 224 | * request user confirmation. By default, the first given option will 225 | * be selected. 226 | * 227 | * @param title Title displayed in the top of the dialog 228 | * @param text Text displayed inside the dialog 229 | * @param options Comma separated labels for the different buttons 230 | * @return the index of the button pressed 231 | */ 232 | int 233 | dialog_confirm(const char *title, const char *text, const char *options); 234 | 235 | #endif // __SNGREP_UI_MANAGER_H 236 | -------------------------------------------------------------------------------- /src/option.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** sngrep - SIP Messages flow viewer 4 | ** 5 | ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) 6 | ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. 7 | ** 8 | ** This program is free software: you can redistribute it and/or modify 9 | ** it under the terms of the GNU General Public License as published by 10 | ** the Free Software Foundation, either version 3 of the License, or 11 | ** (at your option) any later version. 12 | ** 13 | ** This program is distributed in the hope that it will be useful, 14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ** GNU General Public License for more details. 17 | ** 18 | ** You should have received a copy of the GNU General Public License 19 | ** along with this program. If not, see . 20 | ** 21 | ****************************************************************************/ 22 | /** 23 | * @file option.c 24 | * @author Ivan Alonso [aka Kaian] 25 | * 26 | * @brief Source code of functions defined in option.h 27 | * 28 | */ 29 | #include "config.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "keybinding.h" 36 | #include "option.h" 37 | #include "setting.h" 38 | #include "util.h" 39 | 40 | /** 41 | * @brief Configuration options array 42 | * 43 | * Contains all availabe options that can be optionured 44 | * @todo make this dynamic 45 | */ 46 | option_opt_t options[1024]; 47 | int optscnt = 0; 48 | 49 | int 50 | init_options(int no_config) 51 | { 52 | // Custom user conf file 53 | char *homedir = NULL; 54 | char *userconf = NULL; 55 | char *rcfile; 56 | char pwd[MAX_SETTING_LEN]; 57 | 58 | 59 | // Use $HOME directory as default savepath 60 | if ((homedir = getenv("HOME"))) { 61 | setting_set_value(SETTING_SAVEPATH, homedir); 62 | } else { 63 | // Use current directory as savepath if no HOME is set 64 | if (getcwd(pwd, MAX_SETTING_LEN)) { 65 | setting_set_value(SETTING_SAVEPATH, pwd); 66 | } 67 | } 68 | 69 | // Initialize settings 70 | setting_set_value(SETTING_FILTER_METHODS, "REGISTER,INVITE,SUBSCRIBE,NOTIFY,OPTIONS,PUBLISH,MESSAGE,INFO,REFER,UPDATE,KDMQ"); 71 | 72 | // Add Call list column options 73 | set_option_value("cl.column0", "index"); 74 | set_option_value("cl.column1", "method"); 75 | set_option_value("cl.column2", "sipfrom"); 76 | set_option_value("cl.column3", "sipto"); 77 | set_option_value("cl.column4", "msgcnt"); 78 | set_option_value("cl.column5", "src"); 79 | set_option_value("cl.column6", "dst"); 80 | set_option_value("cl.column7", "state"); 81 | 82 | // Done if config file should not be read 83 | if(no_config) { 84 | return 0; 85 | } 86 | 87 | // Read options from configuration files 88 | read_options("/etc/sngreprc"); 89 | read_options("/usr/local/etc/sngreprc"); 90 | // Get user configuration 91 | if ((rcfile = getenv("SNGREPRC"))) { 92 | read_options(rcfile); 93 | } else if ((rcfile = getenv("HOME"))) { 94 | if ((userconf = sng_malloc(strlen(rcfile) + RCFILE_EXTRA_LEN))) { 95 | sprintf(userconf, "%s/.sngreprc", rcfile); 96 | read_options(userconf); 97 | sng_free(userconf); 98 | } 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | void 105 | deinit_options() 106 | { 107 | int i; 108 | // Deallocate options memory 109 | for (i = 0; i < optscnt; i++) { 110 | sng_free(options[i].opt); 111 | sng_free(options[i].value); 112 | } 113 | } 114 | 115 | int 116 | read_options(const char *fname) 117 | { 118 | FILE *fh; 119 | char line[1024], type[20], option[50], value[500]; 120 | int id; 121 | 122 | if (!(fh = fopen(fname, "rt"))) 123 | return -1; 124 | 125 | while (fgets(line, 1024, fh) != NULL) { 126 | // Check if this line is a commentary or empty line 127 | if (!strlen(line) || *line == '#') 128 | continue; 129 | 130 | // Get configuration option from setting line 131 | if (sscanf(line, "%19s %49s %499[^\t\n]", type, option, value) == 3) { 132 | if (!strcasecmp(type, "set")) { 133 | if ((id = setting_id(option)) >= 0) { 134 | setting_set_value(id, value); 135 | } else { 136 | set_option_value(option, value); 137 | } 138 | } else if (!strcasecmp(type, "alias")) { 139 | set_alias_value(option, value); 140 | } else if (!strcasecmp(type, "bind")) { 141 | key_bind_action(key_action_id(option), key_from_str(value)); 142 | } else if (!strcasecmp(type, "unbind")) { 143 | key_unbind_action(key_action_id(option), key_from_str(value)); 144 | } 145 | } 146 | } 147 | fclose(fh); 148 | return 0; 149 | } 150 | 151 | const char* 152 | get_option_value(const char *opt) 153 | { 154 | int i; 155 | for (i = 0; i < optscnt; i++) { 156 | if (!strcasecmp(opt, options[i].opt)) { 157 | return options[i].value; 158 | } 159 | } 160 | return NULL; 161 | } 162 | 163 | int 164 | get_option_int_value(const char *opt) 165 | { 166 | const char *value; 167 | if ((value = get_option_value(opt))) { 168 | return atoi(value); 169 | } 170 | return -1; 171 | } 172 | 173 | void 174 | set_option_value(const char *opt, const char *value) 175 | { 176 | if (!opt || !value) 177 | return; 178 | 179 | int i; 180 | if (!get_option_value(opt)) { 181 | options[optscnt].type = COLUMN; 182 | options[optscnt].opt = strdup(opt); 183 | options[optscnt].value = strdup(value); 184 | optscnt++; 185 | } else { 186 | for (i = 0; i < optscnt; i++) { 187 | if (!strcasecmp(opt, options[i].opt)) { 188 | sng_free(options[i].value); 189 | options[i].value = strdup(value); 190 | } 191 | } 192 | } 193 | } 194 | 195 | void 196 | set_alias_value(const char *address, const char *alias) 197 | { 198 | options[optscnt].type = ALIAS; 199 | options[optscnt].opt = strdup(address); 200 | options[optscnt].value = strdup(alias); 201 | optscnt++; 202 | } 203 | 204 | const char * 205 | get_alias_value_vs_port(const char *address, uint16_t port) 206 | { 207 | if (!address) 208 | return NULL; 209 | 210 | int i; 211 | 212 | char *addr_port = sng_malloc(ADDRESSLEN + 10); 213 | sprintf(addr_port, "%s:%d", address, port); 214 | for (i = 0; i < optscnt; i++) { 215 | if (options[i].type != ALIAS) 216 | continue; 217 | if (!strcmp(options[i].opt, addr_port) || !strcmp(options[i].opt, address)) { 218 | sng_free(addr_port); 219 | return options[i].value; 220 | } 221 | } 222 | 223 | return address; 224 | } 225 | 226 | const char * 227 | get_alias_value(const char *address) 228 | { 229 | int i; 230 | 231 | if (!address) 232 | return NULL; 233 | 234 | for (i = 0; i < optscnt; i++) { 235 | if (options[i].type != ALIAS) 236 | continue; 237 | if (!strcmp(options[i].opt, address)) 238 | return options[i].value; 239 | } 240 | 241 | return address; 242 | } 243 | 244 | --------------------------------------------------------------------------------