不確定這種需求是不是有點稀少?「使用DHCP,再設定另一組固定IP」。
我目前的工作對網路的安全比較要求,DHCP 都會綁定 MAC,但MAC又沒有對應固定 IP,所以也沒辦法設成固定IP,硬設下去的話就是有一天會跟別人衝IP。嵌入式 Linux 系統工作中有很多設備是換來換去的,不太可能去登記 MAC 取得 IP。所以一般而言,測試設備都是設成固定 IP,PC 則是設定成好幾組固定 IP,以連線到設備上去。如果PC Windows又要取得 DHCP,又要設定固定 IP,找來找去,一直看不到可行的作法。(真正冷知識….)
找到了!DHCP+Static IP 同時運用
經過幾翻搜尋, 終於找到同時可以設定成 DHCP,又可以新增 Static IP (固定IP)的做法。但沒辦法透過現成的 Windows 工具,需要另外寫程式來達到這個功能,我想也是這個原因導致找不到相關文章。不知道 Microsoft 是何用意,為什麼要有這種限制。在 Linux 下,同時擁有 DHCP + Static IP,並不是什麼困難的事。下面我們就稍微解說一下程式碼,此程式也是在網路上找到的,這部份我並不是原創喔~~~~
程式碼
由於我熟悉的是 Linux 的程式,Windows 上程式設計只能大概比對 Linux 上相同的部份,下面就只做粗略的解說。
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
#pragma comment (lib, "iphlpapi.lib") #pragma comment (lib, "ws2_32.lib") #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi.h> #include <stdio.h> #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) int main(int argc, char **argv) { char buf[128]; int found=-1; NET_LUID ifname_luid; char ansiif[64]; char ifname[64]; char *alias; PWSTR ifname_1 = (PWSTR)ifname; PMIB_IPADDRTABLE pIPAddrTable; DWORD dwSize = 0; DWORD dwRetVal = 0; DWORD ifIndex; UINT iaIPAddress; UINT iaIPMask; ULONG NTEContext = 0; ULONG NTEInstance = 0; int i; int op; /* 一定需要5個參數, OP(add/del) 介面名稱, IP 位址, 子網路遮罩 */ if (argc != 5) { printf("Compiled by MZCai @ Taiwan, Republic of China.\n"); printf( "Usage: %s <OP> <IFNAME> <IPAddress> <SubnetMask>\n" , argv[0]); exit(1); } /* 操作就是 add 或 del */ if(strcmp(argv[1],"add" ) == 0) op=1; else if (strcmp(argv[1], "del") == 0) op=0; else { printf( "unknonw op"); exit(1); } alias = argv[2]; /* 從參數2取得網路介面卡名稱 */ iaIPAddress = inet_addr(argv[3]); /* 從參數3取得要設定的 IP */ iaIPMask = inet_addr(argv[4]); /* 從參數3取得要設定的 netmask */ /* 應該只是一般的 Error Handling */ pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC( sizeof (MIB_IPADDRTABLE)); if (pIPAddrTable == NULL) { printf( "Error allocating memory needed to call GetIpAddrTable()\n" ); exit (1); } else { dwSize = 0; if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { FREE(pIPAddrTable); pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(dwSize); } if (pIPAddrTable == NULL) { printf( "Memory allocation failed for GetIpAddrTable()\n" ); exit(1); } } /* 判斷指定的介面名稱是否存在 */ if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) == NO_ERROR) { for(i=0;i<pIPAddrTable->dwNumEntries;i++) { ifIndex = pIPAddrTable->table[i].dwIndex; ConvertInterfaceIndexToLuid(ifIndex, &ifname_luid); ConvertInterfaceLuidToAlias(&ifname_luid, ifname_1, sizeof(ifname)); WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, ifname_1, -1, ansiif, sizeof (ansiif), NULL, NULL ); if(strcmp(ansiif, alias) == 0) { found=i; break; } } if(found == -1) { printf( "Interface %s not found!\n" , alias); exit(1); } ifIndex = pIPAddrTable->table[found].dwIndex; } else { printf( "Call to GetIpAddrTable failed with error %d.\n" , dwRetVal); if (pIPAddrTable) FREE(pIPAddrTable); exit(1); } if (pIPAddrTable) FREE(pIPAddrTable); /* 要新增的話,則呼叫 API 來新增 IPADDress*/ if(op == 1) { if ((dwRetVal = AddIPAddress(iaIPAddress, iaIPMask, ifIndex, &NTEContext, &NTEInstance)) != NO_ERROR) { printf( "AddIPAddress failed with error: %d\n" , dwRetVal); } } else { /* 刪除的話,則呼叫內建的 netsh 命令就可以了 */ sprintf(buf, "netsh interface ip del address \"%s\" %s" , alias, argv[3]); system(buf); } return 0; } |
相容性
目前確定 Windows 7, 10 都可以使用。
操作
在設置 IP 時需要管理員的權限,為了執行這個文字模式的程式,需先以管理員身份執行 Command (CMD.exe) ,再運行設置 IP 的程式(後文稱 iphlp)。下面我們都以Windows 10 為例,並且程式是放置在D槽的狀況來解說。
開啟管理員權限命令列
不管是在 Windows 或 Linux 上設置系統IP都需要管理員權限。因為iphlp工具是命令列工具,所以我們要先執行管理員權限的命令列來執行它。先搜尋 cmd.exe 指令,並按右鍵用「系統管理員身份」執行,就可啟始一個管理員權限的命令視窗。
查看目前IP
在設置固定 IP 前,先確認一下目前的 IP 以供稍後比對。並且我們也需要取得網路介面卡的名稱,才能夠設置 IP。Windows 內建的工具 ipconfig, 可以讓我們在命令列下面檢查 IP。下達 ipconfig /all,可以看到所有詳細網路設置。
從 ipconfig/all 的結果中,有幾個比較重要的部份
- 無線區域網路介面卡 Wi-Fi: 這一行是代表介面卡的名稱是 “Wi-Fi”,稍後設置IP時,就需要指定這個名稱。前面的 “無線區域網路介面卡” 則是在說明他的類型。另外像藍牙 「乙太網路卡 藍牙網路連線」(介面名稱=藍牙網路連線)、有線網路 「乙太網路卡 乙太網路」(介面名稱=乙太網路),都是可能看到的介面列表。這邊使用者要找到自己要使用的介面卡,來做稍後的設定。
- 白白的部份:這是我無線網卡的 MAC 位置, 因為每張網路卡會對到一個獨一無二的實體位址。也就是說看到這MAC的網路封包,我就可以確定你的人或機器就在附近…. 這只是個人比較龜毛的隱私考慮。手機的 WiFi 那問題就更嚴重了… 全民公敵的情節好像也不是不可能。
- IPv4 位址:這就是目前 DHCP 取到的 IP 位址。可以供稍後比對
設定另一組固定 IP
取得介面卡名稱後,我們就可以設置另一組固定 IP 了。透過令令 iphlp add [介面卡名稱] [IP位址] [子網路遮罩],就可以新增一組 IP 。下面顯示的結果,是加入一組 10.0.0.100 後的畫面 (命令 –> iphlp add “Wi-Fi” 10.0.0.100 255.255.255.0)。
從結果圖裡可以看到,除了原本的 DHCP IP 外,另外又多了一組 10.0.0.100 的 IP,這樣就達到我們的目的,可以同時使用 DHCP+Static IP 。
刪除固定IP
刪除的命令,跟加入只差一點,就是把 add 改成 del。以上面的例子,就是下 iphlp del “Wi-Fi” 10.0.0.100 255.255.255.0。另外重開機、進省電模式,這組 IP 都會不見,需要再重新設置一次。
結語
這個 DHCP + Static IP 的問題,是在 Win7 上遇到解決的,現在看起來在 Win10上也可以用。也許 Win10 已經有原生的解決方案了~~ 這個冷知識,希望能幫到有相同困擾的人。
程式勒?
講這麼多卻沒提供程式,好像是有點鳥。不過礙於散佈可執行檔,還是有中毒的風險,目前暫不提供。另外也寫了一篇如何編譯的文章,要自己編出來並不難。如果真的有需求,請再跟我聯繫。
Latest Comments