
الغرض من هذا المشروع هو:
- تعلم DHCP عبر شبكة IPv4
- تعلم بايثون (أكثر بقليل من الصفر ؛))
- استبدال خادم DB2DHCP (شوكة بلدي) الأصلي هنا ، والذي يصعب تجميعه تحت نظام التشغيل الجديد. نعم ، وأنا لا أحب ذلك الثنائي ، وهو غير ممكن "التغيير في الوقت الحالي"
- الحصول على خادم DHCP يعمل مع القدرة على تحديد عنوان IP الخاص بالمشترك عن طريق المشترك mac أو عن طريق مجموعة من مفاتيح mac + port (الخيار 82)
- كتابة دراجة أخرى (أوه! هذا هو هوايتي المفضلة)
- الحصول على luli حول الحول الخاص بك على Habrahabr (أو دعوة أفضل) ؛)
النتيجة: إنه يعمل ؛) تم اختباره على FreeBSD و Ubuntu OS. من الناحية النظرية ، يمكن طلب الرمز للعمل تحت أي نظام تشغيل ، لأنه لا توجد روابط محددة في الكود.
الحذر! أبعد من ذلك بكثير.
رابط إلى مستودع للجماهير
"للمس على قيد الحياة" .
عملية تثبيت وتكوين واستخدام نتيجة "دراسة الأجهزة" أقل بكثير ، ومن ثم نظرية قليلة على بروتوكول DHCP. لنفسي وللقصة ؛)
قليلا من الناحية النظرية
ما هو DHCP؟
هذا هو بروتوكول شبكة يسمح للجهاز باكتشاف عنوان IP الخاص به (جيدًا ، معلمات أخرى مثل البوابة ، DNS ، إلخ) من خادم DHCP. يتم تبادل الحزم عبر UDP. المبدأ العام لتشغيل الجهاز عند طلب معلمات الشبكة هو كما يلي:
- يرسل الجهاز (العميل) طلب بث UDP (DHCPDISCOVER) عبر الشبكة مع الطلب ، "حسنًا ، شخص ما ، أعطني عنوان IP." عادةً (ولكن ليس دائمًا) يكون الطلب من المنفذ 68 (المصدر) ، والوجهة هي المنفذ 67 (الوجهة). تقوم بعض الأجهزة أيضًا بإرسال حزم من المنفذ 67. داخل حزمة DHCPDISCOVER ، يتم تضمين عنوان MAC لجهاز العميل.
- جميع خوادم DHCP الموجودة على الشبكة (وقد يكون هناك عدة) نموذج للجهاز الذي أرسل DHCPDISCOVER جملة DHCPOFFER مع إعدادات الشبكة ، كما يبثها عبر الشبكة. ينتقل تحديد هوية هذه الحزمة إلى عنوان MAC للعميل المقدم مسبقًا في طلب DHCPDISCOVER.
- يتلقى العميل الحزم مع عروض إعدادات الشبكة ، ويختار الأكثر جاذبية (يمكن أن تكون المعايير مختلفة ، على سبيل المثال ، بحلول وقت تسليم الحزمة ، وعدد الطرق الوسيطة) ، ويجعل خادم DHCP "يطلب رسميًا" DHCPREQUEST مع إعدادات الشبكة. في هذه الحالة ، تنتقل الحزمة إلى خادم DHCP معين.
- يرسل الخادم الذي تلقى DHCPREQUEST حزمة DHCPACK يسرد فيها مرة أخرى إعدادات الشبكة لهذا العميل

بالإضافة إلى ذلك ، هناك حزم DHCPINFORM تأتي من العميل ، والغرض منها هو إبلاغ خادم DHCP بأن "العميل على قيد الحياة" ويستخدم إعدادات الشبكة الصادرة. في تنفيذ هذا الخادم ، يتم تجاهل هذه الحزم.
تنسيق الحزمة
بشكل عام ، يبدو إطار حزم Ethernet كما يلي:

