---
name: "dumbnet"
section: "3"
platform: "linux"
package: "libdumbnet-dev"
version: "1.18.0-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/dumbnet/3"
---

# dumbnet(3)

dumb networking library

## NAME

**dumbnet** – dumb networking library

## SYNOPSIS

**#include \<dumbnet.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

**dumbnet** 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, **dumbnet** 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 **dumbnet** routines return 0 on success, or -1 on failure.

## COMPATIBILITY

The library was originally named dnet but was renamed to dumbnet due to a conflict with the DECnet library. This decision affects not only the filename of the shared library, but also the header file names and the library's SONAME tag, which means that software built on a non-Debian-derived distribution will not run with this library and recompiling the software will only work if some adjustments to header include directives and compiler/linker flags are made.

## SEE ALSO

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

## AUTHORS

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