Exemplo n.º 1
0
Arquivo: icmp.c Projeto: krissg/junkie
char *icmp_err_2_str(struct icmp_err const *err, unsigned set_values)
{
    char *str = tempstr();
    snprintf(str, TEMPSTR_SIZE, "protocol=%"PRIu8", src=%s:%"PRIu16", dst=%s:%"PRIu16,
        err->protocol,
        ip_addr_2_str(err->addr+0),
        set_values & ICMP_ERR_PORT_SET ? err->port[0] : 0,
        ip_addr_2_str(err->addr+1),
        set_values & ICMP_ERR_PORT_SET ? err->port[1] : 0);
    return str;
}
Exemplo n.º 2
0
void spawn_rtp_subparsers(struct ip_addr const *this_host, uint16_t this_port, struct ip_addr const *other_host, uint16_t other_port, struct timeval const *now, struct proto *requestor)
{
    SLOG(LOG_DEBUG, "Spawning RT(C)P parsers for %s:%"PRIu16"<->%s:%"PRIu16, ip_addr_2_str(this_host), this_port, ip_addr_2_str(other_host), other_port);

    (void)cnxtrack_ip_new(IPPROTO_UDP, this_host, this_port,   other_host, other_port,   false, proto_rtp,  now, requestor);
    (void)cnxtrack_ip_new(IPPROTO_UDP, this_host, this_port+1, other_host, other_port+1, false, proto_rtcp, now, requestor);
}
Exemplo n.º 3
0
Arquivo: sdp.c Projeto: krissg/junkie
static int sdp_extract_host(unsigned unused_ cmd, struct liner *liner, void *info_)
{
    struct sdp_proto_info *info = info_;

#define IN_IP "IN IP"
#define IN_IP_LEN strlen(IN_IP)

    if (liner_tok_length(liner) < IN_IP_LEN)
        return -1;

    if (strncasecmp(liner->start, IN_IP, IN_IP_LEN))
        return -1;

    char const *start = liner->start + IN_IP_LEN;
    int version = start[0] - '0';
    if (version != 4 && version != 6) {
        SLOG(LOG_DEBUG, "Bogus IP version (%d)", version);
        return -1;
    }

    struct liner space_liner;
    liner_init(&space_liner, &delim_spaces, (char const *)start, liner_tok_length(liner) - IN_IP_LEN);
    liner_next(&space_liner);   // skipping the IP version number

#undef IN_IP
#undef IN_IP_LEN

    if (0 != ip_addr_ctor_from_str(&info->host, space_liner.start, liner_tok_length(&space_liner), version))
        return -1;

    info->set_values |= SDP_HOST_SET;

    SLOG(LOG_DEBUG, "host found (%s)", ip_addr_2_str(&info->host));
    return 0;
}
Exemplo n.º 4
0
char const *ip_addr_2_strv6(struct ip_addr const *addr)
{
    if (ip_addr_is_v6(addr)) return ip_addr_2_str(addr);

    char *str = tempstr();
    snprintf(str, TEMPSTR_SIZE, "::ffff:%"PRINIPQUAD, NIPQUAD(&addr->u.v4));
    return str;
}
Exemplo n.º 5
0
Arquivo: sip.c Projeto: rixed/junkie
static char const *via_2_str(struct sip_via const *via)
{
    char *str = tempstr();
    snprintf(str, TEMPSTR_SIZE, "%s %s:%"PRIu16,
        via_protocol_2_str(via->protocol),
        ip_addr_2_str(&via->addr),
        via->port);
    return str;
}
Exemplo n.º 6
0
Arquivo: sdp.c Projeto: krissg/junkie
static char const *sdp_info_2_str(struct proto_info const *info_)
{
    struct sdp_proto_info const *info = DOWNCAST(info_, info, sdp_proto_info);
    char *str = tempstr();

    snprintf(str, TEMPSTR_SIZE, "%s, host=%s, port=%s",
             proto_info_2_str(info_),
             info->set_values & SDP_HOST_SET ? ip_addr_2_str(&info->host) : "unset",
             info->set_values & SDP_PORT_SET ? tempstr_printf("%u", info->port) : "unset");

    return str;
}
Exemplo n.º 7
0
static char const *dhcp_info_2_str(struct proto_info const *info_)
{
    struct dhcp_proto_info const *info = DOWNCAST(info_, info, dhcp_proto_info);
    char *str = tempstr();
    snprintf(str, TEMPSTR_SIZE, "%s, opcode=%s, msg_type=%s, xid=0x%x, client_ip=%s, client_mac=%s, server=%s",
        proto_info_2_str(info_),
        dhcp_opcode_2_str(info->opcode),
        dhcp_msg_type_2_str(info->msg_type),
        info->xid,
        info->set_values & DHCP_CLIENT_SET     ? ip_addr_2_str(&info->client) : "unset",
        info->hw_addr_is_eth ? eth_addr_2_str(info->client_mac) : "not eth",
        info->server_name[0] != '\0' ? info->server_name : "unset");

    return str;
}
Exemplo n.º 8
0
Arquivo: sip.c Projeto: rixed/junkie
// The Via header may inform us that the peer is expecting answers on a non-standard port. Let's conntrack it.
static void conntrack_via(struct sip_proto_info const *info, struct timeval const *now)
{
    /* We conntrack the Via at every occurence, which will insert many conntrack
     * that will never be used (because most of the time Via is toward default SIP
     * port anyway.
     * We can't but hope that timeouting tracked connection will compensate for our
     * slopyness.
     * Notice that we conntrack from any peer to the Via address. SIP is so fun! */
    SLOG(LOG_DEBUG, "Conntracking SIP via %s %s:%"PRIu16,
        info->via.protocol == IPPROTO_UDP ? "UDP" :
            info->via.protocol == IPPROTO_TCP ? "TCP" : "unknown",
        ip_addr_2_str(&info->via.addr),
        info->via.port);

    assert(info->set_values & SIP_VIA_SET);
    (void)cnxtrack_ip_new(info->via.protocol, &info->via.addr, info->via.port, ADDR_UNKNOWN, PORT_UNKNOWN, false /* only one cnx */, proto_sip, now, NULL);
}
Exemplo n.º 9
0
Arquivo: sdp.c Projeto: krissg/junkie
static void spawn_subparsers(struct ip_addr const *this_host, uint16_t this_port, struct ip_addr const *other_host, uint16_t other_port, struct proto_layer *parent, struct timeval const *now)
{
    ASSIGN_LAYER_AND_INFO_OPT(ip, parent);
    if (! ip) return;

    SLOG(LOG_DEBUG, "Spawning RT(C)P parsers for %s:%"PRIu16"<->%s:%"PRIu16, ip_addr_2_str(this_host), this_port, ip_addr_2_str(other_host), other_port);

    unsigned way2;
    struct mux_subparser *udp_parser =
        ip_subparser_lookup(layer_ip->parser, proto_udp, NULL, IPPROTO_UDP, this_host, other_host, &way2, now);

    if (! udp_parser) return;

    // Notice that we request RT(C)P on behalf of our parent
    (void)udp_subparser_and_parser_new(udp_parser->parser, proto_rtp,  parent->parser, this_port,   other_port,   way2, now); // rtp conntrack
    (void)udp_subparser_and_parser_new(udp_parser->parser, proto_rtcp, parent->parser, this_port+1, other_port+1, way2, now); // rtcp conntrack
}
Exemplo n.º 10
0
static void ip_addr_ctor_from_str_check(void)
{
    static struct {
        char const *str;
        int mode;
    } const tests[] = {
        { "0.0.0.0",        4, },
        { "1.2.3.4",        4, },
        { "0.0.0.1",        4, },
        { "128.2.1.255",    4, },
        { "::ffff:1.2.3.4", 6, },
    };

    for (unsigned t = 0; t < NB_ELEMS(tests); t++) {
        struct ip_addr addr;
        ip_addr_ctor_from_str(&addr, tests[t].str, strlen(tests[t].str), tests[t].mode );
        char const *str = ip_addr_2_str(&addr);
        SLOG(LOG_DEBUG, "Comparing '%s' with '%s'", tests[t].str, str);
        assert(0 == strcmp(str, tests[t].str));
    }
}
Exemplo n.º 11
0
Arquivo: sdp.c Projeto: krissg/junkie
static enum proto_parse_status sdp_parse(struct parser *parser, struct proto_layer *parent, unsigned way, uint8_t const *packet, size_t cap_len, size_t wire_len, struct timeval const *now, proto_okfn_t *okfn)
{
    struct sdp_parser *sdp_parser = DOWNCAST(parser, parser, sdp_parser);