في حالتنا ، سننظر فقط في البيانات مباشرةً من محتويات حزمة UDP ، دون رؤوس بروتوكول طبقة OSI ، وهي بنية DHCP:
DHCPDISCOVER
لذلك ، تبدأ عملية الحصول على عنوان IP للجهاز بحقيقة أن عميل DHCP يرسل طلب بث من المنفذ 68 إلى 255.255.255.255:67. في هذه الحزمة ، يتضمن العميل عنوان MAC الخاص به ، وكذلك ما يريد تلقيه من خادم DHCP. ويرد وصف هيكل الحزمة في الجدول أدناه.
جدول بنية حزم DHCPDISCOVERموقف حزمة | اسم القيمة | مثال | فكرة | بايت | توضيح |
1 | طلب التمهيد | 1 | عرافة | 1 | نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل |
2 | نوع الجهاز | 1 | عرافة | 1 | نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC |
3 | طول adrees الأجهزة | 6 | عرافة | 1 | طول عنوان MAC للجهاز |
4 | القفزات | 1 | عرافة | 1 | عدد الطرق الوسيطة |
5 | معرف المعاملة | 23: راجع: de: 1d | عرافة | 4 | معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب |
7 | الثاني المنقضي | 0 | عرافة | 4 | الوقت بالثواني منذ بداية عملية الحصول على العنوان |
9 | أعلام Bootp | 0 | عرافة | 2 | بعض العلامات التي يمكن تعيينها كدليل على معلمات البروتوكول |
11 | عنوان IP للعميل | 0.0.0.0 | صف | 4 | عنوان IP للعميل (إن وجد) |
15 | عنوان IP الخاص بالعميل | 0.0.0.0 | صف | 4 | عنوان IP المقترح من قبل الخادم (إن وجد) |
19 | خادم عنوان IP التالي | 0.0.0.0 | صف | 4 | عنوان IP للخادم (إذا كان معروفًا) |
23 | ترحيل عنوان IP الوكيل | 172.16.114.41 | صف | 4 | عنوان IP لعامل الترحيل (على سبيل المثال ، رمز تبديل) |
27 | عنوان MAC العميل | 14: d6: 4d: a7: c9: 55 | عرافة | 6 | عنوان MAC لمُرسِل الحزمة (العميل) |
31 | حشوة عنوان جهاز العميل | | عرافة | 10 | مكان محجوز. عادة أصفار |
41 | اسم مضيف الخادم | | صف | 64 | اسم خادم DHCP. عادة لا تنتقل |
105 | اسم ملف التمهيد | | صف | 128 | اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد |
235 | ملف تعريف الارتباط السحري | 63: 82: 53: 63 | عرافة | 4 | الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP |
خيارات DHCP. يمكن أن تذهب في أي ترتيب |
236 | رقم الخيار | 53 | ديسمبر | 1 | الخيار 53 الذي يحدد نوع حزمة DHCP
1 - DHCPDISCOVER 3 - DHCPREQUEST 2 - DHCPOFFER 5 - DHCPACK 8 - DHCPINFORM |
| طول الخيار | 1 | ديسمبر | 1 |
| قيمة الخيار | 1 | ديسمبر | 1 |
| رقم الخيار | 50 | ديسمبر | 1 | ما عنوان IP الذي يريد العميل استلامه؟ |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 172.16.134.61 | صف | 4 |
| رقم الخيار | 55 | | 1 | معلمات الشبكة المطلوبة من قبل العميل. التكوين قد يكون مختلفا
01 - قناع الشبكة 03 - بوابة 06 - DNS اسم المضيف 0f - اسم مجال الشبكة 1C - عنوان طلب البث (البث) 42 - اسم خادم TFTP 79 - طريق ثابت بدون طبقات |
| طول الخيار | 8 | | 1 |
| قيمة الخيار | 01: 03: 06: 0c: 0f: 1c: 42: 79 | | 8 |
| رقم الخيار | 82 | ديسمبر | | الخيار 82 ، الذي يتم فيه إرسال عنوان MAC لجهاز التكرار وبعض القيم الإضافية.
غالبًا ما يكون منفذ التبديل الذي يعمل عليه عميل نهاية DHCP ، حيث يتم "تضمين" الخيارات الإضافية في هذا الخيار ، البايتة الأولى هي رقم "suboption" ، والثاني هو طوله ، ثم قيمته.
في هذه الحالة ، في الخيار 82 ، يتم تداخل الخيارات الفرعية: معرف حلبة الوكيل = 00: 04: 00: 01: 00: 04 ، حيث آخر وحدتي بايت هما منفذ عميل DHCP الذي جاء منه الطلب
معرف العميل عن بُعد = 00: 06: c8: be: 19: 93: 11: 48 - عنوان MAC لجهاز ترحيل DHCP |
| طول الخيار | 18 | ديسمبر | |
| قيمة الخيار | 01:06 00: 04: 00: 01: 00: 04 02:08 00: 06: c8: be: 19: 93: 11: 48 | عرافة | |
| نهاية الحزمة | 255 | ديسمبر | 1 | 255 يرمز إلى نهاية الحزمة |
DHCPOFFER
بمجرد أن يتلقى الخادم حزمة DHCPDISCOVER وإذا رأى أنه يمكن أن يقدم للعميل شيئًا من المطلوب ، فإنه يشكل استجابة لذلك - DHCPOFFER. يتم إرسال الجواب إلى المنفذ "من أين جاء" ، البث ، لأنه في هذه اللحظة ، ليس لدى العميل بعد عنوان IP ، لذلك ، لا يمكنه تلقي حزمة إلا إذا تم إرساله بالبث. يدرك العميل أنها عبارة عن حزمة له من قِبل لجنة الهدنة العسكرية على عنوانه داخل الحزمة ، وكذلك رقم المعاملة الذي ينشئه في وقت إنشاء الحزمة الأولى.
جدول هيكل الحزمة DHCPOFFERموقف حزمة | اسم القيمة (مشترك) | مثال | فكرة | بايت | توضيح |
1 | طلب التمهيد | 1 | عرافة | 1 | نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل |
2 | نوع الجهاز | 1 | عرافة | 1 | نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC |
3 | طول adrees الأجهزة | 6 | عرافة | 1 | طول عنوان MAC للجهاز |
4 | القفزات | 1 | عرافة | 1 | عدد الطرق الوسيطة |
5 | معرف المعاملة | 23: راجع: de: 1d | عرافة | 4 | معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب |
7 | الثاني المنقضي | 0 | عرافة | 4 | الوقت بالثواني منذ بداية عملية الحصول على العنوان |
9 | أعلام Bootp | 0 | عرافة | 2 | بعض العلامات التي يمكن تعيينها كدليل على معلمات البروتوكول. في هذه الحالة ، يعني 0 نوع طلب البث الأحادي |
11 | عنوان IP للعميل | 0.0.0.0 | صف | 4 | عنوان IP للعميل (إن وجد) |
15 | عنوان IP الخاص بالعميل | 172.16.134.61 | صف | 4 | عنوان IP المقترح من قبل الخادم (إن وجد) |
19 | خادم عنوان IP التالي | 0.0.0.0 | صف | 4 | عنوان IP للخادم (إذا كان معروفًا) |
23 | ترحيل عنوان IP الوكيل | 172.16.114.41 | صف | 4 | عنوان IP لعامل الترحيل (على سبيل المثال ، رمز تبديل) |
27 | عنوان MAC العميل | 14: d6: 4d: a7: c9: 55 | عرافة | 6 | عنوان MAC لمُرسِل الحزمة (العميل) |
31 | حشوة عنوان جهاز العميل | | عرافة | 10 | مكان محجوز. عادة أصفار |
41 | اسم مضيف الخادم | | صف | 64 | اسم خادم DHCP. عادة لا تنتقل |
105 | اسم ملف التمهيد | | صف | 128 | اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد |
235 | ملف تعريف الارتباط السحري | 63: 82: 53: 63 | عرافة | 4 | الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP |
خيارات DHCP. يمكن أن تذهب في أي ترتيب |
236 | رقم الخيار | 53 | ديسمبر | 1 | الخيار 53 الذي يحدد نوع حزمة DHCP 2 - DHCPOFFER |
| طول الخيار | 1 | ديسمبر | 1 |
| قيمة الخيار | 2 | ديسمبر | 1 |
| رقم الخيار | 1 | ديسمبر | 1 | خيار تقديم قناع شبكة عميل DHCP |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 255.255.224.0 | صف | 4 |
| رقم الخيار | 3 | ديسمبر | 1 | خيار تقديم العبارة الافتراضية عميل DHCP |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 172.16.12.1 | صف | 4 |
| رقم الخيار | 6 | ديسمبر | 1 | خيار تقديم DHCP إلى عميل DNS |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 8.8.8.8 | صف | 4 |
| رقم الخيار | 51 | ديسمبر | 1 | عمر معلمات الشبكة الصادرة بالثواني ، وبعد ذلك يجب على عميل DHCP طلبها مرة أخرى |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 86400 | ديسمبر | 4 |
| رقم الخيار | 82 | ديسمبر | 1 | الخيار 82 ، يكرر ما جاء في DHCPDISCOVER |
| طول الخيار | 18 | ديسمبر | 1 |
| قيمة الخيار | 01: 08: 00: 06: 00 01: 01: 00: 00: 01 02: 06: 00: 03: 0f 26: 4 أيام: ec | ديسمبر | 18 |
| نهاية الحزمة | 255 | ديسمبر | 1 | 255 يرمز إلى نهاية الحزمة |
DHCPREQUEST
بعد أن يتلقى العميل DHCPOFFER ، فإنه يشكل حزمة مع طلب لمعلمات الشبكة ليس لجميع خوادم DHCP في الشبكة ، ولكن فقط لخادم واحد محدد ، والذي اقترحه DHCPOFFER أكثر. يمكن أن تكون معايير "أعجبني" مختلفة وتعتمد على تنفيذ عميل DHCP. تتم الإشارة إلى مستلم الطلب باستخدام عنوان MAC لخادم DHCP. أيضًا ، يمكن إرسال حزمة DHCPREQUEST من قبل العميل دون تكوين DHCPDISCOVER مسبقًا ، إذا كان قد تم استلام عنوان IP الخاص بالخادم مسبقًا مسبقًا.
DHCPREQUEST جدول بنية الحزمةموقف حزمة | اسم القيمة (مشترك) | مثال | فكرة | بايت | توضيح |
1 | طلب التمهيد | 1 | عرافة | 1 | نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل |
2 | نوع الجهاز | 1 | عرافة | 1 | نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC |
3 | طول adrees الأجهزة | 6 | عرافة | 1 | طول عنوان MAC للجهاز |
4 | القفزات | 1 | عرافة | 1 | عدد الطرق الوسيطة |
5 | معرف المعاملة | 23: راجع: de: 1d | عرافة | 4 | معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب |
7 | الثاني المنقضي | 0 | عرافة | 4 | الوقت بالثواني منذ بداية عملية الحصول على العنوان |
9 | أعلام Bootp | 8000 | عرافة | 2 | بعض العلامات التي يمكن تعيينها كدليل على معلمات البروتوكول. في هذه الحالة ، "البث" |
11 | عنوان IP للعميل | 0.0.0.0 | صف | 4 | عنوان IP للعميل (إن وجد) |
15 | عنوان IP الخاص بالعميل | 172.16.134.61 | صف | 4 | عنوان IP المقترح من قبل الخادم (إن وجد) |
19 | خادم عنوان IP التالي | 0.0.0.0 | صف | 4 | عنوان IP للخادم (إذا كان معروفًا) |
23 | ترحيل عنوان IP الوكيل | 172.16.114.41 | صف | 4 | عنوان IP لعامل الترحيل (على سبيل المثال ، رمز تبديل) |
27 | عنوان MAC العميل | 14: d6: 4d: a7: c9: 55 | عرافة | 6 | عنوان MAC لمُرسِل الحزمة (العميل) |
31 | حشوة عنوان جهاز العميل | | عرافة | 10 | مكان محجوز. عادة أصفار |
41 | اسم مضيف الخادم | | صف | 64 | اسم خادم DHCP. عادة لا تنتقل |
105 | اسم ملف التمهيد | | صف | 128 | اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد |
235 | ملف تعريف الارتباط السحري | 63: 82: 53: 63 | عرافة | 4 | الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP |
خيارات DHCP. يمكن أن تذهب في أي ترتيب |
236 | رقم الخيار | 53 | ديسمبر | 3 | الخيار 53 الذي يحدد نوع حزمة DHCP 3 - DHCPREQUEST |
| طول الخيار | 1 | ديسمبر | 1 |
| قيمة الخيار | 3 | ديسمبر | 1 |
| رقم الخيار | 61 | ديسمبر | 1 | معرف العميل: 01 (لإيثرنت) + عنوان MAC للعميل |
| طول الخيار | 7 | ديسمبر | 1 |
| قيمة الخيار | 01: 2c: ab: 25: ff: 72: a6 | عرافة | 7 |
| رقم الخيار | 60 | ديسمبر | | "معرف فئة البائع." في حالتي ، يتم الإبلاغ عن إصدار عميل DHCP. ربما تقوم الأجهزة الأخرى بإرجاع شيء آخر. تقارير Windows على سبيل المثال MSFT 5.0 |
| طول الخيار | 11 | ديسمبر | |
| قيمة الخيار | udhcp 0.9.8 | صف | |
| رقم الخيار | 55 | | 1 | معلمات الشبكة المطلوبة من قبل العميل. التكوين قد يكون مختلفا
01 - قناع الشبكة 03 - بوابة 06 - DNS اسم المضيف 0f - اسم مجال الشبكة 1C - عنوان طلب البث (البث) 42 - اسم خادم TFTP 79 - طريق ثابت بدون طبقات |
| طول الخيار | 8 | | 1 |
| قيمة الخيار | 01: 03: 06: 0c: 0f: 1c: 42: 79 | | 8 |
| رقم الخيار | 82 | ديسمبر | 1 | الخيار 82 ، يكرر ما جاء في DHCPDISCOVER |
| طول الخيار | 18 | ديسمبر | 1 |
| قيمة الخيار | 01: 08: 00: 06: 00 01: 01: 00: 00: 01 02: 06: 00: 03: 0f 26: 4 أيام: ec | ديسمبر | 18 |
| نهاية الحزمة | 255 | ديسمبر | 1 | 255 يرمز إلى نهاية الحزمة |
DHCPACK
كتأكيد لحقيقة "نعم ، إنه عنوان IP الخاص بك ، ولن أعطيها لأي شخص آخر" من خادم DHCP ، هناك حزمة DHCPACK من الخادم إلى العميل. هو نفس بقية الحزم المرسلة للبث. على الرغم من أنه في التعليمة البرمجية أدناه الخاصة بخادم DHCP الذي تم تنفيذه في بيثون ، في الحال ، أنا أكرر أي طلب بث عن طريق إرسال حزمة إلى عنوان IP لعميل معين ، إذا كان معروفًا بالفعل. علاوة على ذلك ، لا يهم خادم DHCP على الإطلاق ما إذا كانت الحزمة DHCPACK قد وصلت إلى العميل. إذا لم يتلق العميل DHCPACK ، فحينئذٍ يكرر DHCPREQUEST
جدول هيكل حزم DHCPACKموقف حزمة | اسم القيمة (مشترك) | مثال | فكرة | بايت | توضيح |
1 | طلب التمهيد | 2 | عرافة | 1 | نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل |
2 | نوع الجهاز | 1 | عرافة | 1 | نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC |
3 | طول adrees الأجهزة | 6 | عرافة | 1 | طول عنوان MAC للجهاز |
4 | القفزات | 1 | عرافة | 1 | عدد الطرق الوسيطة |
5 | معرف المعاملة | 23: راجع: de: 1d | عرافة | 4 | معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب |
7 | الثاني المنقضي | 0 | عرافة | 4 | الوقت بالثواني منذ بداية عملية الحصول على العنوان |
9 | أعلام Bootp | 8000 | عرافة | 2 | بعض العلامات التي يمكن تعيينها كدليل على معلمات البروتوكول. في هذه الحالة ، "البث" |
11 | عنوان IP للعميل | 0.0.0.0 | صف | 4 | عنوان IP للعميل (إن وجد) |
15 | عنوان IP الخاص بالعميل | 172.16.134.61 | صف | 4 | عنوان IP المقترح من قبل الخادم (إن وجد) |
19 | خادم عنوان IP التالي | 0.0.0.0 | صف | 4 | عنوان IP للخادم (إذا كان معروفًا) |
23 | ترحيل عنوان IP الوكيل | 172.16.114.41 | صف | 4 | عنوان IP لعامل الترحيل (على سبيل المثال ، رمز تبديل) |
27 | عنوان MAC العميل | 14: d6: 4d: a7: c9: 55 | عرافة | 6 | عنوان MAC لمُرسِل الحزمة (العميل) |
31 | حشوة عنوان جهاز العميل | | عرافة | 10 | مكان محجوز. عادة أصفار |
41 | اسم مضيف الخادم | | صف | 64 | اسم خادم DHCP. عادة لا تنتقل |
105 | اسم ملف التمهيد | | صف | 128 | اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد |
235 | ملف تعريف الارتباط السحري | 63: 82: 53: 63 | عرافة | 4 | الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP |
خيارات DHCP. يمكن أن تذهب في أي ترتيب |
236 | رقم الخيار | 53 | ديسمبر | 3 | الخيار 53 الذي يحدد نوع حزمة DHCP - DHCPACK |
| طول الخيار | 1 | ديسمبر | 1 |
| قيمة الخيار | 5 | ديسمبر | 1 |
| رقم الخيار | 1 | ديسمبر | 1 | خيار تقديم قناع شبكة عميل DHCP |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 255.255.224.0 | صف | 4 |
| رقم الخيار | 3 | ديسمبر | 1 | خيار تقديم العبارة الافتراضية عميل DHCP |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 172.16.12.1 | صف | 4 |
| رقم الخيار | 6 | ديسمبر | 1 | خيار تقديم DHCP إلى عميل DNS |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 8.8.8.8 | صف | 4 |
| رقم الخيار | 51 | ديسمبر | 1 | عمر معلمات الشبكة الصادرة بالثواني ، وبعد ذلك يجب على عميل DHCP طلبها مرة أخرى |
| طول الخيار | 4 | ديسمبر | 1 |
| قيمة الخيار | 86400 | ديسمبر | 4 |
| رقم الخيار | 82 | ديسمبر | 1 | الخيار 82 ، يكرر ما جاء في DHCPDISCOVER |
| طول الخيار | 18 | ديسمبر | 1 |
| قيمة الخيار | 01: 08: 00: 06: 00 01: 01: 00: 00: 01 02: 06: 00: 03: 0f 26: 4 أيام: ec | ديسمبر | 18 |
| نهاية الحزمة | 255 | ديسمبر | 1 | 255 يرمز إلى نهاية الحزمة |
تركيب
يتكون التثبيت بالفعل من تثبيت وحدات بيثون اللازمة لهذه المهمة. من المفترض أن MySQL قد تم تثبيته وتهيئته بالفعل.
فري
pkg تثبيت python3
python3 - م Enspip
pip3 تثبيت mysql الموصل
أوبونتو
سودو الرابطة بين الحصول على تثبيت python3
sudo الحصول على تثبيت pip3
sudo pip3 تثبيت mysql الموصل
نقوم بإنشاء قاعدة بيانات MySQL ، وملء ملف التفريغ pydhcp.sql ، تكوين ملف التكوين.
ترتيب
جميع إعدادات الخادم في تنسيق ملف XML. الملف المرجعي:
<؟ xml version = "1.0"؟>
<التكوين>
<Dhcpserver>
<host> 0.0.0.0 </host>
<broadcast> 255.255.255.255 </broadcast>
<DHCPServer> 192.168.0.71 </DHCPServer>
<LeaseTime> 8600 </LeaseTime>
<ThreadLimit> 1 </ThreadLimit>
<defaultMask> 255.255.255.0 </defaultMask>
<defaultRouter> 192.168.0.1 </defaultRouter>
<defaultDNS> 8.8.8.8 </defaultDNS>
</ Dhcpserver>
<ماي>
<host> المضيف المحلي </ المضيف>
<username> test </username>
<password> test </password>
<اسم الملف> pydhcp </basename>
</ ماي>
<خيارات>
<option> option_82_hex: sw_port1: 20:22 </option>
<option> option_82_hex: sw_port2: 16:18 </option>
<option> option_82_hex: sw_mac: 26: 40 </option>
</ خيارات>
<سؤال>
<offer_count> 3 </offer_count>
<offer_1> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث upper (mac) = upper ('{option_82_AgentRemoteId_hex}') و upper (port) = upper ('{option_82_AgentCircuitId_port_hex}') </offer_1>
<offer_2> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث العلوي (mac) = العلوي ('{sw_mac}') والأعلى (منفذ) = العلوي ('{sw_port2}') </offer_2>
<offer_3> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث upper (mac) = upper ('{ClientMacAddress}') </offer_3>
<history_sql> تضاف إلى قيم التاريخ (id ، dt ، mac ، ip ، comment) (خالية ، now () ، '{ClientMacAddress}' ، '{RequestedIpAddress}' ، 'DHCPACK / INFORM') </history_sql>
</ استعلام>
</ التكوين>
الآن بمزيد من التفاصيل على العلامات:
يصف قسم dhcpserver الإعدادات الأساسية لبدء تشغيل الخادم ، وهي:
- مضيف - عنوان IP الذي يستمع إليه الخادم على المنفذ 67
- البث - الذي هو البث IP ل DHCPOFFER و DHCPACK
- DHCPServer - ما هو الملكية الفكرية لخادم DHCP
- LeaseTime وقت تأجير عنوان IP الصادر
- ThreadLimit - كم عدد مؤشرات الترابط التي يتم تشغيلها في وقت واحد لمعالجة حزم UDP الواردة على المنفذ 67. من المفترض أن يساعد ذلك في المشروعات المحملة بدرجة عالية ؛)
- defaultMask ، defaultRouter ، defaultDNS - ما يتم تقديمه للمشترك بشكل افتراضي إذا تم العثور على IP في قاعدة البيانات ، ولكن لم يتم تحديد معلمات إضافية له
ميسكل القسم:
المضيف ، اسم المستخدم ، كلمة المرور ، اسم الملف - كل شيء يتحدث عن نفسه. نموذج بنية قاعدة البيانات المنشورة على
جيثبقسم الاستعلامات: يصف هذا القسم طلبات العرض / ACK:
- offer_count - عدد الأسطر مع الطلبات التي تُرجع نتيجة النموذج ip ، قناع ، جهاز التوجيه ، نظام أسماء النطاقات
- offer_n هي سلسلة الاستعلام. إذا كانت الإرجاع فارغة ، فسيتم تنفيذ طلب العرض التالي
- history_sql - طلب كتابة ، على سبيل المثال ، إلى "سجل التفويض" من قبل المشترك
يمكن لأي متغيرات من قسم الخيارات أو خيارات من بروتوكول DHCP المشاركة في الطلبات.
خيارات القسم. هنا هو بالفعل أكثر إثارة للاهتمام. هنا يمكننا إنشاء متغيرات يمكننا استخدامها لاحقًا في قسم الاستعلام.
على سبيل المثال:
option_82_hex:sw_port1:20:22
، هذا السطر هو أمر أخذ السطر بالكامل الذي جاء في طلب DHCP للخيار 82 ، بتنسيق سداسي عشرية ، في النطاق من 20 إلى 22 بايت ، ضمنيًا ووضعه في المتغير الجديد sw_port1 (منفذ التبديل الذي جاء منه الطلب)
option_82_hex:sw_mac:26:40
، قم بتعريف متغير sw_mac ، مع أخذ عرافة من نطاق 26:40
يمكنك رؤية جميع الخيارات الممكنة التي يمكن استخدامها في الاستعلامات عن طريق بدء تشغيل الخادم مع مفتاح التبديل -d. سنرى شيئًا مثل هذا السجل:
- جاءت حزمة DHCPINFORM على المنفذ 67 ، من 0025224ad764 ، b '\ x91 \ xa5 \ xe0 \ xa3 \ xa5 \ xa9- \ x8f \ x8a' ، ("172.30.114.25" ، 68)
{'ClientMacAddress': '0025224ad764' ،
'ClientMacAddressByte': b '\ x00٪ "J \ xd7d' ،
"HType": "Ethernet" ،
'HostName': b '\ x91 \ xa5 \ xe0 \ xa3 \ xa5 \ xa9- \ x8f \ x8a' ،
"ReqListDNS": صحيح ،
'ReqListDomainName': صحيح ،
'ReqListPerfowmRouterDiscover': صحيح ،
'ReqListRouter': صحيح ،
'ReqListStaticRoute': صحيح ،
'ReqListSubnetMask': صحيح ،
'ReqListVendorSpecInfo': 43 ،
'RequestedIpAddress': '0.0.0.0' ،
"البائع": b'MSFT 5.0 '،
'chaddr': '0025224ad764' ،
"السدر": "172.30.128.13" ،
"الأعلام": b '\ x00 \ x00' ،
'giaddr': '172.30.114.25' ،
"gpoz": 308 ،
"hlen": 6 ،
"القفزات": 1 ،
'htype': 'MAC' ،
'magic_cookie': b'c \ x82Sc '،
"المرجع": "DHCPINFORM" ،
"الخيار 12": 12 ،
"الخيار 53": 53 ،
الخيار 55: 55
"الخيار 60": 60 ،
"الخيار 61": 61 ،
"الخيار 82": 82 ،
'option_82_byte': b '\ x12 \ x01 \ x06 \ x00 \ x04 \ x00 \ x01 \ x00 \ x06 \ x02 \ x08 \ x00'
b '\ x06 \ x00 \ x1eX \ x9e \ xb2 \ xad' ،
'option_82_hex': '12010600040001000602080006001e589eb2ad' ،
'option_82_len': 18 ،
'option_82_str': "b '\\ x12 \\ x01 \\ x06 \\ x00 \\ x04 \\ x00 \\ x01 \\ x00 \\ x06 \\ x02 \\ x08 \\ x08 \\ x00 \\ x06 \\ x00 \ \ x1eX \\ x9e \\ xb2 \\ xad '"،
'النتيجة': خطأ ،
ثوانى: 768
'siaddr': '0.0.0.0' ،
'sw_mac': '001e589eb2ad' ،
'sw_port1': '06' ،
'xidbyte': b '<\ x89} \ x8c' ،
'xidhex': '3c897d8c' ،
'yiaddr': '0.0.0.0'}
وفقًا لذلك ، يمكننا التفاف أي متغير في {} وسيتم استخدامه في استعلام SQL.
دعنا نتعرف على السجل الذي تلقى فيه العميل عنوان IP:


