Question

Pour un projet, j'essaie d'envoyer des paquets UDP à partir de l'espace noyau Linux. Je suis actuellement en train de "coder en dur" mon code dans le noyau (ce qui, j'en suis conscient, n'est pas le meilleur moyen / le plus ordonné), mais j'essaie de faire fonctionner un simple test (l'envoi de "TEST"). Il convient de mentionner que je suis un débutant en piratage du noyau - je ne suis pas au courant de beaucoup de principes et de techniques!

Chaque fois que mon code est exécuté, le système se bloque et je dois redémarrer - aucune réponse souris / clavier et les touches de défilement et de verrouillage majuscule clignotent ensemble - Je ne suis pas sûr de ce que cela signifie, mais je suppose que c'est un panique du noyau?

Le code repeat_send n'est pas nécessaire pour ce code de test. Néanmoins, lorsqu'il fonctionne, je souhaite envoyer des messages volumineux pouvant nécessiter l'envoi de plusieurs messages. Je ne suis pas sûr que cela puisse être la cause de mes problèmes?

N.B. Ce code est inséré dans le fichier voisin.c de linux-source / net / core / origin, d’où l’utilisation de NEIGH_PRINTK1, c’est juste une enveloppe de macro autour de printk.

Je frappe vraiment la tête contre un mur de briques ici, je ne vois rien d’évident, est-ce que quelqu'un peut me diriger dans la bonne direction (ou repérer cette erreur si aveuglante!)?

Voici ce que j'ai jusqu'à présent:

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

Toute aide serait grandement appréciée, merci!

Était-ce utile?

La solution

Il est peut-être plus facile d'utiliser API netpoll pour UDP. Consultez netconsole pour obtenir un exemple de la manière c'est utilisé. Les API que vous utilisez sont davantage destinées à l’espace utilisateur (vous ne devriez jamais avoir à jouer avec les descripteurs de segment pour envoyer des données réseau!)

Autres conseils

Exécutez votre code lorsque vous êtes dans une console en mode texte (c.-à-d. appuyez sur Ctrl + Alt + F1 pour accéder à la console texte). De cette façon, une panique du noyau affichera la trace de la pile et toute information supplémentaire sur ce qui ne va pas.

Si cela ne vous aide pas, mettez à jour votre question avec le suivi de la pile.

Je ne suis pas vraiment un développeur de noyau Linux, mais pouvez-vous ajouter des printk et regarder dmesg avant qu'il ne tombe en panne? Ou avez-vous pensé à vous connecter avec un débogueur de noyau?

Je pense que vous devriez essayer de placer toutes les variables en dehors de la fonction mymethod () et de les rendre statiques. N'oubliez pas que la taille de la pile du noyau est limitée à 8 Ko, de sorte que trop de / trop grandes variables locales peuvent provoquer un dépassement de capacité de la pile et un blocage du système.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top