3-bo‘lim

Ethernet, MAC manzil va ARP

Kadr tuzilishi, MAC manzil nima va uning bitlari nimani anglatadi, kalit qanday ishlaydi va ARP qanday qilib IP dan MAC ni topadi.

🕑 10 daqiqa o‘qish 📄 806 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Kanal qatlami nima qiladi?
  2. Ethernet kadri
  3. Kadrni ochish
  4. MAC manzil ichida nima bor?
  5. Kalit (switch) qanday ishlaydi?
  6. ARP - IP dan MAC ni topish
  7. Xulosa

Eng pastki amaliy qatlamdan boshlaymiz. Bu yerda kompyuterlar bir-birini IP manzil bilan emas, butunlay boshqa manzil bilan topadi.

Kanal qatlami nima qiladi? #

Uning vazifasi juda tor: bitta tarmoq ichida, qo'shnidan qo'shniga bir bo'lak ma'lumot yetkazish. Boshqa shaharga yo'l topish uning ishi emas - u bilan 3-qatlam shug'ullanadi.

Bu qatlamdagi ma'lumot bo'lagi kadr (frame) deb ataladi.

Kanal qatlami qiladiQilmaydi
Qo'shni qurilmaga yetkazishUzoq tarmoqqa yo'l topish
Kadr buzilganini aniqlashYo'qolgan kadrni qayta yuborish
Kimga mo'ljallanganini belgilashQaysi dasturga tegishlini bilish

Ethernet kadri #

Ethernet - eng keng tarqalgan kanal protokoli. Uning sarlavhasi hayratlanarli darajada sodda: bor-yo'g'i 14 bayt.

Ethernet kadri Kimga (MAC) 6 bayt Kimdan (MAC) 6 bayt Turi 2 bayt Foydali yuk 46 - 1500 bayt CRC 4 bayt sarlavha - 14 bayt ichida IP paketi turadi "Turi" maydoni nima uchun kerak Qabul qiluvchi ichkarida nima borligini bilishi kerak: 0x0800 = IPv4, 0x0806 = ARP, 0x86DD = IPv6 Usiz kadrni kimga uzatishni - IP moduligami yoki ARP gami - aniqlab bo'lmaydi Bu - qatlamlar bir-biriga qanday "ulanishini" ko'rsatadigan eng aniq misol
Ellik yildan beri deyarli o'zgarmagan tuzilma

Kadrni qo'lda yig'ib ko'ramiz:

Python
import struct

# Qo'lda yig'ilgan Ethernet kadri (sarlavha + kichik foydali yuk)
manzil = bytes.fromhex("aabbccddeeff")     # kimga
jonatuvchi = bytes.fromhex("001a2b3c4d5e")  # kimdan
tur = struct.pack("!H", 0x0800)             # 0x0800 = ichida IPv4
yuk = b"...IP paketi..."

kadr = manzil + jonatuvchi + tur + yuk

print("kadr uzunligi:", len(kadr), "bayt")
print("o'n oltilik ko'rinishi:")
h = kadr.hex()
for i in range(0, len(h), 48):
    oxir = min(i + 48, len(h))
    qator = " ".join(h[j:j + 2] for j in range(i, oxir, 2))
    print("  " + qator)
Natija
kadr uzunligi: 29 bayt
o'n oltilik ko'rinishi:
  aa bb cc dd ee ff 00 1a 2b 3c 4d 5e 08 00 2e 2e 2e 49 50 20 70 61 6b 65
  74 69 2e 2e 2e

Birinchi 6 bayt - kimga, keyingi 6 bayt - kimdan, keyin 08 00 - "ichida IPv4 bor". Qolgani - foydali yuk.

!H nima degani?

struct.pack("!H", 0x0800) - sonni ikki baytga aylantiradi.

  • H - ikki baytli musbat son (unsigned short)
  • ! - tarmoq tartibi (network byte order), ya'ni eng katta bayt oldinda

Bu juda muhim: protsessorlar sonlarni xotirada turlicha saqlaydi, tarmoqda esa yagona tartib kelishib olingan. Tarmoq tartibi har doim "katta bayt oldinda".

Kadrni ochish #

Yozish qanchalik oson bo'lsa, o'qish ham shunchalik:

Python
import struct

TURLAR = {0x0800: "IPv4", 0x0806: "ARP", 0x86DD: "IPv6"}


def mac(bayt):
    return ":".join(f"{b:02x}" for b in bayt)


def kadrni_och(kadr):
    manzil, jonatuvchi, tur = struct.unpack("!6s6sH", kadr[:14])
    return {
        "kimga": mac(manzil),
        "kimdan": mac(jonatuvchi),
        "tur": TURLAR.get(tur, f"0x{tur:04x}"),
        "yuk": kadr[14:],
    }


kadr = bytes.fromhex("aabbccddeeff001a2b3c4d5e0800") + b"...IP paketi..."
q = kadrni_och(kadr)

print("kimdan:", q["kimdan"])
print("kimga :", q["kimga"])
print("ichida:", q["tur"])
print("yuk   :", q["yuk"].decode())
Natija
kimdan: 00:1a:2b:3c:4d:5e
kimga : aa:bb:cc:dd:ee:ff
ichida: IPv4
yuk   : ...IP paketi...

