Pergunta

Para um projeto, eu estou tentando enviar pacotes UDP a partir do Linux kernel-espaço. Atualmente estou 'embutir' meu código no kernel (que eu aprecio não é o melhor caminho / mais puro), mas eu estou tentando obter um teste simples para o trabalho (enviando "TEST"). Deve-se mencionar Eu sou um novato para kernel hacker - Não que clued em muitos princípios e técnicas sou

Toda vez que meu código é executado o sistema trava e eu tenho que reboot - nenhum rato resposta / teclado e o livro e Caps Lock Acende-chave piscam juntos - Eu não tenho certeza o que isso significa, mas eu estou assumindo que é um kernel do pânico?

O código repeat_send é desnecessário para este código de teste, mas quando ele está trabalhando Quero enviar mensagens grandes que podem exigir múltiplo 'send de? - Não tenho certeza de que se poderia ser uma causa dos meus problemas

NB. Este código está sendo inserido neighbour.c de linux-source / net / core / origem, daí o uso de NEIGH_PRINTK1, é apenas uma macro invólucro printk rodada.

Eu estou realmente batendo a cabeça contra uma parede de tijolos aqui, não pode manchar nada óbvio, pode apontar ninguém me na direção certa (ou detectar esse erro óbvias!)?

Aqui está o que eu tenho até agora:

void mymethod()
{
    struct socket sock;
    struct sockaddr_in addr_in;
    int ret_val;
    unsigned short port = htons(2048);
    unsigned int host = in_aton("192.168.1.254");
    unsigned int length = 5;
    char *buf = "TEST\0";
    struct msghdr msg;
    struct iovec iov;
    int len = 0, written = 0, left = length;
    mm_segment_t oldmm;

    NEIGH_PRINTK1("forwarding sk_buff at: %p.\n", skb);

    if ((ret_val = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
        NEIGH_PRINTK1("Error during creation of socket; terminating. code: %d\n", ret_val);
        return;
    }

    memset(&addr_in, 0, sizeof(struct sockaddr_in));
    addr_in.sin_family=AF_INET;
    addr_in.sin_port = port;
    addr_in.sin_addr.s_addr = host;

    if((ret_val = sock.ops->bind(&sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in))) < 0) {
    NEIGH_PRINTK1("Error trying to bind socket. code: %d\n", ret_val);
    goto close;
    }

    memset(&msg, 0, sizeof(struct msghdr));
    msg.msg_flags = 0;
    msg.msg_name = &addr_in;
    msg.msg_namelen = sizeof(struct sockaddr_in);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;

repeat_send:
    msg.msg_iov->iov_len = left;
    msg.msg_iov->iov_base = (char *)buf + written;

    oldmm = get_fs(); 
    set_fs(KERNEL_DS);
    len = sock_sendmsg(&sock, &msg, left);
    set_fs(oldmm);

    if (len == -ERESTARTSYS)
        goto repeat_send;
    if (len > 0) {
        written += len;
        left -= len;
        if (left)
            goto repeat_send;
    }

close:
    sock_release(&sock);
}

Qualquer ajuda seria extremamente apreciada, obrigado!

Foi útil?

Solução

Você pode achar que é mais fácil usar o netpoll API para UDP. Dê uma olhada na netconsole para um exemplo de como ele é usado. As APIs que você está usando são mais destinado para userspace (você nunca deve ter que jogar com descritores de segmento para enviar os dados da rede!)

Outras dicas

Executar seu código quando você está em um console modo texto (ou seja, pressione Ctrl + Alt + F1 para ir para o console de texto). Desta forma, um kernel panic irá imprimir o rastreamento de pilha e qualquer informação extra sobre o que deu errado.

Se isso não ajudar, atualizar sua pergunta com o rastreamento de pilha.

Eu não sou muito de um desenvolvedor Linux Kernel, mas você pode lançar alguma printk de lá e dmesg relógio antes que ele vai para baixo? Ou você já pensou em se juntar com um depurador de kernel?

Eu acho que você deve tentar colocar todas as funções fora mymethod () variáveis ??e torná-los estática. Lembre-se que o tamanho da pilha do kernel é limitado fazer 8KiB, por assim grande parte / grandes demais variáveis ??locais pode causar estouro de pilha e desligamento do sistema.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top