NetworkInterface.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. //
  2. // System.Net.NetworkInformation.NetworkInterface
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. // Atsushi Enomoto ([email protected])
  7. // Miguel de Icaza ([email protected])
  8. // Eric Butler ([email protected])
  9. // Marek Habersack ([email protected])
  10. //
  11. // Copyright (c) 2006-2008 Novell, Inc. (http://www.novell.com)
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. #if NET_2_0
  33. using System;
  34. using System.Collections.Generic;
  35. using System.Collections;
  36. using System.Net;
  37. using System.Net.Sockets;
  38. using System.Runtime.InteropServices;
  39. using System.Text;
  40. using System.IO;
  41. using System.Globalization;
  42. namespace System.Net.NetworkInformation {
  43. public abstract class NetworkInterface {
  44. static Version windowsVer51 = new Version (5, 1);
  45. static internal readonly bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
  46. protected NetworkInterface ()
  47. {
  48. }
  49. public static NetworkInterface [] GetAllNetworkInterfaces ()
  50. {
  51. if (runningOnUnix) {
  52. try {
  53. if (Platform.IsMacOS)
  54. return MacOsNetworkInterface.ImplGetAllNetworkInterfaces ();
  55. else
  56. return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
  57. } catch (SystemException ex) {
  58. throw ex;
  59. } catch {
  60. return new NetworkInterface [0];
  61. }
  62. } else {
  63. if (Environment.OSVersion.Version >= windowsVer51)
  64. return Win32NetworkInterface2.ImplGetAllNetworkInterfaces ();
  65. return new NetworkInterface [0];
  66. }
  67. }
  68. [MonoTODO("Always returns true")]
  69. public static bool GetIsNetworkAvailable ()
  70. {
  71. return true;
  72. }
  73. internal static string ReadLine (string path)
  74. {
  75. using (FileStream fs = File.OpenRead (path)){
  76. using (StreamReader sr = new StreamReader (fs)){
  77. return sr.ReadLine ();
  78. }
  79. }
  80. }
  81. [MonoTODO("Only works on Linux. Returns 0 on other systems.")]
  82. public static int LoopbackInterfaceIndex {
  83. get {
  84. if (runningOnUnix) {
  85. try {
  86. return UnixNetworkInterface.IfNameToIndex ("lo");
  87. } catch {
  88. return 0;
  89. }
  90. } else
  91. return 0;
  92. }
  93. }
  94. public abstract IPInterfaceProperties GetIPProperties ();
  95. public abstract IPv4InterfaceStatistics GetIPv4Statistics ();
  96. public abstract PhysicalAddress GetPhysicalAddress ();
  97. public abstract bool Supports (NetworkInterfaceComponent networkInterfaceComponent);
  98. public abstract string Description { get; }
  99. public abstract string Id { get; }
  100. public abstract bool IsReceiveOnly { get; }
  101. public abstract string Name { get; }
  102. public abstract NetworkInterfaceType NetworkInterfaceType { get; }
  103. public abstract OperationalStatus OperationalStatus { get; }
  104. public abstract long Speed { get; }
  105. public abstract bool SupportsMulticast { get; }
  106. }
  107. abstract class UnixNetworkInterface : NetworkInterface
  108. {
  109. [DllImport("libc")]
  110. static extern int if_nametoindex(string ifname);
  111. protected IPv4InterfaceStatistics ipv4stats;
  112. protected IPInterfaceProperties ipproperties;
  113. string name;
  114. //int index;
  115. protected List <IPAddress> addresses;
  116. byte[] macAddress;
  117. NetworkInterfaceType type;
  118. internal UnixNetworkInterface (string name)
  119. {
  120. this.name = name;
  121. addresses = new List<IPAddress> ();
  122. }
  123. public static int IfNameToIndex (string ifname)
  124. {
  125. return if_nametoindex(ifname);
  126. }
  127. internal void AddAddress (IPAddress address)
  128. {
  129. addresses.Add (address);
  130. }
  131. internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
  132. {
  133. //this.index = index;
  134. this.macAddress = macAddress;
  135. this.type = type;
  136. }
  137. public override PhysicalAddress GetPhysicalAddress ()
  138. {
  139. if (macAddress != null)
  140. return new PhysicalAddress (macAddress);
  141. else
  142. return PhysicalAddress.None;
  143. }
  144. public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
  145. {
  146. bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
  147. bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
  148. foreach (IPAddress address in addresses) {
  149. if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
  150. return true;
  151. else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
  152. return true;
  153. }
  154. return false;
  155. }
  156. public override string Description {
  157. get { return name; }
  158. }
  159. public override string Id {
  160. get { return name; }
  161. }
  162. public override bool IsReceiveOnly {
  163. get { return false; }
  164. }
  165. public override string Name {
  166. get { return name; }
  167. }
  168. public override NetworkInterfaceType NetworkInterfaceType {
  169. get { return type; }
  170. }
  171. [MonoTODO ("Parse dmesg?")]
  172. public override long Speed {
  173. get {
  174. // Bits/s
  175. return 1000000;
  176. }
  177. }
  178. }
  179. //
  180. // This class needs support from the libsupport.so library to fetch the
  181. // data using arch-specific ioctls.
  182. //
  183. // For this to work, we have to create this on the factory above.
  184. //
  185. class LinuxNetworkInterface : UnixNetworkInterface
  186. {
  187. [DllImport ("libc")]
  188. static extern int getifaddrs (out IntPtr ifap);
  189. [DllImport ("libc")]
  190. static extern void freeifaddrs (IntPtr ifap);
  191. const int AF_INET = 2;
  192. const int AF_INET6 = 10;
  193. const int AF_PACKET = 17;
  194. //NetworkInterfaceType type;
  195. string iface_path;
  196. string iface_operstate_path;
  197. string iface_flags_path;
  198. internal string IfacePath {
  199. get { return iface_path; }
  200. }
  201. public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
  202. {
  203. var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
  204. IntPtr ifap;
  205. if (getifaddrs (out ifap) != 0)
  206. throw new SystemException ("getifaddrs() failed");
  207. try {
  208. IntPtr next = ifap;
  209. while (next != IntPtr.Zero) {
  210. ifaddrs addr = (ifaddrs) Marshal.PtrToStructure (next, typeof (ifaddrs));
  211. IPAddress address = IPAddress.None;
  212. string name = addr.ifa_name;
  213. int index = -1;
  214. byte[] macAddress = null;
  215. NetworkInterfaceType type = NetworkInterfaceType.Unknown;
  216. if (addr.ifa_addr != IntPtr.Zero) {
  217. sockaddr_in sockaddr = (sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_in));
  218. if (sockaddr.sin_family == AF_INET6) {
  219. sockaddr_in6 sockaddr6 = (sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_in6));
  220. address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
  221. } else if (sockaddr.sin_family == AF_INET) {
  222. address = new IPAddress (sockaddr.sin_addr);
  223. } else if (sockaddr.sin_family == AF_PACKET) {
  224. sockaddr_ll sockaddrll = (sockaddr_ll) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_ll));
  225. if (((int)sockaddrll.sll_halen) > sockaddrll.sll_addr.Length){
  226. Console.Error.WriteLine ("Got a bad hardware address length for an AF_PACKET {0} {1}",
  227. sockaddrll.sll_halen, sockaddrll.sll_addr.Length);
  228. next = addr.ifa_next;
  229. continue;
  230. }
  231. macAddress = new byte [(int) sockaddrll.sll_halen];
  232. Array.Copy (sockaddrll.sll_addr, 0, macAddress, 0, macAddress.Length);
  233. index = sockaddrll.sll_ifindex;
  234. int hwtype = (int)sockaddrll.sll_hatype;
  235. if (Enum.IsDefined (typeof (LinuxArpHardware), hwtype)) {
  236. switch ((LinuxArpHardware)hwtype) {
  237. case LinuxArpHardware.EETHER:
  238. goto case LinuxArpHardware.ETHER;
  239. case LinuxArpHardware.ETHER:
  240. type = NetworkInterfaceType.Ethernet;
  241. break;
  242. case LinuxArpHardware.PRONET:
  243. type = NetworkInterfaceType.TokenRing;
  244. break;
  245. case LinuxArpHardware.ATM:
  246. type = NetworkInterfaceType.Atm;
  247. break;
  248. case LinuxArpHardware.SLIP:
  249. type = NetworkInterfaceType.Slip;
  250. break;
  251. case LinuxArpHardware.PPP:
  252. type = NetworkInterfaceType.Ppp;
  253. break;
  254. case LinuxArpHardware.LOOPBACK:
  255. type = NetworkInterfaceType.Loopback;
  256. macAddress = null;
  257. break;
  258. case LinuxArpHardware.FDDI:
  259. type = NetworkInterfaceType.Fddi;
  260. break;
  261. case LinuxArpHardware.TUNNEL6:
  262. goto case LinuxArpHardware.TUNNEL;
  263. case LinuxArpHardware.TUNNEL:
  264. type = NetworkInterfaceType.Tunnel;
  265. break;
  266. }
  267. }
  268. }
  269. }
  270. LinuxNetworkInterface iface = null;
  271. if (!interfaces.TryGetValue (name, out iface)) {
  272. iface = new LinuxNetworkInterface (name);
  273. interfaces.Add (name, iface);
  274. }
  275. if (!address.Equals (IPAddress.None))
  276. iface.AddAddress (address);
  277. if (macAddress != null || type == NetworkInterfaceType.Loopback) {
  278. if (type == NetworkInterfaceType.Ethernet) {
  279. if (Directory.Exists(iface.IfacePath + "wireless")) {
  280. type = NetworkInterfaceType.Wireless80211;
  281. }
  282. }
  283. iface.SetLinkLayerInfo (index, macAddress, type);
  284. }
  285. next = addr.ifa_next;
  286. }
  287. } finally {
  288. freeifaddrs (ifap);
  289. }
  290. NetworkInterface [] result = new NetworkInterface [interfaces.Count];
  291. int x = 0;
  292. foreach (NetworkInterface thisInterface in interfaces.Values) {
  293. result [x] = thisInterface;
  294. x++;
  295. }
  296. return result;
  297. }
  298. LinuxNetworkInterface (string name)
  299. : base (name)
  300. {
  301. iface_path = "/sys/class/net/" + name + "/";
  302. iface_operstate_path = iface_path + "operstate";
  303. iface_flags_path = iface_path + "flags";
  304. }
  305. public override IPInterfaceProperties GetIPProperties ()
  306. {
  307. if (ipproperties == null)
  308. ipproperties = new LinuxIPInterfaceProperties (this, addresses);
  309. return ipproperties;
  310. }
  311. public override IPv4InterfaceStatistics GetIPv4Statistics ()
  312. {
  313. if (ipv4stats == null)
  314. ipv4stats = new LinuxIPv4InterfaceStatistics (this);
  315. return ipv4stats;
  316. }
  317. public override OperationalStatus OperationalStatus {
  318. get {
  319. if (!Directory.Exists (iface_path))
  320. return OperationalStatus.Unknown;
  321. try {
  322. string s = ReadLine (iface_operstate_path);
  323. switch (s){
  324. case "unknown":
  325. return OperationalStatus.Unknown;
  326. case "notpresent":
  327. return OperationalStatus.NotPresent;
  328. case "down":
  329. return OperationalStatus.Down;
  330. case "lowerlayerdown":
  331. return OperationalStatus.LowerLayerDown;
  332. case "testing":
  333. return OperationalStatus.Testing;
  334. case "dormant":
  335. return OperationalStatus.Dormant;
  336. case "up":
  337. return OperationalStatus.Up;
  338. }
  339. } catch {
  340. }
  341. return OperationalStatus.Unknown;
  342. }
  343. }
  344. public override bool SupportsMulticast {
  345. get {
  346. if (!Directory.Exists (iface_path))
  347. return false;
  348. try {
  349. string s = ReadLine (iface_flags_path);
  350. if (s.Length > 2 && s [0] == '0' && s [1] == 'x')
  351. s = s.Substring (2);
  352. ulong f = UInt64.Parse (s, NumberStyles.HexNumber);
  353. // Hardcoded, only useful for Linux.
  354. return ((f & 0x1000) == 0x1000);
  355. } catch {
  356. return false;
  357. }
  358. }
  359. }
  360. }
  361. class MacOsNetworkInterface : UnixNetworkInterface
  362. {
  363. [DllImport ("libc")]
  364. static extern int getifaddrs (out IntPtr ifap);
  365. [DllImport ("libc")]
  366. static extern void freeifaddrs (IntPtr ifap);
  367. const int AF_INET = 2;
  368. const int AF_INET6 = 30;
  369. const int AF_LINK = 18;
  370. public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
  371. {
  372. var interfaces = new Dictionary <string, MacOsNetworkInterface> ();
  373. IntPtr ifap;
  374. if (getifaddrs (out ifap) != 0)
  375. throw new SystemException ("getifaddrs() failed");
  376. try {
  377. IntPtr next = ifap;
  378. while (next != IntPtr.Zero) {
  379. MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
  380. IPAddress address = IPAddress.None;
  381. string name = addr.ifa_name;
  382. int index = -1;
  383. byte[] macAddress = null;
  384. NetworkInterfaceType type = NetworkInterfaceType.Unknown;
  385. if (addr.ifa_addr != IntPtr.Zero) {
  386. MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
  387. if (sockaddr.sa_family == AF_INET6) {
  388. MacOsStructs.sockaddr_in6 sockaddr6 = (MacOsStructs.sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in6));
  389. address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
  390. } else if (sockaddr.sa_family == AF_INET) {
  391. MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
  392. address = new IPAddress (sockaddrin.sin_addr);
  393. } else if (sockaddr.sa_family == AF_LINK) {
  394. MacOsStructs.sockaddr_dl sockaddrdl = (MacOsStructs.sockaddr_dl) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_dl));
  395. macAddress = new byte [(int) sockaddrdl.sdl_alen];
  396. Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, Math.Min (macAddress.Length, sockaddrdl.sdl_data.Length - sockaddrdl.sdl_nlen));
  397. index = sockaddrdl.sdl_index;
  398. int hwtype = (int) sockaddrdl.sdl_type;
  399. if (Enum.IsDefined (typeof (MacOsArpHardware), hwtype)) {
  400. switch ((MacOsArpHardware) hwtype) {
  401. case MacOsArpHardware.ETHER:
  402. type = NetworkInterfaceType.Ethernet;
  403. break;
  404. case MacOsArpHardware.ATM:
  405. type = NetworkInterfaceType.Atm;
  406. break;
  407. case MacOsArpHardware.SLIP:
  408. type = NetworkInterfaceType.Slip;
  409. break;
  410. case MacOsArpHardware.PPP:
  411. type = NetworkInterfaceType.Ppp;
  412. break;
  413. case MacOsArpHardware.LOOPBACK:
  414. type = NetworkInterfaceType.Loopback;
  415. macAddress = null;
  416. break;
  417. case MacOsArpHardware.FDDI:
  418. type = NetworkInterfaceType.Fddi;
  419. break;
  420. }
  421. }
  422. }
  423. }
  424. MacOsNetworkInterface iface = null;
  425. if (!interfaces.TryGetValue (name, out iface)) {
  426. iface = new MacOsNetworkInterface (name);
  427. interfaces.Add (name, iface);
  428. }
  429. if (!address.Equals (IPAddress.None))
  430. iface.AddAddress (address);
  431. if (macAddress != null || type == NetworkInterfaceType.Loopback)
  432. iface.SetLinkLayerInfo (index, macAddress, type);
  433. next = addr.ifa_next;
  434. }
  435. } finally {
  436. freeifaddrs (ifap);
  437. }
  438. NetworkInterface [] result = new NetworkInterface [interfaces.Count];
  439. int x = 0;
  440. foreach (NetworkInterface thisInterface in interfaces.Values) {
  441. result [x] = thisInterface;
  442. x++;
  443. }
  444. return result;
  445. }
  446. MacOsNetworkInterface (string name)
  447. : base (name)
  448. {
  449. }
  450. public override IPInterfaceProperties GetIPProperties ()
  451. {
  452. if (ipproperties == null)
  453. ipproperties = new MacOsIPInterfaceProperties (this, addresses);
  454. return ipproperties;
  455. }
  456. public override IPv4InterfaceStatistics GetIPv4Statistics ()
  457. {
  458. if (ipv4stats == null)
  459. ipv4stats = new MacOsIPv4InterfaceStatistics (this);
  460. return ipv4stats;
  461. }
  462. public override OperationalStatus OperationalStatus {
  463. get {
  464. return OperationalStatus.Unknown;
  465. }
  466. }
  467. public override bool SupportsMulticast {
  468. get {
  469. return false;
  470. }
  471. }
  472. }
  473. class Win32NetworkInterface2 : NetworkInterface
  474. {
  475. [DllImport ("iphlpapi.dll", SetLastError = true)]
  476. static extern int GetAdaptersInfo (byte [] info, ref int size);
  477. [DllImport ("iphlpapi.dll", SetLastError = true)]
  478. static extern int GetAdaptersAddresses (uint family, uint flags, IntPtr reserved, byte [] info, ref int size);
  479. [DllImport ("iphlpapi.dll", SetLastError = true)]
  480. static extern int GetIfEntry (ref Win32_MIB_IFROW row);
  481. public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
  482. {
  483. // Win32_IP_ADAPTER_INFO [] ai = GetAdaptersInfo ();
  484. Win32_IP_ADAPTER_ADDRESSES [] aa = GetAdaptersAddresses ();
  485. NetworkInterface [] ret = new NetworkInterface [aa.Length];
  486. for (int i = 0; i < ret.Length; i++)
  487. ret [i] = new Win32NetworkInterface2 (aa [i]);
  488. return ret;
  489. }
  490. public static Win32_IP_ADAPTER_INFO GetAdapterInfoByIndex (int index)
  491. {
  492. foreach (Win32_IP_ADAPTER_INFO info in GetAdaptersInfo ())
  493. if (info.Index == index)
  494. return info;
  495. return null;
  496. }
  497. unsafe static Win32_IP_ADAPTER_INFO [] GetAdaptersInfo ()
  498. {
  499. byte [] bytes = null;
  500. int len = 0;
  501. GetAdaptersInfo (bytes, ref len);
  502. bytes = new byte [len];
  503. int ret = GetAdaptersInfo (bytes, ref len);
  504. if (ret != 0)
  505. throw new NetworkInformationException (ret);
  506. List<Win32_IP_ADAPTER_INFO> l = new List<Win32_IP_ADAPTER_INFO> ();
  507. fixed (byte* ptr = bytes) {
  508. Win32_IP_ADAPTER_INFO info;
  509. for (IntPtr p = (IntPtr) ptr; p != IntPtr.Zero; p = info.Next) {
  510. info = new Win32_IP_ADAPTER_INFO ();
  511. Marshal.PtrToStructure (p, info);
  512. l.Add (info);
  513. }
  514. }
  515. return l.ToArray ();
  516. }
  517. unsafe static Win32_IP_ADAPTER_ADDRESSES [] GetAdaptersAddresses ()
  518. {
  519. byte [] bytes = null;
  520. int len = 0;
  521. GetAdaptersAddresses (0, 0, IntPtr.Zero, bytes, ref len);
  522. bytes = new byte [len];
  523. int ret = GetAdaptersAddresses (0, 0, IntPtr.Zero, bytes, ref len);
  524. if (ret != 0)
  525. throw new NetworkInformationException (ret);
  526. List<Win32_IP_ADAPTER_ADDRESSES> l = new List<Win32_IP_ADAPTER_ADDRESSES> ();
  527. fixed (byte* ptr = bytes) {
  528. Win32_IP_ADAPTER_ADDRESSES info;
  529. for (IntPtr p = (IntPtr) ptr; p != IntPtr.Zero; p = info.Next) {
  530. info = new Win32_IP_ADAPTER_ADDRESSES ();
  531. Marshal.PtrToStructure (p, info);
  532. l.Add (info);
  533. }
  534. }
  535. return l.ToArray ();
  536. }
  537. Win32_IP_ADAPTER_ADDRESSES addr;
  538. Win32_MIB_IFROW mib4, mib6;
  539. Win32IPv4InterfaceStatistics ip4stats;
  540. IPInterfaceProperties ip_if_props;
  541. Win32NetworkInterface2 (Win32_IP_ADAPTER_ADDRESSES addr)
  542. {
  543. this.addr = addr;
  544. mib4 = default (Win32_MIB_IFROW);
  545. mib4.Index = addr.Alignment.IfIndex;
  546. if (GetIfEntry (ref mib4) != 0)
  547. mib4.Index = -1; // unavailable;
  548. mib6 = default (Win32_MIB_IFROW);
  549. mib6.Index = addr.Ipv6IfIndex;
  550. if (GetIfEntry (ref mib6) != 0)
  551. mib6.Index = -1; // unavailable;
  552. ip4stats = new Win32IPv4InterfaceStatistics (mib4);
  553. ip_if_props = new Win32IPInterfaceProperties2 (addr, mib4, mib6);
  554. }
  555. public override IPInterfaceProperties GetIPProperties ()
  556. {
  557. return ip_if_props;
  558. }
  559. public override IPv4InterfaceStatistics GetIPv4Statistics ()
  560. {
  561. return ip4stats;
  562. }
  563. public override PhysicalAddress GetPhysicalAddress ()
  564. {
  565. byte [] bytes = new byte [addr.PhysicalAddressLength];
  566. Array.Copy (addr.PhysicalAddress, 0, bytes, 0, bytes.Length);
  567. return new PhysicalAddress (bytes);
  568. }
  569. public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
  570. {
  571. switch (networkInterfaceComponent) {
  572. case NetworkInterfaceComponent.IPv4:
  573. return mib4.Index >= 0;
  574. case NetworkInterfaceComponent.IPv6:
  575. return mib6.Index >= 0;
  576. }
  577. return false;
  578. }
  579. public override string Description {
  580. get { return addr.Description; }
  581. }
  582. public override string Id {
  583. get { return addr.AdapterName; }
  584. }
  585. public override bool IsReceiveOnly {
  586. get { return addr.IsReceiveOnly; }
  587. }
  588. public override string Name {
  589. get { return addr.FriendlyName; }
  590. }
  591. public override NetworkInterfaceType NetworkInterfaceType {
  592. get { return addr.IfType; }
  593. }
  594. public override OperationalStatus OperationalStatus {
  595. get { return addr.OperStatus; }
  596. }
  597. public override long Speed {
  598. get { return mib6.Index >= 0 ? mib6.Speed : mib4.Speed; }
  599. }
  600. public override bool SupportsMulticast {
  601. get { return !addr.NoMulticast; }
  602. }
  603. }
  604. }
  605. #endif