基于LwIP:点对点无线电台桥接LAN与Web服务器的流量分流技术问询
Great question! Building a point-to-point radio bridge that also hosts a local web server requires careful traffic shunting to separate inter-LAN bridge traffic from local management requests. Let’s break down how to implement this, including key C functions and code integration points:
1. Traffic Flow Overview
First, clarify the two distinct traffic paths your radio needs to handle:
- Inter-LAN Bridge Traffic: All Ethernet frames intended for devices on the remote LAN (not targeted at the radio itself) must be encapsulated and transmitted to the peer radio.
- Local Web Server Traffic: Packets addressed to the radio’s own MAC/IP need to be intercepted and routed to the local web server process instead of being forwarded to the peer.
2. Core Traffic Shunting Mechanisms
You’ll need to inspect incoming frames at the network interface layer and route them based on their destination:
- Layer 2 MAC Check: If the Ethernet frame’s destination MAC matches the radio’s own interface MAC, it’s a local request.
- Layer 3 IP Check: For IP packets, verify if the destination IP matches the radio’s configured management IP (even if the MAC is broadcast, this ensures web traffic reaches the server).
3. C Function & Code Integration Points
Assuming you’re working with a Linux-based embedded system (common for radio devices) or a custom network stack, here are the key areas to focus on:
a. Raw Socket Frame Capture
Use raw sockets to intercept all Ethernet frames on the LAN interface. Relevant functions:
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)): Creates a raw socket that captures every Ethernet frame on the interface.recvfrom(): Reads frames from the raw socket for inspection.sendto(): Sends frames either to the radio transmission module (for bridge traffic) or injects them back into the local network stack (for web server traffic).
b. Netfilter Hook (Linux-Specific)
For Linux systems, leverage the Netfilter API to filter and redirect local traffic without raw socket overhead:
nf_register_hook(): Registers a custom hook function in the network stack’s packet processing pipeline.- Your hook function will check if the packet’s destination IP matches the radio’s management IP. If yes, mark it for local delivery; else, forward it to the radio link.
c. Custom Network Stack Hook
If using a proprietary embedded network stack, insert a check in the frame reception path:
- After receiving a frame from the LAN interface, add logic to compare the destination MAC/IP against the radio’s own.
- If it’s a local request, pass the frame to the TCP/IP stack’s upper layers (where the web server listens on port 80/443).
- If not, forward the frame to your radio’s transmission module (after adding any radio-specific encapsulation headers).
d. Web Server Integration
Implement a lightweight web server (or use a minimal library like uHTTPd) with standard socket functions:
socket(AF_INET, SOCK_STREAM, 0): Creates a TCP socket for HTTP connections.bind(): Binds the socket to the radio’s management IP and port 80/443.listen()&accept(): Handles incoming web requests from connected LAN devices.
4. Step-by-Step Implementation
- Initialize Frame Capture: Set up a raw socket or Netfilter hook to intercept all Ethernet frames from the LAN interface.
- Frame Inspection: For each received frame:
- Parse the Ethernet header to check the destination MAC.
- If the MAC is local, parse the IP header (if applicable) to confirm the destination IP matches the radio’s management IP.
- Route local requests to the web server; forward all other frames to the peer radio (after encapsulation).
- Peer Radio Handling: On the remote radio, decapsulate received frames and send them to the local LAN interface.
- Web Server Setup: Configure the web server to listen on the radio’s management IP and handle device management endpoints.
5. Example Snippet (Raw Socket Frame Inspection)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/ethernet.h> #include <arpa/inet.h> // Replace with your radio's actual MAC and IP #define RADIO_MAC "\x00\x1A\x2B\x3C\x4D\x5E" #define RADIO_IP "192.168.0.10" int main() { int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) { perror("Failed to create raw socket"); exit(EXIT_FAILURE); } unsigned char buffer[ETH_FRAME_LEN]; while (1) { ssize_t frame_len = recvfrom(sock, buffer, ETH_FRAME_LEN, 0, NULL, NULL); if (frame_len < 0) { perror("recvfrom failed"); continue; } struct ether_header* eth_hdr = (struct ether_header*)buffer; // Check if frame is addressed to this radio if (memcmp(eth_hdr->ether_dhost, RADIO_MAC, ETH_ALEN) == 0) { // Check if it's an IP packet if (ntohs(eth_hdr->ether_type) == ETH_P_IP) { struct iphdr* ip_hdr = (struct iphdr*)(buffer + ETH_HLEN); char dst_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ip_hdr->daddr, dst_ip, INET_ADDRSTRLEN); if (strcmp(dst_ip, RADIO_IP) == 0) { printf("Received web server request\n"); // Inject frame into local TCP stack or pass to web server process } } } else { printf("Forwarding frame to peer radio\n"); // Call your radio transmission function here (add encapsulation if needed) } } close(sock); return 0; }
Key Notes
- Performance: Use BPF (Berkeley Packet Filter) with raw sockets to filter out non-relevant frames early and reduce CPU load.
- Encapsulation: Add a radio-specific header to bridge frames before transmission, and decapsulate them on the peer radio.
- Security: Secure your web server with basic authentication or HTTPS to prevent unauthorized device access.
内容的提问来源于stack exchange,提问作者Kashyap Gada

