---
name: "dnet"
section: "3"
platform: "linux"
package: "libdnet"
version: "1.18.2-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/dnet/3"
---

# dnet(3)

dumb networking library

## NAME

**dnet** – dumb networking library

## SYNOPSIS

**#include \<dnet.h\>**

### Network addressing

*int*\

**addr\_cmp**(*const struct addr \*a*, *const struct addr \*b*);

*int*\

**addr\_bcast**(*const struct addr \*a*, *struct addr \*b*);

*int*\

**addr\_net**(*const struct addr \*a*, *struct addr \*b*);

*char* *\**\

**addr\_ntop**(*const struct addr \*src*, *char \*dst*, *size\_t size*);

*int*\

**addr\_pton**(*const char \*src*, *struct addr \*dst*);

*char* *\**\

**addr\_ntoa**(*const struct addr \*a*);

*int*\

**addr\_aton**(*const char \*src*, *struct addr \*dst*);

*int*\

**addr\_ntos**(*const struct addr \*a*, *struct sockaddr \*sa*);

*int*\

**addr\_ston**(*const struct sockaddr \*sa*, *struct addr \*a*);

*int*\

**addr\_btos**(*uint16\_t bits*, *struct sockaddr \*sa*);

*int*\

**addr\_stob**(*const struct sockaddr \*sa*, *uint16\_t \*bits*);

*int*\

**addr\_btom**(*uint16\_t bits*, *void \*mask*, *size\_t size*);

*int*\

**addr\_mtob**(*const void \*mask*, *size\_t size*, *uint16\_t \*bits*);

### Address Resolution Protocol

typedef *int* **(\*arp\_handler)**(*const struct arp\_entry \*entry*, *void \*arg*);

*arp\_t* *\**\

**arp\_open**(*void*);

*int*\

**arp\_add**(*arp\_t \*a*, *const struct arp\_entry \*entry*);

*int*\

**arp\_delete**(*arp\_t \*a*, *const struct arp\_entry \*entry*);

*int*\

**arp\_get**(*arp\_t \*a*, *struct arp\_entry \*entry*);

*int*\

**arp\_loop**(*arp\_t \*a*, *arp\_handler callback*, *void \*arg*);

*arp\_t* *\**\

**arp\_close**(*arp\_t \*a*);

### Binary buffers

*blob\_t* *\**\

**blob\_new**(*void*);

*int*\

**blob\_read**(*blob\_t \*b*, *void \*buf*, *int len*);

*int*\

**blob\_write**(*blob\_t \*b*, *const void \*buf*, *int len*);

*int*\

**blob\_seek**(*blob\_t \*b*, *int off*, *int whence*);

*int*\

**blob\_index**(*blob\_t \*b*, *const void \*buf*, *int len*);

*int*\

**blob\_rindex**(*blob\_t \*b*, *const void \*buf*, *int len*);

*int*\

**blob\_pack**(*blob\_t \*b*, *const void \*fmt*, *...*);

*int*\

**blob\_unpack**(*blob\_t \*b*, *const void \*fmt*, *...*);

*int*\

**blob\_print**(*blob\_t \*b*, *char \*style*, *int len*);

*blob\_t* *\**\

**blob\_free**(*blob\_t \*b*);

### Ethernet

*eth\_t* *\**\

**eth\_open**(*const char \*device*);

*int*\

**eth\_get**(*eth\_t \*e*, *eth\_addr\_t \*ea*);

*int*\

**eth\_set**(*eth\_t \*e*, *const eth\_addr\_t \*ea*);

*ssize\_t*\

**eth\_send**(*eth\_t \*e*, *const void \*buf*, *size\_t len*);

*eth\_t* *\**\

**eth\_close**(*eth\_t \*e*);

### Firewalling

typedef *int* **(\*fw\_handler)**(*const struct fw\_rule \*rule*, *void \*arg*);

*fw\_t* *\**\

**fw\_open**(*void*);

*int*\

**fw\_add**(*fw\_t \*f*, *const struct fw\_rule \*rule*);

*int*\

**fw\_delete**(*fw\_t \*f*, *const struct fw\_rule \*rule*);

*int*\

**fw\_loop**(*fw\_t \*f*, *fw\_handler callback*, *void \*arg*);

*fw\_t* *\**\

**fw\_close**(*fw\_t \*f*);

### Network interfaces

typedef *int* **(\*intf\_handler)**(*const struct intf\_entry \*entry*, *void \*arg*);

*intf\_t* *\**\

