Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/libsrtp/src/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 24 kB image not shown  

Quelle  rtp_decoder.c   Sprache: C

 
/*
 * rtp_decoder.c
 *
 * decoder structures and functions for SRTP pcap decoder
 *
 * Example:
 * $ wget --no-check-certificate \
 *     https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
 * $ ./test/rtp_decoder -a -t 10 -e 128 -b \
 *     aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
 *         < ~/marseillaise-srtp.pcap \
 *         | text2pcap -t "%M:%S." -u 10000,10000 - - \
 *         > ./marseillaise-rtp.pcap
 *
 * There is also a different way of setting up key size and tag size
 * based upon RFC 4568 crypto suite specification, i.e.:
 *
 * $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b \
 *     aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
 *
 * Audio can be extracted using extractaudio utility from the RTPproxy
 * package:
 *
 * $ extractaudio -A ./marseillaise-rtp.pcap ./marseillaise-out.wav
 *
 * Bernardo Torres <bernardo@torresautomacao.com.br>
 *
 * Some structure and code from https://github.com/gteissier/srtp-decrypt
 */

/*
 *
 * Copyright (c) 2001-2017 Cisco Systems, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 *   Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 *   Neither the name of the Cisco Systems, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "getopt_s.h" /* for local getopt()  */
#include <assert.h>   /* for assert()  */

#include <pcap.h>
#include "rtp_decoder.h"
#include "util.h"

#ifndef timersub
#define timersub(a, b, result)                                                 \
    do {                                                                       \
        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                          \
        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                       \
        if ((result)->tv_usec < 0) {                                           \
            --(result)->tv_sec;                                                \
            (result)->tv_usec += 1000000;                                      \
        }                                                                      \
    } while (0)
#endif

#define MAX_KEY_LEN 96
#define MAX_FILTER 256
#define MAX_FILE 255

struct srtp_crypto_suite {
    const char *can_name;
    int gcm_on;
    int key_size;
    int tag_size;
};

static struct srtp_crypto_suite srtp_crypto_suites[] = {
#if 0
  {.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
#endif
    {.can_name = "AES_CM_128_HMAC_SHA1_32",
     .gcm_on = 0,
     .key_size = 128,
     .tag_size = 4 },
    {.can_name = "AES_CM_128_HMAC_SHA1_80",
     .gcm_on = 0,
     .key_size = 128,
     .tag_size = 10 },
    {.can_name = "AES_192_CM_HMAC_SHA1_32",
     .gcm_on = 0,
     .key_size = 192,
     .tag_size = 4 },
    {.can_name = "AES_192_CM_HMAC_SHA1_80",
     .gcm_on = 0,
     .key_size = 192,
     .tag_size = 10 },
    {.can_name = "AES_256_CM_HMAC_SHA1_32",
     .gcm_on = 0,
     .key_size = 256,
     .tag_size = 4 },
    {.can_name = "AES_256_CM_HMAC_SHA1_80",
     .gcm_on = 0,
     .key_size = 256,
     .tag_size = 10 },
    {.can_name = "AEAD_AES_128_GCM",
     .gcm_on = 1,
     .key_size = 128,
     .tag_size = 16 },
    {.can_name = "AEAD_AES_256_GCM",
     .gcm_on = 1,
     .key_size = 256,
     .tag_size = 16 },
    {.can_name = NULL }
};

void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
                                  const char *msg,
                                  void *data)
{
    char level_char = '?';
    switch (level) {
    case srtp_log_level_error:
        level_char = 'e';
        break;
    case srtp_log_level_warning:
        level_char = 'w';
        break;
    case srtp_log_level_info:
        level_char = 'i';
        break;
    case srtp_log_level_debug:
        level_char = 'd';
        break;
    }
    fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
}

