mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-30 12:50:58 +00:00
add tests for L2
This commit is contained in:
1 parent
fdcefb087e
commit
e5e13ff156
8 files changed
+779
-27
No files matched your search
+10
-2
@@ -29,7 +29,7 @@ COMMON_CFLAGS ?= $(C_WARN) $(WARN) $(INCS) $(DEFS) -DMG_ENABLE_IPV6=$(IPV6) $(TF
|
||||
CFLAGS ?= $(OPTS) $(ASAN) $(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
|
||||
.PHONY: clean_tutorials tutorials mip_test test valgrind
|
||||
.PHONY: clean_tutorials tutorials mip_test eth_test ppp_test test valgrind
|
||||
|
||||
ifeq "$(findstring ++,$(CC))" ""
|
||||
# $(CC) does not end with ++, i.e. we're using C. Apply C flags
|
||||
@@ -81,12 +81,20 @@ endif
|
||||
all:
|
||||
$(MAKE) -C ../tutorials/http/http-server
|
||||
|
||||
tall: mg_prefix unamalgamated test valgrind fuzz fuzz_tls vc98 vc17 vc22 mingw mingw++ arm armhf riscv s390 tutorials tutorials_win tutorials_embedded mip_test mip_vc98
|
||||
tall: mg_prefix unamalgamated test valgrind fuzz fuzz_tls vc98 vc17 vc22 mingw mingw++ arm armhf riscv s390 tutorials tutorials_win tutorials_embedded mip_test eth_test ppp_test mip_vc98
|
||||
|
||||
mip_test: mip_test.c mongoose.c mongoose.h packed_fs.c Makefile
|
||||
$(CC) mip_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
||||
|
||||
eth_test: eth_test.c mongoose.c mongoose.h Makefile
|
||||
$(CC) eth_test.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
||||
|
||||
ppp_test: ppp_test.c mongoose.c mongoose.h Makefile
|
||||
$(CC) ppp_test.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
||||
|
||||
mip_tap_test: mip_x_test.c mip_tap_test.c mongoose.c mongoose.h packed_fs.c Makefile tls_multirec/server
|
||||
$(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
||||
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||
|
||||
#include "mongoose.c"
|
||||
|
||||
static int s_num_tests = 0;
|
||||
static bool s_error = false;
|
||||
|
||||
#ifdef NO_ABORT
|
||||
static int s_abort = 0;
|
||||
#define ABORT() ++s_abort, s_error = true
|
||||
#else
|
||||
#ifdef NO_SLEEP_ABORT
|
||||
#define ABORT() abort()
|
||||
#else
|
||||
#define ABORT() \
|
||||
sleep(2); /* 2s, GH print reason */ \
|
||||
abort();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ASSERT(expr) \
|
||||
do { \
|
||||
s_num_tests++; \
|
||||
if (!(expr)) { \
|
||||
printf("FAILURE %s:%d: %s\n", __FILE__, __LINE__, #expr); \
|
||||
fflush(stdout); \
|
||||
ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const uint8_t s_mac[6] = {2, 3, 4, 5, 6, 7};
|
||||
static const uint8_t s_src[6] = {8, 9, 10, 11, 12, 13};
|
||||
|
||||
static void reset_if(struct mg_tcpip_if *ifp) {
|
||||
memset(ifp, 0, sizeof(*ifp));
|
||||
memcpy(ifp->mac, s_mac, sizeof(s_mac));
|
||||
ifp->l2type = MG_TCPIP_L2_ETH;
|
||||
}
|
||||
|
||||
static size_t mk_eth(uint8_t *buf, const uint8_t *dst, uint16_t type,
|
||||
const uint8_t *payload, size_t len) {
|
||||
struct eth *eth = (struct eth *) buf;
|
||||
memcpy(eth->dst, dst, sizeof(eth->dst));
|
||||
memcpy(eth->src, s_src, sizeof(eth->src));
|
||||
eth->type = mg_htons(type);
|
||||
memcpy(eth + 1, payload, len);
|
||||
return sizeof(*eth) + len;
|
||||
}
|
||||
|
||||
static size_t mk_vlan(uint8_t *buf, const uint8_t *dst, uint16_t vlan,
|
||||
uint16_t type, const uint8_t *payload, size_t len) {
|
||||
struct eth *eth = (struct eth *) buf;
|
||||
struct qtag *qtag = (struct qtag *) ð->type;
|
||||
memcpy(eth->dst, dst, sizeof(eth->dst));
|
||||
memcpy(eth->src, s_src, sizeof(eth->src));
|
||||
qtag->tpid = mg_htons(0x8100);
|
||||
qtag->tci = mg_htons(vlan);
|
||||
MG_STORE_BE16(qtag + 1, type);
|
||||
memcpy((uint8_t *) (qtag + 1) + sizeof(uint16_t), payload, len);
|
||||
return sizeof(*eth) + sizeof(*qtag) + len;
|
||||
}
|
||||
|
||||
static size_t add_fcs(uint8_t *buf, size_t len) {
|
||||
uint32_t crc = mg_crc32(0, (const char *) buf, len);
|
||||
memcpy(buf + len, &crc, 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) \
|
||||
printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true")
|
||||
|
||||
int main(void) {
|
||||
s_error = false;
|
||||
test_plain_accept();
|
||||
test_plain_discard();
|
||||
DASHBOARD("eth");
|
||||
|
||||
s_error = false;
|
||||
test_mac_check_accept();
|
||||
test_mac_check_discard();
|
||||
DASHBOARD("mac");
|
||||
|
||||
s_error = false;
|
||||
test_fcs_check_accept();
|
||||
test_fcs_check_discard();
|
||||
test_fcs_check_disabled();
|
||||
DASHBOARD("fcs");
|
||||
|
||||
s_error = false;
|
||||
test_vlan_accept();
|
||||
test_vlan_discard();
|
||||
test_tagged_without_vlan_discard();
|
||||
printf("HEALTH_DASHBOARD\t\"vlan\": %s\n", s_error ? "false" : "true");
|
||||
|
||||
#ifdef NO_ABORT
|
||||
if (s_abort != 0) return EXIT_FAILURE;
|
||||
#endif
|
||||
|
||||
printf("SUCCESS. Total tests: %d\n", s_num_tests);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
+455
@@ -0,0 +1,455 @@
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||
|
||||
#include "mongoose.c"
|
||||
#include "driver_mock.c"
|
||||
|
||||
static int s_num_tests = 0;
|
||||
static bool s_error = false;
|
||||
|
||||
#ifdef NO_ABORT
|
||||
static int s_abort = 0;
|
||||
#define ABORT() ++s_abort, s_error = true
|
||||
#else
|
||||
#ifdef NO_SLEEP_ABORT
|
||||
#define ABORT() abort()
|
||||
#else
|
||||
#define ABORT() \
|
||||
sleep(2); /* 2s, GH print reason */ \
|
||||
abort();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ASSERT(expr) \
|
||||
do { \
|
||||
s_num_tests++; \
|
||||
if (!(expr)) { \
|
||||
printf("FAILURE %s:%d: %s\n", __FILE__, __LINE__, #expr); \
|
||||
fflush(stdout); \
|
||||
ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const uint8_t s_mac[6] = {2, 3, 4, 5, 6, 7};
|
||||
static const uint8_t s_src[6] = {8, 9, 10, 11, 12, 13};
|
||||
|
||||
static uint8_t s_tx[2048];
|
||||
|
||||
static void init_if(struct mg_tcpip_if *ifp, enum mg_l2type type) {
|
||||
memset(ifp, 0, sizeof(*ifp));
|
||||
memcpy(ifp->mac, s_mac, sizeof(s_mac));
|
||||
ifp->driver = &mg_tcpip_driver_mock;
|
||||
ifp->l2type = type;
|
||||
ifp->tx.buf = (char *) s_tx;
|
||||
ifp->tx.len = sizeof(s_tx);
|
||||
mg_l2_init(ifp);
|
||||
}
|
||||
|
||||
static size_t mk_ppp(uint8_t *buf, uint16_t proto, const void *payload,
|
||||
size_t len) {
|
||||
struct hdlc_ *hdlc = (struct hdlc_ *) buf;
|
||||
struct ppp *ppp = (struct ppp *) (hdlc + 1);
|
||||
hdlc->addr = MG_PPP_ADDR;
|
||||
hdlc->ctrl = MG_PPP_CTRL;
|
||||
ppp->proto = mg_htons(proto);
|
||||
memcpy(ppp + 1, payload, len);
|
||||
memset((uint8_t *) (ppp + 1) + len, 0, 2);
|
||||
return sizeof(*hdlc) + sizeof(*ppp) + len + 2;
|
||||
}
|
||||
|
||||
static void *ppp_payload(uint8_t *frame) {
|
||||
return (struct ppp *) ((struct hdlc_ *) frame + 1) + 1;
|
||||
}
|
||||
|
||||
static size_t mk_pppoe_disc(uint8_t *buf, uint8_t code, uint16_t id,
|
||||
const void *payload, size_t len) {
|
||||
struct eth *eth = (struct eth *) buf;
|
||||
struct pppoe *pppoe = (struct pppoe *) (eth + 1);
|
||||
memcpy(eth->dst, s_mac, sizeof(eth->dst));
|
||||
memcpy(eth->src, s_src, sizeof(eth->src));
|
||||
eth->type = mg_htons(0x8863);
|
||||
pppoe->vertype = 0x11;
|
||||
pppoe->code = code;
|
||||
pppoe->id = mg_htons(id);
|
||||
pppoe->len = mg_htons((uint16_t) len);
|
||||
if (len > 0) memcpy(pppoe + 1, payload, len);
|
||||
return sizeof(*eth) + sizeof(*pppoe) + len;
|
||||
}
|
||||
|
||||
static size_t mk_pppoe_sess(uint8_t *buf, uint16_t id, uint16_t proto,
|
||||
const void *payload, size_t len) {
|
||||
struct eth *eth = (struct eth *) buf;
|
||||
struct pppoe *pppoe = (struct pppoe *) (eth + 1);
|
||||
struct ppp *ppp = (struct ppp *) (pppoe + 1);
|
||||
memcpy(eth->dst, s_mac, sizeof(eth->dst));
|
||||
memcpy(eth->src, s_src, sizeof(eth->src));
|
||||
eth->type = mg_htons(0x8864);
|
||||
pppoe->vertype = 0x11;
|
||||
pppoe->code = 0;
|
||||
pppoe->id = mg_htons(id);
|
||||
pppoe->len = mg_htons((uint16_t) (sizeof(*ppp) + len));
|
||||
ppp->proto = mg_htons(proto);
|
||||
memcpy(ppp + 1, payload, len);
|
||||
return sizeof(*eth) + sizeof(*pppoe) + sizeof(*ppp) + len;
|
||||
}
|
||||
|
||||
static void test_ppp_lcp_accept(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct lcp lcp = {MG_PPP_LCP_CFG_ACK, 1, mg_htons(sizeof(lcp))};
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
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 == true);
|
||||
}
|
||||
|
||||
static void test_ppp_lcp_discard(void) {
|
||||
uint8_t frame[64], lcp[] = {MG_PPP_LCP_CFG_ACK, 1};
|
||||
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 = 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) {
|
||||
uint8_t frame[64], 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_PPP);
|
||||
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)));
|
||||
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_ppp_ip_discard(void) {
|
||||
uint8_t frame[64], 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_PPP);
|
||||
s_lcpup = false;
|
||||
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
|
||||
static void test_ppp_ipv6_accept(void) {
|
||||
uint8_t frame[96], payload[sizeof(struct ip6)];
|
||||
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_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) {
|
||||
uint8_t frame[96], payload[sizeof(struct ip6)];
|
||||
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_PPP);
|
||||
s_lcpup = false;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_ppp(frame, MG_PPP_PROTO_IPV6, payload, sizeof(payload)));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
}
|
||||
|
||||
static void test_ppp_ipv6cp_accept(void) {
|
||||
uint8_t frame[64], ipv6cp[] = {MG_PPP_IPV6CP_CFG_REQ, 1, 0, 14,
|
||||
MG_PPP_IPV6CP_OPT_IFCID, 10,
|
||||
2, 3, 4, 5, 6, 7, 8, 9};
|
||||
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(memcmp(&((struct mg_l2addr *) ifp.gwmac)->addr.ieee64, ipv6cp + 6,
|
||||
8) == 0);
|
||||
ASSERT(((struct ipv6cp *) ppp_payload(frame))->code ==
|
||||
MG_PPP_IPV6CP_CFG_ACK);
|
||||
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
|
||||
|
||||
static void test_ppp_unknown_reject(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;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPP);
|
||||
s_lcpup = true;
|
||||
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 == 1);
|
||||
}
|
||||
|
||||
static void test_ppp_unknown_discard(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;
|
||||
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) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
MG_DEBUG(("MTU: %u, frame size: %u", ifp.l2mtu, ifp.framesize));
|
||||
ASSERT(ifp.l2mtu != 0);
|
||||
ASSERT(ifp.framesize != 0);
|
||||
s_state = MG_PPPoE_ST_DISC;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_REQ);
|
||||
ASSERT(ifp.nsent == 1);
|
||||
}
|
||||
|
||||
static void test_pppoe_pado_discard(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
s_state = MG_PPPoE_ST_REQ;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADO, 0, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_REQ);
|
||||
ASSERT(ifp.nsent == 0);
|
||||
}
|
||||
|
||||
static void test_pppoe_pads_accept(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
s_state = MG_PPPoE_ST_REQ;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_SESS);
|
||||
ASSERT(s_id == mg_htons(0x1234));
|
||||
}
|
||||
|
||||
static void test_pppoe_pads_discard(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
s_state = MG_PPPoE_ST_DISC;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADS, 0x1234, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_DISC);
|
||||
}
|
||||
|
||||
static void test_pppoe_padt_accept(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
s_state = MG_PPPoE_ST_SESS;
|
||||
s_id = mg_htons(0x1234);
|
||||
s_lcpup = true;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_DISC);
|
||||
ASSERT(s_id == 0);
|
||||
ASSERT(s_lcpup == false);
|
||||
}
|
||||
|
||||
static void test_pppoe_padt_discard(void) {
|
||||
uint8_t frame[64];
|
||||
struct mg_tcpip_if ifp;
|
||||
struct mg_str raw, pay;
|
||||
enum mg_l2proto proto = MG_TCPIP_L2PROTO_ARP;
|
||||
init_if(&ifp, MG_TCPIP_L2_PPPoE);
|
||||
s_state = MG_PPPoE_ST_SESS;
|
||||
s_id = mg_htons(0x4321);
|
||||
s_lcpup = true;
|
||||
raw = mg_str_n((char *) frame,
|
||||
mk_pppoe_disc(frame, MG_PPPoE_PADT, 0x1234, NULL, 0));
|
||||
ASSERT(mg_l2_rx(&ifp, &proto, &pay, &raw) == false);
|
||||
ASSERT(s_state == MG_PPPoE_ST_SESS);
|
||||
ASSERT(s_id == mg_htons(0x4321));
|
||||
ASSERT(s_lcpup == true);
|
||||
}
|
||||
|
||||
static void test_pppoe_session_accept(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_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) \
|
||||
printf("HEALTH_DASHBOARD\t\"%s\": %s,\n", x, s_error ? "false" : "true")
|
||||
|
||||
int main(void) {
|
||||
s_error = false;
|
||||
test_ppp_lcp_accept();
|
||||
test_ppp_lcp_discard();
|
||||
DASHBOARD("lcp");
|
||||
|
||||
s_error = false;
|
||||
test_ppp_ipcp_accept();
|
||||
test_ppp_ipcp_reject();
|
||||
DASHBOARD("ipcp");
|
||||
|
||||
#if MG_ENABLE_IPV6
|
||||
s_error = false;
|
||||
test_ppp_ipv6cp_accept();
|
||||
test_ppp_ipv6cp_reject();
|
||||
DASHBOARD("ipv6cp");
|
||||
#endif
|
||||
|
||||
s_error = false;
|
||||
test_ppp_ip_accept();
|
||||
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");
|
||||
|
||||
s_error = false;
|
||||
test_pppoe_pado_accept();
|
||||
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");
|
||||
|
||||
#ifdef NO_ABORT
|
||||
if (s_abort != 0) return EXIT_FAILURE;
|
||||
#endif
|
||||
|
||||
printf("SUCCESS. Total tests: %d\n", s_num_tests);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in new issue
Block a user