سؤال

لمشروع, أنا أحاول إرسال حزم UDP من نواة لينكس-الفضاء.أنا حاليا 'الثابت-ترميز' قانون بلدي في النواة (التي أنا أقدر ليست أفضل/أبرع طريقة) ولكن أنا أحاول الحصول على اختبار بسيط للعمل (إرسال "اختبار").تجدر الإشارة انا مبتدئ نواة القرصنة - أنا لا تأثير على العديد من المبادئ والتقنيات!

كل مرة رمز يحصل تشغيل نظام تعليق و أنا أضطر إلى إعادة تشغيل أي الماوس/لوحة المفاتيح استجابة و التمرير و قبعات قفل مفتاح أضواء فلاش معا - لست متأكدا ماذا يعني هذا, ولكن أنا على افتراض انها نواة الذعر ؟

على repeat_send البرمجية غير الضرورية لهذا الاختبار رمز ، ولكن عندما تعمل أريد أن إرسال الرسائل الكبيرة التي قد تتطلب عدة إرسال أنا لست متأكدا من أنه إذا كان يمكن أن يكون قضية من القضايا ؟

N. B.هذا الكود يتم إدراجها في الجار.ج لينكس-المصدر/net/core/ الأصل ، ومن ثم استخدام 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);
}

أي مساعدة سوف أكون ممتنا بشكل كبير, وذلك بفضل!

هل كانت مفيدة؟

المحلول

قد تجد أنه من الأسهل استخدام netpoll API UDP.نلقي نظرة على netconsole للحصول على مثال عن كيفية استخدامها.واجهات برمجة التطبيقات كنت تستخدم أكثر المقصود userspace (لم يكن عليك أن تلعب مع الجزء واصفات إرسال بيانات الشبكة!)

نصائح أخرى

وتشغيل التعليمات البرمجية الخاصة بك عندما كنت في وحدة التحكم وضع النص (أي اضغط Ctrl + Alt + F1 للذهاب إلى وحدة النص). بهذه الطريقة حالة من الذعر نواة سوف بطباعة تتبع المكدس وأية معلومات إضافية حول ما حدث من خطأ.

وإذا كان هذا لا يساعد لكم، تحديث سؤالك مع تتبع المكدس.

وأنا لست كثير من مطور نواة لينكس، ولكن يمكنك رمي بعض لprintk هناك ومشاهدة dmesg قبل أن يذهب إلى أسفل؟ أو هل فكرت في تركيب مع مصحح أخطاء kernel؟

وأعتقد أنك يجب أن تحاول وضع كل المتغيرات خارج وظيفة mymethod () وجعلها ثابتة. تذكر، أن حجم كومة نواة يقتصر القيام 8KiB، وذلك إلى الكثير من / المتغيرات المحلية كبيرة جدا قد يسبب فيضان المكدس واغلاق الخط النظام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top