از اونجايي كه به جهت سادگي در ارائه مفهوم از پردازش بخش Option صرفنظر كرديم و همینطور از قابليت Fragmentation در اين پروتكل استفاده نمیکنیم؛ لذا تعريف تابع IP_Process() هم بهصورت زير انجام شده:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | uint16_t IP_Process ( IP_Frame* ipFrame, uint16_t frameLen ) { uint16_t newFrameLen = 0; if (memcmp(ipFrame->destIpAddr, ipAddr, IP_ADDRESS_BYTES_NUM) == 0) { uint16_t rxCheckSum = ipFrame->checkSum; ipFrame->checkSum = 0; uint16_t calcCheckSum = IP_CalcCheckSum((uint8_t*)ipFrame, sizeof(IP_Frame)); if (rxCheckSum == calcCheckSum) { uint16_t dataLen = ntohs(ipFrame->len) - ((ipFrame->verHeaderLen & 0x0F)*4); uint16_t newDataLen = 0; if (ipFrame->protocol == IP_FRAME_PROTOCOL_ICMP) //=0x01 { //do something for ICMP } else if (ipFrame->protocol == IP_FRAME_PROTOCOL_UDP) //=0x11 { //do something for UDP } else if (ipFrame->protocol == IP_FRAME_PROTOCOL_TCP) //=0x06 { //do something for TCP } if(newDataLen) newFrameLen = newDataLen + sizeof(IP_Frame); else newFrameLen=0; if(newFrameLen) { ipFrame->len = htons(newFrameLen); ipFrame->fragId = 0; ipFrame->fragOffset = 0; //swap IP Addresses for reply memcpy(ipFrame->destIpAddr, ipFrame->srcIpAddr, IP_ADDRESS_BYTES_NUM); memcpy(ipFrame->srcIpAddr, ipAddr, IP_ADDRESS_BYTES_NUM); //calculate new checksum ipFrame->checkSum = IP_CalcCheckSum((uint8_t*)ipFrame, sizeof(IP_Frame)); } } } return newFrameLen; } |
در گام اول با بررسي آدرس آیپی موجود در پيام؛ بررسي میکنیم كه آيا پيام فعلي براي ما ارسال شده يا نه؟
قدم بعدي، محاسبه چك سام و بررسي تساوي چك سام دريافتي و چك سام محاسبه شده است. اگر هر دو بخش رو رد كرديم؛
شناسایی نوع پروتکل لایه چهارم
حالا بايد بررسي كنيم كدام پروتكل در لايه چهارم اين پيام رو فرستاده؛ سه پروتكل ICMP,UDP و TCP براي ما اهميت دارند؛ پس بخش پروتكل از هدر IP رو بررسي میکنیم و عمليات مناسب رو براي پردازش اين پروتکلها انجام خواهيم داد. از اونجاييكه اين پروتکلها رو هنوز معرفي نكرديم؛ تنها هسته مناسب براي پیادهسازی اونها رو در كد میبینیم. اينجا دوباره شماره پروتکلهای لايه چهارم رو نوشتيم:
ICMP = 0x01
UDP = 0x11
TCP = 0x06
در انتهاي تابع هم اگر پکت دریافتی، نیاز به ارسال پاسخ داشته باشه (با بررسی اندازه پاسخ) جاي آدرسهای IP فرستنده و گيرنده رو تغيير ميديم؛ بیتهای متعلق به Fragmentation رو پاك میکنیم و چك سام جديد رو محاسبه میکنیم تا چينش هدر IP انجام شده باشه و در نهايت ميزان دادههای پاسخ رو برميگردونيم. اگر اين عدد صفر نباشه به اين معني هست كه پيام IP داراي پاسخ هست؛ لذا لايه دوم هم كه از قبل كدهاش رو نوشتيم، پيغام رو ارسال خواهد كرد.
اگه بخوایم وضعیت این پروتکلها رو در مدل OSI یا TCP/IP نشون بدیم مثل جدول زیر باید باشه:
(Transport Layer) لایه 4 | TCP(segment) | UDP(segment) | ICMP |
|
(Network Layer) لایه 3 | IP (packet) | ARP | ||
(Data Link Layer) لایه 2 | Ethernet ii (frame) | |||
(Physical Layer) لایه 1 | ‘0’ , ‘1’ (Stream) |
اولین لایه از بالا که قادر به ارسال داده خام هست، لایه چهارمه. مثلاً فرض کنید بردی طراحی کردید که قراره اطلاعات یک تعداد سنسور دما که شمارهگذاری شدهاند رو به یک کامپیوتر منتقل کنه. در این حالت میتونید از دو پروتکل UDP یا TCP برای ارسال اطلاعات متنی، مثل رشته زیر استفاده کنید.
“T1=10.1,T2=12.3,T3=14.1”
پروتکل ICMP(Intenet Control Message Protocol) همونطور که از اسمش پیداست؛ جهت ارسال/دریافت پیامهای کنترلی شبکه استفاده میشه (مثل موارد خطا). دو عملیات ping و trace route در شبکه با استفاده از قابلیتهای پروتكل ICMP پیادهسازی میشن که بهشون اشاره خواهیم کرد و در ادامه ICMP اولین پروتکلی هست که بعد از IP میریم سراغش. پروتکل ICMP برای این بوجود اومده که اگر یک ارتباط IP دچار مشکل شد؛ بشه به فرستنده یا ادمین شبکه اطلاع داد.
اما برای ارسال داده خام از دو پروتکل UDP(User Datagram Protocol) یا TCP(Transmission Control Protocol) استفاده میشه. هر گاه در تبادل اطلاعات زمان بر صحت و سلامت ارسال، ارجحیت داشته باشه از UDP و هرگاه صحت و سلامت تبادل اطلاعات بر زمان ارجح باشه از TCP استفاده میشه. در UDP، داده ها، فقط ارسال میشن؛ بدون اینکه بررسی بشه آیا بطور صحيح به مقصد رسیدن یا نه؟ (اصلا رسیدن یا نه) اما در TCP، صحت رسیدن اطلاعات به مقصد بررسی میشه و چنانچه خطایی رخ بده با استفاده از قابلیت هایی مثل بازارسال (retransmission)؛ داده ها رو مجددا ارسال می کنند. با اینکه هر دو پروتکل به صورت کلاینت/سرور (مشتری/خدمات دهنده) در نظر گرفته میشه؛ اما هر دو سمت شبکه، میتونن داده هایی ارسال یا از طرف مقابل دریافت کنند.
فرض کنید شما در حال استفاده از یک دوربین با رزولوشن بالا هستید و سرعت نمونه برداری و ارسال فریم های تصویر هم بالاست. در این حالت بهتره از UDP استفاده بشه زیرا گم شدن یک یا دو فریم از تصویر اهمیتی نداره. بعنوان یک مثال دیگه از این پروتکل، میشه به ارسال اطلاعات دما یا حتا سیگنال دیجیتال یک میکروفون اشاره کرد زیرا در هر دو حالت، اگر یک یا چند نمونه از بین بروند و به مقصد نرسند؛ اهمیتی نداره؛ اما وقتی که شما در حال ارسال اطلاعات یک دیتابیس (database یا پایگاه داده) هستید یا اینکه دارید اطلاعات یک صفحه وب رو ارسال میکنید؛ در این حالت، صحت ارسال و دریافت بسیار مهم هست و درنتیجه، در این جا از پروتکل TCP استفاده میشه.
با بررسي وضعيت پيغام هاي موجود روي خط با wireshark خواهيم ديد كه در هر لحظه پيغام هاي زيادي روي خط ردوبدل ميشن كه مقصد تعداد زيادي از اونها برد ما نيست؛ در يك شبكه واقعي، تعداد زيادي از اين پيام ها توسط تجهيزات مياني مثل روترها و سوييچ ها فيلتر ميشن. اما در وضعيت فعلي كه ما با يك كابل بطور مستقيم به PC متصل هستيم؛ براي اينكه تعداد پيام هاي نامرتبط رو كاهش بديم؛ پيشنهاد ميشه كه فيلترهاي ENC رو فعال كنيم تا از دريافت تمامی پيغام ها و پردازش اضافه در میکروکنترلر جلوگيري بشه.
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.