最近寫了不少網路管理自動化,發現很多內容會使用集合set(),這樣方便做比對。
這裡講Switch MAC,Switch外箱上或是設備上的標籤會標明該設備的MAC Address,但如果在MAC Table去看就會發現Switch MAC跟設備寫的MAC有一點點不同。
如果Switch MAC為「00:00:00:00:00:00」,在VLAN 1中,該設備MAC會是「00:00:00:00:00:01」,而在VLAN255中就是「00:00:00:00:00:ff」。
我們透過檢查Switch MAC是否存在於MAC Table的某一Port中,可以於繪製拓樸圖。
但是,一旦Switch數目增多,就會導致Interface數飛漲與MAC數飛漲,這時候就需要有個好的算法,才能避免運算時間長到不想等。
這裡要導入一個很重要的觀念,LAN與VLAN。
Local Area Network(LAN)一開始是指實體設備與實體線路的網路,在LAN之下,大家都在同一個網路。如果我們想做出區隔,避免網路區域過大造成效率低下或是安全考量,這時候可以再買一整套設備與線做實體區隔,或是切VLAN。
Virtual Local Area Network(VLAN)是透過指令產生的虛擬LAN,即便是在接在同一臺交換器上,只要虛擬LAN不同就可以做到區隔,彼此互相不看到。
具有VLAN、路由功能的L3 Switch,可能會存在於多個VLAN中扮演Gateway(Router)的角色,正常的終端設備(MAC)只會出現在一個VLAN中,而Switch為了扮演不同VLAN上的一個終端,就需要讓MAC隨著VLAN ID變化。
先講如果不調整MAC,就以ARP跟MAC Table的學習機制,即便Switch在不同VLAN都使用相同MAC,也是可以正常運作的。那為什麼Switch在不同VLAN要讓MAC產生變化?
MAC Address可以用於作為設備的唯一識別,理論上任一VLAN上學到的MAC應該是不重覆,否則就無法辨識。如果一個設備(MAC)出現在VLAN 1與VLAN 2是一個很奇怪的現象,這代表在某處始得VLAN1與VLAN2相通,是設定上或接線上的疏失。
如果一個MAC出現在不同VLAN,就會偵測到FLAPPING!
如果L3 Switch都會隨著VLAN ID調整MAC,即便是不同VLAN,MAC也不會重覆出現。對其他台Switch來說,就不會判斷有Flapping的現象發生。
知道Switch (VLAN) MAC在不同VLAN之下會有所差異
從MAC Table中,我們可以得到「(Endpoint) MAC Address」「VLAN ID」「Interface」。如果要同時看許多台Switch MAC是否存在於MAC Table中,顯然我們要先對Switch MAC做調整,加上VLAN ID。
以下是python的函式
# 將MAC轉換為:分割,每2個分隔
def format_mac(mac, delimiter=":", interval=2, case="lower"):
"""將MAC轉換為:分割,每2個分隔"""
mac = re.sub("[:\-]", "", mac)
hex_digits = re.findall(r'[\dA-Fa-f]{:}'.format("{"+str(interval)+"}"), mac)
if case == "upper": return delimiter.join(hex_digits).upper()
return delimiter.join(hex_digits).lower()
# 將MAC地址轉換為十進位數字
def mac_to_decimal(mac_address, delimiter=":"):
"""將MAC地址轉換為十進位數字"""
mac_address = mac_address.replace(delimiter, "")
return int(mac_address, 16)
# 將十進位數字轉換為MAC地址
def decimal_to_mac(decimal, delimiter=":"):
"""將十進位數字轉換為MAC地址"""
mac = "{:0>12}".format(format(decimal, '02x'))
#print(mac)
return format_mac(mac, delimiter=delimiter) # 重新組合為MAC地址
# 對MAC地址進行加減操作
def modify_mac_address(mac_address, offset, delimiter=":"):
"""對MAC地址進行位移操作"""
decimal_list = mac_to_decimal(mac_address, delimiter=delimiter) # 將MAC地址轉換為十進位數字
decimal_list += offset
modified_mac_address = decimal_to_mac(decimal_list, delimiter=delimiter) # 將十進位數字轉換回MAC地址
return modified_mac_address
mac_address = '00:11:22:33:44:55'
print('Original MAC Address:', mac_address)
modified_mac_address = modify_mac_address(mac_address, 10)
print('Modified MAC Address:', modified_mac_address)
=>
Original MAC Address: 00:11:22:33:44:55
Modified MAC Address: 00:11:22:33:44:5f
功能寫法
- 先把MAC Table,依Interface跟VLANID去把MAC Address做集合A。
- 將各SwitchMAC加上VLANID做成集合B。
- 將集合A跟集合B做聯集得到集合C
- 如果集合C不為空集合,則表示有SwitchMAC在,再逐一提取MAC扣除VLANID,還原為原始的SwitchMAC。