Example #1
0
void icmps_tx_error(TCPIPS* tcpips, IO* original, ICMP_ERROR err, unsigned int offset)
{
    //unhide ip header
    IP_STACK* ip_stack;
    ip_stack = io_stack(original);
    original->data_offset -= ip_stack->hdr_size;
    original->data_size += ip_stack->hdr_size;
    switch (err)
    {
    case ICMP_ERROR_NETWORK:
    case ICMP_ERROR_HOST:
    case ICMP_ERROR_PROTOCOL:
    case ICMP_ERROR_PORT:
    case ICMP_ERROR_FRAGMENTATION:
    case ICMP_ERROR_ROUTE:
        icmps_tx_destination_unreachable(tcpips, err, original);
        break;
    case ICMP_ERROR_TTL_EXCEED:
    case ICMP_ERROR_FRAGMENT_REASSEMBLY_EXCEED:
        icmps_tx_time_exceed(tcpips, err - ICMP_ERROR_TTL_EXCEED, original);
        break;
    case ICMP_ERROR_PARAMETER:
        icmps_tx_parameter_problem(tcpips, offset, original);
        break;
    case ICMP_ERROR_OK:
        break;
    }

    original->data_offset -= ip_stack->hdr_size;
    original->data_size += ip_stack->hdr_size;
}
Example #2
0
static inline void udps_write(TCPIPS* tcpips, HANDLE handle, IO* io)
{
    IO* cur;
    unsigned int offset, size;
    unsigned short remote_port;
    IP dst;
    UDP_STACK* udp_stack;
    UDP_HEADER* udp;
    UDP_HANDLE* uh = so_get(&tcpips->udps.handles, handle);
    if (uh == NULL)
        return;
#if (ICMP)
    if (uh->err != ERROR_OK)
    {
        error(uh->err);
        return;
    }
#endif //ICMP
    //listening socket
    if (uh->remote_port == 0)
    {
        if (io->stack_size < sizeof(UDP_STACK))
        {
            error(ERROR_INVALID_PARAMS);
            return;
        }
        udp_stack = io_stack(io);
        remote_port = udp_stack->remote_port;
        dst.u32.ip = udp_stack->remote_addr.u32.ip;
        io_pop(io, sizeof(UDP_STACK));
    }
    else
    {
        remote_port = uh->remote_port;
        dst.u32.ip = uh->remote_addr.u32.ip;
    }

    for (offset = 0; offset < io->data_size; offset += size)
    {
        size = UDP_FRAME_MAX_DATA_SIZE;
        if (size > io->data_size - offset)
            size = io->data_size - offset;
        cur = ips_allocate_io(tcpips, size + sizeof(UDP_HEADER), PROTO_UDP);
        if (cur == NULL)
            return;
        //copy data
        memcpy((uint8_t*)io_data(cur) + sizeof(UDP_HEADER), (uint8_t*)io_data(io) + offset, size);
        udp = io_data(cur);
// correct size
        cur->data_size = size + sizeof(UDP_HEADER);
        //format header
        short2be(udp->src_port_be, uh->local_port);
        short2be(udp->dst_port_be, remote_port);
        short2be(udp->len_be, size + sizeof(UDP_HEADER));
        short2be(udp->checksum_be, 0);
        short2be(udp->checksum_be, udp_checksum(io_data(cur), cur->data_size, &tcpips->ips.ip, &dst));
        ips_tx(tcpips, cur, &dst);
    }
}
Example #3
0
static void icmps_control_prepare(TCPIPS* tcpips, uint8_t cmd, uint8_t code, IO* original)
{
    IP_STACK* ip_stack;
    ip_stack = io_stack(original);
    //cmd
    ((uint8_t*)io_data(original))[0] = cmd;
    //code
    ((uint8_t*)io_data(original))[1] = code;
    //generally unused
    *(uint32_t*)(((uint8_t*)io_data(original)) + 4) = 0;
    //64 bits + original IP header
    memmove(((uint8_t*)io_data(original)) + sizeof(ICMP_HEADER), ((uint8_t*)io_data(original)) - ip_stack->hdr_size, ip_stack->hdr_size + 8);
}
Example #4
0
static inline void icmps_tx_time_exceed(TCPIPS* tcpips, uint8_t code, IO* original)
{
    ICMP_HEADER* icmp;
    IP_STACK* ip_stack = io_stack(original);
    IP_HEADER* hdr = io_data(original);
#if (ICMP_DEBUG)
    printf("ICMP: Time exceeded(%d) to ", code);
    ip_print(&hdr->src);
    printf("\n");
#endif
    IO* io = ips_allocate_io(tcpips, sizeof(ICMP_HEADER) + ip_stack->hdr_size + 8, PROTO_ICMP);
    if (io == NULL)
        return;
    icmp = io_data(io);
    icmp->type = ICMP_CMD_TIME_EXCEEDED;
    icmp->code = code;
    memcpy(((uint8_t*)io_data(io)) + sizeof(ICMP_HEADER), io_data(original), ip_stack->hdr_size + 8);
    io->data_size = ip_stack->hdr_size + 8 + sizeof(ICMP_HEADER);
    icmps_tx(tcpips, io, &hdr->src);
}
Example #5
0
static inline void icmps_tx_destination_unreachable(TCPIPS* tcpips, uint8_t code, IO* original)
{
    ICMP_HEADER* icmp;
    IP_STACK* ip_stack = io_stack(original);
    IP_HEADER* hdr = io_data(original);
#if (ICMP_DEBUG)
    printf("ICMP: Destination unreachable(%d) to ", code);
    ip_print(&hdr->src);
    printf("\n");
#endif
    IO* io = ips_allocate_io(tcpips, sizeof(ICMP_HEADER) + ip_stack->hdr_size + 8, PROTO_ICMP);
    if (io == NULL)
        return;
    icmp = io_data(io);
    icmp->type = ICMP_CMD_DESTINATION_UNREACHABLE;
    icmp->code = code;
    memcpy(((uint8_t*)io_data(io)) + sizeof(ICMP_HEADER), io_data(original), ip_stack->hdr_size + 8);
    io->data_size = ip_stack->hdr_size + 8 + sizeof(ICMP_HEADER);
    icmps_tx(tcpips, io, &hdr->src);
}
Example #6
0
static inline void icmps_tx_parameter_problem(TCPIPS* tcpips, uint8_t offset, IO* original)
{
    ICMP_HEADER_PARAM* icmp;
    IP_STACK* ip_stack = io_stack(original);
    IP_HEADER* hdr = io_data(original);
#if (ICMP_DEBUG)
    printf("ICMP: Parameter problem(%d) to ", offset);
    ip_print(&hdr->src);
    printf("\n");
#endif
    IO* io = ips_allocate_io(tcpips, sizeof(ICMP_HEADER_PARAM) + ip_stack->hdr_size + 8, PROTO_ICMP);
    if (io == NULL)
        return;
    icmp = io_data(io);
    icmp->type = ICMP_CMD_PARAMETER_PROBLEM;
    icmp->code = 0;
    icmp->param = offset;
    memcpy(((uint8_t*)io_data(io)) + sizeof(ICMP_HEADER_PARAM), io_data(original), ip_stack->hdr_size + 8);
    io->data_size = ip_stack->hdr_size + 8 + sizeof(ICMP_HEADER_PARAM);
    icmps_tx(tcpips, io, &hdr->src);
}
Example #7
0
static inline void lpc_sdmmc_io(CORE* core, HANDLE process, HANDLE user, IO* io, unsigned int size, bool read)
{
    SHA1_CTX sha1;
    unsigned int count;
    STORAGE_STACK* stack = io_stack(io);
    io_pop(io, sizeof(STORAGE_STACK));
    if (!core->sdmmc.active)
    {
        error(ERROR_NOT_CONFIGURED);
        return;
    }
    if (core->sdmmc.state != SDMMC_STATE_IDLE)
    {
        error(ERROR_IN_PROGRESS);
        return;
    }
    if ((user != core->sdmmc.user) || (size == 0))
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    //erase
    if (!read && ((stack->flags & STORAGE_MASK_MODE) == 0))
    {
        sdmmcs_erase(&core->sdmmc.sdmmcs, stack->sector, size);
        return;
    }
    if (size % core->sdmmc.sdmmcs.sector_size)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    count = size / core->sdmmc.sdmmcs.sector_size;
    core->sdmmc.total = size;
    if (core->sdmmc.total > LPC_SDMMC_TOTAL_SIZE)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    if ((core->sdmmc.activity != INVALID_HANDLE) && !(stack->flags & STORAGE_FLAG_IGNORE_ACTIVITY_ON_REQUEST))
    {
        ipc_post_inline(core->sdmmc.activity, HAL_CMD(HAL_SDMMC, STORAGE_NOTIFY_ACTIVITY), core->sdmmc.user, read ? 0 : STORAGE_FLAG_WRITE, 0);
        core->sdmmc.activity = INVALID_HANDLE;
    }
    core->sdmmc.io = io;
    core->sdmmc.process = process;

    lpc_sdmmc_prepare_descriptors(core);

    if (read)
    {
        io->data_size = 0;
        core->sdmmc.state = SDMMC_STATE_READ;
        if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count))
            error(ERROR_SYNC);
    }
    else
    {
        switch (stack->flags & STORAGE_MASK_MODE)
        {
        case STORAGE_FLAG_WRITE:
            core->sdmmc.state = SDMMC_STATE_WRITE;
            if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count))
                error(ERROR_SYNC);
            break;
        default:
            //verify/verify write
            sha1_init(&sha1);
            sha1_update(&sha1, io_data(io), core->sdmmc.total);
            sha1_final(&sha1, core->sdmmc.hash);
            core->sdmmc.sector = stack->sector;
            switch (stack->flags & STORAGE_MASK_MODE)
            {
            case STORAGE_FLAG_VERIFY:
                core->sdmmc.state = SDMMC_STATE_VERIFY;
                if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count))
                    error(ERROR_SYNC);
                break;
            case (STORAGE_FLAG_VERIFY | STORAGE_FLAG_WRITE):
                core->sdmmc.state = SDMMC_STATE_WRITE_VERIFY;
                if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count))
                    error(ERROR_SYNC);
                break;
            default:
                error(ERROR_NOT_SUPPORTED);
                return;
            }
        }
    }
}