int main(int argc, char *argv[])
{
    char errbuf[PCAP_ERRBUF_SIZE];
    bpf_u_int32 pcap_net = 0;
    pcap_t *pcap_handle;
#if BEW
    struct sockaddr_in local;
#endif
    srtp_sec_serv_t sec_servs = sec_serv_none;
    int c;
    struct srtp_crypto_suite scs, *i_scsp;
    scs.key_size = 128;
    scs.tag_size = 0;
    int gcm_on = 0;
    char *input_key = NULL;
    int b64_input = 0;
    char key[MAX_KEY_LEN];
    struct bpf_program fp;
    char filter_exp[MAX_FILTER] = "";
    char pcap_file[MAX_FILE] = "-";
    int rtp_packet_offset = DEFAULT_RTP_OFFSET;
    rtp_decoder_t dec;
    srtp_policy_t policy = { { 0 } };
    rtp_decoder_mode_t mode = mode_rtp;
    srtp_err_status_t status;
    int len;
    int expected_len;
    int do_list_mods = 0;

    fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(),
            srtp_get_version());

    /* initialize srtp library */
    status = srtp_init();
    if (status) {
        fprintf(stderr,
                "error: srtp initialization failed with error code %d\n",
                status);
        exit(1);
    }

    status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
    if (status) {
        fprintf(stderr, "error: install log handler failed\n");
        exit(1);
    }

    /* check args */
    while (1) {
        c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:");
        if (c == -1) {
            break;
        }
        switch (c) {
        case 'b':
            b64_input = 1;
        /* fall thru */
        case 'k':
            input_key = optarg_s;
            break;
        case 'e':
            scs.key_size = atoi(optarg_s);
            if (scs.key_size != 128 && scs.key_size != 192 &&
                scs.key_size != 256) {
                fprintf(
                    stderr,
                    "error: encryption key size must be 128, 192 or 256 (%d)\n",
                    scs.key_size);
                exit(1);
            }
            input_key = malloc(scs.key_size);
            sec_servs |= sec_serv_conf;
            break;
        case 't':
            scs.tag_size = atoi(optarg_s);
            break;
        case 'a':
            sec_servs |= sec_serv_auth;
            break;
        case 'g':
            gcm_on = 1;
            sec_servs |= sec_serv_auth;
            break;
        case 'd':
            status = srtp_set_debug_module(optarg_s, 1);
            if (status) {
                fprintf(stderr, "error: set debug module (%s) failed\n",
                        optarg_s);
                exit(1);
            }
            break;
        case 'f':
            if (strlen(optarg_s) > MAX_FILTER) {
                fprintf(stderr, "error: filter bigger than %d characters\n",
                        MAX_FILTER);
                exit(1);
            }
            fprintf(stderr, "Setting filter as %s\n", optarg_s);
            strcpy(filter_exp, optarg_s);
            break;
        case 'l':
            do_list_mods = 1;
            break;
        case 's':
            for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL;
                 i_scsp++) {
                if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
                    break;
                }
            }
            if (i_scsp->can_name == NULL) {
                fprintf(stderr, "Unknown/unsupported crypto suite name %s\n",
                        optarg_s);
                exit(1);
            }
            scs = *i_scsp;
            input_key = malloc(scs.key_size);
            sec_servs |= sec_serv_conf | sec_serv_auth;
            gcm_on = scs.gcm_on;
            break;
        case 'm':
            if (strcasecmp("rtp", optarg_s) == 0) {
                mode = mode_rtp;
            } else if (strcasecmp("rtcp", optarg_s) == 0) {
                mode = mode_rtcp;
            } else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
                mode = mode_rtcp_mux;
            } else {
                fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
                exit(1);
            }
            break;
        case 'p':
            if (strlen(optarg_s) > MAX_FILE) {
                fprintf(stderr,
                        "error: pcap file path bigger than %d characters\n",
                        MAX_FILE);
                exit(1);
            }
            strcpy(pcap_file, optarg_s);
            break;
        case 'o':
            rtp_packet_offset = atoi(optarg_s);
            break;
        default:
            usage(argv[0]);
        }
    }

    if (scs.tag_size == 0) {
        if (gcm_on) {
            scs.tag_size = 16;
        } else {
            scs.tag_size = 10;
        }
    }

    if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
        fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
                scs.tag_size);
        exit(1);
    }

    if (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
        fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
                scs.tag_size);
        exit(1);
    }

    if (do_list_mods) {
        status = srtp_list_debug_modules();
        if (status) {
            fprintf(stderr, "error: list of debug modules failed\n");
            exit(1);
        }
        return 0;
    }

    if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
        /*
         * a key must be provided if and only if security services have
         * been requested
         */

        if (input_key == NULL) {
            fprintf(stderr, "key not provided\n");
        }
        if (!sec_servs) {
            fprintf(stderr, "no secservs\n");
        }
        fprintf(stderr, "provided\n");
        usage(argv[0]);
    }

    /* report security services selected on the command line */
    fprintf(stderr, "security services: ");
    if (sec_servs & sec_serv_conf)
        fprintf(stderr, "confidentiality ");
    if (sec_servs & sec_serv_auth)
        fprintf(stderr, "message authentication");
    if (sec_servs == sec_serv_none)
        fprintf(stderr, "none");
    fprintf(stderr, "\n");

    /* set up the srtp policy and master key */
    if (sec_servs) {
        /*
         * create policy structure, using the default mechanisms but
         * with only the security services requested on the command line,
         * using the right SSRC value
         */

        switch (sec_servs) {
        case sec_serv_conf_and_auth:
            if (gcm_on) {
#ifdef OPENSSL
                switch (scs.key_size) {
                case 128:
                    if (scs.tag_size == 16) {
                        srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
                        srtp_crypto_policy_set_aes_gcm_128_16_auth(
                            &policy.rtcp);
                    } else {
                        srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
                        srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
                    }
                    break;
                case 256:
                    if (scs.tag_size == 16) {
                        srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
                        srtp_crypto_policy_set_aes_gcm_256_16_auth(
                            &policy.rtcp);
                    } else {
                        srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
                        srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
                    }
                    break;
                }
#else
                fprintf(stderr, "error: GCM mode only supported when using the "
                                "OpenSSL crypto engine.\n");
                return 0;
#endif
            } else {
                switch (scs.key_size) {
                case 128:
                    if (scs.tag_size == 4) {
                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
                            &policy.rtcp);
                    } else {
                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
                            &policy.rtcp);
                    }
                    break;
                case 192:
#ifdef OPENSSL
                    if (scs.tag_size == 4) {
                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
                            &policy.rtcp);
                    } else {
                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
                            &policy.rtcp);
                    }