Mana shu - tarmoq kartasi har kadr uchun bajaradigan ishning soddalashtirilgan modeli.

MAC manzil ichida nima bor? #

MAC manzil 6 bayt, ya'ni 48 bit. U shunchaki tasodifiy son emas - birinchi baytning ikki eng past biti maxsus ma'noga ega:

Python
def mac_tahlil(matn):
    bayt = bytes.fromhex(matn.replace(":", ""))
    birinchi = bayt[0]
    return {
        "manzil": matn,
        # eng past bit: 0 = bitta qurilmaga, 1 = guruhga
        "yuborish": "guruhga" if birinchi & 1 else "bitta qurilmaga",
        # ikkinchi bit: 0 = ishlab chiqaruvchi bergan, 1 = mahalliy
        "kim bergan": "mahalliy" if birinchi & 2 else "ishlab chiqaruvchi",
        "ishlab chiqaruvchi qismi": matn[:8],
        "qurilma qismi": matn[9:],
    }


for m in ["00:1a:2b:3c:4d:5e", "ff:ff:ff:ff:ff:ff", "02:42:ac:11:00:02"]:
    q = mac_tahlil(m)
    print(q["manzil"])
    print("   yuborish  :", q["yuborish"])
    print("   kim bergan:", q["kim bergan"])
    print("   OUI / qurilma:", q["ishlab chiqaruvchi qismi"],
          "/", q["qurilma qismi"])
Natija
00:1a:2b:3c:4d:5e
   yuborish  : bitta qurilmaga
   kim bergan: ishlab chiqaruvchi
   OUI / qurilma: 00:1a:2b / 3c:4d:5e
ff:ff:ff:ff:ff:ff
   yuborish  : guruhga
   kim bergan: mahalliy
   OUI / qurilma: ff:ff:ff / ff:ff:ff
02:42:ac:11:00:02
   yuborish  : bitta qurilmaga
   kim bergan: mahalliy
   OUI / qurilma: 02:42:ac / 11:00:02

Uchta manzil, uchta hikoya:

ManzilNima ekani
00:1a:2b:...Oddiy tarmoq kartasi
ff:ff:ff:ff:ff:ffTarqatish (broadcast) - hammaga
02:42:ac:...Dasturiy qurilma - masalan konteyner
ff:ff:... bo'yicha natijani to'g'ri o'qing

Dastur ff:ff:ff:ff:ff:ff uchun "mahalliy" deb yozdi, chunki ikkinchi bit haqiqatan yoqilgan.

Lekin bu manzil alohida ajratib qo'yilgan: u "hamma eshitsin" degani. Uni hech kim "o'ziniki" qilib qo'ymaydi.

Bit tahlili qoidani to'g'ri qo'lladi - shunchaki bu manzil qoidadan tashqarida turadi. Protokollarni o'qiyotganda bunday istisnolarni alohida eslab qolish kerak.

02: bilan boshlanadigan manzillar ham qiziq: ikkinchi bit yoqilgan, ya'ni uni ishlab chiqaruvchi emas, dastur bergan. Docker konteynerlari va virtual mashinalar aynan shunday manzillar ishlatadi.

Kalit (switch) qanday ishlaydi? #

Eski tarmoqlarda hab (hub) ishlatilardi: u kelgan kadrni hamma portga takrorlardi. Natijada tarmoqning butun tezligi hammaga bo'linardi.

Kalit boshqacha ish tutadi - u o'rganadi:

  1. Kadr keldi - kalit uning jo'natuvchi MAC ini va qaysi portdan kelganini yozib qo'yadi.
  2. Kadrni kimga uzatishni jadvaldan qaraydi.
  3. Jadvalda yo'q bo'lsa - hamma portga yuboradi (bir marta).
  4. Javob kelganda ikkinchi manzilni ham o'rganadi.

Bir necha kadrdan keyin kalit butun tarmoq xaritasini biladi va har kadrni faqat kerakli portga yuboradi.

ARP - IP dan MAC ni topish #

Endi eng muhim savol. Siz 192.168.1.20 ga murojaat qilasiz, lekin kadr yuborish uchun MAC manzil kerak. Uni qayerdan olasiz?

Javob: so'raysiz. Bu ARP protokoli.

Python
class Tarmoq:
    """Bitta LAN - qurilmalar bir-birini eshitadi."""

    def __init__(self):
        self.qurilmalar = {}   # IP -> MAC
        self.efir = []         # tarqatilgan so'rovlar jurnali

    def qosh(self, ip, mac):
        self.qurilmalar[ip] = mac

    def arp_sorov(self, kim_soradi, qidirilayotgan_ip):
        self.efir.append(f"{kim_soradi} tarqatdi: {qidirilayotgan_ip} kimda?")
        return self.qurilmalar.get(qidirilayotgan_ip)


