獲取網絡接口信息——ioctl()函數與結構體struct ifreq、 struct ifconf

http://blog.csdn.net/windeal3203/article/details/39320605

Linux 下 可以使用ioctl()函數 以及 結構體 struct ifreq ?結構體struct ifconf來獲取網絡接口的各種信息。


ioctl

首先看ioctl()用法
ioctl()原型如下:
#include <sys/ioctl.h>
int ioctl(int fd, int request, ...);
參數:
? ??fd ? ? : 文件描述符
request: ?表示要請求的信息。如IP地址、網絡掩碼等
? ???...? ?????后面的可變參數根據request而定

比如我們請求所有網絡接口的清單:
[cpp]?view plaincopy
  1. struct?ifconf?IoCtlReq;??
  2. ...??
  3. ioctl(?Sock,?SIOCGIFCONF,?&IoCtlReq?)??

其中IoCtlReq 是一個

與接口相關的request如下表所示(來源:?<http://baike.baidu.com/view/1081282.htm?fr=aladdin>):
SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
SIOCxxx
獲取所有接口的清單
設置接口地址
獲取接口地址
設置接口標志
獲取接口標志
設置點到點地址
獲取點到點地址
獲取廣播地址
設置廣播地址
獲取子網掩碼
設置子網掩碼
獲取接口的測度
設置接口的測度
獲取接口MTU
(還有很多取決于系統的實現)
struct ifconf
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq


關于ioctl的詳細解釋清查閱本博其它博文

struct ifreq

結構體 struct ifreq用來保存某個接口的信息。
[cpp]?view plaincopy
  1. //?if.h??
  2. /*?
  3. ?*?Interface?request?structure?used?for?socket?
  4. ?*?ioctl's.??All?interface?ioctl's?must?have?parameter?
  5. ?*?definitions?which?begin?with?ifr_name.??The?
  6. ?*?remainder?may?be?interface?specific.?
  7. ?*/??
  8. struct?ifreq?{??
  9. #define?IFHWADDRLEN?6??
  10. ????union??
  11. ????{??
  12. ????????char????ifrn_name[IFNAMSIZ];????????/*?if?name,?e.g.?"en0"?*/??
  13. ????}?ifr_ifrn;??
  14. ??????
  15. ????union?{??
  16. ????????struct??sockaddr?ifru_addr;??
  17. ????????struct??sockaddr?ifru_dstaddr;??
  18. ????????struct??sockaddr?ifru_broadaddr;??
  19. ????????struct??sockaddr?ifru_netmask;??
  20. ????????struct??sockaddr?ifru_hwaddr;??
  21. ????????short???ifru_flags;??
  22. ????????int?ifru_ivalue;??
  23. ????????int?ifru_mtu;??
  24. ????????struct??ifmap?ifru_map;??
  25. ????????char????ifru_slave[IFNAMSIZ];???/*?Just?fits?the?size?*/??
  26. ????????char????ifru_newname[IFNAMSIZ];??
  27. ????????void?__user?*???ifru_data;??
  28. ????????struct??if_settings?ifru_settings;??
  29. ????}?ifr_ifru;??
  30. };??
  31. #define?ifr_name????ifr_ifrn.ifrn_name??/*?interface?name???*/??
  32. #define?ifr_hwaddr??ifr_ifru.ifru_hwaddr????/*?MAC?address??????*/??
  33. #define?ifr_addr????ifr_ifru.ifru_addr??/*?address??????*/??
  34. #define?ifr_dstaddr?ifr_ifru.ifru_dstaddr???/*?other?end?of?p-p?lnk?*/??
  35. #define?ifr_broadaddr???ifr_ifru.ifru_broadaddr?/*?broadcast?address????*/??
  36. #define?ifr_netmask?ifr_ifru.ifru_netmask???/*?interface?net?mask???*/??
  37. #define?ifr_flags???ifr_ifru.ifru_flags?/*?flags????????*/??
  38. #define?ifr_metric??ifr_ifru.ifru_ivalue????/*?metric???????*/??
  39. #define?ifr_mtu?????ifr_ifru.ifru_mtu???/*?mtu??????????*/??
  40. #define?ifr_map?????ifr_ifru.ifru_map???/*?device?map???????*/??
  41. #define?ifr_slave???ifr_ifru.ifru_slave?/*?slave?device?????*/??
  42. #define?ifr_data????ifr_ifru.ifru_data??/*?for?use?by?interface?*/??
  43. #define?ifr_ifindex?ifr_ifru.ifru_ivalue????/*?interface?index??*/??
  44. #define?ifr_bandwidth???ifr_ifru.ifru_ivalue????/*?link?bandwidth???*/??
  45. #define?ifr_qlen????ifr_ifru.ifru_ivalue????/*?Queue?length?????*/??
  46. #define?ifr_newname?ifr_ifru.ifru_newname???/*?New?name?????*/??
  47. #define?ifr_settings????ifr_ifru.ifru_settings??/*?Device/proto?settings*/??



ifr_name 標識了某一接口。
可以通過ioctl獲取該接口的信息。如:
ioctl(Sock, SIOCGIFNETMASK, &IfReq);//獲取網絡接口地址掩碼
該代碼需要先對IfReq->ifr_name賦值,然后獲取與IfReq->ifr_name向匹配的網絡接口 的地址掩碼



struct ifconf

結構體struct ifconf通常用來保存所有接口信息
[cpp]?view plaincopy
  1. //?if.h??
  2. /*?
  3. ?*?Structure?used?in?SIOCGIFCONF?request.?
  4. ?*?Used?to?retrieve?interface?configuration?
  5. ?*?for?machine?(useful?for?programs?which?
  6. ?*?must?know?all?networks?accessible).?
  7. ?*/??
  8. struct?ifconf??{??
  9. ????int?ifc_len;????????????/*?size?of?buffer???*/??
  10. ????union?{??
  11. ????????char?__user?*ifcu_buf;??
  12. ????????struct?ifreq?__user?*ifcu_req;??
  13. ????}?ifc_ifcu;??
  14. };??
  15. #define?ifc_buf?ifc_ifcu.ifcu_buf???????/*?buffer?address???*/??
  16. #define?ifc_req?ifc_ifcu.ifcu_req???????/*?array?of?structures??*/??


該結構體可以用來獲取所喲網絡接口的名字和信息(不是全部信息,是ip地址)
(圖片來自:http://tech.sunplusedu.com/space/post-4064.aspx



Example:

[cpp]?view plaincopy
  1. #include?<sys/types.h>????
  2. #include?<sys/ioctl.h>????
  3. #include?<sys/socket.h>????
  4. #include?<net/if.h>????
  5. #include?<stdio.h>????
  6. #include?<stdlib.h>????
  7. #include?<unistd.h>????
  8. #include?<netdb.h>????
  9. #include?<string.h>????
  10. #include?<fcntl.h>????
  11. #include?<string.h>????
  12. #include?<errno.h>??
  13. typedef?uint32_t?uint32;???
  14. #define?MAX_IF?10??
  15. int???
  16. main()??
  17. {??
  18. ????struct?ifreq?ifVec[MAX_IF];//用來保存所有接口??
  19. ??????
  20. ????int?sock?=?-1;??
  21. ????if?(?(sock?=?socket(?AF_INET,?SOCK_DGRAM,?0?))?<?0?)??
  22. ????????fprintf(stderr,?"Error:%d,?cannot?open?RAM;\n");??
  23. ??????
  24. ????//?get?if?vector??
  25. ????struct?ifconf?ioIfConf;??
  26. ????????ioIfConf.ifc_buf?=?(void?*)ifVec;??
  27. ????????ioIfConf.ifc_len?=?sizeof(ifVec);??
  28. ?????printf("Len:%d\n",?ioIfConf.ifc_len);???????
  29. ??????????
  30. ????if?(ioctl(sock,?SIOCGIFCONF,?&ioIfConf)?<?0?)//獲取所有網絡接口信息??
  31. ????????fprintf(stderr,?"Error:%d???ioctl?IFCONF\n");??
  32. ??????
  33. ?????printf("Len:%d\n",?ioIfConf.ifc_len);//?和前面到len對比,發現ioctl修改里len到大小???????
  34. ????//循環打印每個網絡接口到信息??
  35. ????{??
  36. ????????struct?ifreq?*ifPt;??
  37. ????????struct?ifreq?*ifEndPt;??
  38. ????????ifPt?=?ifVec;??
  39. ????????ifEndPt?=?(void?*)((char?*)ifVec?+?ioIfConf.ifc_len);??
  40. ????????for?(ifPt?=?ifVec;?ifPt?<?ifEndPt;?ifPt++)??
  41. ????????{??
  42. ????????????struct?ifreq?ifReq;??
  43. ????????????if?(?ifPt->ifr_addr.sa_family?!=?AF_INET?)?{??
  44. ????????????????????????continue;??
  45. ????????????????????}??
  46. ??????????????
  47. ????????????//?Temp?keepers?of?interface?params...??
  48. ????????????uint32?u32_addr,?u32_mask;??
  49. ??????????????
  50. ????????????/*??打印ip地址??*/??
  51. ????????????char?ipDotBuf[16],?subnetDotBuf[16],?maskDotBuf[16];?//?保存點分十進制到ip地址??
  52. ????????????u32_addr?=?((struct?sockaddr_in?*)&ifPt->ifr_addr)->sin_addr.s_addr;??
  53. ????????????inet_ntop(AF_INET,?&u32_addr,?ipDotBuf,?(socklen_t?)sizeof(ipDotBuf));???
  54. ????????????printf("IP?Address:?%s\n",?ipDotBuf);??
  55. ??????????????
  56. ????????????/*????打印地址掩碼????*/??
  57. ????????????bzero(&ifReq,sizeof(struct?ifreq));????
  58. ????????????memcpy(ifReq.ifr_name,?ifPt->ifr_name,?sizeof(ifReq.ifr_name));????
  59. ????????????if?(ioctl(sock,?SIOCGIFNETMASK,?&ifReq?)?<?0){??
  60. ????????????????fprintf(stderr,?"Error:?%d,?cannot?get?mask\n",?errno);??
  61. ????????????}??
  62. ????????????else{??
  63. ????????????????u32_mask?=?((struct?sockaddr_in?*)&ifReq.ifr_addr)->sin_addr.s_addr;??
  64. ????????????????inet_ntop(AF_INET,?&u32_mask,?maskDotBuf,?(socklen_t?)sizeof(maskDotBuf));??
  65. ????????????????printf("Mask:?%s\n",?maskDotBuf);??
  66. ????????????}?????
  67. ????????????/*????打印MTU????*/??
  68. ????????????bzero(&ifReq,sizeof(struct?ifreq));????
  69. ????????????memcpy(ifReq.ifr_name,?ifPt->ifr_name,?sizeof(ifReq.ifr_name));????
  70. ????????????if?(ioctl(sock,?SIOCGIFMTU,?&ifReq?)?<?0){??
  71. ????????????????fprintf(stderr,?"Error:?%d,?cannot?get?MTU\n",?errno);??
  72. ????????????}??
  73. ????????????else{??
  74. ????????????????printf("SIOCGIFMTU:%d\n",?ifReq.ifr_mtu);???
  75. ????????????}??
  76. ???????????????/*????其他信息的打印方式與掩碼和MTU相同????*/??
  77. ????????}??
  78. ????}??
  79. ??????
  80. ??????
  81. ??????
  82. }??



運行結果:
[cpp]?view plaincopy
  1. windeal@ubuntu:~/Windeal/apue$?./exe???
  2. Len:320??
  3. Len:64??
  4. IP?Address:?127.0.0.1??
  5. Mask:?255.0.0.0??
  6. SIOCGIFMTU:16436??
  7. IP?Address:?172.17.92.198??
  8. Mask:?255.255.254.0??
  9. SIOCGIFMTU:1500??
  10. windeal@ubuntu:~/Windeal/apue$???

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383872.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383872.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383872.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

歐拉降冪

我們記f(n)為n的歐拉函數值&#xff0c;則 當B>f©時&#xff0c;AB%CAB%f©f©%C&#xff0c;這里A,C可能不互質。 很好用&#xff0c;證明很復雜&#xff0c;等有時間回來學習一下。

房多多面試總結

測試一個ATM機 功能上 取錢 ????正常 ????????要取的錢的面值是否支持ATM機服務 ????????要取的錢的數目是否小于等于存的錢的數目 ????????要取的錢的數目大于存錢的數目 ????異常 ????????取錢的時候操作出現異常&#xff0c;導致…

BZOJ3884上帝與集合的正確用法-歐拉函數

剛開始我想的是歐拉降冪&#xff0c;可是覺得復雜度還是挺高的就去找了一下題解。 思路大方向沒有問題&#xff0c;仍然是使用歐拉函數降低指數然后遞歸處理。但是不是簡單的使用歐拉降冪而是應該對模數p稍微處理一下。因為底數已經確定為2&#xff0c;所以我們可以將p寫成p2k…

比較ArrayList和數組的區別

區別1:創建時的區別 一般數組在創建的時候都需要指定數組的大小&#xff0c;但是ArrayList不需要指定數組的大小 //創建一個ArrayList對象 ArrayList<String> myList new ArrayList<String>(); //創建一個數組 String [] myList new String[2];區別2&#xff1…

linux C如何獲取服務器節點上所有網口的ip地址

http://blog.csdn.net/weiyuefei/article/details/22198659 之前項目原因&#xff0c;需要獲取當前服務器節點上所有網口的ip地址&#xff0c;但是當時由于時間比較緊&#xff0c;一直沒搞出來&#xff0c;最近沒那么忙了&#xff0c;又在網上找了一下&#xff0c;終于實現了這…

HDU1573-模線性方程

模線性方程的模板題。&#xff08;卡了一會&#xff0c;發現讀入弄錯了&#xff09; #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cmath> #include<cstdlib> #include<ctime> #include<…

java中引用傳遞

基本概念 棧內存 所謂的棧內存就是存儲進程在運行過程中變量的內存空間 堆內存 所謂的堆內存就是存儲系統中數據的內存空間 數組相關的引用傳遞 先來看一段代碼 public class ArrayDemo {public static void main(String[] args) {int[] x null;x new int[3];System.o…

(原創)C++11改進我們的程序之右值引用

http://www.cnblogs.com/qicosmos/p/3369940.html 本次主要講c11中的右值引用&#xff0c;后面還會講到右值引用如何結合std::move優化我們的程序。 c11增加了一個新的類型&#xff0c;稱作右值引用(R-value reference)&#xff0c;標記為T &&&#xff0c;說到右值引用…

(原創)C++11改進我們的程序之move和完美轉發

http://www.cnblogs.com/qicosmos/p/3376241.html 本次要講的是右值引用相關的幾個函數&#xff1a;std::move, std::forward和成員的emplace_back&#xff0c;通過這些函數我們可以避免不必要的拷貝&#xff0c;提高程序性能。move是將對象的狀態或者所有權從一個對象轉移到另…

微型個人博客服務器

Http相關簡介 Http是應用層的基于請求響應的一個協議, 其中Http的請求響應可以分為四部分. 請求行, 請求報頭,空行, 請求正文.其中請求行包括了請求方法, url, 版本號, 請求報頭包括請求屬性, 冒分割的鍵值對, 每組屬性之間都以換行的形式分開, 最后一空行作為請求的結束標識.…

HDU6428-Calculate-數論函數

并不知道為什么同樣一份代碼早上超時下午就A了…好像數據是隨機的? 做的第一道不是簡單板題的數論函數題.果然做不出來… 在網上研究了好久,才算稍微研究明白.看到了兩種推導的思路.(寫了半天發現講起來好麻煩,有時間再來更新) #include<cstdio> #include<cstring&g…

[C/C++]關于C++11中的std::move和std::forward

http://blog.sina.com.cn/s/blog_53b7ddf00101p5t0.htmlstd::move是一個用于提示優化的函數&#xff0c;過去的c98中&#xff0c;由于無法將作為右值的臨時變量從左值當中區別出來&#xff0c;所以程序運行時有大量臨時變量白白的創建后又立刻銷毀&#xff0c;其中又尤其是返回…

BZOJ3930-莫比烏斯反演+杜教篩

題目的意思很簡單&#xff0c;求給定區間內的gcdk的個數&#xff0c;這應該是傳統的莫比烏斯反演了。 有兩種思路&#xff0c;一種是直接將里面變成gcd1&#xff0c;然后里面看作元函數用莫比烏斯函數和恒等函數展開&#xff0c;然后改變求和順序。 還有一種是構造兩個函數&…

HDU1999不可摸數-暴力打表

看到這約數和第一反應是約數和函數&#xff0c;然后仔細一看不是正經的約數和函數&#xff0c;就去推去了&#xff0c;然后推的有點小復雜。&#xff08;數論函數那部分做多了&#xff09; 然后觀察也沒有用到什么數論部分的特殊知識啊&#xff0c;難不成真的要暴力&#xff1f…

BZOJ2818-莫比烏斯反演/歐拉函數

這道題之前沒有看數論函數的時候搞懂了,想到直接用歐拉函數做,現在再來看第一個想法就是這不是莫比烏斯反演嘛. 但還是能用簡單數論知識直接做出來的還是盡量做簡單一點. 兩種方法想到后都寫的差不多對了,都爆long long 了.萬惡的long long .實在是煩.切記切記,只要是乘積,或…

epoll用法整理 實現回聲服務端

http://blog.csdn.net/chenxun_2010/article/details/504934811、epoll是什么&#xff1f; epoll是當前在Linux下開發大規模并發網絡程序的熱門人選&#xff0c;epoll 在Linux2.6內核中正式引入&#xff0c;和select相似&#xff0c;都是I/O多路復用(IO multiplexing)技術。 Li…

HDU3430-擴展中國剩余定理

剛開始一直把題意看錯了。。。體測完智商急劇下降 正確理解題意以后自己寫一直wa&#xff0c;而且并不知道是哪里的問題&#xff0c;在網上看了一下其他人寫的改了改自己的就過了&#xff0c;可是之前的還是不知道為什么不對。 題意大概就是有一個置換群&#xff0c;問運算多…

linux shell編程多線程和wait命令學習

http://blog.csdn.net/shuanghujushi/article/details/38186303最近在使用shell做一些部署工作&#xff0c;在使用過程中&#xff0c;效率一直不高。想提高效率&#xff0c;經過分析發現&#xff0c;并不是所有操作都是需要串行的&#xff0c;一些操作是可以進行并行操作的。經…

#ifndef的作用

#ifndef是一條預編譯指令&#xff0c;就是說實在編譯的時候就會運行的指令。這個指令的作用很簡單&#xff0c;就是字面意思&#xff0c;如果沒有定義的話&#xff0c;但是卻經常使用。 因為使用這個可以避免一個源文件中兩次兩次包含同一個文件&#xff0c;或者一個工程文件中…

C++中結構體和類的區別和聯系

最主要的不同點就是結構體的訪問權限為public而且不能改變&#xff0c;而類的訪問權限可以改變&#xff0c;public的類和結構體基本一樣。 繼承上同樣表現出這樣的特點&#xff0c;struct是public繼承的&#xff0c;而class是private繼承的&#xff0c;繼承的子類的訪問權限取…