#else
                    fprintf(stderr,
                            "error: AES 192 mode only supported when using the "
                            "OpenSSL crypto engine.\n");
                    return 0;

#endif
                    break;
                case 256:
                    if (scs.tag_size == 4) {
                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
                            &policy.rtcp);
                    } else {
                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
                            &policy.rtp);
                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
                            &policy.rtcp);
                    }
                    break;
                }
            }
            break;
        case sec_serv_conf:
            if (gcm_on) {
                fprintf(
                    stderr,
                    "error: GCM mode must always be used with auth enabled\n");
                return -1;
            } else {
                switch (scs.key_size) {
                case 128:
                    srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
                    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
                        &policy.rtcp);
                    break;
                case 192:
#ifdef OPENSSL
                    srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
                    srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
                        &policy.rtcp);
#else
                    fprintf(stderr,
                            "error: AES 192 mode only supported when using the "
                            "OpenSSL crypto engine.\n");
                    return 0;

#endif
                    break;
                case 256:
                    srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
                        &policy.rtcp);
                    break;
                }
            }
            break;
        case sec_serv_auth:
            if (gcm_on) {
#ifdef OPENSSL
                switch (scs.key_size) {
                case 128:
                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
                        &policy.rtcp);
                    break;
                case 256:
                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
                        &policy.rtcp);
                    break;
                }
