www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get an IP address from network interfaces

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
I want to get the IP address of the network interface. There is 
both a wireless interface and a wired one. Is it possible, 
knowing the name of the network interface, to get its IP address?
Apr 21 2022
parent reply dangbinghoo <dangbinghoo gmail.com> writes:
On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov 
wrote:
 I want to get the IP address of the network interface. There is 
 both a wireless interface and a wired one. Is it possible, 
 knowing the name of the network interface, to get its IP 
 address?
```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { nIP = 0; } else { nIP = *cast(uint*)(&ifr.ifr_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*)&nIP)).idup; } } ```
Apr 21 2022
next sibling parent dangbinghoo <dangbinghoo gmail.com> writes:
On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote:
 On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov 
 wrote:
 I want to get the IP address of the network interface. There 
 is both a wireless interface and a wired one. Is it possible, 
 knowing the name of the network interface, to get its IP 
 address?
```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { nIP = 0; } else { nIP = *cast(uint*)(&ifr.ifr_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*)&nIP)).idup; } } ```
PS: ```d //handle binding to net/if.h struct ifmap { c_ulong mem_start; c_ulong mem_end; ushort base_addr; ubyte irq; ubyte dma; ubyte port; /* 3 bytes spare */ } struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; private union ifr_ifru_ { sockaddr ifru_addr; sockaddr ifru_dstaddr; sockaddr ifru_broadaddr; sockaddr ifru_netmask; sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; ifmap ifru_map; byte[IFNAMSIZ] ifru_slave; /* Just fits the size */ byte[IFNAMSIZ] ifru_newname; byte * ifru_data; } ifr_ifru_ ifr_ifru; // NOTE: alias will not work : alias ifr_ifrn.ifrn_name ifr_name; property ref ifr_name() { return ifr_ifrn.ifrn_name; } /* interface name */ property ref ifr_hwaddr() { return ifr_ifru.ifru_hwaddr; } /* MAC address */ property ref ifr_addr() { return ifr_ifru.ifru_addr; } /* address */ property ref ifr_dstaddr() { return ifr_ifru.ifru_dstaddr; } /* other end of p-p lnk */ property ref ifr_broadaddr() { return ifr_ifru.ifru_broadaddr; } /* broadcast address */ property ref ifr_netmask() { return ifr_ifru.ifru_netmask; } /* interface net mask */ property ref ifr_flags() { return ifr_ifru.ifru_flags; } /* flags */ property ref ifr_metric() { return ifr_ifru.ifru_ivalue; } /* metric */ property ref ifr_mtu() { return ifr_ifru.ifru_mtu; } /* mtu */ property ref ifr_map() { return ifr_ifru.ifru_map; } /* device map */ property ref ifr_slave() { return ifr_ifru.ifru_slave; } /* slave device */ property ref ifr_data() { return ifr_ifru.ifru_data; } /* for use by interface */ property ref ifr_ifindex() { return ifr_ifru.ifru_ivalue; } /* interface index */ property ref ifr_bandwidth() { return ifr_ifru.ifru_ivalue; } /* link bandwidth */ property ref ifr_qlen() { return ifr_ifru.ifru_ivalue; } /* queue length */ property ref ifr_newname() { return ifr_ifru.ifru_newname; } /* New name */ } ```
Apr 21 2022
prev sibling next sibling parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote:
 On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov 
 wrote:
 I want to get the IP address of the network interface. There 
 is both a wireless interface and a wired one. Is it possible, 
 knowing the name of the network interface, to get its IP 
 address?
```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { nIP = 0; } else { nIP = *cast(uint*)(&ifr.ifr_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*)&nIP)).idup; } } ```
Gives a lot of errors when compiling ```d app.d(19): Error: function `std.stdio.makeGlobal!"core.stdc.stdio.stderr".makeGlobal` at /usr/include/dlang/dmd/std/stdio.d(5198) conflicts with variable `core.stdc.stdio.stderr` at /usr/include/dlang/dmd/core/stdc/stdio.d(927) app.d(19): Error: function `core.stdc.stdio.fprintf(shared(_IO_FILE)* stream, scope const(char*) format, scope const ...)` is not callable using argument types `(void, string, int)` app.d(19): cannot pass argument `makeGlobal(StdFileHandle _iob)()` of type `void` to parameter `shared(_IO_FILE)* stream` app.d(23): Error: undefined identifier `ifreq` app.d(26): Error: undefined identifier `string` in package `std` app.d(39): Error: undefined identifier `macaddr` app.d(48): Error: undefined identifier `fromStringz` ```
Apr 21 2022
parent reply dangbinghoo <dangbinghoo gmail.com> writes:
On Thursday, 21 April 2022 at 07:38:04 UTC, Alexander Zhirov 
wrote:
 On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote:
 On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov 
 wrote:
 I want to get the IP address of the network interface. There 
 is both a wireless interface and a wired one. Is it possible, 
 knowing the name of the network interface, to get its IP 
 address?
