summaryrefslogtreecommitdiff
path: root/libhw_generic/include/libhw/generic/net.h
blob: d1d4194ebadcfd10e6b207142085002654f7484c (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* libhw/generic/net.h - Device-independent network definitions
 *
 * Copyright (C) 2024-2025  Luke T. Shumaker <lukeshu@lukeshu.com>
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#ifndef _LIBHW_GENERIC_NET_H_
#define _LIBHW_GENERIC_NET_H_

#include <stddef.h>    /* for size_t */
#include <stdint.h>    /* for uint{n}_t} */

#include <libhw/generic/io.h>
#include <libmisc/fmt.h>

/* Address types **************************************************************/

struct net_ip4_addr {
	unsigned char   octets[4];
};

static const struct net_ip4_addr net_ip4_addr_broadcast = {{255, 255, 255, 255}};
static const struct net_ip4_addr net_ip4_addr_zero      = {{0, 0, 0, 0}};
void fmt_print_net_ip4_addr(lo_interface fmt_dest, struct net_ip4_addr);

struct net_eth_addr {
	unsigned char   octets[6];
};

void fmt_print_net_eth_addr(lo_interface fmt_dest, struct net_eth_addr);

/* Streams (e.g. TCP) *********************************************************/

#define net_stream_conn_LO_IFACE                                      \
	LO_NEST(io_readwriter)                                        \
	LO_NEST(io_bidi_closer)                                       \
	                                                              \
	/**                                                           \
	 * Set a timestamp after which calls to read() will return    \
	 * NET_ETIMEDOUT.  The timestamp is in nanoseconds on the     \
	 * system monotonic clock, which is usually (on pico-sdk and  \
	 * on the Linux kernel) nanoseconds-since-boot.               \
	 *                                                            \
	 * A zero value disables the deadline.                        \
	 *                                                            \
	 * (2⁶⁴-1 nanoseconds is more than 500 years; there is little \
	 * risk of this overflowing)                                  \
	 */                                                           \
	LO_FUNC(void, set_read_deadline, uint64_t ns_since_boot)
LO_INTERFACE(net_stream_conn);

typedef lo_interface net_stream_conn net_stream_conn;
DECLARE_ERROR_OR(net_stream_conn);

#define net_stream_listener_LO_IFACE                                 \
	/**                                                          \
	 * It is invalid to accept() a new connection if an existing \
	 * connection is still open.                                 \
	 */                                                          \
	LO_FUNC(net_stream_conn_or_error, accept)                    \
	                                                             \
	/**                                                          \
	 * The net_stream_conn returned from accept() may still be   \
	 * valid after the listener is closed.                       \
	 */                                                          \
	LO_NEST(io_closer)
LO_INTERFACE(net_stream_listener);

/* Packets (e.g. UDP) *********************************************************/

#define net_packet_conn_LO_IFACE                                       \
	LO_FUNC(error, sendto,                                         \
	        void *buf, size_t len,                                 \
	        struct net_ip4_addr node, uint16_t port)               \
	                                                               \
	/**                                                            \
	 * @return The full length of the message, which may be more   \
	 * than the given `len` (as if the Linux MSG_TRUNC flag were   \
	 * given).                                                     \
	 */                                                            \
	LO_FUNC(size_t_or_error, recvfrom,                             \
	        void *buf, size_t len,                                 \
	        struct net_ip4_addr *ret_node, uint16_t *ret_port)     \
	                                                               \
	/**                                                            \
	 * Set a timestamp after which calls to recvfrom() will return \
	 * NET_ETIMEDOUT.  The timestamp is in nanoseconds on the      \
	 * system monotonic clock, which is usually (on pico-sdk and   \
	 * on the Linux kernel) nanoseconds-since-boot.                \
	 *                                                             \
	 * A zero value disables the deadline.                         \
	 *                                                             \
	 * (2⁶⁴-1 nanoseconds is more than 500 years; there is little  \
	 * risk of this overflowing)                                   \
	 */                                                            \
	LO_FUNC(void, set_recv_deadline,                               \
	        uint64_t ns_since_boot)                                \
	                                                               \
	LO_NEST(io_closer)
LO_INTERFACE(net_packet_conn);

/* Interfaces *****************************************************************/

struct net_iface_config {
	struct net_ip4_addr addr;
	struct net_ip4_addr gateway_addr;
	struct net_ip4_addr subnet_mask;
};

#define net_iface_LO_IFACE                                                                                           \
	LO_FUNC(struct net_eth_addr             , hwaddr    )                                                        \
	LO_FUNC(void                            , ifup      , struct net_iface_config)                               \
	LO_FUNC(void                            , ifdown    )                                                        \
	                                                                                                             \
	LO_FUNC(lo_interface net_stream_listener, tcp_listen, uint16_t local_port)                                   \
	LO_FUNC(net_stream_conn_or_error        , tcp_dial  , struct net_ip4_addr remote_node, uint16_t remote_port) \
	LO_FUNC(lo_interface net_packet_conn    , udp_conn  , uint16_t local_port)                                   \
	                                                                                                             \
	/** FIXME: arp_ping should probably have an explicit timeout or something.  */                               \
	LO_FUNC(bool                            , arp_ping  , struct net_ip4_addr)
LO_INTERFACE(net_iface);

#endif /* _LIBHW_GENERIC_NET_H_ */