#else
                printf("error: GCM mode only supported when using the OpenSSL "
                       "crypto engine.\n");
                return 0;
#endif
            } else {
                srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
                srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
            }
            break;
        default:
            fprintf(stderr, "error: unknown security service requested\n");
            return -1;
        }

        policy.key = (uint8_t *)key;
        policy.next = NULL;
        policy.window_size = 128;
        policy.allow_repeat_tx = 0;
        policy.rtp.sec_serv = sec_servs;
        policy.rtcp.sec_serv =
            sec_servs; // sec_serv_none;  /* we don't do RTCP anyway */
        fprintf(stderr, "setting tag len %d\n", scs.tag_size);
        policy.rtp.auth_tag_len = scs.tag_size;

        if (gcm_on && scs.tag_size != 8) {
            fprintf(stderr, "set tag len %d\n", scs.tag_size);
            policy.rtp.auth_tag_len = scs.tag_size;
        }

        /*
         * read key from hexadecimal or base64 on command line into an octet
         * string
         */

        if (b64_input) {
            int pad;
            expected_len = policy.rtp.cipher_key_len * 4 / 3;
            len = base64_string_to_octet_string(key, &pad, input_key,
                                                strlen(input_key));
        } else {
            expected_len = policy.rtp.cipher_key_len * 2;
            len = hex_string_to_octet_string(key, input_key, expected_len);
        }
        /* check that hex string is the right length */
        if (len < expected_len) {
            fprintf(stderr, "error: too few digits in key/salt "
                            "(should be %d digits, found %d)\n",
                    expected_len, len);
            exit(1);
        }
        if (strlen(input_key) > policy.rtp.cipher_key_len * 2) {
            fprintf(stderr, "error: too many digits in key/salt "
                            "(should be %d hexadecimal digits, found %u)\n",
                    policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
            exit(1);
        }

        int key_octets = (scs.key_size / 8);
        int salt_octets = policy.rtp.cipher_key_len - key_octets;
        fprintf(stderr, "set master key/salt to %s/",
                octet_string_hex_string(key, key_octets));
        fprintf(stderr, "%s\n",
                octet_string_hex_string(key + key_octets, salt_octets));

    } else {
        fprintf(stderr,
                "error: neither encryption or authentication were selected\n");
        exit(1);
    }

    pcap_handle = pcap_open_offline(pcap_file, errbuf);

    if (!pcap_handle) {
        fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
        exit(1);
    }
    assert(pcap_handle != NULL);
    if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
                pcap_geterr(pcap_handle));
        return (2);
    }
    if (pcap_setfilter(pcap_handle, &fp) == -1) {
        fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
                pcap_geterr(pcap_handle));
        return (2);
    }
    dec = rtp_decoder_alloc();
    if (dec == NULL) {
        fprintf(stderr, "error: malloc() failed\n");
        exit(1);
    }
    fprintf(stderr, "Starting decoder\n");
    if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) {
        fprintf(stderr, "error: init failed\n");
        exit(1);
    }

    pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);

    if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
        fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
    }
    if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
        fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
    }
    fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);

    rtp_decoder_deinit(dec);
    rtp_decoder_dealloc(dec);

    status = srtp_shutdown();
    if (status) {
        fprintf(stderr, "error: srtp shutdown failed with error code %d\n",
                status);
        exit(1);
    }

    return 0;
}

