Windows 同時擁有DHCP + 固定IP - 月半人的家

文章推薦指數: 80 %
投票人數:10人

如果PC Windows又要取得DHCP,又要設定固定IP,找來找去,一直看不到可行的作法。

(真正冷知識….) 找到了!DHCP+Static IP 同時運用. 經過幾翻搜尋, 終於 ... Home程式設計Windows同時擁有DHCP+固定IP 瀏覽數: 4,318 不確定這種需求是不是有點稀少?「使用DHCP,再設定另一組固定IP」。

我目前的工作對網路的安全比較要求,DHCP都會綁定MAC,但MAC又沒有對應固定IP,所以也沒辦法設成固定IP,硬設下去的話就是有一天會跟別人衝IP。

嵌入式Linux系統工作中有很多設備是換來換去的,不太可能去登記MAC取得IP。

所以一般而言,測試設備都是設成固定IP,PC則是設定成好幾組固定IP,以連線到設備上去。

如果PCWindows又要取得DHCP,又要設定固定IP,找來找去,一直看不到可行的作法。

(真正冷知識….) 找到了!DHCP+StaticIP同時運用 經過幾翻搜尋,終於找到同時可以設定成DHCP,又可以新增StaticIP(固定IP)的做法。

但沒辦法透過現成的Windows工具,需要另外寫程式來達到這個功能,我想也是這個原因導致找不到相關文章。

不知道Microsoft是何用意,為什麼要有這種限制。

在Linux下,同時擁有DHCP+StaticIP,並不是什麼困難的事。

下面我們就稍微解說一下程式碼,此程式也是在網路上找到的,這部份我並不是原創喔~~~~ 程式碼 由於我熟悉的是Linux的程式,Windows上程式設計只能大概比對Linux上相同的部份,下面就只做粗略的解說。

