နားလည်ထားရမယ့် အချက်
Frame တစ်ခုဟာ address အတွဲ နှစ်တွဲ သယ်ဆောင်ပါတယ်၊ စတင်လေ့လာသူတွေက အတွဲတစ်တွဲတည်းနဲ့ မလုံလောက်ဘူးလား လို့ မေးတာ သင့်လျော်ပါတယ်။ အဖြေက သူတို့ဟာ မေးခွန်း မတူညီတာ နှစ်ခုကို ဖြေပေးနေလို့ ဖြစ်ပါတယ်။ IP address တွေက end-to-end ဖြစ်ပါတယ် — မူရင်း ပို့သူနဲ့ နောက်ဆုံး ခရီးဆုံးကို အမည်တပ်ပြီး၊ ခရီးတစ်လျှောက်လုံး ပုံမှန်အားဖြင့် မပြောင်းလဲပါဘူး။ MAC address တွေကတော့ hop-by-hop ဖြစ်ပါတယ် — ဒီ physical link တစ်ခုတည်းရဲ့ အစွန်းနှစ်ဖက်က device နှစ်ခုကိုသာ အမည်တပ်ပြီး၊ router တိုင်းမှာ ပြန်ရေးခံရပါတယ်။ သင့် laptop က ကမ္ဘာတစ်ဖက်ခြမ်းက server ဆီ packet ပို့တဲ့အခါ destination IP က server ရဲ့ဟာ ဖြစ်ပေမယ့်၊ destination MAC ကတော့ သင့်အိမ်က router ရဲ့ဟာ ဖြစ်ပါတယ် — ဘာလို့လဲဆိုတော့ သင့် laptop က frame တစ်ခုကို physical အနေနဲ့ လက်ဆင့်ကမ်းပေးနိုင်တဲ့ တစ်ခုတည်းသော device က အဲဒါဖြစ်လို့ပါ။
MAC address က 48 bit ဖြစ်ပြီး၊ များသောအားဖြင့် hex byte ခြောက်လုံးအဖြစ် ရေးပါတယ်။ ရှေ့ဆုံး byte သုံးလုံးက OUI ဖြစ်ပြီး၊ ထုတ်လုပ်သူကို သတ်မှတ်ပေးထားတဲ့ organizationally unique identifier ဖြစ်လို့ MAC တစ်ခုက vendor ကို ဖော်ပြတတ်ပါတယ်။ ပထမ byte ထဲက bit နှစ်လုံးမှာ အဓိပ္ပာယ် ရှိပါတယ် — အနိမ့်ဆုံး bit က group (multicast/broadcast) address ဖြစ်ကြောင်း ပြပြီး၊ နောက်တစ်လုံးက globally assigned မဟုတ်ဘဲ locally administered ဖြစ်ကြောင်း ပြပါတယ် — randomized-MAC privacy feature တွေက ဒီ bit ကို set လုပ်ကြတာ ဖြစ်ပါတယ်။
ARP က ဒီကမ္ဘာ နှစ်ခုကို ချိတ်ဆက်ပေးပါတယ်။ Destination က ကိုယ့် subnet ထဲမှာ ရှိတယ်လို့ ဆုံးဖြတ်ပြီးတဲ့နောက်၊ host တစ်ခုက အဲဒီ host ရဲ့ MAC ကို ရှာရပါသေးတယ်။ သူက ARP request တစ်ခုကို — "192.168.1.20 ကို ဘယ်သူ ပိုင်လဲ" — LAN ပေါ်က စက်တိုင်းဆီ broadcast လုပ်လိုက်ပါတယ်၊ ပိုင်ရှင်တစ်ယောက်တည်းကသာ သူ့ MAC ပါတဲ့ unicast နဲ့ ပြန်ဖြေပါတယ်။ ရလဒ်ကို အချိန်တိုတိုသာ တည်တံ့တဲ့ ARP cache ထဲ ထည့်ထားလို့၊ broadcast က packet တိုင်းအတွက် မဟုတ်ဘဲ တစ်ကြိမ်သာ ဖြစ်ပါတယ်။ ARP မှာ authentication မရှိတာကြောင့် အလွယ်တကူ လိမ်လည်နိုင်ပြီး၊ ဒါက ARP-poisoning တိုက်ခိုက်မှုတွေရဲ့ အခြေခံ ဖြစ်ပါတယ်။
ARP: FINDING THE MAC THAT OWNS AN IP
------------------------------------
Host A wants to reach 192.168.1.20 but knows no MAC for it.
Host A switch Host B
192.168.1.10 | 192.168.1.20
aa:bb:cc:00:00:0a | dd:ee:ff:00:00:14
| | |
STEP 1 -- ARP REQUEST, broadcast: every host must look
| | |
|--- to ff:ff:ff:ff:ff:ff --------------------------->|
| "who has 192.168.1.20? tell 192.168.1.10" |
| | |
| +--> also delivered to |
| every other host |
| |
STEP 2 -- ARP REPLY, unicast: only Host A needs the answer
| |
|<--- to aa:bb:cc:00:00:0a ---------------------------|
| "192.168.1.20 is at dd:ee:ff:00:00:14" |
| |
STEP 3 -- Host A caches it, then sends the real frame
ARP cache on Host A
+---------------+---------------------+-----------+
| IP | MAC | expires |
+---------------+---------------------+-----------+
| 192.168.1.20 | dd:ee:ff:00:00:14 | ~60 s |
+---------------+---------------------+-----------+လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Routing ပြဿနာလို မြင်ရပေမယ့် တကယ်တော့ မဟုတ်တဲ့ လက္ခဏာတစ်ခု ရှိပါတယ်။ Server တစ်လုံးကို hardware အသစ်နဲ့ လဲလိုက်ပေမယ့် IP အတူတူ ဆက်သုံးထားတယ်။ Client အချို့က ချက်ချင်း ရောက်နိုင်ပေမယ့် အချို့က တစ်မိနစ်လောက် ရပ်နေပြီးမှ စ အလုပ်လုပ်တယ်။ Routing နဲ့ ပတ်သက်ပြီး ဘာမှ မပြောင်းလဲပါဘူး — အဟောင်း client တွေမှာ ARP cache ထဲက MAC အဟောင်း ကျန်နေသေးလို့၊ မရှိတော့တဲ့ NIC တစ်ခုဆီကို frame တွေ ဆက်ပို့နေတာ ဖြစ်ပါတယ်။ Cache entry သက်တမ်း ကုန်သွားတဲ့အခါ သူတို့က ARP ပြန်လုပ်ပြီး MAC အသစ်ကို သိကာ ပြန်ကောင်းသွားပါတယ်။ ဒါကြောင့်ပဲ arp -d လုပ်တာ ဒါမှမဟုတ် ခဏ စောင့်တာက အဖြေဖြစ်ပြီး၊ gratuitous ARP ရှိရတဲ့ အကြောင်းရင်းလည်း ဖြစ်ပါတယ် — စက်အသစ်က သူ့ mapping ကို ကိုယ်တိုင် broadcast လုပ်ပြီး လူတိုင်းရဲ့ cache ကို ချက်ချင်း update လုပ်ပေးလိုက်တာပါ။
ကိုယ့် LAN ပေါ်က host တစ်ခုကို မရောက်နိုင်တဲ့အခါ အထက်ပိုင်းကို အပြစ်မတင်ခင် ARP cache ကို အရင်စစ်တာ ယေဘုယျ လုပ်ထုံးလုပ်နည်း ဖြစ်ပါတယ်။ Entry လုံးဝ မရှိဘူးဆိုရင် ARP request ကို ဖြေပေးသူ မရှိတာပါ — subnet mask မှားနေခြင်း၊ host ပိတ်နေခြင်း၊ ဒါမှမဟုတ် switch ပြဿနာ ဖြစ်နိုင်ပါတယ်။ Entry ရှိပေမယ့် MAC မှားနေတာ ဒါမှမဟုတ် IP နှစ်ခုက MAC တစ်ခုတည်းကို မျှသုံးနေတာ တွေ့ရင် duplicate address ဒါမှမဟုတ် ARP spoofing ကို သံသယ ဝင်သင့်ပါတယ်။
အောက်က code က အသုံးများတဲ့ ရေးနည်း သုံးမျိုးနဲ့ ရေးထားတဲ့ MAC address တွေကို ဖတ်ပြီး၊ OUI ကို ခွဲထုတ်ကာ၊ ပထမ byte ထဲက flag bit နှစ်လုံးကို ဖော်ပြပေးပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
HEX_DIGITS = "0123456789abcdefABCDEF"
def normalize(raw):
"""Accept aa:bb:.., aa-bb-.. or aabb.ccdd.eeff and return 6 bytes."""
digits = "".join(c for c in raw if c in HEX_DIGITS)
if len(digits) != 12:
raise ValueError("not a 48-bit MAC address: %r" % raw)
return bytes.fromhex(digits)
def group(data, sep=":"):
return sep.join("%02x" % b for b in data)
def describe(raw):
mac = normalize(raw)
first = mac[0]
ig = first & 1 # bit 0 of the first byte
ul = (first >> 1) & 1 # bit 1 of the first byte
print("input :", raw)
print("normalized :", group(mac))
print("OUI (vendor) :", group(mac[:3]))
print("device part :", group(mac[3:]))
print("first byte :", format(first, "08b"))
if mac == b"\xff" * 6:
print(" special : broadcast (all 48 bits set)")
print(" I/G bit :", ig, "->", "group" if ig else "unicast")
print(" U/L bit :", ul, "->",
"locally administered" if ul else "globally unique (vendor)")
print()
for candidate in ("00:1A:2B:3C:4D:5E", "02-00-00-11-22-33",
"ffff.ffff.ffff"):
describe(candidate)
# The same physical NIC, written three ways -- all one address.
forms = ["00:1a:2b:3c:4d:5e", "00-1A-2B-3C-4D-5E", "001a.2b3c.4d5e"]
print("all three forms equal:", len({normalize(f) for f in forms}) == 1)
input : 00:1A:2B:3C:4D:5E
normalized : 00:1a:2b:3c:4d:5e
OUI (vendor) : 00:1a:2b
device part : 3c:4d:5e
first byte : 00000000
I/G bit : 0 -> unicast
U/L bit : 0 -> globally unique (vendor)
input : 02-00-00-11-22-33
normalized : 02:00:00:11:22:33
OUI (vendor) : 02:00:00
device part : 11:22:33
first byte : 00000010
I/G bit : 0 -> unicast
U/L bit : 1 -> locally administered
input : ffff.ffff.ffff
normalized : ff:ff:ff:ff:ff:ff
OUI (vendor) : ff:ff:ff
device part : ff:ff:ff
first byte : 11111111
special : broadcast (all 48 bits set)
I/G bit : 1 -> group
U/L bit : 1 -> locally administered
all three forms equal: True၅ မိနစ် စမ်းကြည့်
describe() ကို တိုးချဲ့ပြီး MAC တစ်ခုက IPv4 multicast MAC (01:00:5e နဲ့ စတယ်) ဟုတ်မဟုတ် စစ်ဆေးပြီး ဖော်ပြပါ။ ပြီးရင် "00:1a:2b:3c:4d" (byte ၅ လုံးသာ) ကို ထည့်စမ်းပြီး ValueError တက်လာတာကို ကြည့်ကာ ဘာကြောင့် ဒီ validation က အရေးကြီးလဲ ရေးပါ။
သတိလေးတစ်ချက်
MAC address ကို ကမ္ဘာတစ်ဝှမ်း တစ်မူထူးခြားပြီး ဘယ်တော့မှ မပြောင်းလဲဘူးလို့ ယူဆခြင်း — U/L bit ကို set လုပ်ထားတဲ့ locally administered address တွေ ရှိပြီး၊ ခေတ်မီ ဖုန်းနဲ့ laptop တွေက Wi-Fi network တစ်ခုစီအတွက် MAC ကို ကျပန်း ပြောင်းလဲပါတယ်
Server ရဲ့ IP ကို ထိန်းထားပြီး hardware လဲပြီးတဲ့နောက် ချက်ချင်း အလုပ်လုပ်လိမ့်မယ်လို့ မျှော်လင့်ခြင်း — client တွေရဲ့ ARP cache က သက်တမ်းမကုန်မချင်း MAC အဟောင်းကို ဆက်သုံးနေလို့ gratuitous ARP ဒါမှမဟုတ် cache ရှင်းခြင်း လိုအပ်ပါတယ်
RFC 826 — An Ethernet Address Resolution Protocol — Computer Networking