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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/* 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 <inttypes.h> /* for PRI{u,x}{n} */
#include <stdbool.h> /* for bool */
#include <stddef.h> /* for size_t */
#include <stdint.h> /* for uint{n}_t} */
#include <sys/types.h> /* for ssize_t */
#include <libhw/generic/io.h>
/* Errnos *********************************************************************/
#define NET_EOTHER 1
#define NET_EARP_TIMEOUT 2
#define NET_EACK_TIMEOUT 3
#define NET_ERECV_TIMEOUT 4
#define NET_ETHREAD 5
#define NET_ECLOSED 6
#define NET_EMSGSIZE 7
const char *net_strerror(int net_errno);
/* 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}};
#define PRI_net_ip4_addr "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8
#define ARG_net_ip4_addr(addr) (addr).octets[0], \
(addr).octets[1], \
(addr).octets[2], \
(addr).octets[3]
struct net_eth_addr {
unsigned char octets[6];
};
#define PRI_net_eth_addr "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8
#define ARG_net_eth_addr(addr) (addr).octets[0], \
(addr).octets[1], \
(addr).octets[2], \
(addr).octets[3], \
(addr).octets[4], \
(addr).octets[5]
/* Streams (e.g. TCP) *********************************************************/
lo_interface 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(lo_interface net_stream_conn, 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)
#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)
/* Packets (e.g. UDP) *********************************************************/
#define net_packet_conn_LO_IFACE \
LO_FUNC(ssize_t, 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(ssize_t, 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(lo_interface net_stream_conn , 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)
LO_INTERFACE(net_iface)
#endif /* _LIBHW_GENERIC_NET_H_ */
|