simplify eth and ppp tests, add IPV6 testing for VC targets

This commit is contained in:
Sergio R. Caprile committed 2026-07-01 16:19:38 -03:00
1 parent 8bb65c6492
commit dfbbe5fa8b
3 files changed
+449 -491

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
SRCS = mongoose.c unit_test.c packed_fs.c SRCS = mongoose.c unit_test.c packed_fs.c
HDRS = $(wildcard ../src/*.h) $(wildcard ../src/drivers/*.h) HDRS = $(wildcard ../src/*.h) $(wildcard ../src/drivers/*.h)
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_SSI=1 -DMG_ENABLE_ASSERT=1 DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_SSI=1 -DMG_ENABLE_ASSERT=1 -DMG_ENABLE_IPV6=$(IPV6)
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
OPTS ?= -O3 -g3 OPTS ?= -O3 -g3
INCS ?= -Isrc -I. INCS ?= -Isrc -I.
@@ -25,7 +25,7 @@ PREFIX ?= /usr/local
LIBDIR ?= $(PREFIX)/lib LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR ?= $(PREFIX)/include INCLUDEDIR ?= $(PREFIX)/include
VERSION ?= $(shell cut -d'"' -f2 ../src/version.h) VERSION ?= $(shell cut -d'"' -f2 ../src/version.h)
COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) -DMG_ENABLE_IPV6=$(IPV6) $(TFLAGS) -pthread COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -pthread
CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS) CFLAGS ?= $(OPTS) $(ASAN) $(COMMON_CFLAGS)
VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS) VALGRIND_CFLAGS ?= $(OPTS) $(COMMON_CFLAGS)
VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes --fair-sched=yes VALGRIND_RUN ?= valgrind --tool=memcheck --gen-suppressions=all --leak-check=full --show-leak-kinds=all --leak-resolution=high --track-origins=yes --error-exitcode=1 --exit-on-first-error=yes --fair-sched=yes
+180 -183
View File
@@ -67,203 +67,200 @@ static size_t add_fcs(uint8_t *buf, size_t len) {
return len + sizeof(crc); return len + sizeof(crc);
} }
static void test_plain_accept(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
mg_l2_init(&ifp);
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
ASSERT(ifp.l2mtu != 0);
ASSERT(ifp.framesize != 0);
len = mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_plain_discard(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
char sentinel[] = "discard";
struct mg_tcpip_if ifp;
struct mg_str raw, pay = mg_str_n(sentinel, sizeof(sentinel));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
mg_l2_init(&ifp);
len = mk_eth(frame, s_mac, 0x1234, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
}
static void test_mac_check_accept(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.enable_mac_check = true;
mg_l2_init(&ifp);
len = mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_mac_check_discard(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4}, dst[6] = {1, 1, 1, 1, 1, 1};
char sentinel[] = "discard";
struct mg_tcpip_if ifp;
struct mg_str raw, pay = mg_str_n(sentinel, sizeof(sentinel));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.enable_mac_check = true;
mg_l2_init(&ifp);
len = mk_eth(frame, dst, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
static void test_fcs_check_accept(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.enable_fcs_check = true;
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload)));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_fcs_check_discard(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
char sentinel[] = "discard";
struct mg_tcpip_if ifp;
struct mg_str raw, pay = mg_str_n(sentinel, sizeof(sentinel));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.enable_fcs_check = true;
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload)));
frame[len - 1] ^= 1;
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
static void test_fcs_check_disabled(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload)));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload) + sizeof(uint32_t));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_vlan_accept(void) {
uint8_t frame[64], payload[] = {5, 6, 7, 8};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.l2data.eth.vlan_id = 123;
mg_l2_init(&ifp);
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
ASSERT(ifp.l2mtu != 0);
ASSERT(ifp.framesize != 0);
len = mk_vlan(frame, s_mac, 123, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV6);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_vlan_discard(void) {
uint8_t frame[64], payload[] = {5, 6, 7, 8};
char sentinel[] = "discard";
struct mg_tcpip_if ifp;
struct mg_str raw, pay = mg_str_n(sentinel, sizeof(sentinel));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
ifp.l2data.eth.vlan_id = 123;
mg_l2_init(&ifp);
len = mk_vlan(frame, s_mac, 124, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
static void test_tagged_without_vlan_discard(void) {
uint8_t frame[64], payload[] = {5, 6, 7, 8};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
size_t len;
reset_if(&ifp);
mg_l2_init(&ifp);
len = mk_vlan(frame, s_mac, 123, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
}
#define DASHBOARD(x) \ #define DASHBOARD(x) \
printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true") printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true")
static void test_eth(void) {
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto;
size_t len;
uint8_t frame[64];
{ // Plain Ethernet frame is accepted
uint8_t payload[] = {1, 2, 3, 4};
reset_if(&ifp);
mg_l2_init(&ifp);
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
ASSERT(ifp.l2mtu != 0);
ASSERT(ifp.framesize != 0);
len = mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // Unknown Ethernet type is discarded
uint8_t payload[] = {1, 2, 3, 4};
char sentinel[] = "discard";
reset_if(&ifp);
mg_l2_init(&ifp);
len = mk_eth(frame, s_mac, 0x1234, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
pay = mg_str_n(sentinel, sizeof(sentinel));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
}
}
static void test_mac(void) {
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto;
size_t len;
uint8_t frame[64];
{ // MAC check accepts frames addressed to us
uint8_t payload[] = {1, 2, 3, 4};
reset_if(&ifp);
ifp.enable_mac_check = true;
mg_l2_init(&ifp);
len = mk_eth(frame, s_mac, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // MAC check discards alien unicast frames
uint8_t payload[] = {1, 2, 3, 4}, dst[6] = {1, 1, 1, 1, 1, 1};
char sentinel[] = "discard";
reset_if(&ifp);
ifp.enable_mac_check = true;
mg_l2_init(&ifp);
len = mk_eth(frame, dst, 0x0800, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
pay = mg_str_n(sentinel, sizeof(sentinel));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
}
static void test_fcs(void) {
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto;
size_t len;
uint8_t frame[64];
{ // FCS check strips a valid CRC
uint8_t payload[] = {1, 2, 3, 4};
reset_if(&ifp);
ifp.enable_fcs_check = true;
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload,
sizeof(payload)));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // FCS check rejects a bad CRC
uint8_t payload[] = {1, 2, 3, 4};
char sentinel[] = "discard";
reset_if(&ifp);
ifp.enable_fcs_check = true;
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload,
sizeof(payload)));
frame[len - 1] ^= 1;
raw = mg_str_n((char *) frame, len);
pay = mg_str_n(sentinel, sizeof(sentinel));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
{ // Disabled FCS check leaves the CRC in payload
uint8_t payload[] = {1, 2, 3, 4};
reset_if(&ifp);
mg_l2_init(&ifp);
len = add_fcs(frame, mk_eth(frame, s_mac, 0x0800, payload,
sizeof(payload)));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload) + sizeof(uint32_t));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
}
static void test_vlan(void) {
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto;
size_t len;
uint8_t frame[64];
{ // Configured VLAN accepts matching tagged frames
uint8_t payload[] = {5, 6, 7, 8};
reset_if(&ifp);
ifp.l2data.eth.vlan_id = 123;
mg_l2_init(&ifp);
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
ASSERT(ifp.l2mtu != 0);
ASSERT(ifp.framesize != 0);
len = mk_vlan(frame, s_mac, 123, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV6);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // Configured VLAN rejects non-matching tags
uint8_t payload[] = {5, 6, 7, 8};
char sentinel[] = "discard";
reset_if(&ifp);
ifp.l2data.eth.vlan_id = 123;
mg_l2_init(&ifp);
len = mk_vlan(frame, s_mac, 124, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
pay = mg_str_n(sentinel, sizeof(sentinel));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
ASSERT(pay.buf == sentinel);
ASSERT(pay.len == sizeof(sentinel));
}
{ // Tagged frames are rejected when no VLAN is configured
uint8_t payload[] = {5, 6, 7, 8};
reset_if(&ifp);
mg_l2_init(&ifp);
len = mk_vlan(frame, s_mac, 123, 0x86dd, payload, sizeof(payload));
raw = mg_str_n((char *) frame, len);
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(proto == MG_TCPIP_L2PROTO_ARP);
}
}
int main(void) { int main(void) {
s_error = false; s_error = false;
test_plain_accept(); test_eth();
test_plain_discard();
DASHBOARD("eth"); DASHBOARD("eth");
s_error = false; s_error = false;
test_mac_check_accept(); test_mac();
test_mac_check_discard();
DASHBOARD("mac"); DASHBOARD("mac");
s_error = false; s_error = false;
test_fcs_check_accept(); test_fcs();
test_fcs_check_discard();
test_fcs_check_disabled();
DASHBOARD("fcs"); DASHBOARD("fcs");
s_error = false; s_error = false;
test_vlan_accept(); test_vlan();
test_vlan_discard();
test_tagged_without_vlan_discard();
printf("HEALTH_DASHBOARD\t\"vlan\": %s\n", s_error ? "false" : "true"); printf("HEALTH_DASHBOARD\t\"vlan\": %s\n", s_error ? "false" : "true");
#ifdef NO_ABORT #ifdef NO_ABORT
+267 -306
View File
@@ -93,314 +93,292 @@ static size_t mk_pppoe_sess(uint8_t *buf, uint16_t id, uint16_t proto,
return sizeof(*eth) + sizeof(*pppoe) + sizeof(*ppp) + len; return sizeof(*eth) + sizeof(*pppoe) + sizeof(*ppp) + len;
} }
static void test_ppp_lcp_accept(void) { static void test_lcp(void) {
uint8_t frame[64]; uint8_t frame[64];
struct mg_tcpip_if ifp; struct mg_tcpip_if ifp;
struct lcp lcp = {MG_PPP_LCP_CFG_ACK, 1, mg_htons(sizeof(lcp))};
struct mg_str raw, pay; struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; enum mg_l2proto proto;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false; { // LCP ACK brings PPP link up
raw = mg_str_n((char *) frame, struct lcp lcp = {MG_PPP_LCP_CFG_ACK, 1, mg_htons(sizeof(lcp))};
mk_ppp(frame, MG_PPP_PROTO_LCP, &lcp, sizeof(lcp))); init_if(&ifp, MG_TCPIP_L2_PPP);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); s_lcpup = false;
ASSERT(s_lcpup == true); raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_LCP, &lcp, sizeof(lcp)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(s_lcpup == true);
}
{ // Short LCP frame is discarded
uint8_t lcp[] = {MG_PPP_LCP_CFG_ACK, 1};
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_LCP, lcp, sizeof(lcp)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(s_lcpup == false);
}
} }
static void test_ppp_lcp_discard(void) { static void test_ipcp(void) {
uint8_t frame[64], lcp[] = {MG_PPP_LCP_CFG_ACK, 1}; uint8_t frame[64];
struct mg_tcpip_if ifp; struct mg_tcpip_if ifp;
struct mg_str raw, pay; struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; enum mg_l2proto proto;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_LCP, lcp, sizeof(lcp)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(s_lcpup == false);
}
static void test_ppp_ip_accept(void) { { // IPCP request with peer IP address is ACKed
uint8_t frame[64], payload[sizeof(struct ip)]; uint8_t ipcp[] = {MG_PPP_IPCP_CFG_REQ, 1, 0, 10,
struct mg_tcpip_if ifp; MG_PPP_IPCP_OPT_IPADDR, 6, 192, 0, 2, 1};
struct mg_str raw, pay; uint32_t peer;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; init_if(&ifp, MG_TCPIP_L2_PPP);
memset(payload, 0, sizeof(payload)); s_lcpup = true;
init_if(&ifp, MG_TCPIP_L2_PPP); memcpy(&peer, ipcp + 6, sizeof(peer));
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize)); raw = mg_str_n((char *) frame,
ASSERT(ifp.l2mtu != 0); mk_ppp(frame, MG_PPP_PROTO_IPCP, ipcp, sizeof(ipcp)));
ASSERT(ifp.framesize != 0); proto = MG_TCPIP_L2PROTO_ARP;
s_lcpup = true; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
raw = mg_str_n((char *) frame, ASSERT(ifp.gw == peer);
mk_ppp(frame, MG_PPP_PROTO_IP, payload, sizeof(payload))); ASSERT(((struct ipcp *) ppp_payload(frame))->code == MG_PPP_IPCP_CFG_ACK);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true); ASSERT(ifp.nsent == 2);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4); }
ASSERT(pay.len == sizeof(payload)); { // IPCP request without peer IP address is rejected
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0); uint8_t ipcp[] = {MG_PPP_IPCP_CFG_REQ, 1, 0, 4};
} init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
static void test_ppp_ip_discard(void) { raw = mg_str_n((char *) frame,
uint8_t frame[64], payload[sizeof(struct ip)]; mk_ppp(frame, MG_PPP_PROTO_IPCP, ipcp, sizeof(ipcp)));
struct mg_tcpip_if ifp; proto = MG_TCPIP_L2PROTO_ARP;
struct mg_str raw, pay; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; ASSERT(ifp.gw == 0);
memset(payload, 0, sizeof(payload)); ASSERT(((struct ipcp *) ppp_payload(frame))->code ==
init_if(&ifp, MG_TCPIP_L2_PPP); MG_PPP_IPCP_CFG_REJECT);
s_lcpup = false; ASSERT(ifp.nsent == 3);
raw = mg_str_n((char *) frame, }
mk_ppp(frame, MG_PPP_PROTO_IP, payload, sizeof(payload)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
}
static void test_ppp_ipcp_accept(void) {
uint8_t frame[64], ipcp[] = {MG_PPP_IPCP_CFG_REQ, 1, 0, 10,
MG_PPP_IPCP_OPT_IPADDR, 6, 192, 0, 2, 1};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
uint32_t peer;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
memcpy(&peer, ipcp + 6, sizeof(peer));
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPCP, ipcp, sizeof(ipcp)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(ifp.gw == peer);
ASSERT(((struct ipcp *) ppp_payload(frame))->code == MG_PPP_IPCP_CFG_ACK);
ASSERT(ifp.nsent == 2);
}
static void test_ppp_ipcp_reject(void) {
uint8_t frame[64], ipcp[] = {MG_PPP_IPCP_CFG_REQ, 1, 0, 4};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPCP, ipcp, sizeof(ipcp)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(ifp.gw == 0);
ASSERT(((struct ipcp *) ppp_payload(frame))->code == MG_PPP_IPCP_CFG_REJECT);
ASSERT(ifp.nsent == 3);
} }
#if MG_ENABLE_IPV6 #if MG_ENABLE_IPV6
static void test_ppp_ipv6_accept(void) { static void test_ipv6cp(void) {
uint8_t frame[96], payload[sizeof(struct ip6)]; uint8_t frame[64];
struct mg_tcpip_if ifp; struct mg_tcpip_if ifp;
struct mg_str raw, pay; struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; enum mg_l2proto proto;
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPV6, payload, sizeof(payload)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV6);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_ppp_ipv6_discard(void) { { // IPv6CP request with interface ID is ACKed
uint8_t frame[96], payload[sizeof(struct ip6)]; uint8_t ipv6cp[] = {MG_PPP_IPV6CP_CFG_REQ, 1, 0, 14,
struct mg_tcpip_if ifp; MG_PPP_IPV6CP_OPT_IFCID, 10, 2, 3, 4, 5, 6, 7, 8, 9};
struct mg_str raw, pay; init_if(&ifp, MG_TCPIP_L2_PPP);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; s_lcpup = true;
memset(payload, 0, sizeof(payload)); raw = mg_str_n((char *) frame,
init_if(&ifp, MG_TCPIP_L2_PPP); mk_ppp(frame, MG_PPP_PROTO_IPV6CP, ipv6cp,
s_lcpup = false; sizeof(ipv6cp)));
raw = mg_str_n((char *) frame, proto = MG_TCPIP_L2PROTO_ARP;
mk_ppp(frame, MG_PPP_PROTO_IPV6, payload, sizeof(payload))); ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); ASSERT(memcmp(&((struct mg_l2addr *) ifp.gwmac)->addr.ieee64, ipv6cp + 6,
} 8) == 0);
ASSERT(((struct ipv6cp *) ppp_payload(frame))->code ==
static void test_ppp_ipv6cp_accept(void) { MG_PPP_IPV6CP_CFG_ACK);
uint8_t frame[64], ipv6cp[] = {MG_PPP_IPV6CP_CFG_REQ, 1, 0, 14, ASSERT(ifp.nsent == 2);
MG_PPP_IPV6CP_OPT_IFCID, 10, }
2, 3, 4, 5, 6, 7, 8, 9}; { // IPv6CP request with zero interface ID is rejected
struct mg_tcpip_if ifp; uint8_t ipv6cp[] = {MG_PPP_IPV6CP_CFG_REQ, 1, 0, 14,
struct mg_str raw, pay; MG_PPP_IPV6CP_OPT_IFCID, 10, 0, 0, 0, 0, 0, 0, 0, 0};
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; init_if(&ifp, MG_TCPIP_L2_PPP);
init_if(&ifp, MG_TCPIP_L2_PPP); s_lcpup = true;
s_lcpup = true; raw = mg_str_n((char *) frame,
raw = mg_str_n((char *) frame, mk_ppp(frame, MG_PPP_PROTO_IPV6CP, ipv6cp,
mk_ppp(frame, MG_PPP_PROTO_IPV6CP, ipv6cp, sizeof(ipv6cp))); sizeof(ipv6cp)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(memcmp(&((struct mg_l2addr *) ifp.gwmac)->addr.ieee64, ipv6cp + 6, ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
8) == 0); ASSERT(((struct ipv6cp *) ppp_payload(frame))->code ==
ASSERT(((struct ipv6cp *) ppp_payload(frame))->code == MG_PPP_IPV6CP_CFG_REJECT);
MG_PPP_IPV6CP_CFG_ACK); ASSERT(ifp.nsent == 1);
ASSERT(ifp.nsent == 2); }
}
static void test_ppp_ipv6cp_reject(void) {
uint8_t frame[64], ipv6cp[] = {MG_PPP_IPV6CP_CFG_REQ, 1, 0, 14,
MG_PPP_IPV6CP_OPT_IFCID, 10,
0, 0, 0, 0, 0, 0, 0, 0};
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPV6CP, ipv6cp, sizeof(ipv6cp)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(((struct ipv6cp *) ppp_payload(frame))->code ==
MG_PPP_IPV6CP_CFG_REJECT);
ASSERT(ifp.nsent == 1);
} }
#endif #endif
static void test_ppp_unknown_reject(void) { static void test_ppp(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4}; uint8_t frame[96];
struct mg_tcpip_if ifp; struct mg_tcpip_if ifp;
struct mg_str raw, pay; struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; enum mg_l2proto proto;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true; { // IPv4 packet is accepted after LCP is up
raw = mg_str_n((char *) frame, uint8_t payload[sizeof(struct ip)];
mk_ppp(frame, 0x1234, payload, sizeof(payload))); memset(payload, 0, sizeof(payload));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); init_if(&ifp, MG_TCPIP_L2_PPP);
ASSERT(ifp.nsent == 1); MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
ASSERT(ifp.l2mtu != 0);
ASSERT(ifp.framesize != 0);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IP, payload, sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // IPv4 packet is discarded while LCP is down
uint8_t payload[sizeof(struct ip)];
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IP, payload, sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
}
#if MG_ENABLE_IPV6
{ // IPv6 packet is accepted after LCP is up
uint8_t payload[sizeof(struct ip6)];
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPV6, payload,
sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV6);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
{ // IPv6 packet is discarded while LCP is down
uint8_t payload[sizeof(struct ip6)];
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, MG_PPP_PROTO_IPV6, payload,
sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
}
#endif
{ // Unknown protocol is rejected after LCP is up
uint8_t payload[] = {1, 2, 3, 4};
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_ppp(frame, 0x1234, payload, sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(ifp.nsent == 1);
}
{ // Unknown protocol is discarded while LCP is down
uint8_t payload[] = {1, 2, 3, 4};
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, 0x1234, payload, sizeof(payload)));
proto = MG_TCPIP_L2PROTO_ARP;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(ifp.nsent == 0);
}
} }
static void test_ppp_unknown_discard(void) { static void test_pppoe(void) {
uint8_t frame[64], payload[] = {1, 2, 3, 4}; uint8_t frame[96];
struct mg_tcpip_if ifp; struct mg_tcpip_if ifp;
struct mg_str raw, pay; struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; enum mg_l2proto proto;
init_if(&ifp, MG_TCPIP_L2_PPP);
s_lcpup = false;
raw = mg_str_n((char *) frame,
mk_ppp(frame, 0x1234, payload, sizeof(payload)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(ifp.nsent == 0);
}
static void test_pppoe_pado_accept(void) { { // PADO moves discovery to request state
uint8_t frame[64]; init_if(&ifp, MG_TCPIP_L2_PPPoE);
struct mg_tcpip_if ifp; MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
struct mg_str raw, pay; ASSERT(ifp.l2mtu != 0);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; ASSERT(ifp.framesize != 0);
init_if(&ifp, MG_TCPIP_L2_PPPoE); s_state = MG_PPPoE_ST_DISC;
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize)); raw = mg_str_n((char *) frame,
ASSERT(ifp.l2mtu != 0); mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0));
ASSERT(ifp.framesize != 0); proto = MG_TCPIP_L2PROTO_ARP;
s_state = MG_PPPoE_ST_DISC; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
raw = mg_str_n((char *) frame, ASSERT(s_state == MG_PPPoE_ST_REQ);
mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0)); ASSERT(ifp.nsent == 1);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); }
ASSERT(s_state == MG_PPPoE_ST_REQ); { // PADO is ignored outside discovery state
ASSERT(ifp.nsent == 1); init_if(&ifp, MG_TCPIP_L2_PPPoE);
} s_state = MG_PPPoE_ST_REQ;
raw = mg_str_n((char *) frame,
static void test_pppoe_pado_discard(void) { mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0));
uint8_t frame[64]; proto = MG_TCPIP_L2PROTO_ARP;
struct mg_tcpip_if ifp; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
struct mg_str raw, pay; ASSERT(s_state == MG_PPPoE_ST_REQ);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; ASSERT(ifp.nsent == 0);
init_if(&ifp, MG_TCPIP_L2_PPPoE); }
s_state = MG_PPPoE_ST_REQ; { // PADS establishes the session
raw = mg_str_n((char *) frame, init_if(&ifp, MG_TCPIP_L2_PPPoE);
mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0)); s_state = MG_PPPoE_ST_REQ;
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); raw = mg_str_n((char *) frame,
ASSERT(s_state == MG_PPPoE_ST_REQ); mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0));
ASSERT(ifp.nsent == 0); proto = MG_TCPIP_L2PROTO_ARP;
} ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(s_state == MG_PPPoE_ST_SESS);
static void test_pppoe_pads_accept(void) { ASSERT(s_id == mg_htons(0x1234));
uint8_t frame[64]; }
struct mg_tcpip_if ifp; { // PADS is ignored outside request state
struct mg_str raw, pay; init_if(&ifp, MG_TCPIP_L2_PPPoE);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; s_state = MG_PPPoE_ST_DISC;
init_if(&ifp, MG_TCPIP_L2_PPPoE); raw = mg_str_n((char *) frame,
s_state = MG_PPPoE_ST_REQ; mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0));
raw = mg_str_n((char *) frame, proto = MG_TCPIP_L2PROTO_ARP;
mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0)); ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); ASSERT(s_state == MG_PPPoE_ST_DISC);
ASSERT(s_state == MG_PPPoE_ST_SESS); }
ASSERT(s_id == mg_htons(0x1234)); { // PADT matching the session tears it down
} init_if(&ifp, MG_TCPIP_L2_PPPoE);
s_state = MG_PPPoE_ST_SESS;
static void test_pppoe_pads_discard(void) { s_id = mg_htons(0x1234);
uint8_t frame[64]; s_lcpup = true;
struct mg_tcpip_if ifp; raw = mg_str_n((char *) frame,
struct mg_str raw, pay; mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; proto = MG_TCPIP_L2PROTO_ARP;
init_if(&ifp, MG_TCPIP_L2_PPPoE); ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
s_state = MG_PPPoE_ST_DISC; ASSERT(s_state == MG_PPPoE_ST_DISC);
raw = mg_str_n((char *) frame, ASSERT(s_id == 0);
mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0)); ASSERT(s_lcpup == false);
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); }
ASSERT(s_state == MG_PPPoE_ST_DISC); { // PADT for a different session is ignored
} init_if(&ifp, MG_TCPIP_L2_PPPoE);
s_state = MG_PPPoE_ST_SESS;
static void test_pppoe_padt_accept(void) { s_id = mg_htons(0x4321);
uint8_t frame[64]; s_lcpup = true;
struct mg_tcpip_if ifp; raw = mg_str_n((char *) frame,
struct mg_str raw, pay; mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0));
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; proto = MG_TCPIP_L2PROTO_ARP;
init_if(&ifp, MG_TCPIP_L2_PPPoE); ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
s_state = MG_PPPoE_ST_SESS; ASSERT(s_state == MG_PPPoE_ST_SESS);
s_id = mg_htons(0x1234); ASSERT(s_id == mg_htons(0x4321));
s_lcpup = true; ASSERT(s_lcpup == true);
raw = mg_str_n((char *) frame, }
mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0)); { // PPPoE session packet is accepted in session state
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); uint8_t payload[sizeof(struct ip)];
ASSERT(s_state == MG_PPPoE_ST_DISC); memset(payload, 0, sizeof(payload));
ASSERT(s_id == 0); init_if(&ifp, MG_TCPIP_L2_PPPoE);
ASSERT(s_lcpup == false); s_state = MG_PPPoE_ST_SESS;
} s_lcpup = true;
raw = mg_str_n((char *) frame,
static void test_pppoe_padt_discard(void) { mk_pppoe_sess(frame, 0x1234, MG_PPP_PROTO_IP, payload,
uint8_t frame[64]; sizeof(payload)));
struct mg_tcpip_if ifp; proto = MG_TCPIP_L2PROTO_ARP;
struct mg_str raw, pay; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP; ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
init_if(&ifp, MG_TCPIP_L2_PPPoE); ASSERT(pay.len == sizeof(payload));
s_state = MG_PPPoE_ST_SESS; ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
s_id = mg_htons(0x4321); }
s_lcpup = true; { // PPPoE session packet is discarded outside session state
raw = mg_str_n((char *) frame, uint8_t payload[sizeof(struct ip)];
mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0)); memset(payload, 0, sizeof(payload));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false); init_if(&ifp, MG_TCPIP_L2_PPPoE);
ASSERT(s_state == MG_PPPoE_ST_SESS); s_state = MG_PPPoE_ST_REQ;
ASSERT(s_id == mg_htons(0x4321)); s_lcpup = true;
ASSERT(s_lcpup == true); raw = mg_str_n((char *) frame,
} mk_pppoe_sess(frame, 0x1234, MG_PPP_PROTO_IP, payload,
sizeof(payload)));
static void test_pppoe_session_accept(void) { proto = MG_TCPIP_L2PROTO_ARP;
uint8_t frame[96], payload[sizeof(struct ip)]; ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
struct mg_tcpip_if ifp; }
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPPoE);
s_state = MG_PPPoE_ST_SESS;
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_pppoe_sess(frame, 0x1234, MG_PPP_PROTO_IP, payload,
sizeof(payload)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == true);
ASSERT(proto == MG_TCPIP_L2PROTO_IPV4);
ASSERT(pay.len == sizeof(payload));
ASSERT(memcmp(pay.buf, payload, sizeof(payload)) == 0);
}
static void test_pppoe_session_discard(void) {
uint8_t frame[96], payload[sizeof(struct ip)];
struct mg_tcpip_if ifp;
struct mg_str raw, pay;
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
memset(payload, 0, sizeof(payload));
init_if(&ifp, MG_TCPIP_L2_PPPoE);
s_state = MG_PPPoE_ST_REQ;
s_lcpup = true;
raw = mg_str_n((char *) frame,
mk_pppoe_sess(frame, 0x1234, MG_PPP_PROTO_IP, payload,
sizeof(payload)));
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
} }
#define DASHBOARD(x) \ #define DASHBOARD(x) \
@@ -408,42 +386,25 @@ static void test_pppoe_session_discard(void) {
int main(void) { int main(void) {
s_error = false; s_error = false;
test_ppp_lcp_accept(); test_lcp();
test_ppp_lcp_discard();
DASHBOARD("lcp"); DASHBOARD("lcp");
s_error = false; s_error = false;
test_ppp_ipcp_accept(); test_ipcp();
test_ppp_ipcp_reject();
DASHBOARD("ipcp"); DASHBOARD("ipcp");
#if MG_ENABLE_IPV6 #if MG_ENABLE_IPV6
s_error = false; s_error = false;
test_ppp_ipv6cp_accept(); test_ipv6cp();
test_ppp_ipv6cp_reject();
DASHBOARD("ipv6cp"); DASHBOARD("ipv6cp");
#endif #endif
s_error = false; s_error = false;
test_ppp_ip_accept(); test_ppp();
test_ppp_ip_discard();
#if MG_ENABLE_IPV6
test_ppp_ipv6_accept();
test_ppp_ipv6_discard();
#endif
test_ppp_unknown_reject();
test_ppp_unknown_discard();
DASHBOARD("ppp"); DASHBOARD("ppp");
s_error = false; s_error = false;
test_pppoe_pado_accept(); test_pppoe();
test_pppoe_pado_discard();
test_pppoe_pads_accept();
test_pppoe_pads_discard();
test_pppoe_padt_accept();
test_pppoe_padt_discard();
test_pppoe_session_accept();
test_pppoe_session_discard();
printf("HEALTH_DASHBOARD\t\"pppoe\": %s\n", s_error ? "false" : "true"); printf("HEALTH_DASHBOARD\t\"pppoe\": %s\n", s_error ? "false" : "true");
#ifdef NO_ABORT #ifdef NO_ABORT