Пример #1
0
static int icmpv6_extract_err_infos(struct icmp_proto_info *info, uint8_t const *packet, size_t packet_len)
{
    struct icmp_err *err = &info->err;
    struct ipv6_hdr const *iphdr = (struct ipv6_hdr *)packet;

    if (packet_len < sizeof(*iphdr)) {
        SLOG(LOG_DEBUG, "Bogus ICMPv6 packet too short for IPv6 header");
        return -1;
    }

    err->protocol = READ_U8(&iphdr->next);
    ip_addr_ctor_from_ip6(err->addr+0, &iphdr->src);
    ip_addr_ctor_from_ip6(err->addr+1, &iphdr->dst);

    switch (iphdr->next) {
        case IPPROTO_TCP:
        case IPPROTO_UDP:
            if (packet_len >= sizeof(*iphdr) + 4) {
                info->set_values |= ICMP_ERR_PORT_SET;
                return icmp_extract_err_ports(err, packet + sizeof(*iphdr));
            }
            break;
        default:
            SLOG(LOG_DEBUG, "ICMPv6 Error for unsuported protocol %u", iphdr->next);
            break;
    }
    return 0;
}
Пример #2
0
int ip_addr_ctor_from_sockaddr(struct ip_addr *ip, struct sockaddr const *addr, socklen_t addrlen)
{
    switch (addr->sa_family) {
    case AF_INET:
    {
        struct sockaddr_in *ip_addr = (struct sockaddr_in *)addr;
        if (addrlen < sizeof(*ip_addr)) {
            SLOG(LOG_NOTICE, "Invalid AF_INET sockaddr of size %zu", (size_t)addrlen);
            return -1;
        }
        ip_addr_ctor_from_ip4(ip, ip_addr->sin_addr.s_addr);
        return 0;
    }
    case AF_INET6:
    {
        struct sockaddr_in6 *ip_addr = (struct sockaddr_in6 *)addr;
        if (addrlen < sizeof(*ip_addr)) {
            SLOG(LOG_NOTICE, "Invalid AF_INET6 sockaddr of size %zu", (size_t)addrlen);
            return -1;
        }
        ip_addr_ctor_from_ip6(ip, &ip_addr->sin6_addr);
        return 0;
    }
    }

    SLOG(LOG_DEBUG, "Unknown sockaddr family %u", (unsigned)addr->sa_family);
    return -1;
}
Пример #3
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;
}
Пример #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;
}