بايتكب
مكدس TCP/IP المكتوب بلغة بايثون
PyTCP عبارة عن مكدس TCP/IP كامل الوظائف مكتوب بلغة Python. وهو يدعم النقل القائم على تدفق TCP مع تسليم حزم موثوق به يعتمد على آلية النافذة المنزلقة والتحكم الأساسي في الازدحام. كما أنه يدعم بروتوكولات IPv6/ICMPv6 مع تكوين عنوان SLAAC. إنه يعمل كبرنامج مساحة مستخدم متصل بواجهة Linux TAP. لقد قام بتطبيق توجيه بسيط ويمكنه إرسال واستقبال حركة المرور عبر الشبكة المحلية والإنترنت.
الإصدار 2.7، على عكس الإصدارات السابقة، يحتوي على كود مكدس PyTCP في شكل مكتبة بحيث يمكن استيراده بسهولة واستخدامه بواسطة كود خارجي. وهذا من شأنه أن يجعل تجربة المستخدم أكثر سلاسة ويوفر في النهاية القدرة الكاملة على استبدال استدعاءات مكدس Linux القياسية (على سبيل المثال، مكتبة المقبس) باستدعاءات PyTCP في أي تطبيق تابع لجهة خارجية.
بدأ هذا المشروع في البداية كجهد تعليمي بحت يهدف إلى تحسين مهاراتي في لغة بايثون وتحديث معرفتي بالشبكة كجزء من التحضير لدور مهندس الشبكات في فيسبوك. ومنذ ذلك الحين، أصبح الأمر أشبه بـ "مشروع محبوب" أخصص له بعضًا من وقتي على أساس غير منتظم إلى حد ما. ومع ذلك، عادةً ما تتم إضافة بعض التحديثات إليه كل شهر أو شهرين.
أرحب بأي مساهمات ومساعدة من أي شخص مهتم ببرمجة الشبكات. هو موضع تقدير أي مدخلات. تذكر أيضًا أن بعض ميزات المكدس قد يتم تنفيذها جزئيًا فقط (حسب الحاجة لتشغيل المكدس). قد يتم تنفيذها بطريقة دون المستوى الأمثل أو بطريقة غير متوافقة بنسبة 100% مع RFC (بسبب ضيق الوقت)، أو قد تحتوي على أخطاء (أخطاء) لا أزال بحاجة إلى إصلاحها.
لا تتردد في التحقق من مشروعي الآخرين ذوي الصلة:
- RusTCP - محاولة إعادة كتابة بعض وظائف PyTCP في Rust واستخدامها لإنشاء جهاز توجيه مختبري IPv6/SRv6.
- SeaTCP - محاولة إنشاء مكدس زمن الوصول المنخفض باستخدام لغات C وAssembly.
مبدأ التشغيل وإعداد الاختبار
يعتمد مكدس PyTCP على واجهة Linux TAP. واجهة TAP هي واجهة افتراضية يمكن، على طرف الشبكة، "توصيلها" بالبنية التحتية للشبكة الافتراضية الموجودة عبر جسر Linux أو Open vSwitch. على الجانب الداخلي، يمكن استخدام واجهة TAP مثل أي بطاقة NIC أخرى عن طريق إرسال واستقبال الحزم برمجيًا إليها/ منها.
إذا كنت ترغب في اختبار مكدس PyTCP في شبكتك المحلية، أقترح إنشاء إعداد الشبكة التالي الذي سيسمح لك بتوصيل كل من Linux kernel (أساسًا نظام التشغيل Linux الخاص بك) ومكدس PyTCP بشبكتك المحلية في نفس الوقت .
<INTERNET> <---> [ROUTER] <---> (eth0)-[Linux bridge]-(br0) <---> [Linux TCP/IP stack]
|
|--(tap7) <---> [PyTCP TCP/IP stack]
بعد أن يبدأ البرنامج النموذجي (سواء العميل أو الخدمة) المكدس، يمكنه التواصل معه عبر مقابس BSD المبسطة مثل واجهة API. هناك أيضًا إمكانية إرسال الحزم مباشرة عن طريق استدعاء إحدى طرق _*_phtx()
من فئة PacketHandler
.
استنساخ PyTCP من مستودع GitHub
في معظم الحالات، يجب استنساخ PyTCP مباشرةً من مستودع GitHub، حيث يوفر هذا النوع من التثبيت بيئة تطوير واختبار كاملة.
git clone http://github.com/ccie18643/PyTCP
بعد الاستنساخ يمكننا تشغيل أحد الأمثلة المضمنة:
- انتقل إلى الدليل الجذر للمكدس (يسمى "PyTCP").
- قم بتشغيل الأمر
sudo make bridge
لإنشاء الجسر "br0" إذا لزم الأمر. - قم بتشغيل الأمر
sudo make tap
لإنشاء واجهة Tap7 وتعيينها للجسر "br0". - قم بتشغيل أمر
make
لإنشاء البيئة الافتراضية المناسبة للتطوير والاختبار. - يجري
. venv/bin/activate
الأمر . venv/bin/activate
لتنشيط البيئة الافتراضية. - قم بتنفيذ أي مثال، على سبيل المثال،
example/run_stack.py
. - اضغط على Ctrl-C لإيقافه.
لضبط المعلمات التشغيلية المختلفة للمكدس، يرجى تحرير ملف pytcp/config.py
وفقًا لذلك.
تثبيت PyTCP من مستودع PyPi
يمكن أيضًا تثبيت PyTCP كوحدة نمطية عادية من مستودع PyPi.
python -m pip install PyTCP
بعد التثبيت، يرجى التأكد من تشغيل واجهة TAP وإضافتها إلى الجسر.
sudo ip tuntap add name tap7 mode tap
sudo ip link set dev tap7 up
sudo brctl addbr br0
sudo brctl addif br0 tap7
يمكن استيراد مكدس PyTCP وبدء تشغيله باستخدام الكود التالي. فهو يبدأ تشغيل الأنظمة الفرعية للمكدس ويقوم تلقائيًا بتكوين عناوين بروتوكول IPv4 وIPv6 باستخدام DHCPv4 وIPv6 SLAAC، على التوالي.
from pytcp import TcpIpStack
stack = TcpIpStack ( interface = "tap7" )
stack . start ()
تعمل الأنظمة الفرعية للمكدس في سلاسل الرسائل الخاصة بها. بعد البدء، تعيد المكدس التحكم إلى رمز المستخدم ويمكن إيقافه باستخدام الاستدعاء التالي.
سمات
تم تنفيذها بالفعل:
- Stack - محلل الحزم السريع باستخدام أسلوب "النسخة الصفرية".
- Stack - مجمع الحزم السريع باستخدام نهج "النسخة الصفرية".
- Stack - مكتبة معالجة عنوان MAC - متوافقة مع بروتوكول المخزن المؤقت (Memoryview).
- Stack - مكتبة معالجة عناوين IPv4 - متوافقة مع بروتوكول المخزن المؤقت (Memoryview) ولا تعتمد على مكتبة Python القياسية.
- Stack - مكتبة معالجة عنوان IPv6 - متوافقة مع بروتوكول المخزن المؤقت (Memoryview) ولا تعتمد على مكتبة Python القياسية.
- الكود - اختبار الوحدة لبعض المكتبات والوحدات النمطية (استنادًا إلى إطار عمل Testslide الخاص بفيسبوك)
- بروتوكول Ethernet - دعم الإطارات القياسية لـ Ethernet II.
- بروتوكول Ethernet - البث الأحادي والبث المتعدد IPv4 والبث المتعدد IPv6 وعنونة البث.
- بروتوكول ARP - الردود والاستعلامات وآلية ذاكرة التخزين المؤقت لـ ARP.
- بروتوكول ARP - آلية الكشف عن تعارض IP (ACD) لمسبار/إعلان ARP.
- بروتوكول IPv4 - التوجيه الافتراضي، يمكن للمكدس التحدث إلى المضيفين عبر الإنترنت باستخدام بروتوكول IPv4.
- بروتوكول IPv4 - تكوين عنوان IPv4 التلقائي باستخدام بروتوكول DHCPv4.
- بروتوكول IPv4 - إلغاء تجزئة الحزم الواردة، وهو آلية قوية قادرة على التعامل مع أجزاء البيانات المتداخلة وغير مرتبة.
- بروتوكول IPv4 - تجزئة الحزمة الصادرة.
- بروتوكول IPv4 - خيارات IPv4 مقبولة ولكنها غير مدعومة.
- بروتوكول IPv4 - يتم دعم عناوين IPv4 للمكدسات المتعددة، ويعمل كل منها كما تم تعيينه لفصل VRF
- بروتوكول ICMPv4 - رسائل طلب الارتداد ورد الارتداد والرسائل التي لا يمكن الوصول إليها عبر المنفذ.
- بروتوكول IPv6 - التوجيه الافتراضي، يمكن للمكدس التحدث إلى المضيفين عبر الإنترنت باستخدام بروتوكول IPv6.
- بروتوكول IPv6 - التكوين التلقائي لعنوان الارتباط المحلي باستخدام EUI64 واكتشاف العناوين المكررة.
- بروتوكول IPv6 - التكوين التلقائي لعنوان GUA باستخدام إعلان جهاز التوجيه / EUI64.
- بروتوكول IPv6 - التعيين التلقائي لعناوين البث المتعدد للعقدة المطلوبة.
- بروتوكول IPv6 - التعيين التلقائي لعناوين MAC للبث المتعدد IPv6.
- بروتوكول IPv6 - إلغاء تجزئة الحزم الواردة، وهو آلية قوية قادرة على التعامل مع أجزاء البيانات المتداخلة وغير مرتبة.
- بروتوكول IPv6 - تجزئة الحزمة الصادرة.
- بروتوكول ICMPv6 - رسائل طلب الارتداد ورد الارتداد والرسائل التي لا يمكن الوصول إليها عبر المنفذ.
- بروتوكول ICMPv6 - اكتشاف الجوار واكتشاف العناوين المكررة.
- بروتوكول ICMPv6 - آلية ذاكرة التخزين المؤقت لاكتشاف الجوار.
- بروتوكول ICMPv6 - تنفيذ بروتوكول اكتشاف مستمع البث المتعدد v2 (MLDv2) (فقط الرسائل التي يحتاجها المكدس).
- بروتوكول UDP - الدعم الكامل. يمكن للمكدس تبادل البيانات مع مضيفين آخرين باستخدام بروتوكول UDP.
- مقابس UDP - دعم كامل، واجهة برمجة تطبيقات "المستخدم النهائي" للمكدس المشابهة لمقابس بيركلي.
- خدمات UDP - خدمات الصدى والتجاهل والنهار التي يتم تنفيذها لأغراض الاختبار (في "الأمثلة").
- بروتوكول TCP - التنفيذ الكامل لـ TCP Finite State Machine. عند هذه النقطة، يمكن للمكدس تبادل البيانات المجمعة مع مضيفين آخرين عبر بروتوكول TCP.
- بروتوكول TCP - دعم خيارات TCP لـ: MSS، وWSCALE، وSACKPERM، وTIMESTAMP.
- بروتوكول TCP - آلية نافذة TCP المنزلقة مع إعادة إرسال البيانات (إعادة الإرسال السريع والسيناريوهات المستندة إلى الوقت).
- بروتوكول TCP - آلية التراجع TCP / التحكم الأساسي في الازدحام.
- بروتوكول TCP - إعادة إرسال حزمة TCP SYN/FIN.
- مقابس TCP - دعم كامل، واجهة برمجة تطبيقات "المستخدم النهائي" للمكدس المشابهة لمقابس بيركلي
المراد تنفيذها:
أمثلة
تم تسليم عدة حزم ping واثنين من القرود عبر TCP عبر بروتوكول IPv6.
اكتشاف جار IPv6 / اكتشاف العنوان المكرر / التكوين التلقائي للعنوان.
- يحاول Stack تكوين عنوان الارتباط المحلي الخاص به تلقائيًا. يقوم بإنشائه كعنوان EUI64. وكجزء من عملية DAD، فإنه ينضم إلى مجموعة البث المتعدد ذات العقدة المطلوبة المناسبة ويرسل طلبًا مجاورًا للحصول على عنوانه الذي تم إنشاؤه.
- لا يتلقى Stack أي إعلان مجاور للعنوان الذي أنشأه، لذا فهو يعينه للواجهة الخاصة به.
- يحاول Stack تعيين عنوان ثابت تم تكوينه مسبقًا. وكجزء من عملية DAD، فإنه ينضم إلى مجموعة البث المتعدد ذات العقدة المطلوبة المناسبة ويرسل طلبًا مجاورًا للحصول على العنوان الثابت.
- مضيف آخر بنفس العنوان قام بالفعل بتعيين ردود برسالة إعلان مجاور. يخبر هذا المكدس أن مضيفًا آخر قد قام بالفعل بتعيين العنوان الذي يحاول تعيينه، لذلك لا يمكن للمكدس استخدامه.
- يرسل Stack رسالة طلب جهاز التوجيه للتحقق مما إذا كان هناك أي بادئات عامة يجب استخدامه.
- يستجيب جهاز التوجيه بإعلان جهاز التوجيه الذي يحتوي على بادئة إضافية.
- يحاول Stack تعيين عنوان تم إنشاؤه بناءً على البادئة المستلمة وجزء مضيف EUI64. وكجزء من عملية DAD، فإنه ينضم إلى مجموعة البث المتعدد ذات العقدة المطلوبة المناسبة ويرسل طلبًا مجاورًا للحصول على العنوان الثابت.
- لا يتلقى Stack أي إعلان مجاور للعنوان الذي أنشأه، لذا فهو يعينه للواجهة الخاصة به.
- بعد تعيين جميع العناوين، يرسل المكدس تقريرًا آخر لمستمع البث المتعدد يسرد جميع عناوين البث المتعدد التي يريد الاستماع إليها.
إعادة إرسال TCP السريع قيد التنفيذ بعد فقدان حزمة TX.
- يتم "فقد" الحزمة الصادرة بسبب محاكاة آلية فقدان الحزمة.
- يلاحظ النظير عدم الاتساق في أرقام SEQ للحزمة ويرسل "طلب إعادة إرسال سريع".
- يتلقى Stack الطلب ويعيد إرسال الحزمة المفقودة.
قائمة الانتظار خارج الترتيب قيد التنفيذ أثناء حدث فقدان حزمة RX
- يتم "فقد" الحزمة الواردة بسبب محاكاة آلية فقدان الحزمة.
- يلاحظ Stack وجود عدم تناسق في الرقم التسلسلي للحزمة الواردة ويرسل طلب "إعادة إرسال سريع".
- قبل أن يتلقى النظير الطلب، فإنه يرسل حزمًا متعددة ذات تسلسل أعلى مما تتوقعه المكدس. المكدس يصطف في قائمة الانتظار لكل تلك الحزم.
- يقوم النظير بإعادة إرسال الحزمة المفقودة.
- يتلقى Stack الحزمة المفقودة، ويسحب جميع الحزم المخزنة في قائمة الانتظار خارج الترتيب، ويعالجها.
- ترسل الحزم المكدسة حزمة ACK للاعتراف بأحدث الحزم التي تم سحبها من قائمة الانتظار.
TCP Finite State Machine - المكدس يقوم بتشغيل خدمة TCP Echo.
- يفتح النظير الاتصال.
- يرسل النظير البيانات.
- المكدس يردد البيانات مرة أخرى.
- يقوم النظير بإغلاق الاتصال.
TCP Finite State Machine - المكدس يقوم بتشغيل عميل TCP Echo.
- المكدس يفتح الاتصال.
- المكدس يرسل البيانات.
- نظير يردد البيانات مرة أخرى.
- المكدس يغلق الاتصال.
عملية التحقق من صحة الحزمة قبل التحليل.
- تُظهر لقطة الشاشة الأولى المكدس مع إيقاف تشغيل فحص السلامة. يمكن أن تؤدي حزمة ICMPv6 المشوهة إلى تعطلها.
- تُظهر لقطة الشاشة الثانية المكدس مع تشغيل فحص السلامة. يتم تجاهل حزمة ICMPv6 المشوهة قبل تمريرها إلى محلل بروتوكول ICMPv6.
- تُظهر لقطة الشاشة الثالثة الحزمة المشوهة. تم تعيين عدد حقول سجلات MA على 777 على الرغم من أن الحزمة تحتوي على سجل واحد فقط.
آلية مسبار/إعلان ARP.
- يستخدم Stack مجسات ARP للعثور على أي تعارضات محتملة لكل عنوان IP تم تكوينه.
- أحد عناوين IP (192.168.9.102) مأخوذ بالفعل، لذلك يتم إخطار المكدس به وتخطيه.
- أما باقي عناوين IP فهي مجانية، لذا قم بالمطالبة بها عن طريق إرسال إعلان ARP لكل منها.
دقة ARP والتعامل مع حزم ping.
- يحاول المضيف 192.168.9.20 تنفيذ الأمر ping على المكدس. لتتمكن من القيام بذلك، تقوم أولاً بإرسال حزمة طلب ARP لمعرفة عنوان MAC الخاص بالمكدس.
- يستجيب Stack عن طريق إرسال حزمة رد ARP (لا يحتاج Stack إلى إرسال طلبه لأنه قام بالفعل بتدوين ملاحظة حول MAC الخاص بالمضيف من طلب المضيف).
- يرسل المضيف حزم ping، ويستجيب المكدس لها.
تجزئة الملكية الفكرية.
- يرسل المضيف مخطط بيانات UDP بحجم 4 كيلو بايت باستخدام ثلاث حزم IP مجزأة (ثلاثة أجزاء).
- يستقبل Stack الحزم ويجمعها في قطعة واحدة، ثم يمررها (عبر معالج بروتوكول UDP ومقبس UDP) إلى خدمة UDO Echo.
- تقوم خدمة UDP Echo بالتقاط البيانات وإعادتها إلى مقبس UDP.
- يتم تمرير مخطط بيانات UDP إلى معالج بروتوكول IP، الذي يقوم بإنشاء حزمة IP، وبعد التحقق من تجاوزها للارتباط، تقوم MTU بتجزئةها إلى ثلاث حزم IP منفصلة.
- يتم تغليف حزم IP في إطارات Ethernet ووضعها على حلقة TX.