class Kompyuter:
    def __init__(self, nom, ip, mac, tarmoq):
        self.nom, self.ip, self.mac = nom, ip, mac
        self.tarmoq = tarmoq
        self.arp_jadval = {}
        tarmoq.qosh(ip, mac)

    def mac_topish(self, ip):
        if ip in self.arp_jadval:
            print(f"  {self.nom}: {ip} keshda bor - so'rov kerak emas")
            return self.arp_jadval[ip]

        print(f"  {self.nom}: {ip} keshda yo'q - ARP so'rovi tarqatiladi")
        mac = self.tarmoq.arp_sorov(self.nom, ip)
        if mac:
            self.arp_jadval[ip] = mac
        return mac


lan = Tarmoq()
husanboy = Kompyuter("husanboy-pc", "192.168.1.10", "00:1a:2b:3c:4d:5e", lan)
Kompyuter("malika-pc", "192.168.1.20", "00:1a:2b:99:88:77", lan)

print("1-urinish:")
print("  natija:", husanboy.mac_topish("192.168.1.20"))
print("2-urinish:")
print("  natija:", husanboy.mac_topish("192.168.1.20"))
print("yo'q qurilma:")
print("  natija:", husanboy.mac_topish("192.168.1.99"))

print()
print("efirga chiqqan so'rovlar:", len(lan.efir))
for q in lan.efir:
    print("  ", q)
Natija
1-urinish:
  husanboy-pc: 192.168.1.20 keshda yo'q - ARP so'rovi tarqatiladi
  natija: 00:1a:2b:99:88:77
2-urinish:
  husanboy-pc: 192.168.1.20 keshda bor - so'rov kerak emas
  natija: 00:1a:2b:99:88:77
yo'q qurilma:
  husanboy-pc: 192.168.1.99 keshda yo'q - ARP so'rovi tarqatiladi
  natija: None

efirga chiqqan so'rovlar: 2
   husanboy-pc tarqatdi: 192.168.1.20 kimda?
   husanboy-pc tarqatdi: 192.168.1.99 kimda?

Uch marta murojaat qilindi, lekin efirga faqat ikki so'rov chiqdi - ikkinchisida javob keshdan olindi. Haqiqiy ARP keshi ham xuddi shunday ishlaydi.

O'z kompyuteringizdagi ARP jadvalini ko'ring

Linux va macOS da:

Terminal
ip neigh

Windows da:

Terminal
arp -a

Ro'yxatdagi har qator - yaqinda gaplashgan qo'shningiz. Odatda u yerda marshrutizator (router) ham bo'ladi - chunki tashqi dunyoga chiqadigan har paket avval unga boradi.

ARP hech narsani tekshirmaydi

ARP 1982-yilda yozilgan va u davrda tarmoqdagi hamma bir-biriga ishonardi.

Natijada: javobni kim bergani tekshirilmaydi. Bir tarmoqdagi hujumchi "192.168.1.1 mening MAC imda" deb yolg'on javob yuborishi mumkin - va butun trafik undan o'tadi.

Bu ARP spoofing deb ataladi. Himoya kanal qatlamida emas, yuqorida quriladi: TLS ishlatilsa, hujumchi trafikni ko'radi, lekin o'qiy olmaydi. Buni 15-bo'limda ko'ramiz.

Amaliy topshiriq
  1. Kadr yig'ish misolini ishga tushiring.
  2. tur ni 0x86DD ga o'zgartiring va kadrni qayta oching.
  3. Noma'lum tur raqami bering - dastur nima chiqaradi?
  4. MAC tahlilini 01:00:5e:00:00:01 uchun ishga tushiring.
  5. O'z kompyuteringizdagi MAC manzilni toping va uni tahlil qiling.
  6. ARP misolida uchinchi kompyuter qo'shing.
  7. ARP keshini tozalaydigan metod yozing va so'rovlar sonini qaytadan sanang.
  8. ip neigh yoki arp -a ni ishga tushiring va natijani o'qing.
  9. Hab va kalit farqini uch qatorda yozing.
  10. Nima uchun kanal qatlami uzoq tarmoqqa yo'l topa olmasligini tushuntiring.

Xulosa #

  • Kanal qatlami faqat bitta tarmoq ichida, qo'shnidan qo'shniga yetkazadi.
  • Bu qatlamdagi ma'lumot bo'lagi - kadr.
  • Ethernet sarlavhasi 14 bayt: kimga (6), kimdan (6), turi (2).
  • "Turi" maydoni ichkarida nima borligini aytadi: IPv4, ARP yoki IPv6.
  • Tarmoqda sonlar katta bayt oldinda tartibida yoziladi (! formati).
  • MAC 48 bit; birinchi baytning ikki biti yuborish turini va manba'ni bildiradi.
  • ff:ff:ff:ff:ff:ff - tarqatish manzili, uni hamma eshitadi.
  • Kalit jo'natuvchi manzillarni eslab, kadrni faqat kerakli portga yuboradi.
  • ARP IP manzildan MAC manzilni topadi va natijani keshlaydi.
  • ARP javobni tekshirmaydi - shuning uchun himoya yuqori qatlamlarda quriladi.

Keyingi bo'limda bir tarmoqdan chiqamiz va IP manzil bilan tarmoq maskasini o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.