بداية الخادم
./pydhcpdb.py -d -c config.xml
- وضع الإخراج د إلى وحدة التحكم DEBUG
- ملف التكوين <file_name>
إستخلاص المعلومات
والآن أكثر على تنفيذ الخادم في بيثون. هذا ألم. بيثون درس على الطاير. تم صنع العديد من اللحظات بأسلوب: "واو ، لقد فعلت ما يعمل بطريقة ما." ليس الأمثل على الإطلاق ، ويترك في هذا النموذج ويرجع ذلك أساسا إلى الخبرة الصغيرة للتنمية في الثعبان. سوف أتحدث عن أكثر اللحظات إثارة للاهتمام في تنفيذ الخادم في "الكود".
محلل ملف تكوين XML
يتم استخدام وحدة Python القياسية xml.dom. يبدو الأمر بسيطًا ، لكن أثناء التنفيذ كان هناك نقص ملحوظ في الوثائق والأمثلة المعقولة على الشبكة باستخدام هذه الوحدة.
tree = minidom.parse (gconfig ["config_file"])
mconfig = tree.getElementsByTagName ("mysql")
لـ elem في mconfig:
gconfig ["mysql_host"] = elem.getElementsByTagName ("host") [0] .firstChild.data
gconfig ["mysql_username"] = elem.getElementsByTagName ("اسم المستخدم") [0] .firstChild.data
gconfig ["mysql_password"] = elem.getElementsByTagName ("password") [0] .firstChild.data
gconfig ["mysql_basename"] = elem.getElementsByTagName ("basename") [0] .firstChild.data
dconfig = tree.getElementsByTagName ("dhcpserver")
ل elem في dconfig:
gconfig ["broadcast"] = elem.getElementsByTagName ("broadcast") [0] .firstChild.data
gconfig ["dhcp_host"] = elem.getElementsByTagName ("host") [0] .firstChild.data
gconfig ["dhcp_LeaseTime"] = elem.getElementsByTagName ("LeaseTime") [0] .firstChild.data
gconfig ["dhcp_ThreadLimit"] = int (elem.getElementsByTagName ("ThreadLimit") [0] .firstChild.data)
gconfig ["dhcp_Server"] = elem.getElementsByTagName ("DHCPServer") [0] .firstChild.data
gconfig ["dhcp_defaultMask"] = elem.getElementsByTagName ("defaultMask") [0] .firstChild.data
gconfig ["dhcp_defaultRouter"] = elem.getElementsByTagName ("defaultRouter") [0] .firstChild.data
gconfig ["dhcp_defaultDNS"] = elem.getElementsByTagName ("defaultDNS") [0] .firstChild.data
qconfig = tree.getElementsByTagName ("استعلام")
عن العلم في qconfig:
gconfig ["offer_count"] = elem.getElementsByTagName ("offer_count") [0] .firstChild.data
بالنسبة إلى num in range (int (gconfig ["offer_count"])):
gconfig ["offer _" + str (num + 1)] = elem.getElementsByTagName ("offer _" + str (num + 1)) [0] .firstChild.data
gconfig ["history_sql"] = elem.getElementsByTagName ("history_sql") [0] .firstChild.data
خيارات = tree.getElementsByTagName ("خيارات")
للعنصر في الخيارات:
عقدة = elem.getElementsByTagName ("الخيار")
للحصول على خيارات في العقدة:
optionsMod.append (options.firstChild.data)
خاصية تعدد
الغريب ، أن تعدد مؤشرات الترابط في بيثون يتم تنفيذه بوضوح شديد وبساطة.
def PacketWork (البيانات ، addr):
...
# تنفيذ تحليل الحزمة المستلمة ، والإجابة عليها
...
بينما صحيح:
البيانات ، addr = udp_socket.recvfrom (1024) # انتظر حزمة UDP
thread = threading.Thread (target = PacketWork، args = (data، addr،)). start () # كما جاء - قم بتشغيل الدالة PacketWork المحددة مسبقًا في الخلفية مع المعلمات
أثناء threading.active_count ()> gconfig ["dhcp_ThreadLimit"]:
time.sleep (1) # إذا كان عدد سلاسل العمليات قيد التشغيل بالفعل أكبر من الإعدادات ، فانتظر حتى تصبح أقل
تلقي / إرسال حزمة DHCP
من أجل اعتراض حزم UDP القادمة عبر بطاقة الشبكة ، تحتاج إلى "رفع" المقبس:
udp_socket = socket.socket (socket.AF_INET ، socket.SOCK_DGRAM ، socket.IPPROTO_UDP)
udp_socket.bind ((gconfig ["dhcp_host"] ، 67))
حيث الأعلام هي:
- AF_INET - يعني أن تنسيق العنوان سيكون IP: port. ربما AF_UNIX - حيث يتم إعطاء العنوان بواسطة اسم الملف.
- SOCK_DGRAM - يعني أننا لا نقبل "حزمة خام" ، ولكننا مررنا بالفعل من خلال جدار الحماية ، ومع الحزمة المقطوعة جزئيًا. أي نحصل على حزمة UDP فقط دون المكون "الفعلي" لبرنامج تغليف حزم UDP. إذا كنت تستخدم علامة SOCK_RAW ، فستظل بحاجة إلى تحليل هذه "المجموعة" أيضًا.
يمكن أن يكون إرسال الحزمة مثل البث:
udp_socket.setsockopt (socket.SOL_SOCKET ، socket.SO_BROADCAST ، 1) # التبديل المقبس إلى وضع البث
rz = udp_socket.sendto (packetack ، (gconfig ["broadcast"] ، 68))
وإلى العنوان "من أين جاءت الحزمة":
udp_socket.setsockopt (socket.SOL_SOCKET ، socket.SO_REUSEADDR ، 1) # التبديل المقبس إلى وضع "العديد من المستمعين"
rz = udp_socket.sendto (packetack ، addr)
حيث يعني SOL_SOCKET "مستوى البروتوكول" لإعداد خيارات ،
خيار SO_BROADCAST هو أن حزمة خوذة البث
يقوم خيار SO_REUSEADDR بتبديل المقبس إلى وضع الاستماع المتعدد. من الناحية النظرية ، ليس من الضروري في هذه الحالة ، ولكن على أحد خوادم FreeBSD التي اختبرت فيها ، لم يعمل الرمز بدون هذا الخيار.
تحليل حزمة DHCP
هنا أحببت بيثون حقًا. اتضح من "المربع" أنه يسمح لك بسهولة التعامل مع الرمز البريدي. السماح بالبساطة في الترجمة إلى القيم العشرية والسلاسل والسداسية - أي ما نحتاج إليه فعلا لفهم بنية الحزمة. على سبيل المثال ، يمكنك الحصول على مجموعة من البايتات في HEX والبايتات فقط:
الدقة ["xidhex"] = البيانات [4: 8] .hex ()
الدقة ["xidbyte"] = البيانات [4: 8]
، حزمة بايت في هيكل:
res ["flags"] = pack ('BB' ، data [10] ، data [11])
الحصول على IP من الهيكل:
res ["ciaddr"] = socket.inet_ntoa (pack ('BBBB'، data [12]، data [13]، data [14]، data [15]))؛
والعكس صحيح:
res = res + socket.inet_pton (socket.AF_INET، gconfig ["dhcp_Server"])
هذا كل شيء ؛)