سؤال

أريد أن أكتب أداة تحليل في الوقت الحقيقي لحركة المرور اللاسلكية.

هل يعرف أحد كيفية القراءة من جهاز غير شرعي (أو استنشاق) في لغة C؟

أعلم أنك بحاجة إلى الوصول إلى الجذر للقيام بذلك.كنت أتساءل إذا كان أي شخص يعرف ما هي الوظائف اللازمة للقيام بذلك.لا يبدو أن المقابس العادية منطقية هنا.

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

المحلول

في نظام التشغيل Linux، يمكنك استخدام مقبس PF_PACKET لقراءة البيانات من جهاز أولي، مثل واجهة إيثرنت التي تعمل في الوضع المختلط:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

سيؤدي هذا إلى إرسال نسخ من كل حزمة تم استلامها إلى المقبس الخاص بك.ومع ذلك، فمن المحتمل جدًا أنك لا تريد حقًا كل حزمة.يمكن للنواة تنفيذ المستوى الأول من التصفية باستخدام BPF، مرشح حزمة بيركلي.BPF هو في الأساس جهاز افتراضي قائم على المكدس:يتعامل مع مجموعة صغيرة من التعليمات مثل:

ldh = load halfword (from packet)  
jeq = jump if equal  
ret = return with exit code  

يخبر رمز الخروج الخاص بـ BPF النواة ما إذا كان سيتم نسخ الحزمة إلى المقبس أم لا.من الممكن كتابة برامج BPF صغيرة نسبيًا مباشرةً، باستخدام setockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, ).(تحذير:تأخذ النواة البنية sock_fprog، وليس البنية bpf_program، فلا تخلط بينها وإلا فلن يعمل برنامجك على بعض الأنظمة الأساسية).

بالنسبة لأي شيء معقد إلى حد معقول، فأنت تريد حقًا استخدام libpcap.BPF محدود فيما يمكنه فعله، لا سيما في عدد التعليمات التي يمكنه تنفيذها لكل حزمة. libpcap سيهتم بتقسيم مرشح معقد إلى جزأين، حيث تؤدي النواة المستوى الأول من التصفية ويقوم كود مساحة المستخدم الأكثر قدرة بإسقاط الحزم التي لا يريد رؤيتها بالفعل.

يقوم libpcap أيضًا باستخراج واجهة kernel من كود التطبيق الخاص بك.يستخدم Linux وBSD واجهات برمجة تطبيقات مشابهة، لكن Solaris يتطلب DLPI ويستخدم Windows شيئًا آخر.

نصائح أخرى

لقد اضطررت ذات مرة إلى الاستماع إلى إطارات إيثرنت خام وانتهى بي الأمر بإنشاء غلاف لهذا الغرض.عن طريق استدعاء الوظيفة باسم الجهاز، على سبيل المثال eth0 حصلت على مقبس في المقابل كان في وضع غير شرعي.ما عليك فعله هو إنشاء مقبس خام ثم وضعه في الوضع المختلط.هنا كيف فعلت ذلك.

int raw_init (const char *device)
{
    struct ifreq ifr;
    int raw_socket;

    memset (&ifr, 0, sizeof (struct ifreq));

    /* Open A Raw Socket */
    if ((raw_socket = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 1)
    {
        printf ("ERROR: Could not open socket, Got #?\n");
        exit (1);
    }

    /* Set the device to use */
    strcpy (ifr.ifr_name, device);

    /* Get the current flags that the device might have */
    if (ioctl (raw_socket, SIOCGIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not retrive the flags from the device.\n");
        exit (1);
    }

    /* Set the old flags plus the IFF_PROMISC flag */
    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl (raw_socket, SIOCSIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not set flag IFF_PROMISC");
        exit (1);
    }
    printf ("Entering promiscuous mode\n");

    /* Configure the device */

    if (ioctl (raw_socket, SIOCGIFINDEX, &ifr) < 0)
    {
        perror ("Error: Error getting the device index.\n");
        exit (1);
    }

    return raw_socket;
}

ثم عندما يكون لديك المقبس الخاص بك، يمكنك فقط استخدام التحديد للتعامل مع الحزم عند وصولها.

يمكنك استخدام مكتبة pcap (انظر http://www.tcpdump.org/pcap.htm) والذي يستخدمه أيضًا tcpdump وWireshark.

لماذا لا تستخدم شيئا مثل واير شارك?

إنه مفتوح المصدر، لذا يمكنك على الأقل تعلم بعض الأشياء منه إذا كنت لا ترغب في استخدامه فقط.

يتمتع WireShark على نظام Linux بالقدرة على التقاط معلومات رأس PLCP (بروتوكول تقارب الطبقة المادية).

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