move to new skeleton

This commit is contained in:
Sergio R. Caprile committed 2024-04-29 10:58:43 -03:00
1 parent 4f15392440
commit a0b6e70ff8
23 files changed
+34 -37

No files matched your search

+35
View File
@@ -0,0 +1,35 @@
PROG ?= example # Program we are building
DELETE = rm -rf # Command to remove files
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c net.c packed_fs.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_TCPIP_DRIVER_INIT=0
# Example specific build options. See README.md
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
PROG ?= example.exe # Use .exe suffix for the binary
CC = gcc # Use MinGW gcc compiler
CFLAGS += -lws2_32 # Link against Winsock library
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
OUT ?= -o $(PROG) # Build output
MAKE += WINDOWS=1 CC=$(CC)
endif
all: $(PROG) # Default target. Build and run program
$(RUN) ./$(PROG) $(ARGS)
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM mbedtls
# see https://mongoose.ws/tutorials/tls/#how-to-build for TLS build options
mbedtls: # Pull and build mbedTLS library
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
$(MAKE) -C mbedtls/library
+173
View File
@@ -0,0 +1,173 @@
# Mongoose TCP/IP stack on a tap interface
This example allows the use of Mongoose's built-in TCP/IP stack in systems that support a TUN/TAP device. The application opens a TAP device and uses the standard socket interface to read and write on it.
The interface can be created by the example itself, but it will also disappear when the example exits. Since we usually need to do something before, like setting up a DHCP server or establishing some connections to the rest of the world, we'll manually create a specific TAP interface and the example will open it; this way, we can have everything setup in advance.
## Linux setup
Create a TAP interface; you can use it as is, attach it to a virtual bridge, or forward/masquerade its traffic.
```sh
$ sudo ip tuntap add dev tap0 mode tap
$ sudo ip link set tap0 up
```
In some systems, you might need superuser privileges to open the device with the example. In others, you can add `user yourusername` or `group yourgroup` at creation time, to grant access to it.
### Use as a virtual interface
In this scenario, Mongoose is only reachable from the hosting machine, but you can add forwarding and masquerading later. Once you have your TAP interface up and running with an IP address, you can configure any services on it.
- Add an IP address
```sh
$ sudo ip addr add 192.168.0.1/24 dev tap0
```
- Start your DHCP server at that interface serving that subnet, or otherwise configure Mongoose to use a fixed address within that subnet.
- Now start the example opening the very same TAP interface:
```sh
$ make -C tutorials/tcpip/tap-driver/ clean all
```
If you are using a different interface name than `tap0`, add `ARGS="-i ifcname"`, and use the proper interface name
```
[DHCP server for 192.168.0.x]
192.168.0.1 192.168.0.x
┌─────────┐
│ tap0 ├──────────────────── tap-driver
└─────────┘
```
As you can't access any other host than your workstation, you need to add any required services (as DNS) there, and configure Mongoose appropriately. This is a foundation, you can expand it by choosing one of the solutions that follow.
### Bridge to your network
If you happen to have a virtual bridge interface (for linking several virtual machines together, for example) (probably `br0` or `virbr0`), we can take advantage of it.
We will attach one end of the virtual interface to a bridge, which will also be attached to your network interface. In this case, Mongoose will have access to your network (and through it, to the Internet) and will also be reachable from your own workstation and other hosts in your network. You don't need to add IP addresses as in the example above, unless you don't have a DHCP server in your network, in which case you will configure Mongoose for a fixed address in your subnet.
- If you don't already have a virtual bridge interface, as mentioned above, you'll have to create it and attach your network interface (NIC) to it. Your IP address has to be assigned to the bridge, instead of the NIC. If you are using DHCP, the client must run on the bridge interface instead of the NIC.
```sh
$ ip link add virbr0 type bridge
$ sudo ip link set virbr0 up
$ sudo ip addr del 10.1.0.10/24 dev enp9s0
$ sudo ip link set enp9s0 master virbr0
$ sudo ip addr add 10.1.0.10/24 dev virbr0
```
Check using `ifconfig`, and try to ping some host in your network
- Attach the TAP interface to the bridge:
```sh
$ sudo ip link set tap0 master virbr0
```
- You won't see your interface state is UP until it is open, but you can check you see something like this:
```sh
$ ip link show master virbr0
2: enp9s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UP mode DEFAULT group default qlen 1000
link/ether 30:5a:3a:08:db:90 brd ff:ff:ff:ff:ff:ff
6: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT group default qlen 1000
link/ether 66:91:e2:5f:d7:ed brd ff:ff:ff:ff:ff:ff
```
- Now start the example
```sh
$ make -C tutorials/tcpip/tap-driver/ clean all
```
If you are using a different interface name than `tap0`, add `ARGS="-i ifcname"`, and use the proper interface name
- Now if everything is fine, besides the example working, you'll see your interface state is UP:
```sh
$ ip link show master virbr0
2: enp9s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UP mode DEFAULT group default qlen 1000
link/ether 30:5a:3a:08:db:90 brd ff:ff:ff:ff:ff:ff
6: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UP mode DEFAULT group default qlen 1000
link/ether 66:91:e2:5f:d7:ed brd ff:ff:ff:ff:ff:ff
```
```
10.1.0.10
virbr0
│
┌──────────────────┴──────────────────┐
│ │ 10.1.0.x
│ ┌────────┐ │
│ │ tap0 ├─────────────┼─────── tap-driver
│ └────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ vnet1 │ │ enp9s0 │ │ vnet2 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
└──────┼───────────┼───────────┼──────┘
│ │ │
│
Ethernet [WiFi]
│ Local LAN 10.1.0.x
│ DHCP server, router
▼
Internet
```
If you have _Docker_ running, it may introduce firewall rules that will disrupt your bridging.
### Forward/Masquerade
Once you have your virtual interface up and running with an IP address, you can use your Linux to NAT and forward Mongoose traffic to another interface, for example the one that connects you to the Internet. In this case, Mongoose will have access to the Internet and will also be reachable from your own workstation; but not from any other hosts in your local network (if there is one). You can use this setup with a direct connection to the Internet or being part of a network, when you want to isolate Mongoose from the rest of your network.
- We assume you already have a firewall in place (you should); to configure masquerading and forwarding do:
```sh
$ sudo iptables -t nat -A POSTROUTING -o enp9s0 -j MASQUERADE
$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
```
Remember to use the proper network interface name
- Now start the example
```sh
$ make -C tutorials/tcpip/tap-driver/ clean all
```
If you are using a different interface name than `tap0`, add `ARGS="-i ifcname"`, and use the proper interface name
```
[DHCP server for 192.168.0.x]
┌────────────► 192.168.0.1 192.168.0.x
│ forwarding ┌─────────┐
│ masquerading │ tap0 ├──────────────────── tap-driver
│ └─────────┘
▼
Your IP (LAN / Public)
┌─────────┐
│ enp9s0 │
└────┬────┘
│
│
Ethernet
│
▼
Internet
```
You can also use this setup if your NIC is part of a bridge (for example: you have virtual machines); in that case:
- use the bridge interface for masquerading, instead of the Ethernet (your IP now belongs to the virtual bridge, not the NIC):
```sh
$ sudo iptables -t nat -A POSTROUTING -o virbr0 -j MASQUERADE
$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
```
Remember to use the proper bridge interface name
```
[DHCP server for 192.168.0.x]
10.1.0.10 ◀──────────────► 192.168.0.1 192.168.0.x
virbr0 forwarding ┌─────────┐
│ masquerading │ tap0 ├──────────────────── tap-driver
│ └─────────┘
┌──────────────────┴──────────────────┐
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ vnet1 │ │ enp9s0 │ │ vnet2 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
└──────┼───────────┼───────────┼──────┘
│ │ │
│
Ethernet [WiFi]
│ Local LAN 10.1.0.x
│ DHCP server, router
▼
Internet
```
+115
View File
@@ -0,0 +1,115 @@
// Copyright (c) 2022 Cesanta Software Limited
// All rights reserved
//
// example using built-in TCP/IP stack and TUN/TAP interface
#include <sys/socket.h>
#ifndef __OpenBSD__
#include <linux/if.h>
#include <linux/if_tun.h>
#else
#include <net/if.h>
#include <net/if_tun.h>
#include <net/if_types.h>
#endif
#include <sys/ioctl.h>
#include "mongoose.h"
#include "net.h"
static int s_signo;
void signal_handler(int signo) {
s_signo = signo;
}
static size_t tap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
ssize_t res = write(*(int *) ifp->driver_data, buf, len);
if (res < 0) {
MG_ERROR(("tap_tx failed: %d", errno));
return 0;
}
return (size_t) res;
}
static bool tap_up(struct mg_tcpip_if *ifp) {
return ifp->driver_data ? true : false;
}
static size_t tap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
ssize_t received = read(*(int *) ifp->driver_data, buf, len);
usleep(1); // This is to avoid 100% CPU
if (received < 0) return 0;
return (size_t) received;
}
int main(int argc, char *argv[]) {
const char *iface = "tap0"; // Network iface
const char *mac = "02:00:01:02:03:77"; // MAC address
// 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], "-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
#ifndef __OpenBSD__
const char *tuntap_device = "/dev/net/tun";
#else
const char *tuntap_device = "/dev/tap0";
#endif
int fd = open(tuntap_device, O_RDWR);
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
#ifndef __OpenBSD__
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
MG_ERROR(("Failed to setup TAP interface: %s", ifr.ifr_name));
abort(); // return EXIT_FAILURE;
}
#else
ifr.ifr_flags = (short) (IFF_UP | IFF_BROADCAST | IFF_MULTICAST);
if (ioctl(fd, TUNSIFMODE, (void *) &ifr) < 0) {
MG_ERROR(("Failed to setup TAP interface: %s", ifr.ifr_name));
abort(); // return EXIT_FAILURE;
}
#endif
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode
MG_INFO(("Opened TAP interface: %s", iface));
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
struct mg_mgr mgr; // Event manager
mg_mgr_init(&mgr); // Initialise event manager
struct mg_tcpip_driver driver = {.tx = tap_tx, .up = tap_up, .rx = tap_rx};
struct mg_tcpip_if mif = {.driver = &driver, .driver_data = &fd};
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"));
// Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION));
MG_INFO(("Listening on : %s", HTTP_URL));
MG_INFO(("Listening on : %s", HTTPS_URL));
web_init(&mgr);
while (s_signo == 0) mg_mgr_poll(&mgr, 100); // Infinite event loop
mg_mgr_free(&mgr);
close(fd);
printf("Exiting on signal %d\n", s_signo);
return 0;
}
+1
View File
@@ -0,0 +1 @@
../../../mongoose.c
+1
View File
@@ -0,0 +1 @@
../../../mongoose.h
+1
View File
@@ -0,0 +1 @@
../../../examples/device-dashboard/net.c
+1
View File
@@ -0,0 +1 @@
../../../examples/device-dashboard/net.h
+1
View File
@@ -0,0 +1 @@
../../../examples/device-dashboard/packed_fs.c