Пример #1
0
void icmps_rx(TCPIPS* tcpips, IO *io, IP* src)
{
    ICMP_HEADER* icmp = io_data(io);
    //drop broken ICMP without control, because ICMP is control protocol itself
    if (io->data_size < sizeof(ICMP_HEADER))
    {
        ips_release_io(tcpips, io);
        return;
    }
    if (ip_checksum(io_data(io), io->data_size))
    {
        ips_release_io(tcpips, io);
        return;
    }

    switch (icmp->type)
    {
    case ICMP_CMD_ECHO_REPLY:
        icmps_rx_echo_reply(tcpips, io, src);
        break;
#if (ICMP_ECHO)
    case ICMP_CMD_ECHO:
        icmps_rx_echo(tcpips, io, src);
        break;
#endif
    case ICMP_CMD_DESTINATION_UNREACHABLE:
        icmps_rx_destination_unreachable(tcpips, io);
        break;
    case ICMP_CMD_TIME_EXCEEDED:
        icmps_rx_time_exceeded(tcpips, io);
        break;
    case ICMP_CMD_PARAMETER_PROBLEM:
        icmps_rx_parameter_problem(tcpips, io);
        break;
    default:
#if (ICMP_DEBUG)
        printf("ICMP: unhandled type %d from ", icmp->type);
        ip_print(src);
        printf("\n");
#endif
        ips_release_io(tcpips, io);
        break;

    }
}
Пример #2
0
static void icmps_rx_error(TCPIPS* tcpips, IO* io, ICMP_ERROR code)
{
    //hide ICMP header for protocol-depending processing
    io->data_offset += sizeof(ICMP_HEADER);
    io->data_size -= sizeof(ICMP_HEADER);
    icmps_rx_error_process(tcpips, io, code);
    //restore ICMP header and release
    io->data_offset -= sizeof(ICMP_HEADER);
    io->data_size += sizeof(ICMP_HEADER);
    ips_release_io(tcpips, io);
}
Пример #3
0
static inline void icmps_rx_parameter_problem(TCPIPS* tcpips, IO* io)
{
    ICMP_HEADER_PARAM* icmp = io_data(io);
    //useless if no original header provided
    if (io->data_size < sizeof(ICMP_HEADER_PARAM) + sizeof(IP_HEADER) + 8)
    {
        ips_release_io(tcpips, io);
        return;
    }
#if (ICMP_DEBUG)
    printf("ICMP: Parameter problem (%d) ", icmp->param);
#endif
    icmps_rx_error(tcpips, io, icmp->code + ICMP_ERROR_PARAMETER);
}
Пример #4
0
static inline void icmps_rx_time_exceeded(TCPIPS* tcpips, IO* io)
{
    ICMP_HEADER* icmp = io_data(io);
    //useless if no original header provided
    if (io->data_size < sizeof(ICMP_HEADER) + sizeof(IP_HEADER) + 8)
    {
        ips_release_io(tcpips, io);
        return;
    }
#if (ICMP_DEBUG)
    printf("ICMP: Time exceeded in transit (%d) ", icmp->code);
#endif
    icmps_rx_error(tcpips, io, icmp->code + ICMP_ERROR_TTL_EXCEED);
}
Пример #5
0
static inline void icmps_rx_destination_unreachable(TCPIPS* tcpips, IO* io)
{
    ICMP_HEADER* icmp = io_data(io);
    //useless if no original header provided
    if (io->data_size < sizeof(ICMP_HEADER) + sizeof(IP_HEADER) + 8)
    {
        ips_release_io(tcpips, io);
        return;
    }
#if (ICMP_DEBUG)
    printf("ICMP: Destination unreachable(%d) ", icmp->code);
#endif
    icmps_rx_error(tcpips, io, icmp->code);
}
Пример #6
0
static inline void icmps_rx_echo_reply(TCPIPS* tcpips, IO* io, IP* src)
{
    ICMP_HEADER_ID_SEQ* icmp = io_data(io);
#if (ICMP_DEBUG)
    printf("ICMP: ECHO REPLY from ");
    ip_print(src);
    printf("\n");
#endif
    //compare src, sequence, id and data. Maybe asynchronous response from failed request
    if ((tcpips->icmps.echo_ip.u32.ip != src->u32.ip) || (tcpips->icmps.id != be2short(icmp->id_be)) || (tcpips->icmps.seq != be2short(icmp->seq_be)))
    {
        ips_release_io(tcpips, io);
        return;
    }
    icmps_echo_complete(tcpips, (memcmp(((uint8_t*)io_data(io)) + sizeof(ICMP_HEADER), __ICMP_DATA_MAGIC, ICMP_DATA_MAGIC_SIZE)) ? ERROR_CRC : ERROR_OK);
}
Пример #7
0
void udps_rx(TCPIPS* tcpips, IO* io, IP* src)
{
    HANDLE handle;
    UDP_HEADER* hdr;
    UDP_HANDLE* uh;
    uint16_t src_port, dst_port;
#if(UDP_BROADCAST)
    const IP* dst;
    dst = (const IP*)io_data(io) - 1;
    if (io->data_size < sizeof(UDP_HEADER) || udp_checksum(io_data(io), io->data_size, src, dst))
#else
    if (io->data_size < sizeof(UDP_HEADER) || udp_checksum(io_data(io), io->data_size, src, &tcpips->ips.ip))
#endif
    {
        ips_release_io(tcpips, io);
        return;
    }
    hdr = io_data(io);
    src_port = be2short(hdr->src_port_be);
    dst_port = be2short(hdr->dst_port_be);
#if (UDP_DEBUG_FLOW)
    printf("UDP: ");
    ip_print(src);
    printf(":%d -> ", src_port);
    ip_print(&tcpips->ips.ip);
    printf(":%d, %d byte(s)\n", dst_port, io->data_size - sizeof(UDP_HEADER));
#endif //UDP_DEBUG_FLOW

#if(DHCPS)
    if((dst_port == DHCP_SERVER_PORT)||(src_port == DHCP_CLIENT_PORT))
    {
        io_hide(io, sizeof(UDP_HEADER));
        if(dhcps_rx(tcpips,io,src))
            udps_replay(tcpips,io,&__BROADCAST);
        else
            ips_release_io(tcpips, io);
        return;
    }
#endif

#if(DNSS)
    if((dst_port == DNS_PORT)&&(dst->u32.ip == tcpips->ips.ip.u32.ip))
    {
        io_hide(io, sizeof(UDP_HEADER));
        if(dnss_rx(tcpips,io,src))
            udps_replay(tcpips,io,src);
        else
            ips_release_io(tcpips, io);
        return;
    }
#endif
    //search in listeners
    handle = udps_find(tcpips, dst_port);
    if (handle != INVALID_HANDLE)
    {
        uh = so_get(&tcpips->udps.handles, handle);
        //listener or connected
        if (uh->remote_port == 0 || (uh->remote_port == src_port && uh->remote_addr.u32.ip == src->u32.ip))
            udps_send_user(tcpips, src, io, handle);
        else
            handle = INVALID_HANDLE;
    }
#if(UDP_BROADCAST)
    if ((handle == INVALID_HANDLE) && (dst->u32.ip != BROADCAST))
#else
    if (handle == INVALID_HANDLE)
#endif
    {
#if (UDP_DEBUG)
        printf("UDP: no connection, datagramm dropped\n");
#endif //UDP_DEBUG
#if (ICMP)
        icmps_tx_error(tcpips, io, ICMP_ERROR_PORT, 0);
#endif //ICMP
    }
    ips_release_io(tcpips, io);
}