新增IP程式 #pragmacomment(lib,"iphlpapi.lib") #pragmacomment(lib,"ws2_32.lib") #include #include #include #include #defineMALLOC(x)HeapAlloc(GetProcessHeap(),0,(x)) #defineFREE(x)HeapFree(GetProcessHeap(),0,(x)) intmain(intargc,char**argv) { charbuf[128]; intfound=-1; NET_LUIDifname_luid; charansiif[64]; charifname[64]; char*alias; PWSTRifname_1=(PWSTR)ifname; PMIB_IPADDRTABLEpIPAddrTable; DWORDdwSize=0; DWORDdwRetVal=0; DWORDifIndex; UINTiaIPAddress; UINTiaIPMask; ULONGNTEContext=0; ULONGNTEInstance=0; inti; intop; /*一定需要5個參數,OP(add/del)介面名稱,IP位址,子網路遮罩*/ if(argc!=5) { printf("CompiledbyMZCai@Taiwan,RepublicofChina.\n"); printf("Usage:%s\n",argv[0]); exit(1); } /*操作就是add或del*/ if(strcmp(argv[1],"add")==0) op=1; elseif(strcmp(argv[1],"del")==0) op=0; else{ printf("unknonwop"); exit(1); } alias=argv[2];/*從參數2取得網路介面卡名稱*/ iaIPAddress=inet_addr(argv[3]);/*從參數3取得要設定的IP*/ iaIPMask=inet_addr(argv[4]);/*從參數3取得要設定的netmask*/ /*應該只是一般的ErrorHandling*/ pIPAddrTable=(MIB_IPADDRTABLE*)MALLOC(sizeof(MIB_IPADDRTABLE)); if(pIPAddrTable==NULL) { printf("ErrorallocatingmemoryneededtocallGetIpAddrTable()\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("MemoryallocationfailedforGetIpAddrTable()\n"); exit(1); } } /*判斷指定的介面名稱是否存在*/ if((dwRetVal=GetIpAddrTable(pIPAddrTable,&dwSize,0))==NO_ERROR) { for(i=0;idwNumEntries;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%snotfound!\n",alias); exit(1); } ifIndex=pIPAddrTable->table[found].dwIndex; } else { printf("CalltoGetIpAddrTablefailedwitherror%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("AddIPAddressfailedwitherror:%d\n",dwRetVal); } } else{ /*刪除的話,則呼叫內建的netsh命令就可以了*/ sprintf(buf,"netshinterfaceipdeladdress\"%s\"%s",alias,argv[3]); system(buf); } return0; } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 #pragmacomment(lib,"iphlpapi.lib")#pragmacomment(lib,"ws2_32.lib")#include#include#include#include #defineMALLOC(x)HeapAlloc(GetProcessHeap(),0,(x))#defineFREE(x)HeapFree(GetProcessHeap(),0,(x)) intmain(intargc,char**argv) {    charbuf[128];     intfound=-1;    NET_LUIDifname_luid;    charansiif[64];    charifname[64];    char*alias;    PWSTRifname_1=(PWSTR)ifname;    PMIB_IPADDRTABLEpIPAddrTable;    DWORDdwSize=0;    DWORDdwRetVal=0;    DWORDifIndex;    UINTiaIPAddress;    UINTiaIPMask;    ULONGNTEContext=0;    ULONGNTEInstance=0;    inti;    intop;    /*一定需要5個參數,OP(add/del)介面名稱,IP位址,子網路遮罩*/    if(argc!=5)    {        printf("CompiledbyMZCai@Taiwan,RepublicofChina.\n");        printf("Usage:%s\n",argv[0]);        exit(1);    }    /*操作就是add或del*/    if(strcmp(argv[1],"add")==0)        op=1;    elseif(strcmp(argv[1],"del")==0)        op=0;    else{        printf("unknonwop");        exit(1);    }         alias=argv[2];/*從參數2取得網路介面卡名稱*/    iaIPAddress=inet_addr(argv[3]);/*從參數3取得要設定的IP*/    iaIPMask=inet_addr(argv[4]);/*從參數3取得要設定的netmask*/     /*應該只是一般的ErrorHandling*/    pIPAddrTable=(MIB_IPADDRTABLE*)MALLOC(sizeof(MIB_IPADDRTABLE));    if(pIPAddrTable==NULL)    {        printf("ErrorallocatingmemoryneededtocallGetIpAddrTable()\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("MemoryallocationfailedforGetIpAddrTable()\n");            exit(1);        }    }     /*判斷指定的介面名稱是否存在*/    if((dwRetVal=GetIpAddrTable(pIPAddrTable,&dwSize,0))==NO_ERROR)    {        for(i=0;idwNumEntries;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%snotfound!\n",alias);            exit(1);        }        ifIndex=pIPAddrTable->table[found].dwIndex;    }    else    {        printf("CalltoGetIpAddrTablefailedwitherror%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("AddIPAddressfailedwitherror:%d\n",dwRetVal);        }    }    else{        /*刪除的話,則呼叫內建的netsh命令就可以了*/        sprintf(buf,"netshinterfaceipdel  address\"%s\"%s",alias,argv[3]);        system(buf);    }     return0; }   相容性 目前確定Windows7,10都可以使用。

  操作 在設置IP時需要管理員的權限,為了執行這個文字模式的程式,需先以管理員身份執行Command(CMD.exe),再運行設置IP的程式(後文稱iphlp)。

下面我們都以Windows10為例,並且程式是放置在D槽的狀況來解說。

開啟管理員權限命令列 不管是在Windows或Linux上設置系統IP都需要管理員權限。

因為iphlp工具是命令列工具,所以我們要先執行管理員權限的命令列來執行它。

先搜尋cmd.exe指令,並按右鍵用「系統管理員身份」執行,就可啟始一個管理員權限的命令視窗。

啟動管理員權限命令列 標題會注明是管理員 查看目前IP 在設置固定IP前,先確認一下目前的IP以供稍後比對。

並且我們也需要取得網路介面卡的名稱,才能夠設置IP。

Windows內建的工具ipconfig,可以讓我們在命令列下面檢查IP。

下達ipconfig/all,可以看到所有詳細網路設置。

ipconfig/all結果 從ipconfig/all的結果中,有幾個比較重要的部份 無線區域網路介面卡Wi-Fi:這一行是代表介面卡的名稱是“Wi-Fi”,稍後設置IP時,就需要指定這個名稱。

前面的“無線區域網路介面卡”則是在說明他的類型。

另外像藍牙「乙太網路卡藍牙網路連線」(介面名稱=藍牙網路連線)、有線網路「乙太網路卡乙太網路」(介面名稱=乙太網路),都是可能看到的介面列表。

這邊使用者要找到自己要使用的介面卡,來做稍後的設定。

白白的部份:這是我無線網卡的MAC位置,因為每張網路卡會對到一個獨一無二的實體位址。

也就是說看到這MAC的網路封包,我就可以確定你的人或機器就在附近….這只是個人比較龜毛的隱私考慮。

手機的WiFi那問題就更嚴重了…全民公敵的情節好像也不是不可能。

