Отправка UDP-пакета в ядре Linux - PullRequest
1 голос
/ 29 ноября 2009

Для проекта я пытаюсь отправить UDP-пакеты из пространства ядра Linux. В настоящее время я «жестко программирую» свой код в ядре (что, я ценю, не самый лучший / самый удачный способ), но я пытаюсь заставить работать простой тест (посылая «TEST»). Следует отметить, что я новичок во взломе ядра - я не слишком разбираюсь во многих принципах и методах!

Каждый раз, когда мой код запускается, система зависает, и мне приходится перезагружаться - не реагирует мышь / клавиатура, а клавиши scroll и caps lock мигают вместе - я не уверен, что это значит, но я предполагаю, что это ядро паники?

Код repeat_send не нужен для этого тестового кода, но когда он работает, я хочу отправлять большие сообщения, которые могут потребовать многократной отправки - я не уверен, что может быть причиной моих проблем?

N.B. Этот код вставляется в соседний файл linux-source / net / core / origin, поэтому используется NEIGH_PRINTK1, это просто макрос-оболочка вокруг printk.

Я действительно бьюсь головой о кирпичную стену здесь, я не вижу ничего очевидного, может ли кто-нибудь указать мне правильное направление (или заметить эту ослепительно очевидную ошибку!)?

Вот что у меня есть:

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);
}

Любая помощь будет принята с благодарностью, спасибо!

Ответы [ 4 ]

2 голосов
/ 29 ноября 2009

Возможно, вам будет проще использовать netpoll API для UDP. Взгляните на netconsole , чтобы узнать, как он используется. Используемые вами API больше предназначены для пользовательского пространства (вам никогда не придется играть с дескрипторами сегментов для отправки сетевых данных!)

0 голосов
/ 26 марта 2010

Я думаю, вы должны попытаться поместить все переменные вне функции mymethod () и сделать их статическими. Помните, что размер стека ядра ограничен 8 КБ, поэтому большая часть / слишком большие локальные переменные могут вызвать переполнение стека и зависание системы.

0 голосов
/ 29 ноября 2009

Я не большой разработчик ядра Linux, но можете ли вы добавить туда несколько printk и посмотреть dmesg, прежде чем он выйдет из строя? Или вы думали о подключении к отладчику ядра?

0 голосов
/ 29 ноября 2009

Запускайте код, когда вы находитесь в консоли текстового режима (т.е. нажмите Ctrl + Alt + F1, чтобы перейти к текстовой консоли). Таким образом, паника ядра выведет трассировку стека и любую дополнительную информацию о том, что пошло не так.

Если это не поможет, обновите ваш вопрос с помощью трассировки стека.

...