mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-30 12:50:58 +00:00
move to new skeleton
This commit is contained in:
1 parent
4f15392440
commit
a0b6e70ff8
23 files changed
+34
-37
No files matched your search
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2022 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// SNTP example using MIP and pcap driver
|
||||
|
||||
#include <pcap.h>
|
||||
#include "mongoose.h"
|
||||
|
||||
#define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker to connect to
|
||||
#define MQTT_TOPIC "t/123" // Topic to subscribe to
|
||||
|
||||
#if MG_ARCH == MG_ARCH_WIN32
|
||||
#define usleep(x) Sleep((x) / 1000)
|
||||
#endif
|
||||
|
||||
static int s_signo;
|
||||
void signal_handler(int signo) {
|
||||
s_signo = signo;
|
||||
}
|
||||
|
||||
static size_t pcap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
int res = pcap_inject((pcap_t *) ifp->driver_data, buf, len);
|
||||
if (res == PCAP_ERROR) {
|
||||
MG_ERROR(("pcap_inject: %d", res));
|
||||
}
|
||||
return res == PCAP_ERROR ? 0 : len;
|
||||
}
|
||||
|
||||
static bool pcap_up(struct mg_tcpip_if *ifp) {
|
||||
return ifp->driver_data ? true : false;
|
||||
}
|
||||
|
||||
static size_t pcap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
size_t received = 0;
|
||||
struct pcap_pkthdr *hdr = NULL;
|
||||
const unsigned char *pkt = NULL;
|
||||
usleep(1000); // Sleep 1 millisecond. This is to avoid 100% CPU
|
||||
if (pcap_next_ex((pcap_t *) ifp->driver_data, &hdr, &pkt) == 1) {
|
||||
received = hdr->len < len ? hdr->len : len;
|
||||
memcpy(buf, pkt, received);
|
||||
}
|
||||
return received;
|
||||
}
|
||||
|
||||
static void fn2(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
MG_DEBUG(("Got response (%d) %.*s...", (int) hm->message.len, 12,
|
||||
hm->message.buf));
|
||||
c->is_draining = 1;
|
||||
} else if (ev == MG_EV_CONNECT) {
|
||||
mg_printf(c, "GET %s HTTP/1.1\r\n\r\n", mg_url_uri((char *) c->fn_data));
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
free(c->fn_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_match(hm->uri, mg_str("/api/debug"), NULL)) {
|
||||
int level = mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
|
||||
mg_log_set(level);
|
||||
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
|
||||
} else if (mg_match(hm->uri, mg_str("/api/url"), NULL)) {
|
||||
char *url = mg_json_get_str(hm->body, "$.url");
|
||||
if (url == NULL) {
|
||||
mg_http_reply(c, 200, NULL, "no url, rl %d\r\n", (int) c->recv.len);
|
||||
} else {
|
||||
mg_http_connect(c->mgr, url, fn2, url);
|
||||
mg_http_reply(c, 200, NULL, "ok\r\n");
|
||||
}
|
||||
} else {
|
||||
mg_http_reply(c, 200, NULL, "%.*s\r\n", (int) hm->message.len,
|
||||
hm->message.buf);
|
||||
}
|
||||
}
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *iface = "lo0"; // Network iface
|
||||
const char *mac = "02:00:01:02:03:77"; // MAC address
|
||||
const char *bpf = NULL; // "host x.x.x.x or ether host ff:ff:ff:ff:ff:ff";
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
||||
|
||||
// Parse options
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-i") == 0 && i + 1 < argc) {
|
||||
iface = argv[++i];
|
||||
} else if (strcmp(argv[i], "-mac") == 0 && i + 1 < argc) {
|
||||
mac = argv[++i];
|
||||
} else if (strcmp(argv[i], "-bpf") == 0 && i + 1 < argc) {
|
||||
bpf = argv[++i];
|
||||
} else if (strcmp(argv[i], "-v") == 0 && i + 1 < argc) {
|
||||
mg_log_set(atoi(argv[++i]));
|
||||
} else {
|
||||
MG_ERROR(("unknown option %s", argv[i]));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Open network interface
|
||||
pcap_t *ph = pcap_open_live(iface, 0xffff, 1, 1, errbuf);
|
||||
if (ph == NULL) {
|
||||
pcap_if_t *devs, *d;
|
||||
MG_ERROR(("Failed to open interface %s. Available interfaces:", iface));
|
||||
if (pcap_findalldevs(&devs, errbuf) == 0) {
|
||||
for (d = devs; d != NULL; d = d->next) {
|
||||
MG_ERROR(("%s (%s)", d->name, d->description ? d->description : ""));
|
||||
}
|
||||
pcap_freealldevs(devs);
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
pcap_setnonblock(ph, 1, errbuf);
|
||||
pcap_setdirection(ph, PCAP_D_IN);
|
||||
|
||||
// Apply BPF to reduce noise. Let in only broadcasts and our own traffic
|
||||
if (bpf != NULL) {
|
||||
struct bpf_program bpfp;
|
||||
if (pcap_compile(ph, &bpfp, bpf, 1, 0)) MG_ERROR(("BPF compile failed\n"));
|
||||
pcap_setfilter(ph, &bpfp);
|
||||
pcap_freecode(&bpfp);
|
||||
}
|
||||
|
||||
MG_INFO(("Opened interface %s", iface));
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
|
||||
struct mg_mgr mgr; // Event manager
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
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_if mif = {.driver = &driver, .driver_data = ph};
|
||||
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]);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:8000", fn, &mgr);
|
||||
|
||||
while (s_signo == 0) mg_mgr_poll(&mgr, 100); // Infinite event loop
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
pcap_close(ph);
|
||||
printf("Exiting on signal %d\n", s_signo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user