    static struct sdper_field const fields[] = {
        { 1, "c", sdp_extract_host },
        { 1, "m", sdp_extract_port },
    };

    static struct sdper const sdper = {
        .nb_fields = NB_ELEMS(fields),
        .fields = fields
    };

    SLOG(LOG_DEBUG, "Starting SDP analysis");

    /* Parse */

    struct sdp_proto_info info;
    sdp_proto_info_ctor(&info, wire_len, 0);
    struct proto_layer layer;
    proto_layer_ctor(&layer, parent, parser, &info.info);

    if (0 != sdper_parse(&sdper, &cap_len, packet, cap_len, &info)) return PROTO_PARSE_ERR;

    if (
        (info.set_values & SDP_PORT_SET) &&
        (info.set_values & SDP_HOST_SET)
    ) {
        SLOG(LOG_DEBUG, "SDP@%p, connect info is %s:%"PRIu16, sdp_parser, ip_addr_2_str(&info.host), info.port);

        if (! sdp_parser->host_set) {
            sdp_parser->host_set = true;
            sdp_parser->host = info.host;
            sdp_parser->port = info.port;
            ASSIGN_LAYER_AND_INFO_OPT(ip, parent);
            if (layer_ip) {
                sdp_parser->sender = ip->key.addr[0];
                sdp_parser->sender_set = true;
            } else {
                sdp_parser->sender_set = false;
            }
        } else if (0 != ip_addr_cmp(&sdp_parser->host, &info.host)) {
            // Start conntracking between the advertized hosts
            spawn_subparsers(&sdp_parser->host, sdp_parser->port, &info.host, info.port, parent, now);

            ASSIGN_LAYER_AND_INFO_OPT(ip, parent);
            bool may_use_stun[2] = {
                0 != ip_addr_cmp(&sdp_parser->sender, &sdp_parser->host),
                ip && 0 != ip_addr_cmp(&ip->key.addr[0], &info.host),
            };
            // If the sender IP was different from the advertized host, start conntracking on this socket also
            if (may_use_stun[0]) {
                spawn_subparsers(&sdp_parser->sender, sdp_parser->port, &info.host, info.port, parent, now);
            }
            // If _this_ sender IP is different from this advertized host, start conntracking on this socket as well
            if (may_use_stun[1]) {
                spawn_subparsers(&sdp_parser->host, sdp_parser->port, &ip->key.addr[0], info.port, parent, now);
            }
            // If both senders IP were different from advertized ones then start conntracking between these two senders IP as well
            if (may_use_stun[0] && may_use_stun[1]) {
                spawn_subparsers(&sdp_parser->sender, sdp_parser->port, &ip->key.addr[0], info.port, parent, now);
            }

            // TODO: terminate this parser. meanwhile, reset its state :
            sdp_parser->host_set = false;
            sdp_parser->sender_set = false;
        }
    }