**intf\_open**(*void*);

*int*\

**intf\_get**(*intf\_t \*i*, *struct intf\_entry \*entry*);

*int*\

**intf\_get\_src**(*intf\_t \*i*, *struct intf\_entry \*entry*, *struct addr \*src*);

*int*\

**intf\_get\_dst**(*intf\_t \*i*, *struct intf\_entry \*entry*, *struct addr \*dst*);

*int*\

**intf\_set**(*intf\_t \*i*, *const struct intf\_entry \*entry*);

*int*\

**intf\_loop**(*intf\_t \*i*, *intf\_handler callback*, *void \*arg*);

*intf\_t* *\**\

**intf\_close**(*intf\_t \*i*);

### Internet Protocol

*ip\_t* *\**\

**ip\_open**(*void*);

*ssize\_t*\

**ip\_add\_option**(*void \*buf*, *size\_t len*, *int proto*, *const void \*optbuf*, *size\_t optlen*);

*void*\

**ip\_checksum**(*void \*buf*, *size\_t len*);

*ssize\_t*\

**ip\_send**(*ip\_t \*i*, *const void \*buf*, *size\_t len*);

*ip\_t* *\**\

**ip\_close**(*ip\_t \*i*);

### Internet Protocol Version 6

*void*\

**ip6\_checksum**(*void \*buf*, *size\_t len*);

### Random number generation

*rand\_t* *\**\

**rand\_open**(*void*);

*int*\

**rand\_get**(*rand\_t \*r*, *void \*buf*, *size\_t len*);

*int*\

**rand\_set**(*rand\_t \*r*, *const void \*seed*, *size\_t len*);

*int*\

**rand\_add**(*rand\_t \*r*, *const void \*buf*, *size\_t len*);

*uint8\_t*\

**rand\_uint8**(*rand\_t \*r*);

*uint16\_t*\

**rand\_uint16**(*rand\_t \*r*);

*uint32\_t*\

**rand\_uint32**(*rand\_t \*r*);

*int*\

**rand\_shuffle**(*rand\_t \*r*, *void \*base*, *size\_t nmemb*, *size\_t size*);

*rand\_t* *\**\

**rand\_close**(*rand\_t \*r*);

### Routing

typedef *int* **(\*route\_handler)**(*const struct route\_entry \*entry*, *void \*arg*);

*route\_t* *\**\

**route\_open**(*void*);

*int*\

**route\_add**(*route\_t \*r*, *const struct route\_entry \*entry*);

*int*\

**route\_delete**(*route\_t \*r*, *const struct route\_entry \*entry*);

*int*\

**route\_get**(*route\_t \*r*, *struct route\_entry \*entry*);

*int*\

**route\_loop**(*route\_t \*r*, *route\_handler callback*, *void \*arg*);

*route\_t* *\**\

**route\_close**(*route\_t \*r*);

### Tunnel interface

*tun\_t* *\**\

**tun\_open**(*struct addr \*src*, *struct addr \*dst*, *int mtu*);

*int*\

**tun\_fileno**(*tun\_t \*t*);

*const* *char* *\**\

**tun\_name**(*tun\_t \*t*);

*ssize\_t*\

**tun\_send**(*tun\_t \*t*, *const void \*buf*, *size\_t size*);

*ssize\_t*\

**tun\_recv**(*tun\_t \*t*, *void \*buf*, *size\_t size*);

*tun\_t* *\**\

**tun\_close**(*tun\_t \*t*);

## DESCRIPTION

**dnet** provides a simplified, portable interface to several low-level networking routines, including network address manipulation, kernel [arp(4)](/arp/4.md) cache and [route(4)](/route/4.md) table lookup and manipulation, network firewalling, network interface lookup and manipulation, and raw IP packet and Ethernet frame transmission. It is intended to complement the functionality provided by [pcap(3)](/pcap/3.md).

In addition, **dnet** also provides platform-independent definitions of various network protocol formats and values for portable low-level network programming, as well as a simple binary buffer handling API.

### Network addressing

Network addresses are described by the following structure:

```
struct addr {
	uint16_t		addr_type;
	uint16_t		addr_bits;
	union {
		eth_addr_t	__eth;
		ip_addr_t	__ip;
		ip6_addr_t	__ip6;
		uint8_t		__data8[16];
		uint16_t	__data16[8];
		uint32_t	__data32[4];
	} __addr_u;
};
#define addr_eth	__addr_u.__eth
#define addr_ip		__addr_u.__ip
#define addr_ip6	__addr_u.__ip6
#define addr_data8	__addr_u.__data8
#define addr_data16	__addr_u.__data16
#define addr_data32	__addr_u.__data32
```

