From 615ac3c2efc2875dc27cca6fce925cd5d9230767 Mon Sep 17 00:00:00 2001 From: Andreas Heil Date: Fri, 20 Nov 2020 16:03:55 +0100 Subject: [PATCH] enable parsing of HEP3 packets in capture --- config/sngreprc | 3 +++ doc/sngrep.8 | 6 +++++- src/capture.c | 27 ++++++++++++++++++++++++--- src/capture_eep.c | 26 +++++++++++++++----------- src/capture_eep.h | 4 +++- src/main.c | 14 ++++++++++++-- src/setting.c | 3 +++ src/setting.h | 3 +++ 8 files changed, 68 insertions(+), 18 deletions(-) diff --git a/config/sngreprc b/config/sngreprc index ede990e..565ea5f 100644 --- a/config/sngreprc +++ b/config/sngreprc @@ -35,6 +35,9 @@ ## Set size of pcap capture buffer in MB (default: 2) # set capture.buffer 2 +## Uncomment to enable parsing of captured HEP3 packets +# set capture.eep on + ##----------------------------------------------------------------------------- ## Default path in save dialog # set sngrep.savepath /tmp/sngrep-captures diff --git a/doc/sngrep.8 b/doc/sngrep.8 index 591926b..957e608 100644 --- a/doc/sngrep.8 +++ b/doc/sngrep.8 @@ -11,7 +11,7 @@ sngrep \- SIP Messages flow viewer .SH SYNOPSIS -.B sngrep [-hVcivlkNq] [ -IO +.B sngrep [-hVcivlkNqE] [ -IO .I pcap_dump .B ] [ -d .I dev @@ -112,6 +112,10 @@ Argument must be an IP address and port in the format: udp:A.B.C.D:PORT Start a HEP server listening for packets Argument must be an IP address and port in the format: udp:A.B.C.D:PORT +.TP +.I -E +Enable parsing of captured HEP3 packets. + .TP .I match expression Match given expression in Messages' payload. If one request message matches the diff --git a/src/capture.c b/src/capture.c index 64dba92..1629d76 100644 --- a/src/capture.c +++ b/src/capture.c @@ -275,6 +275,10 @@ parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packe uint32_t size_payload = size_capture - capinfo->link_hl; // Captured packet info packet_t *pkt; +#ifdef USE_EEP + // Captured HEP3 packet info + packet_t *pkt_hep3; +#endif // Ignore packets while capture is paused if (capture_paused()) @@ -318,10 +322,27 @@ parse_packet(u_char *info, const struct pcap_pkthdr *header, const u_char *packe // Remove TCP Header from payload payload = (u_char *) (udp) + udp_off; - // Complete packet with Transport information - packet_set_type(pkt, PACKET_SIP_UDP); - packet_set_payload(pkt, payload, size_payload); +#ifdef USE_EEP + // check for HEP3 header and parse payload + if(setting_enabled(SETTING_CAPTURE_EEP)) { + pkt_hep3 = capture_eep_receive_v3(payload, size_payload); + if (pkt_hep3) { + packet_destroy(pkt); + pkt = pkt_hep3; + } else { + // Complete packet with Transport information + packet_set_type(pkt, PACKET_SIP_UDP); + packet_set_payload(pkt, payload, size_payload); + } + } else { +#endif + // Complete packet with Transport information + packet_set_type(pkt, PACKET_SIP_UDP); + packet_set_payload(pkt, payload, size_payload); +#ifdef USE_EEP + } +#endif } else if (pkt->proto == IPPROTO_TCP) { // Get TCP header tcp = (struct tcphdr *)((u_char *)(data) + (size_capture - size_payload)); diff --git a/src/capture_eep.c b/src/capture_eep.c index 9e2b489..399b772 100644 --- a/src/capture_eep.c +++ b/src/capture_eep.c @@ -488,7 +488,7 @@ capture_eep_receive() case 2: return capture_eep_receive_v2(); case 3: - return capture_eep_receive_v3(); + return capture_eep_receive_v3(NULL, 0); } return NULL; } @@ -600,7 +600,7 @@ capture_eep_receive_v2() * @return packet pointer */ packet_t * -capture_eep_receive_v3() +capture_eep_receive_v3(const u_char *pkt, uint32_t size) { struct hep_generic hg; @@ -623,11 +623,15 @@ capture_eep_receive_v3() //! Packet header struct pcap_pkthdr header; //! New created packet pointer - packet_t *pkt; + packet_t *pkt_new; - /* Receive EEP generic header */ - if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1) - return NULL; + if(!pkt) { + /* Receive EEP generic header */ + if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1) + return NULL; + } else { + memcpy(&buffer, pkt, size); + } // Initialize structs memset(&hg, 0, sizeof(hep_generic_t)); @@ -747,14 +751,14 @@ capture_eep_receive_v3() } // Create a new packet - pkt = packet_create((hg.ip_family.data == AF_INET)?4:6, hg.ip_proto.data, src, dst, 0); - packet_add_frame(pkt, &header, payload); - packet_set_type(pkt, PACKET_SIP_UDP); - packet_set_payload(pkt, payload, header.caplen); + pkt_new = packet_create((hg.ip_family.data == AF_INET)?4:6, hg.ip_proto.data, src, dst, 0); + packet_add_frame(pkt_new, &header, payload); + packet_set_type(pkt_new, PACKET_SIP_UDP); + packet_set_payload(pkt_new, payload, header.caplen); /* FREE */ sng_free(payload); - return pkt; + return pkt_new; } int diff --git a/src/capture_eep.h b/src/capture_eep.h index c163533..5a68bdf 100644 --- a/src/capture_eep.h +++ b/src/capture_eep.h @@ -328,10 +328,12 @@ capture_eep_receive_v2(); * function will parse received EEP data and create a new packet * structure. * + * @param pkt packet structure data, NULL if socket should be used + * @param size size of packet structure data * @return NULL on any error, packet structure otherwise */ packet_t * -capture_eep_receive_v3(); +capture_eep_receive_v3(const u_char *pkt, uint32_t size); /** * @brief Set EEP server url diff --git a/src/main.c b/src/main.c index d78902a..079f6b3 100644 --- a/src/main.c +++ b/src/main.c @@ -57,7 +57,7 @@ usage() " [-k keyfile]" #endif #ifdef USE_EEP - " [-LH capture_url]" + " [-LHE capture_url]" #endif " [] []\n\n" " -h --help\t\t This usage\n" @@ -80,6 +80,7 @@ usage() #ifdef USE_EEP " -H --eep-send\t Homer sipcapture url (udp:X.X.X.X:XXXX)\n" " -L --eep-listen\t Listen for encapsulated packets (udp:X.X.X.X:XXXX)\n" + " -E --eep-parse\t Enable EEP parsing in captured packets\n" #endif #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) " -k --keyfile\t RSA private keyfile to decrypt captured packets\n" @@ -163,13 +164,14 @@ main(int argc, char* argv[]) #ifdef USE_EEP { "eep-listen", required_argument, 0, 'L' }, { "eep-send", required_argument, 0, 'H' }, + { "eep-parse", required_argument, 0, 'E' }, #endif { "quiet", no_argument, 0, 'q' }, }; // Parse command line arguments that have high priority opterr = 0; - char *options = "hVd:I:O:B:pqtW:k:crl:ivNqDL:H:Rf:F"; + char *options = "hVd:I:O:B:pqtW:k:crl:ivNqDL:H:ERf:F"; while ((opt = getopt_long(argc, argv, options, long_options, &idx)) != -1) { switch (opt) { case 'h': @@ -302,6 +304,14 @@ main(int argc, char* argv[]) #else fprintf(stderr, "sngrep is not compiled with HEP/EEP support."); exit(1); +#endif + case 'E': +#ifdef USE_EEP + setting_set_value(SETTING_CAPTURE_EEP, SETTING_ON); + break; +#else + fprintf(stderr, "sngrep is not compiled with HEP/EEP support."); + exit(1); #endif case '?': if (strchr(options, optopt)) { diff --git a/src/setting.c b/src/setting.c index 9f45000..df71fd0 100644 --- a/src/setting.c +++ b/src/setting.c @@ -50,6 +50,9 @@ setting_t settings[SETTING_COUNT] = { #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) { SETTING_CAPTURE_KEYFILE, "capture.keyfile", SETTING_FMT_STRING, "", NULL }, { SETTING_CAPTURE_TLSSERVER, "capture.tlsserver", SETTING_FMT_STRING, "", NULL }, +#endif +#ifdef USE_EEP + { SETTING_CAPTURE_EEP, "capture.eep", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF }, #endif { SETTING_CAPTURE_RTP, "capture.rtp", SETTING_FMT_ENUM, SETTING_OFF, SETTING_ENUM_ONOFF }, { SETTING_CAPTURE_STORAGE, "capture.storage", SETTING_FMT_ENUM, "memory", SETTING_ENUM_STORAGE }, diff --git a/src/setting.h b/src/setting.h index 1ca8113..6411993 100644 --- a/src/setting.h +++ b/src/setting.h @@ -86,6 +86,9 @@ enum setting_id { #if defined(WITH_GNUTLS) || defined(WITH_OPENSSL) SETTING_CAPTURE_KEYFILE, SETTING_CAPTURE_TLSSERVER, +#endif +#ifdef USE_EEP + SETTING_CAPTURE_EEP, #endif SETTING_CAPTURE_RTP, SETTING_CAPTURE_STORAGE,