    return proto_parse(NULL, &layer, way, NULL, 0, 0, now, okfn);
}
Exemplo n.º 12
0
static char const *skinny_info_2_str(struct proto_info const *info_)
{
    struct skinny_proto_info const *info = DOWNCAST(info_, info, skinny_proto_info);
    return tempstr_printf("%s, HeaderVer:%s, MsgId:%s%s%s%s%s%s%s%s%s%s",
        proto_info_2_str(&info->info),
        skinny_header_version_2_str(info->header_ver),
        skinny_msgid_2_str(info->msgid),
        info->set_values & SKINNY_NEW_KEY_PAD   ? tempstr_printf(", Key:%"PRIu32,        info->new_key_pad):"",
        info->set_values & SKINNY_LINE_INSTANCE ? tempstr_printf(", Line:%"PRIu32,       info->line_instance):"",
        info->set_values & SKINNY_CALL_ID       ? tempstr_printf(", CallId:%"PRIu32,     info->call_id):"",
        info->set_values & SKINNY_CONFERENCE_ID ? tempstr_printf(", ConfId:%"PRIu32,     info->conf_id):"",
        info->set_values & SKINNY_PASS_THRU_ID  ? tempstr_printf(", PassThruId:%"PRIu32, info->pass_thru_id):"",
        info->set_values & SKINNY_CALL_STATE    ? tempstr_printf(", CallState:%s", skinny_call_state_2_str(info->call_state)):"",
        info->set_values & SKINNY_MEDIA_CNX     ? tempstr_printf(", MediaIp:%s:%"PRIu16, ip_addr_2_str(&info->media_ip), info->media_port):"",
        info->set_values & SKINNY_CALLING_PARTY ? tempstr_printf(", CallingParty:%s",    info->calling_party):"",
        info->set_values & SKINNY_CALLED_PARTY  ? tempstr_printf(", CalledParty:%s",     info->called_party):"");
}
Exemplo n.º 13
0
static enum proto_parse_status sdp_parse(struct parser *parser, struct proto_info *parent, unsigned way, uint8_t const *packet, size_t cap_len, size_t wire_len, struct timeval const *now, size_t tot_cap_len, uint8_t const *tot_packet)
{
    struct sdp_parser *sdp_parser = DOWNCAST(parser, parser, sdp_parser);