```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { nIP = 0; } else { nIP = *cast(uint*)(&ifr.ifr_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*)&nIP)).idup; } } ```
Gives a lot of errors when compiling ```d app.d(19): Error: function `std.stdio.makeGlobal!"core.stdc.stdio.stderr".makeGlobal` at /usr/include/dlang/dmd/std/stdio.d(5198) conflicts with variable `core.stdc.stdio.stderr` at /usr/include/dlang/dmd/core/stdc/stdio.d(927) app.d(19): Error: function `core.stdc.stdio.fprintf(shared(_IO_FILE)* stream, scope const(char*) format, scope const ...)` is not callable using argument types `(void, string, int)` app.d(19): cannot pass argument `makeGlobal(StdFileHandle _iob)()` of type `void` to parameter `shared(_IO_FILE)* stream` app.d(23): Error: undefined identifier `ifreq` app.d(26): Error: undefined identifier `string` in package `std` app.d(39): Error: undefined identifier `macaddr` app.d(48): Error: undefined identifier `fromStringz` ```
```d struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; private union ifr_ifru_ { sockaddr ifru_addr; sockaddr ifru_dstaddr; sockaddr ifru_broadaddr; sockaddr ifru_netmask; sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; ifmap ifru_map; byte[IFNAMSIZ] ifru_slave; /* Just fits the size */ byte[IFNAMSIZ] ifru_newname; byte * ifru_data; } ifr_ifru_ ifr_ifru; // NOTE: alias will not work : alias ifr_ifrn.ifrn_name ifr_name; property ref ifr_name() { return ifr_ifrn.ifrn_name; } /* interface name */ property ref ifr_hwaddr() { return ifr_ifru.ifru_hwaddr; } /* MAC address */ property ref ifr_addr() { return ifr_ifru.ifru_addr; } /* address */ property ref ifr_dstaddr() { return ifr_ifru.ifru_dstaddr; } /* other end of p-p lnk */ property ref ifr_broadaddr() { return ifr_ifru.ifru_broadaddr; } /* broadcast address */ property ref ifr_netmask() { return ifr_ifru.ifru_netmask; } /* interface net mask */ property ref ifr_flags() { return ifr_ifru.ifru_flags; } /* flags */ property ref ifr_metric() { return ifr_ifru.ifru_ivalue; } /* metric */ property ref ifr_mtu() { return ifr_ifru.ifru_mtu; } /* mtu */ property ref ifr_map() { return ifr_ifru.ifru_map; } /* device map */ property ref ifr_slave() { return ifr_ifru.ifru_slave; } /* slave device */ property ref ifr_data() { return ifr_ifru.ifru_data; } /* for use by interface */ property ref ifr_ifindex() { return ifr_ifru.ifru_ivalue; } /* interface index */ property ref ifr_bandwidth() { return ifr_ifru.ifru_ivalue; } /* link bandwidth */ property ref ifr_qlen() { return ifr_ifru.ifru_ivalue; } /* queue length */ property ref ifr_newname() { return ifr_ifru.ifru_newname; } /* New name */ } ```
Apr 21 2022
parent dangbinghoo <dangbinghoo gmail.com> writes:
On Friday, 22 April 2022 at 05:28:52 UTC, dangbinghoo wrote:
 On Thursday, 21 April 2022 at 07:38:04 UTC, Alexander Zhirov 
 wrote:
 [...]
```d struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; [...]
it's actually POSIX C API binding for D. you should get similar code in C when searching StackOverflow. the only thing to do this is just to look at /usr/include/dlang for POSIX API already complete binding from the official. if something is missing, you just do-it-yourself in your code.
Apr 21 2022
prev sibling parent reply IGotD- <nise nise.com> writes:
On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote:
 [... Berkley sockets network code ...]
It really makes me sad when I see this. D has some native networking API but unfortunately you have go to the OS API to have this basic functionality. D should really expand its own API so that we don't have to use OS APIs.
Apr 22 2022
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Apr 22, 2022 at 09:26:13AM +0000, IGotD- via Digitalmars-d-learn wrote:
 On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote:
 
 [... Berkley sockets network code ...]
 
It really makes me sad when I see this. D has some native networking API but unfortunately you have go to the OS API to have this basic functionality. D should really expand its own API so that we don't have to use OS APIs.
[...] Why would you not want to use OS APIs? T -- Indifference will certainly be the downfall of mankind, but who cares? -- Miquel van Smoorenburg
Apr 22 2022
parent reply IGotD- <nise nise.com> writes:
On Friday, 22 April 2022 at 12:58:24 UTC, H. S. Teoh wrote:
 Why would you not want to use OS APIs?
1. Portability 2. Language APIs are usually much better to use that the OS APIs, like Berkeley sockets for example.
Apr 22 2022
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Apr 22, 2022 at 03:46:01PM +0000, IGotD- via Digitalmars-d-learn wrote:
 On Friday, 22 April 2022 at 12:58:24 UTC, H. S. Teoh wrote:
 
 Why would you not want to use OS APIs?
 
1. Portability
Usually when portability matters, you already have specific OSes that you're targeting, and probably already have your own OS compatibility abstraction for them. If not, just make one, that translates whatever internal API suits your code into per-OS calls. D often makes this a lot less painful than it could otherwise be.
 2. Language APIs are usually much better to use that the OS APIs, like
 Berkeley sockets for example.
Depends on how the language API was designed. :-D Some APIs are truly nightmarish to use, some are nice but incur a performance overhead. I don't mind getting as close to OS API level as I can for performance, then abstracting that layer into a nicer higher-level API that suits my program's current needs. T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
Apr 22 2022