You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式系统原始以太网中UDP/TCP传输层协议同时识别问题求助

Solution for Routing Inbound Ethernet Frames to UDP/TCP Handlers in Embedded Systems

Hey there, let's break down how to fix this protocol routing issue—this is a classic challenge when building raw Ethernet/IP stacks from scratch, so you're definitely on the right track with your ARP, UDP, and TCP implementations!

Core Root Cause

The key missing piece here is layered protocol parsing: Ethernet frames carry different upper-layer protocols, and you need to use standard header fields to identify which handler to send the frame to, instead of guessing or forwarding to all handlers.

Step-by-Step Solution

1. Parse the Ethernet Frame's EtherType Field

Every Ethernet frame starts with a 14-byte header, and the last 2 bytes (offset 12-13) are the EtherType field. This tells you what protocol is encapsulated in the frame:

  • 0x0806: ARP (Address Resolution Protocol)
  • 0x0800: IPv4 (Internet Protocol Version 4)

First, extract this field, convert it from network byte order to host byte order (critical for little-endian embedded systems), and route ARP frames directly to your ARP handler.

2. Parse the IPv4 Header's Protocol Field

For IPv4 frames (EtherType 0x0800), you need to look into the IPv4 header (starts right after the Ethernet header) to find the protocol number (10th byte, offset 9 in the IPv4 header):

  • 6: TCP (Transmission Control Protocol)
  • 17: UDP (User Datagram Protocol)

This field tells you exactly whether the IPv4 packet is carrying TCP or UDP payload. Route the packet to the corresponding handler based on this value.

3. Implement a Routing Logic with Strict Branching

By using layered checks (EtherType → IPv4 Protocol), each incoming frame will only be sent to one handler—eliminating the risk of duplicate processing and data corruption.

Example Pseudocode (Embedded C Style)

#include <stdint.h>
#include <arpa/inet.h> // For ntohs()

// Assume these handlers are already implemented
void handle_arp_frame(uint8_t *frame, size_t frame_len);
void handle_tcp_frame(uint8_t *ip_payload, size_t payload_len);
void handle_udp_frame(uint8_t *ip_payload, size_t payload_len);

void process_incoming_ethernet_frame(uint8_t *frame, size_t frame_len) {
    // Basic sanity check: frame must be at least Ethernet header size (14 bytes)
    if (frame_len < 14) {
        // Drop invalid frame
        return;
    }

    // Extract and convert EtherType from network byte order to host byte order
    uint16_t ether_type = ntohs(*(uint16_t *)(frame + 12));

    switch (ether_type) {
        case 0x0806:
            // ARP frame: send to ARP handler
            handle_arp_frame(frame, frame_len);
            break;
        case 0x0800: {
            // IPv4 frame: check if frame is long enough for basic IPv4 header (20 bytes)
            if (frame_len < 14 + 20) {
                return;
            }

            // Extract IPv4 protocol number (10th byte of IPv4 header)
            uint8_t ip_protocol = frame[14 + 9];

            // Skip Ethernet header when passing to IP-based handlers
            uint8_t *ip_frame = frame + 14;
            size_t ip_frame_len = frame_len - 14;

            switch (ip_protocol) {
                case 6:
                    // TCP packet: send to TCP handler
                    handle_tcp_frame(ip_frame, ip_frame_len);
                    break;
                case 17:
                    // UDP packet: send to UDP handler
                    handle_udp_frame(ip_frame, ip_frame_len);
                    break;
                default:
                    // Unknown protocol: drop or log for debugging
                    break;
            }
            break;
        }
        default:
            // Unknown EtherType: drop or log
            break;
    }
}

Key Embedded-Specific Notes

  • Byte Order: Always use ntohs()/ntohl() to convert network byte-order fields (like EtherType, IP addresses, ports) to host byte order—most embedded systems use little-endian, while network protocols use big-endian.
  • Memory Safety: Add bounds checks for frame lengths to avoid buffer overflows (critical in resource-constrained embedded systems).
  • Validation: For production code, add checks for IPv4 header validity (version number, header length, checksum) to avoid processing corrupted packets.

Once you integrate this logic into your stack, each frame will be routed to the correct handler cleanly, with no overlapping processing or data corruption issues.

内容的提问来源于stack exchange,提问作者Jakub Jakubowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:13:47