news 2026/4/15 15:58:58

Ethernet over UART

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ethernet over UART

TUN vs TAP (one sentence) :

  • TUN = IP-level interface → only L3 packets (IPv4/IPv6)

  • TAP = Ethernet-level interface → full L2 frames (Ethernet header, ARP, etc.)

So TAP is exactly what you want for sending raw Ethernet frames over your own UART transport.

#define _GNU_SOURCE #include <stdio.h> #include <stdint.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/if_tun.h> #include <linux/if.h> #include <errno.h> #define MAX_FRAME 2000 //----------------------------------------------- // TAP allocation //----------------------------------------------- int tap_alloc (char *devname) { struct ifreq ifr; int fd = open("/dev/net/tun", O_RDWR); if (fd < 0) { perror("open /dev/net/tun"); exit(1); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; // TAP = Ethernet frames, no extra header if (*devname) strncpy(ifr.ifr_name, devname, IFNAMSIZ); if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { perror("TUNSETIFF"); exit(1); } strcpy(devname, ifr.ifr_name); return fd; } //----------------------------------------------- // UART open + config //----------------------------------------------- int uart_open (const char *dev) { int fd = open(dev, O_RDWR | O_NOCTTY); if (fd < 0) { perror("open uart"); exit(1); } struct termios tty; tcgetattr(fd, &tty); cfmakeraw(&tty); cfsetspeed(&tty, B115200); tty.c_cflag |= (CLOCAL | CREAD); tcsetattr(fd, TCSANOW, &tty); return fd; } //----------------------------------------------- // Very simple framing: // [0xAA][len_hi][len_lo][FRAME...] //----------------------------------------------- int uart_send_frame (int uart_fd, uint8_t *data, int len) { uint8_t hdr[3]; hdr[0] = 0xAA; hdr[1] = (len >> 8) & 0xFF; hdr[2] = (len) & 0xFF; write(uart_fd, hdr, 3); write(uart_fd, data, len); return 0; } int uart_recv_frame (int uart_fd, uint8_t *buf, int max) { uint8_t hdr[3]; int n; // Wait for sync byte 0xAA do { n = read(uart_fd, hdr, 1); if (n <= 0) return -1; } while (hdr[0] != 0xAA); // Read length if (read(uart_fd, hdr + 1, 2) != 2) return -1; int len = (hdr[1] << 8) | hdr[2]; if (len > max) return -1; // Read frame n = read(uart_fd, buf, len); if (n != len) return -1; return len; } //----------------------------------------------- // Main loop //----------------------------------------------- int main (int argc, char *argv[]) { if (argc != 3) { printf("Usage: %s <tapname> <uartdev>\n", argv[0]); printf("Example: sudo %s tap0 /dev/ttyS1\n", argv[0]); return 1; } char tapname[IFNAMSIZ]; strncpy(tapname, argv[1], IFNAMSIZ); int tap_fd = tap_alloc(tapname); int uart_fd = uart_open(argv[2]); printf("TAP interface created: %s\n", tapname); printf("UART device opened: %s\n", argv[2]); uint8_t buf[MAX_FRAME]; // Set TAP interface up (requires shell command) printf("\nRun this in another terminal:\n"); printf(" sudo ip link set %s up\n", tapname); printf(" sudo ip addr add 192.168.10.1/24 dev %s\n\n", tapname); while (1) { fd_set rfds; FD_ZERO(&rfds); FD_SET(tap_fd, &rfds); FD_SET(uart_fd, &rfds); int maxfd = (tap_fd > uart_fd ? tap_fd : uart_fd) + 1; int r = select(maxfd, &rfds, NULL, NULL, NULL); if (r < 0 && errno == EINTR) continue; if (r < 0) { perror("select"); exit(1); } // Ethernet frame from TAP → UART if (FD_ISSET(tap_fd, &rfds)) { int n = read(tap_fd, buf, MAX_FRAME); if (n > 0) { uart_send_frame(uart_fd, buf, n); } } // Frame from UART → TAP if (FD_ISSET(uart_fd, &rfds)) { int n = uart_recv_frame(uart_fd, buf, MAX_FRAME); if (n > 0) { write(tap_fd, buf, n); } } } return 0; }

How to create a virtual serial port in linux:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

