Пример #1
0
static enum proto_parse_status read_channel(struct skinny_parser *parser, unsigned from, struct skinny_proto_info *info, struct cursor *curs, struct timeval const *now)
{
    assert(from == FROM_MGR || from == FROM_STATION);
    if (curs->cap_len < 4+16+4) return PROTO_TOO_SHORT;
    uint32_t ip_version = cursor_read_u32le(curs);
    if (ip_version == 0) {  // v4
        uint32_t ip = cursor_read_u32(curs);
        ip_addr_ctor_from_ip4(&parser->peer[from], ip);
        cursor_drop(curs, 12);    // this field is 16 bytes in length
    } else if (ip_version == 1) {    // v16
        ip_addr_ctor_from_ip6(&parser->peer[from], (struct in6_addr const *)curs->head);
        cursor_drop(curs, 16);
    } else {
        SLOG(LOG_DEBUG, "Invalid IP version (%d)", ip_version);
        return PROTO_PARSE_ERR;
    }
    parser->port[from] = cursor_read_u32le(curs);
    parser->media_set[from] = true;
    try_cnxtrack(parser, now);

    // Copy these into the info block
    SLOG(LOG_DEBUG, "Got media info");
    info->set_values |= SKINNY_MEDIA_CNX;
    info->media_ip = parser->peer[from];
    info->media_port = parser->port[from];

    return PROTO_OK;
}
Пример #2
0
static enum proto_parse_status read_channel(struct skinny_parser *parser, unsigned from, struct skinny_proto_info *info, struct cursor *curs, struct timeval const *now)
{
    assert(from == FROM_MGR || from == FROM_STATION);
    if (curs->cap_len < 4+16+4) return PROTO_TOO_SHORT;

    uint32_t ip_version = 0;
    // The ip field has a 16 byte lenght on CM7 headers. We
    // need to drop some bytes before parsing remote port
    short offset_ip_port = 0;
    switch (info->header_ver) {
        case SKINNY_BASIC:
            break;
        case SKINNY_CM7_TYPE_A:
        case SKINNY_CM7_TYPE_B:
        case SKINNY_CM7_TYPE_C:
            ip_version = cursor_read_u32le(curs);
            // We drop (16 - 4) for ipv4 and (16 - 8) for ipv6
            offset_ip_port = ip_version ? 8 : 12;
            break;
    }

    if (ip_version == 0) {  // v4
        uint32_t ip = cursor_read_u32(curs);
        ip_addr_ctor_from_ip4(&parser->peer[from], ip);
    } else if (ip_version == 1) {    // v6
        ip_addr_ctor_from_ip6(&parser->peer[from], (struct in6_addr const *)curs->head);
    } else {
        SLOG(LOG_DEBUG, "Invalid IP version (%d)", ip_version);
        return PROTO_PARSE_ERR;
    }

    cursor_drop(curs, offset_ip_port);
    parser->port[from] = cursor_read_u32le(curs);
    parser->media_set[from] = true;
    try_cnxtrack(parser, now);

    // Copy these into the info block
    SLOG(LOG_DEBUG, "Got media info");
    info->set_values |= SKINNY_MEDIA_CNX;
    info->media_ip = parser->peer[from];
    info->media_port = parser->port[from];

    return PROTO_OK;
}