Exemplo n.º 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;
}
Exemplo n.º 2
0
static enum proto_parse_status parse_rpc_reply(struct cursor *cursor, struct rpc_proto_info *info)
{
    CHECK(4);
    info->u.reply_msg.reply_status = cursor_read_u32(cursor);
    switch (info->u.reply_msg.reply_status) {
    case RPC_MSG_ACCEPTED:
    {
        RPC_CHECK_AUTH(credential);
        break;
    }
    case RPC_MSG_DENIED:
    {
        CHECK(4);
        enum rejected_status rejected_status = cursor_read_u32(cursor);
        if (rejected_status > RPC_AUTH_ERROR) return PROTO_PARSE_ERR;
        break;
    }
    }
    return PROTO_OK;
}
Exemplo n.º 3
0
static void cursor_check(void)
{
    struct cursor cursor;

    static uint8_t const data[] = { 1, 2 };
    cursor_ctor(&cursor, data, sizeof(data));
    assert(cursor_peek_u8(&cursor, 0) == 0x01U);
    assert(cursor_peek_u8(&cursor, 1) == 0x02U);
    assert(cursor_read_u8(&cursor) == 0x01U);
    assert(cursor_read_u8(&cursor) == 0x02U);

    static uint16_t const data16[] = { 0x0102, 0x0304 };
    cursor_ctor(&cursor, (uint8_t *)data16, sizeof(data16));
    assert(cursor_peek_u16le(&cursor, 0) == 0x0102U);
    assert(cursor_peek_u16le(&cursor, 2) == 0x0304U);
    assert(cursor_read_u16(&cursor) == 0x0102U);
    assert(cursor_read_u16(&cursor) == 0x0304U);

    static uint32_t const data32[] = { 0x01020304U, 0x05060708U };
    cursor_ctor(&cursor, (uint8_t *)data32, sizeof(data32));
    assert(cursor_peek_u32le(&cursor, 0) == 0x01020304U);
    assert(cursor_peek_u32le(&cursor, 4) == 0x05060708U);
    assert(cursor_read_u32(&cursor) == 0x01020304U);
    assert(cursor_read_u32(&cursor) == 0x05060708U);

    static uint64_t const data64[] = { 0x0102030405060708ULL };
    cursor_ctor(&cursor, (uint8_t *)data64, sizeof(data64));
    assert(cursor_peek_u64le(&cursor, 0) == 0x0102030405060708ULL);
    assert(cursor_read_u64(&cursor) == 0x0102030405060708ULL);

    static uint8_t const datan[] = { 1, 2, 3, 4 };
    cursor_ctor(&cursor, datan, sizeof(datan));
    assert(cursor_peek_u32n(&cursor, 0) == 0x01020304);
    assert(cursor_read_u32n(&cursor) == 0x01020304);

    cursor_ctor(&cursor, datan, sizeof(datan));
    assert(cursor_peek_u16n(&cursor, 0) == 0x0102);
    assert(cursor_read_u16n(&cursor) == 0x0102);
}
Exemplo n.º 4
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;
}