summaryrefslogtreecommitdiff
path: root/libnet/include/libnet/libnet.h
blob: c56b61d6e46e20a1e6117c409231cf31a9383d7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef _NETIO_H_
#define _NETIO_H_

#include <stdbool.h>   /* for bool */
#include <stddef.h>    /* for size_t */
#include <sys/types.h> /* for ssize_t */

struct ip4_addr {
	unsigned char   bytes[4];
}

struct eth_addr {
	unsigned char   bytes[6];
}

struct libnet_conn;
struct libnet_listener;

struct libnet_listener_vtable {
	/**
	 * It is invalid to accept() a new connection if an existing
	 * connection is still open.
	 */
	struct libnet_conn      *(*accept)(struct libnet_listener *self);
};

struct libnet_conn_vtable {
	/**
	 * Return bytes-read on success, 0 on EOF, -errno on error; a
	 * short read is *not* an error.
	 */
	ssize_t                  (*read)(struct libnet_conn *self, void *buf, size_t count);

	/**
	 * Return `count` on success, -errno on error; a short write *is* an
	 * error.
	 *
	 * Writes are *not* guaranteed to be atomic (as this would be
	 * expensive to implement), so if you have concurrent writers then you
	 * should arrange for a mutex to protect the connection.
	 */
	ssize_t                  (*write)(struct libnet_conn *self, void *buf, size_t count);

	/**
	 * Return 0 on success, -errno on error.
	 */
	int                      (*close)(struct libnet_conn *self, bool rd, bool wr);
};

struct libnet_listener {
 	struct libnet_listener_vtable   *vtable;

	/* This is where your implementation data goes.  */
	char                             data[0];
};

struct libnet_conn {
 	struct libnet_conn_vtable       *vtable;

	/* This is where your implementation data goes.  */
	char                             data[0];
};

#endif /* _NETIO_H_ */