    static struct sdper_field const fields[] = {
        { 1, "c", sdp_extract_host },
        { 1, "m", sdp_extract_port },
    };

    static struct sdper const sdper = {
        .nb_fields = NB_ELEMS(fields),
        .fields = fields
    };

    SLOG(LOG_DEBUG, "Starting SDP analysis");

    /* Parse */

    struct sdp_proto_info info;
    sdp_proto_info_ctor(&info, parser, parent, wire_len, 0);

    if (0 != sdper_parse(&sdper, &cap_len, packet, cap_len, &info)) return PROTO_PARSE_ERR;

    // Start conntracking of RT(C)P streams if we have all required informations
    if (
        (info.set_values & SDP_PORT_SET) &&
        (info.set_values & SDP_HOST_SET)
    ) {
        SLOG(LOG_DEBUG, "SDP@%p, connect info is %s:%"PRIu16, sdp_parser, ip_addr_2_str(&info.host), info.port);

        /* FIXME: store both peers of the SDP tunnel and respawn the RT(C)Ps as soon as
         * one of the end changes. Problem is: we don't know which peer this is! */
        if (! sdp_parser->host_set) {
            sdp_parser->host_set = true;
            sdp_parser->host = info.host;
            sdp_parser->port = info.port;
            ASSIGN_INFO_OPT(ip, parent);
            if (ip) {
                sdp_parser->sender = ip->key.addr[0];
                sdp_parser->sender_set = true;
            } else {
                sdp_parser->sender_set = false;
            }
        } else if (0 != ip_addr_cmp(&sdp_parser->host, &info.host)) {
            /* Start conntracking between the advertized hosts
             * Notice that we request RT(C)P on behalf of our parent! */
            spawn_rtp_subparsers(&sdp_parser->host, sdp_parser->port, &info.host, info.port, now, parent->parser->proto);

            ASSIGN_INFO_OPT(ip, parent);
            bool may_use_stun[2] = {
                0 != ip_addr_cmp(&sdp_parser->sender, &sdp_parser->host),
                ip && 0 != ip_addr_cmp(&ip->key.addr[0], &info.host),
            };
            // If the sender IP was different from the advertized host, start conntracking on this socket too
            if (may_use_stun[0]) {
                spawn_rtp_subparsers(&sdp_parser->sender, sdp_parser->port, &info.host, info.port, now, parent->parser->proto);
            }
            // If _this_ sender IP is different from this advertized host, start conntracking on this socket as well
            if (may_use_stun[1]) {
                spawn_rtp_subparsers(&sdp_parser->host, sdp_parser->port, &ip->key.addr[0], info.port, now, parent->parser->proto);
            }
            // If both senders IP were different from advertized ones then start conntracking between these two senders IP as well
            if (may_use_stun[0] && may_use_stun[1]) {
                spawn_rtp_subparsers(&sdp_parser->sender, sdp_parser->port, &ip->key.addr[0], info.port, now, parent->parser->proto);
            }

            // TODO: terminate this parser. meanwhile, reset its state :
            sdp_parser->host_set = false;
            sdp_parser->sender_set = false;
        }
    }

    return proto_parse(NULL, &info.info, way, NULL, 0, 0, now, tot_cap_len, tot_packet);
}