The following values are defined for *addr\_type*:

```
#define ADDR_TYPE_NONE		0	/* No address set */
#define	ADDR_TYPE_ETH		1	/* Ethernet */
#define	ADDR_TYPE_IP		2	/* Internet Protocol v4 */
#define	ADDR_TYPE_IP6		3	/* Internet Protocol v6 */
```

The field *addr\_bits* denotes the length of the network mask in bits.

**addr\_cmp**() compares network addresses *a* and *b*, returning an integer less than, equal to, or greater than zero if *a* is found, respectively, to be less than, equal to, or greater than *b*. Both addresses must be of the same address type.

**addr\_bcast**() computes the broadcast address for the network specified in *a* and writes it into *b*.

**addr\_net**() computes the network address for the network specified in *a* and writes it into *b*.

**addr\_ntop**() converts an address from network format to a string.

**addr\_pton**() converts an address from a string to network format.

**addr\_ntoa**() converts an address from network format to a string, returning a pointer to the result in static memory.

**addr\_aton**() is a synonym for **addr\_pton**().

**addr\_ntos**() converts an address from network format to the appropriate struct sockaddr.

**addr\_ston**() converts an address from a struct sockaddr to network format.

**addr\_btos**() converts a network mask length to a network mask specified as a struct sockaddr.

**addr\_stob**() converts a network mask specified in a struct sockaddr to a network mask length.

**addr\_btom**() converts a network mask length to a network mask in network byte order.

**addr\_mtob**() converts a network mask in network byte order to a network mask length.

### Address Resolution Protocol

ARP cache entries are described by the following structure:

```
struct arp_entry {
	struct addr	arp_pa;		/* protocol address */
	struct addr	arp_ha;		/* hardware address */
};
```

**arp\_open**() is used to obtain a handle to access the kernel [arp(4)](/arp/4.md) cache.

**arp\_add**() adds a new ARP *entry*.

**arp\_delete**() deletes the ARP *entry* for the protocol address specified by *arp\_pa*.

**arp\_get**() retrieves the ARP *entry* for the protocol address specified by *arp\_pa*.

**arp\_loop**() iterates over the kernel [arp(4)](/arp/4.md) cache, invoking the specified *callback* with each *entry* and the context *arg* passed to **arp\_loop**().

**arp\_close**() closes the specified handle.

### Binary buffers

Binary buffers are described by the following structure:

```
typedef struct blob {
	u_char		*base;		/* start of data */
	int		 off;		/* offset into data */
	int		 end;		/* end of data */
	int		 size;		/* size of allocation */
} blob_t;
```

**blob\_new**() is used to allocate a new dynamic binary buffer, returning NULL on failure.

**blob\_read**() reads *len* bytes from the current offset in blob *b* into *buf*, returning the total number of bytes read, or -1 on failure.

**blob\_write**() writes *len* bytes from *buf* to blob *b*, advancing the current offset. It returns the number of bytes written, or -1 on failure.

**blob\_seek**() repositions the offset within blob *b* to *off*, according to the directive *whence* (see [lseek(2)](/lseek/2.md) for details), returning the new absolute offset, or -1 on failure.

**blob\_index**() returns the offset of the first occurrence in blob *b* of the specified *buf* of length *len*, or -1 on failure.

**blob\_rindex**() returns the offset of the last occurrence in blob *b* of the specified *buf* of length *len*, or -1 on failure.

**blob\_pack**() converts and writes, and **blob\_unpack**() reads and converts data in blob *b* according to the given format *fmt* as described below, returning 0 on success, and -1 on failure.

The format string is composed of zero or more directives: ordinary characters (not **%** ), which are copied to / read from the blob, and conversion specifications, each of which results in reading / writing zero or more subsequent arguments.

Each conversion specification is introduced by the character **%**, and may be prefixed by length specifier. The arguments must correspond properly (after type promotion) with the length and conversion specifiers.

The length specifier is either a a decimal digit string specifying the length of the following argument, or the literal character **\*** indicating that the length should be read from an integer argument for the argument following it.

The conversion specifiers and their meanings are:

- **D**

  An unsigned 32-bit integer in network byte order.

- **H**

  An unsigned 16-bit integer in network byte order.

- **b**

  A binary buffer (length specifier required).

- **c**

  An unsigned character.

