mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-27 20:59:00 +08:00
Merge pull request #2926 from cesanta/arp
Fix gw ARP. Make ARP probe public. Add ARP event
This commit is contained in:
commit
f77a7ad623
71
mongoose.c
71
mongoose.c
@ -5107,7 +5107,7 @@ static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac) {
|
||||||
struct eth *eth = (struct eth *) ifp->tx.buf;
|
struct eth *eth = (struct eth *) ifp->tx.buf;
|
||||||
struct arp *arp = (struct arp *) (eth + 1);
|
struct arp *arp = (struct arp *) (eth + 1);
|
||||||
memset(eth->dst, 255, sizeof(eth->dst));
|
memset(eth->dst, 255, sizeof(eth->dst));
|
||||||
@ -5118,6 +5118,7 @@ static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
|||||||
arp->plen = 4;
|
arp->plen = 4;
|
||||||
arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
|
arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
|
||||||
memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
|
memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
|
||||||
|
if (mac != NULL) memcpy(arp->tha, mac, sizeof(arp->tha));
|
||||||
ether_output(ifp, PDIFF(eth, arp + 1));
|
ether_output(ifp, PDIFF(eth, arp + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5126,7 +5127,9 @@ static void onstatechange(struct mg_tcpip_if *ifp) {
|
|||||||
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
||||||
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
||||||
MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac));
|
MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac));
|
||||||
arp_ask(ifp, ifp->gw); // unsolicited GW ARP request
|
} else if (ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
MG_ERROR(("Got IP"));
|
||||||
|
mg_tcpip_arp_request(ifp, ifp->gw, NULL); // unsolicited GW ARP request
|
||||||
} else if (ifp->state == MG_TCPIP_STATE_UP) {
|
} else if (ifp->state == MG_TCPIP_STATE_UP) {
|
||||||
MG_ERROR(("Link up"));
|
MG_ERROR(("Link up"));
|
||||||
srand((unsigned int) mg_millis());
|
srand((unsigned int) mg_millis());
|
||||||
@ -5276,8 +5279,12 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
} else if (pkt->arp->op == mg_htons(2)) {
|
} else if (pkt->arp->op == mg_htons(2)) {
|
||||||
if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
|
if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
|
||||||
if (pkt->arp->spa == ifp->gw) {
|
if (pkt->arp->spa == ifp->gw) {
|
||||||
// Got response for the GW ARP request. Set ifp->gwmac
|
// Got response for the GW ARP request. Set ifp->gwmac and IP -> READY
|
||||||
memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_READY;
|
||||||
|
onstatechange(ifp);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||||
if (c != NULL && c->is_arplooking) {
|
if (c != NULL && c->is_arplooking) {
|
||||||
@ -5352,7 +5359,7 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
// assume DHCP server = router until ARP resolves
|
// assume DHCP server = router until ARP resolves
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||||
ifp->state = MG_TCPIP_STATE_READY; // BOUND state
|
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||||
uint64_t rand;
|
uint64_t rand;
|
||||||
mg_random(&rand, sizeof(rand));
|
mg_random(&rand, sizeof(rand));
|
||||||
srand((unsigned int) (rand + mg_millis()));
|
srand((unsigned int) (rand + mg_millis()));
|
||||||
@ -5400,7 +5407,7 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
res.magic = pkt->dhcp->magic;
|
res.magic = pkt->dhcp->magic;
|
||||||
res.xid = pkt->dhcp->xid;
|
res.xid = pkt->dhcp->xid;
|
||||||
if (ifp->enable_get_gateway) {
|
if (ifp->enable_get_gateway) {
|
||||||
ifp->gw = res.yiaddr;
|
ifp->gw = res.yiaddr; // set gw IP, best-effort gwmac as DHCP server's
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
}
|
}
|
||||||
tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
|
tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
|
||||||
@ -5785,6 +5792,7 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
|||||||
if (pkt.eth->type == mg_htons(0x806)) {
|
if (pkt.eth->type == mg_htons(0x806)) {
|
||||||
pkt.arp = (struct arp *) (pkt.eth + 1);
|
pkt.arp = (struct arp *) (pkt.eth + 1);
|
||||||
if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
|
if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
|
||||||
|
mg_tcpip_call(ifp, MG_TCPIP_EV_ARP, &pkt.raw);
|
||||||
rx_arp(ifp, &pkt);
|
rx_arp(ifp, &pkt);
|
||||||
} else if (pkt.eth->type == mg_htons(0x86dd)) {
|
} else if (pkt.eth->type == mg_htons(0x86dd)) {
|
||||||
pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
|
pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
|
||||||
@ -5816,40 +5824,53 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
|||||||
|
|
||||||
#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
||||||
if (expired_1000ms) {
|
if (expired_1000ms) {
|
||||||
const char *names[] = {"down", "up", "req", "ready"};
|
const char *names[] = {"down", "up", "req", "ip", "ready"};
|
||||||
MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
||||||
ifp->ndrop, ifp->nerr));
|
ifp->ndrop, ifp->nerr));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// Handle gw ARP request timeout, order is important
|
||||||
|
if (expired_1000ms && ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC
|
||||||
|
onstatechange(ifp);
|
||||||
|
}
|
||||||
// Handle physical interface up/down status
|
// Handle physical interface up/down status
|
||||||
if (expired_1000ms && ifp->driver->up) {
|
if (expired_1000ms && ifp->driver->up) {
|
||||||
bool up = ifp->driver->up(ifp);
|
bool up = ifp->driver->up(ifp);
|
||||||
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
||||||
if (up != current) {
|
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
||||||
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
if (up != current) { // link state has changed
|
||||||
: ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP
|
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
||||||
: MG_TCPIP_STATE_READY;
|
: ifp->enable_dhcp_client || ifp->ip == 0
|
||||||
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
? MG_TCPIP_STATE_UP
|
||||||
|
: MG_TCPIP_STATE_IP;
|
||||||
|
onstatechange(ifp);
|
||||||
|
} else if (!ifp->enable_dhcp_client && ifp->state == MG_TCPIP_STATE_UP &&
|
||||||
|
ifp->ip) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
|
||||||
onstatechange(ifp);
|
onstatechange(ifp);
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
||||||
|
mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
||||||
|
|
||||||
// DHCP RFC-2131 (4.4)
|
// DHCP RFC-2131 (4.4)
|
||||||
if (ifp->state == MG_TCPIP_STATE_UP && expired_1000ms) {
|
if (ifp->enable_dhcp_client && expired_1000ms) {
|
||||||
tx_dhcp_discover(ifp); // INIT (4.4.1)
|
if (ifp->state == MG_TCPIP_STATE_UP) {
|
||||||
} else if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY &&
|
tx_dhcp_discover(ifp); // INIT (4.4.1)
|
||||||
ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING
|
} else if (ifp->state == MG_TCPIP_STATE_READY &&
|
||||||
if (ifp->now >= ifp->lease_expire) {
|
ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING
|
||||||
ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP
|
if (ifp->now >= ifp->lease_expire) {
|
||||||
onstatechange(ifp);
|
ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP
|
||||||
} else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
|
onstatechange(ifp);
|
||||||
((ifp->now / 1000) % 60) == 0) {
|
} else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
|
||||||
// hack: 30 min before deadline, try to rebind (4.3.6) every min
|
((ifp->now / 1000) % 60) == 0) {
|
||||||
tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
|
// hack: 30 min before deadline, try to rebind (4.3.6) every min
|
||||||
} // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
|
tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
|
||||||
|
} // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read data from the network
|
// Read data from the network
|
||||||
@ -5943,7 +5964,7 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
|
|||||||
ifp->mtu = MG_TCPIP_MTU_DEFAULT;
|
ifp->mtu = MG_TCPIP_MTU_DEFAULT;
|
||||||
mgr->extraconnsize = sizeof(struct connstate);
|
mgr->extraconnsize = sizeof(struct connstate);
|
||||||
if (ifp->ip == 0) ifp->enable_dhcp_client = true;
|
if (ifp->ip == 0) ifp->enable_dhcp_client = true;
|
||||||
memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set to broadcast
|
memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set best-effort to bcast
|
||||||
mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
|
mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
|
||||||
ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from
|
ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from
|
||||||
// MG_EPHEMERAL_PORT_BASE to 65535
|
// MG_EPHEMERAL_PORT_BASE to 65535
|
||||||
@ -5996,7 +6017,7 @@ void mg_connect_resolved(struct mg_connection *c) {
|
|||||||
rem_ip != ifp->gw) { // skip if gw (onstatechange -> READY -> ARP)
|
rem_ip != ifp->gw) { // skip if gw (onstatechange -> READY -> ARP)
|
||||||
// If we're in the same LAN, fire an ARP lookup.
|
// If we're in the same LAN, fire an ARP lookup.
|
||||||
MG_DEBUG(("%lu ARP lookup...", c->id));
|
MG_DEBUG(("%lu ARP lookup...", c->id));
|
||||||
arp_ask(ifp, rem_ip);
|
mg_tcpip_arp_request(ifp, rem_ip, NULL);
|
||||||
settmout(c, MIP_TTYPE_ARP);
|
settmout(c, MIP_TTYPE_ARP);
|
||||||
c->is_arplooking = 1;
|
c->is_arplooking = 1;
|
||||||
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
||||||
|
@ -2739,6 +2739,8 @@ enum {
|
|||||||
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
||||||
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
||||||
|
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
||||||
|
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
||||||
MG_TCPIP_EV_USER // Starting ID for user events
|
MG_TCPIP_EV_USER // Starting ID for user events
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2775,13 +2777,15 @@ struct mg_tcpip_if {
|
|||||||
uint8_t state; // Current state
|
uint8_t state; // Current state
|
||||||
#define MG_TCPIP_STATE_DOWN 0 // Interface is down
|
#define MG_TCPIP_STATE_DOWN 0 // Interface is down
|
||||||
#define MG_TCPIP_STATE_UP 1 // Interface is up
|
#define MG_TCPIP_STATE_UP 1 // Interface is up
|
||||||
#define MG_TCPIP_STATE_REQ 2 // Interface is up and has requested an IP
|
#define MG_TCPIP_STATE_REQ 2 // Interface is up, DHCP REQUESTING state
|
||||||
#define MG_TCPIP_STATE_READY 3 // Interface is up and has an IP assigned
|
#define MG_TCPIP_STATE_IP 3 // Interface is up and has an IP assigned
|
||||||
|
#define MG_TCPIP_STATE_READY 4 // Interface has fully come up, ready to work
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
||||||
void mg_tcpip_free(struct mg_tcpip_if *);
|
void mg_tcpip_free(struct mg_tcpip_if *);
|
||||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||||
|
void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
|
||||||
|
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||||
|
@ -185,7 +185,7 @@ static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac) {
|
||||||
struct eth *eth = (struct eth *) ifp->tx.buf;
|
struct eth *eth = (struct eth *) ifp->tx.buf;
|
||||||
struct arp *arp = (struct arp *) (eth + 1);
|
struct arp *arp = (struct arp *) (eth + 1);
|
||||||
memset(eth->dst, 255, sizeof(eth->dst));
|
memset(eth->dst, 255, sizeof(eth->dst));
|
||||||
@ -196,6 +196,7 @@ static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
|||||||
arp->plen = 4;
|
arp->plen = 4;
|
||||||
arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
|
arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
|
||||||
memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
|
memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
|
||||||
|
if (mac != NULL) memcpy(arp->tha, mac, sizeof(arp->tha));
|
||||||
ether_output(ifp, PDIFF(eth, arp + 1));
|
ether_output(ifp, PDIFF(eth, arp + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +205,9 @@ static void onstatechange(struct mg_tcpip_if *ifp) {
|
|||||||
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
||||||
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
||||||
MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac));
|
MG_INFO((" MAC: %M", mg_print_mac, &ifp->mac));
|
||||||
arp_ask(ifp, ifp->gw); // unsolicited GW ARP request
|
} else if (ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
MG_ERROR(("Got IP"));
|
||||||
|
mg_tcpip_arp_request(ifp, ifp->gw, NULL); // unsolicited GW ARP request
|
||||||
} else if (ifp->state == MG_TCPIP_STATE_UP) {
|
} else if (ifp->state == MG_TCPIP_STATE_UP) {
|
||||||
MG_ERROR(("Link up"));
|
MG_ERROR(("Link up"));
|
||||||
srand((unsigned int) mg_millis());
|
srand((unsigned int) mg_millis());
|
||||||
@ -354,8 +357,12 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
} else if (pkt->arp->op == mg_htons(2)) {
|
} else if (pkt->arp->op == mg_htons(2)) {
|
||||||
if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
|
if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
|
||||||
if (pkt->arp->spa == ifp->gw) {
|
if (pkt->arp->spa == ifp->gw) {
|
||||||
// Got response for the GW ARP request. Set ifp->gwmac
|
// Got response for the GW ARP request. Set ifp->gwmac and IP -> READY
|
||||||
memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_READY;
|
||||||
|
onstatechange(ifp);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||||
if (c != NULL && c->is_arplooking) {
|
if (c != NULL && c->is_arplooking) {
|
||||||
@ -430,7 +437,7 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
// assume DHCP server = router until ARP resolves
|
// assume DHCP server = router until ARP resolves
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||||
ifp->state = MG_TCPIP_STATE_READY; // BOUND state
|
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||||
uint64_t rand;
|
uint64_t rand;
|
||||||
mg_random(&rand, sizeof(rand));
|
mg_random(&rand, sizeof(rand));
|
||||||
srand((unsigned int) (rand + mg_millis()));
|
srand((unsigned int) (rand + mg_millis()));
|
||||||
@ -478,7 +485,7 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
|||||||
res.magic = pkt->dhcp->magic;
|
res.magic = pkt->dhcp->magic;
|
||||||
res.xid = pkt->dhcp->xid;
|
res.xid = pkt->dhcp->xid;
|
||||||
if (ifp->enable_get_gateway) {
|
if (ifp->enable_get_gateway) {
|
||||||
ifp->gw = res.yiaddr;
|
ifp->gw = res.yiaddr; // set gw IP, best-effort gwmac as DHCP server's
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
}
|
}
|
||||||
tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
|
tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
|
||||||
@ -863,6 +870,7 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
|||||||
if (pkt.eth->type == mg_htons(0x806)) {
|
if (pkt.eth->type == mg_htons(0x806)) {
|
||||||
pkt.arp = (struct arp *) (pkt.eth + 1);
|
pkt.arp = (struct arp *) (pkt.eth + 1);
|
||||||
if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
|
if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return; // Truncated
|
||||||
|
mg_tcpip_call(ifp, MG_TCPIP_EV_ARP, &pkt.raw);
|
||||||
rx_arp(ifp, &pkt);
|
rx_arp(ifp, &pkt);
|
||||||
} else if (pkt.eth->type == mg_htons(0x86dd)) {
|
} else if (pkt.eth->type == mg_htons(0x86dd)) {
|
||||||
pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
|
pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
|
||||||
@ -894,40 +902,53 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
|
|||||||
|
|
||||||
#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
|
||||||
if (expired_1000ms) {
|
if (expired_1000ms) {
|
||||||
const char *names[] = {"down", "up", "req", "ready"};
|
const char *names[] = {"down", "up", "req", "ip", "ready"};
|
||||||
MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
||||||
ifp->ndrop, ifp->nerr));
|
ifp->ndrop, ifp->nerr));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// Handle gw ARP request timeout, order is important
|
||||||
|
if (expired_1000ms && ifp->state == MG_TCPIP_STATE_IP) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC
|
||||||
|
onstatechange(ifp);
|
||||||
|
}
|
||||||
// Handle physical interface up/down status
|
// Handle physical interface up/down status
|
||||||
if (expired_1000ms && ifp->driver->up) {
|
if (expired_1000ms && ifp->driver->up) {
|
||||||
bool up = ifp->driver->up(ifp);
|
bool up = ifp->driver->up(ifp);
|
||||||
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
bool current = ifp->state != MG_TCPIP_STATE_DOWN;
|
||||||
if (up != current) {
|
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
||||||
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
if (up != current) { // link state has changed
|
||||||
: ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP
|
ifp->state = up == false ? MG_TCPIP_STATE_DOWN
|
||||||
: MG_TCPIP_STATE_READY;
|
: ifp->enable_dhcp_client || ifp->ip == 0
|
||||||
if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
|
? MG_TCPIP_STATE_UP
|
||||||
|
: MG_TCPIP_STATE_IP;
|
||||||
|
onstatechange(ifp);
|
||||||
|
} else if (!ifp->enable_dhcp_client && ifp->state == MG_TCPIP_STATE_UP &&
|
||||||
|
ifp->ip) {
|
||||||
|
ifp->state = MG_TCPIP_STATE_IP; // ifp->fn has set an IP
|
||||||
onstatechange(ifp);
|
onstatechange(ifp);
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
|
||||||
|
mg_tcpip_call(ifp, MG_TCPIP_EV_TIMER_1S, NULL);
|
||||||
}
|
}
|
||||||
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
if (ifp->state == MG_TCPIP_STATE_DOWN) return;
|
||||||
|
|
||||||
// DHCP RFC-2131 (4.4)
|
// DHCP RFC-2131 (4.4)
|
||||||
if (ifp->state == MG_TCPIP_STATE_UP && expired_1000ms) {
|
if (ifp->enable_dhcp_client && expired_1000ms) {
|
||||||
tx_dhcp_discover(ifp); // INIT (4.4.1)
|
if (ifp->state == MG_TCPIP_STATE_UP) {
|
||||||
} else if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY &&
|
tx_dhcp_discover(ifp); // INIT (4.4.1)
|
||||||
ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING
|
} else if (ifp->state == MG_TCPIP_STATE_READY &&
|
||||||
if (ifp->now >= ifp->lease_expire) {
|
ifp->lease_expire > 0) { // BOUND / RENEWING / REBINDING
|
||||||
ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP
|
if (ifp->now >= ifp->lease_expire) {
|
||||||
onstatechange(ifp);
|
ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0; // expired, release IP
|
||||||
} else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
|
onstatechange(ifp);
|
||||||
((ifp->now / 1000) % 60) == 0) {
|
} else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
|
||||||
// hack: 30 min before deadline, try to rebind (4.3.6) every min
|
((ifp->now / 1000) % 60) == 0) {
|
||||||
tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
|
// hack: 30 min before deadline, try to rebind (4.3.6) every min
|
||||||
} // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
|
tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
|
||||||
|
} // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read data from the network
|
// Read data from the network
|
||||||
@ -1021,7 +1042,7 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
|
|||||||
ifp->mtu = MG_TCPIP_MTU_DEFAULT;
|
ifp->mtu = MG_TCPIP_MTU_DEFAULT;
|
||||||
mgr->extraconnsize = sizeof(struct connstate);
|
mgr->extraconnsize = sizeof(struct connstate);
|
||||||
if (ifp->ip == 0) ifp->enable_dhcp_client = true;
|
if (ifp->ip == 0) ifp->enable_dhcp_client = true;
|
||||||
memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set to broadcast
|
memset(ifp->gwmac, 255, sizeof(ifp->gwmac)); // Set best-effort to bcast
|
||||||
mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
|
mg_random(&ifp->eport, sizeof(ifp->eport)); // Random from 0 to 65535
|
||||||
ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from
|
ifp->eport |= MG_EPHEMERAL_PORT_BASE; // Random from
|
||||||
// MG_EPHEMERAL_PORT_BASE to 65535
|
// MG_EPHEMERAL_PORT_BASE to 65535
|
||||||
@ -1074,7 +1095,7 @@ void mg_connect_resolved(struct mg_connection *c) {
|
|||||||
rem_ip != ifp->gw) { // skip if gw (onstatechange -> READY -> ARP)
|
rem_ip != ifp->gw) { // skip if gw (onstatechange -> READY -> ARP)
|
||||||
// If we're in the same LAN, fire an ARP lookup.
|
// If we're in the same LAN, fire an ARP lookup.
|
||||||
MG_DEBUG(("%lu ARP lookup...", c->id));
|
MG_DEBUG(("%lu ARP lookup...", c->id));
|
||||||
arp_ask(ifp, rem_ip);
|
mg_tcpip_arp_request(ifp, rem_ip, NULL);
|
||||||
settmout(c, MIP_TTYPE_ARP);
|
settmout(c, MIP_TTYPE_ARP);
|
||||||
c->is_arplooking = 1;
|
c->is_arplooking = 1;
|
||||||
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
} else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
|
||||||
|
@ -22,6 +22,8 @@ enum {
|
|||||||
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
MG_TCPIP_EV_ST_CHG, // state change uint8_t * (&ifp->state)
|
||||||
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_DNS, // DHCP DNS assignment uint32_t *ipaddr
|
||||||
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
MG_TCPIP_EV_DHCP_SNTP, // DHCP SNTP assignment uint32_t *ipaddr
|
||||||
|
MG_TCPIP_EV_ARP, // Got ARP packet struct mg_str *
|
||||||
|
MG_TCPIP_EV_TIMER_1S, // 1 second timer NULL
|
||||||
MG_TCPIP_EV_USER // Starting ID for user events
|
MG_TCPIP_EV_USER // Starting ID for user events
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,13 +60,15 @@ struct mg_tcpip_if {
|
|||||||
uint8_t state; // Current state
|
uint8_t state; // Current state
|
||||||
#define MG_TCPIP_STATE_DOWN 0 // Interface is down
|
#define MG_TCPIP_STATE_DOWN 0 // Interface is down
|
||||||
#define MG_TCPIP_STATE_UP 1 // Interface is up
|
#define MG_TCPIP_STATE_UP 1 // Interface is up
|
||||||
#define MG_TCPIP_STATE_REQ 2 // Interface is up and has requested an IP
|
#define MG_TCPIP_STATE_REQ 2 // Interface is up, DHCP REQUESTING state
|
||||||
#define MG_TCPIP_STATE_READY 3 // Interface is up and has an IP assigned
|
#define MG_TCPIP_STATE_IP 3 // Interface is up and has an IP assigned
|
||||||
|
#define MG_TCPIP_STATE_READY 4 // Interface has fully come up, ready to work
|
||||||
};
|
};
|
||||||
|
|
||||||
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
||||||
void mg_tcpip_free(struct mg_tcpip_if *);
|
void mg_tcpip_free(struct mg_tcpip_if *);
|
||||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||||
|
void mg_tcpip_arp_request(struct mg_tcpip_if *ifp, uint32_t ip, uint8_t *mac);
|
||||||
|
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
extern struct mg_tcpip_driver mg_tcpip_driver_stm32f;
|
||||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
// Copyright (c) 2022 Cesanta Software Limited
|
// Copyright (c) 2022-24 Cesanta Software Limited
|
||||||
// All rights reserved
|
// All rights reserved
|
||||||
//
|
//
|
||||||
// SNTP example using MIP and pcap driver
|
// example using MIP and pcap driver
|
||||||
|
// make CFLAGS_EXTRA="-DMG_TLS=MG_TLS_BUILTIN -DDISABLE_DHCP" for "auto-IP"
|
||||||
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
#define MQTT_URL "mqtt://broker.emqx.io:1883" // MQTT broker URL
|
#define MQTT_URL "mqtt://broker.emqx.io:1883" // MQTT broker URL
|
||||||
#define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not TLS1.3
|
#define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not TLS1.3
|
||||||
#define MQTT_TOPIC "mg/rx" // Topic to subscribe to
|
#define MQTT_TOPIC "mg/rx" // Topic to subscribe to
|
||||||
|
|
||||||
// // Taken from broker.emqx.io
|
|
||||||
static const char *s_ca_cert =
|
static const char *s_ca_cert =
|
||||||
"-----BEGIN CERTIFICATE-----\n"
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
|
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n"
|
||||||
@ -44,29 +44,6 @@ static const char *s_ca_cert =
|
|||||||
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
|
"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
|
||||||
"-----END CERTIFICATE-----\n";
|
"-----END CERTIFICATE-----\n";
|
||||||
|
|
||||||
// "-----BEGIN CERTIFICATE-----\n"
|
|
||||||
// "MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh"
|
|
||||||
// "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
|
|
||||||
// "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"
|
|
||||||
// "MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\n"
|
|
||||||
// "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
|
|
||||||
// "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\n"
|
|
||||||
// "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\n"
|
|
||||||
// "2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\n"
|
|
||||||
// "1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\n"
|
|
||||||
// "q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\n"
|
|
||||||
// "tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\n"
|
|
||||||
// "vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\n"
|
|
||||||
// "BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\n"
|
|
||||||
// "5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\n"
|
|
||||||
// "1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\n"
|
|
||||||
// "NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\n"
|
|
||||||
// "Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\n"
|
|
||||||
// "8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\n"
|
|
||||||
// "pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\n"
|
|
||||||
// "MrY=\n"
|
|
||||||
// "-----END CERTIFICATE-----\n";
|
|
||||||
|
|
||||||
static const char *s_tls_cert =
|
static const char *s_tls_cert =
|
||||||
"-----BEGIN CERTIFICATE-----\n"
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
"MIIBMTCB2aADAgECAgkAluqkgeuV/zUwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI\n"
|
"MIIBMTCB2aADAgECAgkAluqkgeuV/zUwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI\n"
|
||||||
@ -192,6 +169,55 @@ static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void if_ev_handler(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
|
||||||
|
// Trigger MQTT connection when we have an IP address
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_READY && ev == MG_TCPIP_EV_ST_CHG) {
|
||||||
|
struct mg_mqtt_opts opts = {.clean = true};
|
||||||
|
// mg_mqtt_connect(ifp->mgr, MQTT_URL, &opts, mqtt_ev_handler, NULL);
|
||||||
|
mg_mqtt_connect(ifp->mgr, MQTTS_URL, &opts, mqtt_ev_handler, "tls enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DISABLE_DHCP)
|
||||||
|
{
|
||||||
|
static uint32_t ip = 0;
|
||||||
|
static unsigned counter = 0;
|
||||||
|
// Set initial self-assigned IP
|
||||||
|
if (ip == 0) ip = MG_IPV4(169, 254, 2, 100);
|
||||||
|
|
||||||
|
// restart process on link change
|
||||||
|
if (ev == MG_TCPIP_EV_ST_CHG && ifp->state == MG_TCPIP_STATE_DOWN) {
|
||||||
|
ifp->ip = 0;
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ifp->state == MG_TCPIP_STATE_UP) {
|
||||||
|
// Catch ARP packets. Parse them yourself, that's easy.
|
||||||
|
if (ev == MG_TCPIP_EV_ARP) {
|
||||||
|
struct mg_str *frame = ev_data;
|
||||||
|
MG_INFO(("Iface %p: Got ARP frame", ifp));
|
||||||
|
mg_hexdump(frame->buf, frame->len);
|
||||||
|
// TODO: check for conflict. On conflict, increment ip and reset counter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch 1 second timer events
|
||||||
|
if (ev == MG_TCPIP_EV_TIMER_1S) {
|
||||||
|
if (++counter <= 3) {
|
||||||
|
MG_INFO(("Sending ARP probe"));
|
||||||
|
mg_tcpip_arp_request(ifp, ip, NULL);
|
||||||
|
} else {
|
||||||
|
// Seems to be no conflict. Assign us an IP
|
||||||
|
MG_INFO(("Assigning %M, sending gratuitous ARP", mg_print_ip4, &ip));
|
||||||
|
ifp->ip = ip; // state will change to MG_TCPIP_STATE_IP on next poll
|
||||||
|
mg_tcpip_arp_request(ifp, ip, ifp->mac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void) ev_data;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const char *iface = "lo0"; // Network iface
|
const char *iface = "lo0"; // Network iface
|
||||||
const char *mac = "02:00:01:02:03:77"; // MAC address
|
const char *mac = "02:00:01:02:03:77"; // MAC address
|
||||||
@ -247,27 +273,29 @@ int main(int argc, char *argv[]) {
|
|||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||||
|
|
||||||
struct mg_tcpip_driver driver = {.tx = pcap_tx, .up = pcap_up, .rx = pcap_rx};
|
struct mg_tcpip_driver driver = {.tx = pcap_tx, .up = pcap_up, .rx = pcap_rx};
|
||||||
struct mg_tcpip_if mif = {.driver = &driver, .driver_data = ph};
|
struct mg_tcpip_if mif = {.driver = &driver,
|
||||||
|
.driver_data = ph,
|
||||||
|
.enable_mac_check = true,
|
||||||
|
#if defined(DISABLE_DHCP)
|
||||||
|
.mask = MG_IPV4(255, 255, 255, 0),
|
||||||
|
.gw = MG_IPV4(169, 254, 2, 1),
|
||||||
|
#endif
|
||||||
|
.fn = if_ev_handler};
|
||||||
sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1],
|
sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1],
|
||||||
&mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]);
|
&mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]);
|
||||||
mg_tcpip_init(&mgr, &mif);
|
mg_tcpip_init(&mgr, &mif);
|
||||||
|
|
||||||
|
// order is important: set after calling mg_tcpip_init()
|
||||||
|
#if defined(DISABLE_DHCP)
|
||||||
|
mif.enable_dhcp_client = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
MG_INFO(("Init done, starting main loop"));
|
MG_INFO(("Init done, starting main loop"));
|
||||||
mg_http_listen(&mgr, "http://0.0.0.0:8000", http_ev_handler, NULL);
|
mg_http_listen(&mgr, "http://0.0.0.0:8000", http_ev_handler, NULL);
|
||||||
mg_http_listen(&mgr, "https://0.0.0.0:8443", http_ev_handler, "tls enabled");
|
mg_http_listen(&mgr, "https://0.0.0.0:8443", http_ev_handler, "tls enabled");
|
||||||
|
|
||||||
bool got_ip = false;
|
|
||||||
|
|
||||||
while (s_signo == 0) {
|
while (s_signo == 0) {
|
||||||
mg_mgr_poll(&mgr, 100);
|
mg_mgr_poll(&mgr, 100);
|
||||||
|
|
||||||
// Trigger MQTT connection when we receive IP address
|
|
||||||
if (mif.state == MG_TCPIP_STATE_READY && got_ip == false) {
|
|
||||||
struct mg_mqtt_opts opts = {.clean = true};
|
|
||||||
// mg_mqtt_connect(&mgr, MQTT_URL, &opts, mqtt_ev_handler, NULL);
|
|
||||||
mg_mqtt_connect(&mgr, MQTTS_URL, &opts, mqtt_ev_handler, "tls enabled");
|
|
||||||
got_ip = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(&mgr);
|
||||||
|
Loading…
Reference in New Issue
Block a user