قبل از معرفی پروتکل IP؛ اجازه بدید موقعیت اون رو در لایهبندی شبکه، یک بار دیگه یادآوری کنیم. همچنين دوباره بگيم كه منظورمون از IP؛ ورژن چهار اون یعنی IPv4 هست.
(Network Layer) لایه 3 | IP (packet) | ARP (packet) |
(Data Link Layer) لایه 2 | Ethernet ii (frame) | |
(Physical Layer) لایه 1 | ‘0’ , ‘1’ (Stream) |
همونطور که در جدول دیده میشه؛ پروتکل IP در لایه سوم موسوم به لایه شبکه (Network) در مدل OSI یا لایه اینترنت در مدل TCP/IP قرار داره، این پروتکل از یک نوع آدرسدهی منطقی به اندازه 4 بایت استفاده میکنه. با چهار بایت میشه حدود 4.3 میلیارد host در شبکه داشته باشیم. پیشرفت و گسترش هر روزه اینترنت و نیاز به فضای آدرسدهی بزرگتر، باعث به وجود اومدن ورژن جدیدتری از IP شد که بهجای 4 بایت از 8 کلمه دوبایتی (128 بیت) آدرس استفاده میکنه. این دو با نامهای IPv4 و IPv6 از هم تشخیص داده میشن. این پروتکل ها، جدا از بحث آدرسدهی، تفاوتهای دیگه ای هم با هم دارند؛ در نتيجه در لایههای بالاتر، پروتکلهایی مبتنی بر IPv6 تعریف شدهاند که بسیاری از اون ها نمونه مشابهی در ورژن 4 دارند. در حال حاضر، مشکل کمبود آدرس در IPv4 رو به طریقی حل کردهاند (NAT رو در ضمایم ببینید) و IPv4 همچنان گستردهترین پروتکل در لایه سوم هست. اینجا قصد داریم IPv4 رو بررسی و راهاندازی کنیم.
از اونجاییکه پروتکل IP در لایه سوم و در کنار ARP کار میکنه؛ در نتیجه براحتی میتونیم کد مورد نیاز رو در برنامه میکروکنترلر اضافه کنیم. یادمون هست که گفتیم IPv4 در بخش Ether Type از یک فریم استاندارد Ethernet ii عدد 0x0800 رو حمل میکنه. پس یک if دیگه برای پردازش پکت های IP به تابع ETH_Process اضافه می کنیم. اسم تابع رو؛ همچنان که روالمون هست IP_Process میذاریم.
پس تابع ETH_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 | void ETH_Process(ENC28J60_Frame* encFrame) { uint16_t responseSize = 0; uint16_t requestSize = ENC28J60_ReceiveFrame(encFrame); if (requestSize > 0) { ETH_Frame* ethFrame = (ETH_Frame*)encFrame->data; uint16_t etherType = ntohs(ethFrame->etherType); uint16_t ethDataLen = requestSize - sizeof(ETH_Frame); // ARP protocol if (etherType == ETH_FRAME_TYPE_ARP) // ==0x0806 { responseSize = ARP_Process((ARP_Frame*)ethFrame->data, ethDataLen); } // IP protocol if (etherType == ETH_FRAME_TYPE_IP) // ==0x0800 { responseSize = IP_Process((IP_Frame*)ethFrame->data, ethDataLen); } if (responseSize > 0) { ETH_Response(ethFrame, responseSize); } } } |
الان کافیه که تابع IP_Process رو پیادهسازی کنیم، قبلش باید بدونیم یک پکت IP چه شکلی هست. بالطبع این پروتکل هم هدر (Header) مخصوص به خودش رو به دادههای دریافتی از لایه چهارم اضافه میکنه و اونو به لایه دو میده؛ پس مثل ARP بايد در ابتداي بخش دادهها، ابتدا هدر پكت IP رو بررسي كنيم.
فرمت هدر پروتكل IP رو در جدول زير مي بينيد، اعداد، نشون دهنده شماره بيت شروع هر بخش هست.
31 |
| 19 | 16 |
| 8 | 4 | 0 |
Total Length | Type of Service | HLen | Version | ||||
Fragment Offset | Flags | Identification | |||||
Header Checksum | Protocol | TTL | |||||
Source IP Address | |||||||
Destination IP Address | |||||||
Padding |
Options
|
Version : در این بخش که 4 بیت اشغال کرده؛ عدد 4 بعنوان ورژن IPv4 قرار میگیره. بصورت بيتي “0100”
HLen : یا Header Length که گاهی بهش IHLen=Internet Header Length هم گفته میشه. این بخش نیز 4 بیتی هست و طول هدر پروتکل IP رو نشون میده. از اونجاییکه ممکنه بخش Option در هدر وجود نداشته باشه، لذا نیاز بوده که به طریقی طول هدر مشخص باشه. عدد واقع در HLen رو باید در 4 ضرب کنیم تا طول واقعی هدر رو به دست بیاریم؛ زيرا این عدد نشاندهنده طول هدر برحسب DWORD یا کلمات 4 بایتی هست. پس در این محل، حداقل عدد 5 (بهصورت بيتي “0101”) و حداکثر عدد 15 (به صورت بيتي “1111” ) قرار میگیره که نشون میده بخش هدر در پروتکل IP حداقل 20 بایت (بدون Option) و حداکثر 60 بایت (40 بایت برای بخش Option) میتونه باشه. همچنین متوجه شدیم که بخش Option، متغیر و بين صفر تا حداکثر 40 بایت خواهد بود. دو بخش Ver و HLen با هم، یک بایت رو در هدر تشکیل میدن.
TOS : یا type of service ، به اندازه یک بایت؛ بهصورت بیتی تفسیر میشه و پکت ها رو به کلاسهای مختلف سرویسدهی تقسیم میکنه. ما فعلاً در این بخش 0x00 قرار میدیم یعنی از سرویس خاصی استفاده نمیکنیم. در اسناد RFC که آخرین تغییرات پروتکل آیپی رو دارند، این قسمت خودش از دو بخش تشکیل شده. 6 بیت پرارزش با نام DSCP (Differentiated Services Code Point) و 2 بیت کمارزش با نام ECN (Explicit Congestion Notification).
TLen : یا Total Length طول کل پکت IP شامل “هدر + داده” رو بر حسب بایت نشون داده میشه (و نه DWORD). از اونجایی که برای این بخش دو بایت در نظر گرفته شده؛ پس حداکثر 65535 بایت رو میشه در یک پکت IP ارسال کرد. مطابق استاندارد؛ گیرنده پکت IP، حدقل، باید قابلیت دریافت 576 بایت رو داشته باشه و فرستنده، تنها در صورتی باید پکتهای بزرگتر از 576 بایت رو ارسال کنه که مطمئن باشه گیرنده میتونه این پکت رو دریافت کنه.
ID : یا IDentification شناسه پکت. چنانچه داده دریافتی از لایه چهارم خیلی بزرگ باشه و پروتکل IP در سمت فرستنده تصمیم بگیره اون دادهها رو به قطعات کوچکتری تقسیم (Fragmentation) و سپس ارسال کنه؛ از این شناسه به همراه بخش Fragment Offset برای شمارهگذاری و شناسایی ترتیب پکتهای ارسالی استفاده میشه. ما از این قابلیت استفاده نمیکنیم. در نتیجه درون اون میشه صفر یا هر عدد دیگه ای گذاشت.
Flags : یا پرچم؛ این بخش تنها شامل 3 بیت هست، بیت پر ارزش (اولين بيت از سمت چپ) همواره ‘0’ هست. بیت دوم و سوم بترتیب اسمشون DF و MF هست
DF مخفف Don’t Fragment هست. فرستنده این بیت، با یک کردن اون، به اجزای میانی شبکه مثل روتر ها اعلام میکنه که اجازه خرد کردن (Fragmentation ) داده های ارسالی رو ندارند لذا اگر روتری این بسته رو دریافت کنه و نتونه بدون خرد کردن اون رو به مقصد برسونه، پکت رو کنار میذاره (discard it!)
MF : مخفف More Fragment؛ هنگامی که دادههای اصلی خرد میشن، این بیت ‘1’ میشه تا به گیرنده بفهمونه که این بسته هنوز تموم نشده و قسمتهای (Fragment) بیشتری در راهاند. هنگام ارسال آخرین قسمت، این بیت ‘0’ میشه.
در یک ارتباط عادی از طریق IP ما به این پرچمها نیاز نداریم و اونها رو با 0 پر میکنیم.
Fragment Offset: چنانچه بستهای خرد بشه؛ این قسمت نشاندهنده آفست بخش ارسالی از ابتدای داده اصلی است. این بخش، در صورت استفاده، با بخش ID استفاده میشه. از اونجایی که بخش داده اصلی، حداکثر اندازهای برابر با 65535 داره (16 بیت) و این بخش تنها 13 بیت رو شامل میشه؛ عدد واقع در این بخش رو باید در 8 ضرب کنیم. همینطور بیاد داشته باشید که آفست اولین قسمت (Fragment) ارسالی صفر خواهد بود. اجازه بدید مثالی بزنیم، فرض کنید یک داده 1200 بایتی به قسمتهای 576 بایتی تقسیم شده تا ارسال بشه. یک ID ثابت و تصادفی برای این قسمتها در نظر گرفته میشه، مثلاً 1001 ، حالا اولین قسمت با ID=1001 و Offset=0 و MF=’1’ ارسال میشه ، دومین قسمت، مجدد با ID=1001 اما با offset=72 ارسال خواهد شد(576/8=72 ) و MF=’1’ ؛ در انتها و هنگام ارسال آخرین بخش ID=1001 و MF=’0’ و offset=144 خواهد بود. باز یادآوری کنیم که ما از این قابلیت استفاده ای نخواهیم کرد و اطلاعات فوق در اینجا فقط جهت اطلاع ثبت شده.
TTL : یا Time To Live که میشه “زمان زنده بودن” ترجمه ش کرد. با اینکه بنظر میرسه جنس این قسمت، از نوع زمان باشه؛ اما در واقع این بخش، حداکثر تعداد مجاز دستگاه های واسط (روتر یا مسیریاب) در بين مسير از فرستنده تا گيرنده رو مشخص میکنه. این بخش برای این در نظر گرفته شده که اگر پکتی به هر دليلي به مقصد نرسید؛ تا ابد درون شبکه باقی نمونه. فرستنده، TTL رو با یک عدد مطلوب مثلا 128 يا 69 پر میکنه. هنگام ارسال و جابجایی بین زیرشبکه ها، هر وقت این پکت وارد روتری بشه؛ روتر از عدد TTL یکی کم میکنه و اگر نتیجه صفر باشه، این پکت رو دور میندازه (discard)! ولی یه پیغام خطا (با استفاده از پروتكل ICMP) به فرستنده برمیگردونه.
Protocol : این آیتم یک بایتی، نشاندهنده پروتکلی از لایه چهارمه که داره از این پکت استفاده میکنه (پروتكلي در لايه 4 كه دادهها متعلق به اون پروتکل هستند). سه تا از پروتکلهای لایه چهارم که ما قصد داریم در این نوشتار ازشون استفاده کنیم؛ شمارههای شناساییشون عبارت است از:
ICMP = 0x01
UDP = 0x11
TCP = 0x06
CheckSum : دیدیم که در فریم اترنت، برای بررسی صحت ارسال و دریافت دادهها، در انتهای فریم، بخشی بنام CRC اضافه میشد. علاوه بر این، اکثر پروتکلهای لایههای بالاتر مثل IP,ICMP,UDP و TCP به طور جداگانه، درون هدرشون چند بایت برای بررسی مجدد سلامت اطلاعات، قرار میدن که معمولاً محاسباتشون بر اساس فرایند چک سام هست. از اونجاییکه این محاسبات مثل هم هست (فقط دادههایی که روشون عملیات چک سام انجام میشه متفاوته) لذا در همینجا و بعد از معرفی بخش هدر (Header)، توضیح نسبتاً کاملی از روش انجام محاسبه چک سام ارائه میدیم. در پروتکل IP محاسبه چک سام فقط روی هدر انجام میشه در حالی که در بعضی دیگه ممکنه علاوه بر هدر؛ داده ها payload و يا بخش هاي ديگهاي؛ در هنگام محاسبه چك سام استفاده بشوند.
Source & Destination IP : در این دو بخش به ترتیب آدرس IP فرستنده و گیرنده قرار میگیره.
Options+Padding : به طور معمول از بخش Option برای ارسال گزینههای اختیاری یا تنظیمی استفاده میشه. ما از این بخش استفادهای نمیکنیم، در نتیجه اندازه هدر IP همواره برای ما 20 بایت خواهد بود و بخش HLen با عدد 5 پر میشه (همونطور که گفتیم Hlen بر اساس دادههای 4 بایتی محاسبه شده؛ پس عدد داخل HLen باید در 4 ضرب بشه تا طول هدر بر حسب بایت بدست بیاد). از طرفی، چنانچه از بخش Option استفاده بشه و مجموع بایتهای گزینههای استفاده شده، مضربی از 4 نباشند؛ در انتهای بخش Option عملیات padding انجام میشه؛ یعنی با صفر پر میشه تا کل بایتهای بخش Option مضربی از 4 باشند.
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.