IPv4位址:這就是目前DHCP取到的IP位址。

可以供稍後比對   設定另一組固定IP 取得介面卡名稱後,我們就可以設置另一組固定IP了。

透過令令iphlpadd[介面卡名稱][IP位址][子網路遮罩],就可以新增一組IP。

下面顯示的結果,是加入一組10.0.0.100後的畫面(命令–>iphlpadd“Wi-Fi”10.0.0.100255.255.255.0)。

增加了一組IP 從結果圖裡可以看到,除了原本的DHCPIP外,另外又多了一組10.0.0.100的IP,這樣就達到我們的目的,可以同時使用DHCP+StaticIP。

刪除固定IP 刪除的命令,跟加入只差一點,就是把add 改成del。

以上面的例子,就是下 iphlpdel“Wi-Fi”10.0.0.100255.255.255.0。

另外重開機、進省電模式,這組IP都會不見,需要再重新設置一次。

  結語 這個DHCP+StaticIP的問題,是在Win7上遇到解決的,現在看起來在Win10上也可以用。

也許Win10已經有原生的解決方案了~~這個冷知識,希望能幫到有相同困擾的人。

程式勒? 講這麼多卻沒提供程式,好像是有點鳥。

不過礙於散佈可執行檔,還是有中毒的風險,目前暫不提供。

另外也寫了一篇如何編譯的文章,要自己編出來並不難。

如果真的有需求,請再跟我聯繫。

分享本文Print 相關文章: LittleVGL–嵌入式系統的LCD涵式庫(1)Windows下進行模擬 ExcelVBA產生QRCode與自動調整大小 ExcelVBA利用Python程式獨立產生QRCode MicrochipPIC單晶片開發–MPLabX安裝與PIC16F690燒寫範例 Tweet PinIt AboutTheAuthor kebi 誤入科技業的小白兔,立志成為狡兔而有三窟,雖有不誤正業罵名,但終不悔。

只求吃的下,睡的著,人平安。

LatestComments Pingback:VisualStudio2012小學習–編譯TFTPD32與IPHLP–月半人的家2018-09-23 LeaveaReply取消回覆 Comment Savemyname,email,andwebsiteinthisbrowserforthenexttimeIcomment. Notifymeoffollow-upcommentsbyemail.Notifymeofnewpostsbyemail. 分類 Linux學習(60) 看例子學ShellProgramming(6) Maker(11) 健康(10) 家庭親子(10) 影音(8) 旅遊(9) 未分類(1) 理財(6) 程式設計(27) 站台管理(15) 自省(15) 開箱(6) 雜賞(21) 文章列表 2022年三月 (1) 2022年二月 (1) 2022年一月 (2) 2021年十二月 (3) 2021年十月 (5) 2021年九月 (1) 2021年七月 (1) 2021年六月 (2) 2021年五月 (3) 2021年四月 (1) 2021年三月 (8) 2021年二月 (5) 2021年一月 (4) 2020年十二月 (1) 2020年十月 (1) 2020年八月 (2) 2020年七月 (2) 2020年四月 (1) 2020年三月 (1) 2020年二月 (1) 2020年一月 (1) 2019年十二月 (6) 2019年十一月 (1) 2019年九月 (4) 2019年七月 (3) 2019年五月 (2) 2019年四月 (2) 2019年三月 (5) 2019年二月 (5) 2019年一月 (10) 2018年十二月 (7) 2018年十一月 (4) 2018年十月 (5) 2018年九月 (11) 2018年八月 (9) 2018年七月 (2) 2018年六月 (6) 2018年五月 (3) 2018年四月 (3) 2018年三月 (10) 2018年二月 (9) 2018年一月 (15) 2014年七月 (1) 2013年十月 (3) 2012年八月 (1) 2011年十一月 (4) 2010年十一月 (1) 2010年十月 (2) 2006年八月 (1) 2006年七月 (1) 2005年十一月 (6) 隨機文章2021月半人的家《年度回顧》利用socat產生virtualcomport與接入TCP連線這個不常見!四核心CPU壞了一核~~~Teraterm自動記錄(Log)利用Stunnel–TLS-PSK建立安全的網路通道訪客統計 本日訪客:303 訪客總數:458771 本日瀏覽:1354 瀏覽總數:1528960 線上人數:1 你的IP:206.189.149.24 感謝您寶貴意見! 您的意見已經被收到,將儘快回覆您。



請為這篇文章評分?