forked from cesanta/mongoose
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathl2.c
More file actions
150 lines (132 loc) · 6.86 KB
/
Copy pathl2.c
File metadata and controls
150 lines (132 loc) · 6.86 KB
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
145
146
147
148
149
150
#include "l2.h"
#include "net.h"
#include "net_builtin.h"
#if MG_ENABLE_TCPIP
// L2 API
void mg_l2_init(struct mg_tcpip_if *ifp);
bool mg_l2_poll(struct mg_tcpip_if *ifp, bool expired_1000ms);
uint8_t *mg_l2_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
uint8_t *src, uint8_t *dst, uint8_t *frame);
size_t mg_l2_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur);
bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
struct mg_str *pay, struct mg_str *raw);
uint8_t *mg_l2_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame);
uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
struct mg_addr *ip);
#if MG_ENABLE_IPV6
bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
uint8_t *addr);
bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
uint8_t len);
uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts);
#endif
size_t mg_l2_driver_output(struct mg_tcpip_if *ifp, size_t len);
// clang-format off
extern void mg_l2_eth_init(struct mg_tcpip_if *);
extern bool mg_l2_eth_poll(struct mg_tcpip_if *, bool);
extern uint8_t *mg_l2_eth_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
extern size_t mg_l2_eth_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
extern bool mg_l2_eth_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
extern struct mg_l2addr *mg_l2_eth_getaddr(struct mg_tcpip_if *, uint8_t *);
extern struct mg_l2addr *mg_l2_eth_mapip(enum mg_l2addrtype, struct mg_addr *);
#if MG_ENABLE_IPV6
extern bool mg_l2_eth_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
extern bool mg_l2_eth_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
extern uint8_t mg_l2_eth_ip6put(struct mg_l2addr *, uint8_t *);
#endif
extern void mg_l2_ppp_init(struct mg_tcpip_if *);
extern bool mg_l2_ppp_poll(struct mg_tcpip_if *, bool);
extern uint8_t *mg_l2_ppp_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
extern size_t mg_l2_ppp_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
extern bool mg_l2_ppp_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
extern struct mg_l2addr *mg_l2_ppp_getaddr(struct mg_tcpip_if *, uint8_t *);
extern struct mg_l2addr *mg_l2_ppp_mapip(enum mg_l2addrtype, struct mg_addr *);
#if MG_ENABLE_IPV6
extern bool mg_l2_ppp_genip6(uint64_t *, uint8_t, struct mg_l2addr *);
extern bool mg_l2_ppp_ip6get(struct mg_l2addr *, uint8_t *, uint8_t);
extern uint8_t mg_l2_ppp_ip6put(struct mg_l2addr *, uint8_t *);
#endif
extern void mg_l2_pppoe_init(struct mg_tcpip_if *);
extern bool mg_l2_pppoe_poll(struct mg_tcpip_if *, bool);
extern uint8_t *mg_l2_pppoe_header(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *);
extern size_t mg_l2_pppoe_trailer(struct mg_tcpip_if *, size_t, uint8_t *);
extern bool mg_l2_pppoe_rx(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
typedef void (*l2_init_fn)(struct mg_tcpip_if *);
typedef bool (*l2_poll_fn)(struct mg_tcpip_if *, bool);
typedef uint8_t *((*l2_header_fn)(struct mg_tcpip_if *, enum mg_l2proto, struct mg_l2addr *, struct mg_l2addr *, uint8_t *));
typedef size_t (*l2_trailer_fn)(struct mg_tcpip_if *, size_t, uint8_t *);
typedef bool (*l2_rx_fn)(struct mg_tcpip_if *, enum mg_l2proto *, struct mg_str *, struct mg_str *);
typedef struct mg_l2addr (*(*l2_getaddr_fn)(struct mg_tcpip_if *, uint8_t *));
typedef struct mg_l2addr (*(*l2_mapip_fn)(enum mg_l2addrtype, struct mg_addr *));
#if MG_ENABLE_IPV6
typedef bool (*l2_genip6_fn)(uint64_t *, uint8_t, struct mg_l2addr *);
typedef bool (*l2_ip6get_fn)(struct mg_l2addr *, uint8_t *, uint8_t);
typedef uint8_t (*l2_ip6put_fn)(struct mg_l2addr *, uint8_t *);
#endif
// clang-format on
static const l2_init_fn l2_init[] = {mg_l2_eth_init, mg_l2_ppp_init,
mg_l2_pppoe_init};
static const l2_poll_fn l2_poll[] = {mg_l2_eth_poll, mg_l2_ppp_poll,
mg_l2_pppoe_poll};
static const l2_header_fn l2_header[] = {mg_l2_eth_header, mg_l2_ppp_header,
mg_l2_pppoe_header};
static const l2_trailer_fn l2_trailer[] = {mg_l2_eth_trailer, mg_l2_ppp_trailer,
mg_l2_pppoe_trailer};
static const l2_rx_fn l2_rx[] = {mg_l2_eth_rx, mg_l2_ppp_rx, mg_l2_pppoe_rx};
static const l2_getaddr_fn l2_getaddr[] = {mg_l2_eth_getaddr, mg_l2_ppp_getaddr,
mg_l2_ppp_getaddr};
static const l2_mapip_fn l2_mapip[] = {mg_l2_eth_mapip, mg_l2_ppp_mapip,
mg_l2_ppp_mapip};
#if MG_ENABLE_IPV6
static const l2_genip6_fn l2_genip6[] = {mg_l2_eth_genip6, mg_l2_ppp_genip6,
mg_l2_ppp_genip6};
static const l2_ip6get_fn l2_ip6get[] = {mg_l2_eth_ip6get, mg_l2_ppp_ip6get,
mg_l2_ppp_ip6get};
static const l2_ip6put_fn l2_ip6put[] = {mg_l2_eth_ip6put, mg_l2_ppp_ip6put,
mg_l2_ppp_ip6put};
#endif
void mg_l2_init(struct mg_tcpip_if *ifp) {
l2_init[ifp->l2type](ifp);
}
bool mg_l2_poll(struct mg_tcpip_if *ifp, bool expired_1000ms) {
return l2_poll[ifp->l2type](ifp, expired_1000ms);
}
uint8_t *mg_l2_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
uint8_t *src, uint8_t *dst, uint8_t *frame) {
return l2_header[ifp->l2type](ifp, proto, (struct mg_l2addr *) src,
(struct mg_l2addr *) dst, frame);
}
size_t mg_l2_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *frame) {
return l2_trailer[ifp->l2type](ifp, len, frame);
}
bool mg_l2_rx(struct mg_tcpip_if *ifp, enum mg_l2proto *proto,
struct mg_str *pay, struct mg_str *raw) {
return l2_rx[ifp->l2type](ifp, proto, pay, raw);
}
uint8_t *mg_l2_getaddr(struct mg_tcpip_if *ifp, uint8_t *frame) {
return (uint8_t *) l2_getaddr[ifp->l2type](ifp, frame);
}
struct mg_l2addr s_mapip;
uint8_t *mg_l2_mapip(enum mg_l2type type, enum mg_l2addrtype addrtype,
struct mg_addr *ip) {
return (uint8_t *) l2_mapip[type](addrtype, ip);
}
#if MG_ENABLE_IPV6
bool mg_l2_genip6(enum mg_l2type type, uint64_t *ip6, uint8_t prefix_len,
uint8_t *addr) {
return l2_genip6[type](ip6, prefix_len, (struct mg_l2addr *) addr);
}
bool mg_l2_ip6get(enum mg_l2type type, uint8_t *addr, uint8_t *opts,
uint8_t len) {
return l2_ip6get[type]((struct mg_l2addr *) addr, opts, len);
}
uint8_t mg_l2_ip6put(enum mg_l2type type, uint8_t *addr, uint8_t *opts) {
return l2_ip6put[type]((struct mg_l2addr *) addr, opts);
}
#endif
size_t mg_l2_driver_output(struct mg_tcpip_if *ifp, size_t len) {
size_t n = ifp->driver->tx(ifp->tx.buf, len, ifp);
if (n == len) ifp->nsent++;
return n;
}
#endif