配置路由時如何指定源地址

  歡迎大家來到,本文為大家介紹,歡迎大家閱讀,希望能幫到你。

  如果你的一塊網絡卡上配置了多個IP地址,那麼在資料包發出時會使用哪一個呢?在Linux上,使用iproute2工具可以設定src引數強制封裝源地址:

  ip route add 1.2.3.4/32 via 4.3.2.1 src 3.3.3.3

  但是在Windows上,一切都是內部邏輯自動選擇的,其原則如下:

  單網絡卡時,選擇和預設閘道器在同一網段的最匹配IP地址為源;

  多網絡卡時,首先選擇預設閘道器所在的網絡卡作為傳送網絡卡,然而在該網絡卡上按照單網絡卡原則選擇一個IP地址作為源。

  因此,如果你的目標地址是1.2.3.4,預設閘道器是4.3.2.1,本地連線上兩個IP地址:4.3.2.2和3.3.3.3,很顯然,4.3.2.2會作為源IP地址被選擇,這樣在發包的時候,4.3.2.2將作為資料包的源IP地址。

  然而有時候為了實現自己的一些策略或者小技巧,並不希望系統為我如此自動地封裝源IP地址,比如顯而易見地是在使用Open的時候。

  首先我們看下所謂的預設閘道器的本質意義是什麼。預設閘道器其實是一個更加特殊的“下一跳”,它其實就是一個下一跳地址,這個地址的目的在於將資料包扔給下一跳***廢話***,其實它只是一個輔助作用,真正起作用的是由它解析到的MAC地址,因為MAC地址才會真正封裝在以太幀當中,那個預設閘道器只是用來得到這個 MAC地址的,因此如果能靜態指定一個MAC地址,那麼這個預設閘道器可以是任意的。於是就有了一個辦法:

  1.為一條路由生成一個和欲選擇的源IP地址在同一個網段的假的預設閘道器,即假的下一跳;

  2.為該假閘道器IP地址建立一條靜態的到真閘道器的MAC地址的arp對映;

  如此一來,源IP地址的選擇過程將完全符合Windows的選擇邏輯,我們也就從核心外部繞開了它的限制,從而可以選擇任意的本地連線上配置的地址作為源IP地址。

  為了將手工配置的過程實現成一個自動的過程,程式設計是必不可少的,然而我又不想去呼叫那複雜的API***為了實現一個很簡單的功能不得不做超級多的準備工作...***,只能寄希望於指令碼了,然而Windows命令列功能實在太弱,很為難。問同事,百度,google,一遍遍地嘗試,折騰了太久,終於寫出一個批處理指令碼,發現Windows XP的指令碼功能還是很強大的,更不必說Power Shell了。指令碼如下***沒有echo off***:

  [plain]

  set destination=%1

  set mask=%2

  set origw=%3

  set source=%4

  ::獲取預設閘道器***可以自動發現預設閘道器,太花哨,不提倡***

  :::GetGW

  ::set origw=

  ::for /f "delims=: tokens=2" %%i in ***'"ipconfig | find /i "default gateway"| findstr [0-9]."'*** do set origw=%%i

  ::獲取預設閘道器的MAC地址

  :GetMac

  set mac=

  for /f "skip=3 tokens=2" %%i in ***'arp -a %origw%'*** do set mac=%%i

  echo %mac%|findstr \-

  ::這裡有個問題,實際上ping失敗***比如閘道器禁止ping***也無所謂,我們需要的只是它的MAC地址

  ::如果連MAC地址都不讓解析,那就別當預設網關了。因此正確的做法應該搞一個計數器,連續

  ::兩次獲取MAC失敗就算失敗。

  if ERRORLEVEL 1 ***

  ping %origw% -n 1

  if ERRORLEVEL 1 goto end

  goto GetMac

  ***

  set gw=

  set i=

  ::生成假閘道器地址***很簡單的一個演算法,欲使用的源IP地址減去1***

  for /f "delims=. tokens=4" %%i in ***'echo %source%'*** do set /a host=%%i-1

  set i=

  set j=

  set k=

  for /f "delims=. tokens=1,2,3" %%i in ***'echo %source%'*** do set gw=%%i.%%j.%%k.%host%

  ::設定假閘道器的arp對映

  arp -s %gw% %mac%

  ::新增路由

  route add %destination% mask %mask% %gw%

  :end

  將上述指令碼儲存為"route2.bat"就可以直接用了。

  其實,選擇和預設閘道器不屬於同一網段的IP作為源IP地址對於主機而言並非一個常規的做法,如果如此一來,在資料包返回的時候,當初選擇的源IP地址作為目標地址,本網段的預設閘道器在路由的時候會出現問題,除非它將下一跳指向該IP地址所在的主機的相同網段的地址,否則資料包可能會因為目標地址不可達而被丟棄。

  另外,上述的指令碼在靜態建立arp對映的時候有一個問題,那就是沒有和Windows的“死閘道器檢測”功能關聯,這樣就可以在閘道器失效後被Notofy了,或者說閘道器並沒有失效,只是換了臺機器,換了MAC,此時就需要更新那個MAC映射了。