void usage(char *string)
{
    fprintf(
        stderr,
        "usage: %s [-d ]* [[-k][-b] ] [-a][-t][-e] [-s "
        "] [-m ]\n"
        "or %s -l\n"
        "where -a use message authentication\n"
        " -e use encryption (use 128 or 256 for key size)\n"
        " -g Use AES-GCM mode (must be used with -e)\n"
        " -t Tag size to use (in GCM mode use 8 or 16)\n"
        " -k sets the srtp master key given in hexadecimal\n"
        " -b sets the srtp master key given in base64\n"
        " -l list debug modules\n"
        " -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
        " -d turn on debugging for module \n"
        " -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
        " on RFC4568-style crypto suite specification\n"
        " -m set the mode to be one of [rtp]|rtcp|rtcp-mux\n"
        " -p path to pcap file (defaults to stdin)\n"
        " -o byte offset of RTP packet in capture (defaults to 42)\n",
        string, string);
    exit(1);
}

rtp_decoder_t rtp_decoder_alloc(void)
{
    return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
}

void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
{
    free(rtp_ctx);
}

int rtp_decoder_deinit(rtp_decoder_t decoder)
{
    if (decoder->srtp_ctx) {
        return srtp_dealloc(decoder->srtp_ctx);
    }
    return 0;
}

int rtp_decoder_init(rtp_decoder_t dcdr,
                     srtp_policy_t policy,
                     rtp_decoder_mode_t mode,
                     int rtp_packet_offset)
{
    dcdr->rtp_offset = rtp_packet_offset;
    dcdr->srtp_ctx = NULL;
    dcdr->start_tv.tv_usec = 0;
    dcdr->start_tv.tv_sec = 0;
    dcdr->frame_nr = -1;
    dcdr->error_cnt = 0;
    dcdr->rtp_cnt = 0;
    dcdr->rtcp_cnt = 0;
    dcdr->mode = mode;
    dcdr->policy = policy;
    dcdr->policy.ssrc.type = ssrc_any_inbound;

    if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
        return 1;
    }
    return 0;
}

/*
 * decodes key as base64
 */


void hexdump(const void *ptr, size_t size)
{
    int i, j;
    const unsigned char *cptr = ptr;

    for (i = 0; i < size; i += 16) {
        fprintf(stdout, "%04x ", i);
        for (j = 0; j < 16 && i + j < size; j++) {
            fprintf(stdout, "%02x ", cptr[i + j]);
        }
        fprintf(stdout, "\n");
    }
}

void rtp_decoder_handle_pkt(u_char *arg,
                            const struct pcap_pkthdr *hdr,
                            const u_char *bytes)
{
    rtp_decoder_t dcdr = (rtp_decoder_t)arg;
    rtp_msg_t message;
    int rtp;
    int pktsize;
    struct timeval delta;
    int octets_recvd;
    srtp_err_status_t status;
    dcdr->frame_nr++;

    if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
        dcdr->start_tv = hdr->ts;
    }

    if (hdr->caplen < dcdr->rtp_offset) {
        return;
    }
    const void *rtp_packet = bytes + dcdr->rtp_offset;

    memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
    pktsize = hdr->caplen - dcdr->rtp_offset;
    octets_recvd = pktsize;

    if (octets_recvd == -1) {
        return;
    }

    if (dcdr->mode == mode_rtp) {
        rtp = 1;
    } else if (dcdr->mode == mode_rtcp) {
        rtp = 0;
    } else {
        rtp = 1;
        if (octets_recvd >= 2) {
            /* rfc5761 */
            u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
            rtp = payload_type < 64 || payload_type > 95;
        }
    }

    if (rtp) {
        /* verify rtp header */
        if (message.header.version != 2) {
            return;
        }

        status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
        if (status) {
            dcdr->error_cnt++;
            return;
        }
        dcdr->rtp_cnt++;
    } else {
        status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
        if (status) {
            dcdr->error_cnt++;
            return;
        }
        dcdr->rtcp_cnt++;
    }
    timersub(&hdr->ts, &dcdr->start_tv, &delta);
    fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
            (long)delta.tv_usec);
    hexdump(&message, octets_recvd);
}

Messung V0.5
C=98 H=96 G=96

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.