- **d**

  An unsigned 32-bit integer in host byte order.

- **h**

  An unsigned 16-bit integer in host byte order.

- **s**

  A C-style null-terminated string, whose maximum length must be specified when unpacking.

Custom conversion routines and their specifiers may be registered via **blob\_register\_pack**(), currently undocumented.

**blob\_print**() prints *len* bytes of the contents of blob *b* from the current offset in the specified *style*; currently only “hexl” is available.

**blob\_free**() deallocates the memory associated with blob *b* and returns NULL.

### Ethernet

**eth\_open**() is used to obtain a handle to transmit raw Ethernet frames via the specified network *device*.

**eth\_get**() retrieves the hardware MAC address for the interface specified by *e*.

**eth\_set**() configures the hardware MAC address for the interface specified by *e*.

**eth\_send**() transmits *len* bytes of the Ethernet frame pointed to by *buf*.

**eth\_close**() closes the specified handle.

### Firewalling

Firewall rules are described by the following structure:

```
struct fw_rule {
	char		fw_device[INTF_NAME_LEN]; /* interface name */
	uint8_t		fw_op;			  /* operation */
	uint8_t		fw_dir;			  /* direction */
	uint8_t		fw_proto;		  /* IP protocol */
	struct addr	fw_src;			  /* src address / net */
	struct addr	fw_dst;			  /* dst address / net */
	uint16_t	fw_sport[2];		  /* range / ICMP type */
	uint16_t	fw_dport[2];		  /* range / ICMP code */
};
```

The following values are defined for *fw\_op*:

```
#define FW_OP_ALLOW	1
#define FW_OP_BLOCK	2
```

The following values are defined for *fw\_dir*:

```
#define FW_DIR_IN	1
#define FW_DIR_OUT	2
```

**fw\_open**() is used to obtain a handle to access the local network firewall configuration.

**fw\_add**() adds the specified firewall *rule*.

**fw\_delete**() deletes the specified firewall *rule*.

**fw\_loop**() iterates over the active firewall ruleset, invoking the specified *callback* with each *rule* and the context *arg* passed to **fw\_loop**().

**fw\_close**() closes the specified handle.

### Network interfaces

Network interface information is described by the following structure:

```
#define INTF_NAME_LEN	16
struct intf_entry {
	u_int		intf_len;		    /* length of entry */
	char		intf_name[INTF_NAME_LEN];   /* interface name */
	u_short		intf_type;		    /* interface type (r/o) */
	u_short		intf_flags;		    /* interface flags */
	u_int		intf_mtu;		    /* interface MTU */
	struct addr	intf_addr;		    /* interface address */
	struct addr	intf_dst_addr;		    /* point-to-point dst */
	struct addr	intf_link_addr;		    /* link-layer address */
	u_int		intf_alias_num;		    /* number of aliases */
	struct addr	intf_alias_addrs __flexarr; /* array of aliases */
};
```

The following bitmask values are defined for *intf\_type*:

```
#define INTF_TYPE_OTHER		1	/* other */
#define INTF_TYPE_ETH		6	/* Ethernet */
#define INTF_TYPE_LOOPBACK	24	/* software loopback */
#define INTF_TYPE_TUN		53	/* proprietary virtual/internal */
```

The following bitmask values are defined for *intf\_flags*:

```
#define INTF_FLAG_UP		0x01	/* enable interface */
#define INTF_FLAG_LOOPBACK	0x02	/* is a loopback net (r/o) */
#define INTF_FLAG_POINTOPOINT	0x04	/* point-to-point link (r/o) */
#define INTF_FLAG_NOARP		0x08	/* disable ARP */
#define INTF_FLAG_BROADCAST	0x10	/* supports broadcast (r/o) */
#define INTF_FLAG_MULTICAST	0x20	/* supports multicast (r/o) */
```

**intf\_open**() is used to obtain a handle to access the network interface configuration.