# Note the output: "PTY is /dev/pts/2" and "PTY is /dev/pts/3"

How to enable NAT on a interface in Ubuntu:

Assume:

  • Outbound (WAN) interface: eth0

  • Internal/LAN interface(s): eth1, tap0, etc.

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

Ready to go:

Then you need to define a reliable framing protocol running on UART interface that can delimit Ethernet frames.

Use two laptops and do the following test (running two program instances in one laptop and use virtual serial ports to connect each other doesn't work, the TAP interface receives frames and routes to loopback interface):

  1. Laptop A is connected to WIFI and have access to Internet, a TAP interface is also created and uses UART to simulate ethernet.

  2. Laptop B has only TAP network interface and also uses UART to transfer ethernet frames.

  3. Now, laptop A and laptop B can ping each other through UART, but laptop B can't access the WIFI domain and Internetwork.

  4. Config laptop A NAT to support traffic forwarding from TAP interface to WIFI network and finally to Internetwork.

After doing the above steps, laptop B can now successfully pinging www.baidu.com and accessing CSDN web page (though in a very slow speed):

Why doing this?

I saw the need to communicate between MCU systems and Linux systems through secure channels, either we define a protocol for key exchange or we just use TLS protocol.

So I tried this solution using UART to deliver Ethernet frames and create a virtual NIC in Linux to pass Ethernet frames to Linux TCP/IP stack and can also provide frame forwarding so as to let the MCU have access to the Internet.

For the MCU, lwIP or similar TCP/IP stack can be used for this UART based NIC, I personally have tested uIP which pings fine.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/6 1:41:21

Web Scraper零代码网页抓取:5分钟快速上手终极指南

Web Scraper零代码网页抓取&#xff1a;5分钟快速上手终极指南 【免费下载链接】web-scraper-chrome-extension Web data extraction tool implemented as chrome extension 项目地址: https://gitcode.com/gh_mirrors/we/web-scraper-chrome-extension 还在为网页数据采…

作者头像 李华
网站建设 2026/4/11 17:23:22

家具物流抉择建议与注意事项

装修新屋、大量大件家具运输在选择家具物流时&#xff0c;超过40%的用户曾遭遇临时加价&#xff0c;家具运输的平均货损率达5%&#xff0c;而理赔过程往往漫长且繁琐。此外&#xff0c;约62%的用户将“性价比”视为首要标准&#xff0c;但低价背后常隐藏诸多额外费用。为了帮助…

作者头像 李华
网站建设 2026/4/8 6:54:31

28、Linux 文件系统特殊权限位与网络连接管理

Linux 文件系统特殊权限位与网络连接管理 1. Linux 文件系统特殊权限位 Linux 的目录树依据文件功能将文件放置在特定位置,了解这些文件的存放位置有助于定位它们。在探索 Linux 目录树时,会遇到一些需要特别关注的文件类型,这些特殊情况包括“粘滞位”、隐藏文件、获取目录…

作者头像 李华
网站建设 2026/4/13 23:08:04

Zephyr RTOS USB复合设备终极指南:嵌入式系统接口优化深度解析

Zephyr RTOS USB复合设备终极指南&#xff1a;嵌入式系统接口优化深度解析 【免费下载链接】zephyr Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures. 项目地址: https:…

作者头像 李华
网站建设 2026/4/10 21:29:14

换能器分析仪 LCR电桥阻抗分析仪 射频阻抗分析仪

换能器分析仪 LCR电桥阻抗分析仪 射频阻抗分析仪单个电子元件阻抗分析的典型配置包括&#xff1a;阻抗分析仪&#xff1a;仪器的导线连接到测试夹具上&#xff0c;测试夹具应适合 DUT 特定类型的特性。测试夹具&#xff1a;文本夹具经过精心设计&#xff0c;可固定被测试装置&a…

作者头像 李华
网站建设 2026/4/7 9:11:33

0基础转行网络安全必须要知道这些!专治迷茫还不知道方向!

很多朋友问我怎么入行/转行网络安全&#xff0c;今天就带大家来了解一下怎么转行网络安全&#xff01; 一、 打好坚实的基础&#xff08;必备&#xff09; 计算机基础&#xff1a; Linux&#xff1a; 极其重要&#xff01; 熟练掌握常用命令、文件系统结构、用户/组/权限管理、…

作者头像 李华