Thread overview
How to get an IP address from network interfaces
Apr 21, 2022
Alexander Zhirov
Apr 21, 2022
dangbinghoo
Apr 21, 2022
dangbinghoo
Apr 21, 2022
Alexander Zhirov
Apr 22, 2022
dangbinghoo
Apr 22, 2022
dangbinghoo
Apr 22, 2022
IGotD-
Apr 22, 2022
H. S. Teoh
Apr 22, 2022
IGotD-
Apr 22, 2022
H. S. Teoh
April 21, 2022

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?

April 21, 2022

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?

	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;
		}
       }

April 21, 2022

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?

	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 */
}
April 21, 2022

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?

	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

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`
April 22, 2022

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?

	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

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 */
}
April 22, 2022

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.

April 22, 2022

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.

April 22, 2022
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
April 22, 2022
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.

April 22, 2022
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".