**intf\_get**() retrieves an interface configuration *entry*, keyed on *intf\_name*. For all **intf\_get**() functions, *intf\_len* should be set to the size of the buffer pointed to by *entry* (usually sizeof(struct intf\_entry), but should be larger to accommodate any interface alias addresses.

**intf\_get\_src**() retrieves the configuration for the interface whose primary address matches the specified *src*.

**intf\_get\_dst**() retrieves the configuration for the best interface with which to reach the specified *dst*.

**intf\_set**() sets the interface configuration *entry*.

**intf\_loop**() iterates over all network interfaces, invoking the specified *callback* with each interface configuration *entry* and the context *arg* passed to **intf\_loop**().

**intf\_close**() closes the specified handle.

### Internet Protocol

**ip\_open**() is used to obtain a handle to transmit raw IP packets, routed by the kernel.

**ip\_add\_option**() adds the header option for the protocol *proto* specified by *optbuf* of length *optlen* and appends it to the appropriate header of the IP packet contained in *buf* of size *len*, shifting any existing payload and adding NOPs to pad the option to a word boundary if necessary.

**ip\_checksum**() sets the IP checksum and any appropriate transport protocol checksum for the IP packet pointed to by *buf* of length *len*.

**ip\_send**() transmits *len* bytes of the IP packet pointed to by *buf*.

**ip\_close**() closes the specified handle.

### Internet Protocol Version 6

**ip6\_checksum**() sets the appropriate transport protocol checksum for the IPv6 packet pointed to by *buf* of length *len*.

### Random number generation

**rand\_open**() is used to obtain a handle for fast, cryptographically strong pseudo-random number generation. The starting seed is derived from the system random data source device (if one exists), or from the current time and random stack contents.

**rand\_set**() re-initializes the PRNG to start from a known *seed* value, useful in generating repeatable sequences.

**rand\_get**() writes *len* random bytes into *buf*.

**rand\_add**() adds *len* bytes of entropy data from *buf* into the random mix.

**rand\_uint8**(), **rand\_uint16**(), and **rand\_uint32**() return 8, 16, and 32-bit unsigned random values, respectively.

**rand\_shuffle**() randomly shuffles an array of *nmemb* elements of *size* bytes, starting at *base*.

**rand\_close**() closes the specified handle.

### Routing

Routing table entries are described by the following structure:

```
struct route_entry {
	struct addr	route_dst;	/* destination address */
	struct addr	route_gw;	/* gateway address */
};
```

**route\_open**() is used to obtain a handle to access the kernel [route(4)](/route/4.md) table.

**route\_add**() adds a new routing table *entry*.

**route\_delete**() deletes the routing table *entry* for the destination prefix specified by *route\_dst*.

**route\_get**() retrieves the routing table *entry* for the destination prefix specified by *route\_dst*.

**route\_loop**() iterates over the kernel [route(4)](/route/4.md) table, invoking the specified *callback* with each *entry* and the context *arg* passed to **route\_loop**().

**route\_close**() closes the specified handle.

### Tunnel interface

**tun\_open**() is used to obtain a handle to a network tunnel interface, to which IP packets destined for *dst* are delivered (with source addresses rewritten to *src* ), where they may be read by a userland process and processed as desired. IP packets written back to the handle are injected into the kernel networking subsystem.

**tun\_fileno**() returns a file descriptor associated with the tunnel handle, suitable for [select(2)](/select/2.md).

**tun\_name**() returns a pointer to the tunnel interface name.

**tun\_send**() submits a packet to the kernel networking subsystem for delivery.

**tun\_recv**() reads the next packet delivered to the tunnel interface.

**tun\_close**() closes the specified handle.

## RETURN VALUES

**addr\_ntop**() returns a pointer to the *dst* argument, or NULL on failure.

**addr\_ntoa**() returns a pointer to a static memory area containing the printable address, or NULL on failure.

**arp\_open**(), **eth\_open**(), **fw\_open**(), **intf\_open**(), **ip\_open**(), **rand\_open**(), and **route\_open**() return a valid handle on success, or NULL on failure.

**arp\_close**(), **eth\_close**(), **fw\_close**(), **intf\_close**(), **ip\_close**(), **rand\_close**(), and **route\_close**() always return NULL.

**eth\_send**() and **ip\_send**() return the length of the datagram successfully sent, or -1 on failure.

**arp\_loop**(), **fw\_loop**(), **intf\_loop**(), and **route\_loop**() return the status of their *callback* routines. Any non-zero return from a *callback* will cause the loop to exit immediately.

**ip\_add\_option**() returns the length of the inserted option (which may have been padded with NOPs for memory alignment) or -1 on failure.

**rand\_uint8**(), **rand\_uint16**(), and **rand\_uint32**() return 8, 16, and 32-bit unsigned random values, respectively.

All other **dnet** routines return 0 on success, or -1 on failure.

## SEE ALSO

[pcap(3)](/pcap/3.md)

## AUTHORS

Dug Song ⟨dugsong@monkey.org⟩\
 Oliver Falk ⟨oliver@linux-kernel.at⟩
